index.vue 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449
  1. <template>
  2. <view class="luckyDraw">
  3. <image src="../../static/backImg.png" class="back" mode="widthFix"></image>
  4. <view class="luckyDrawContent">
  5. <!-- 个人信息模块 -->
  6. <view class="luckyDrawTop">
  7. <view class="left">
  8. <view class="avatarView" @click="startAni(3)">
  9. <!-- <open-data type="userAvatarUrl" class="avatar"></open-data> -->
  10. <image src="../../static/avatar.png" mode="widthFix"></image>
  11. </view>
  12. <view class="userInfo">
  13. <view class="account" v-if="mpName">{{mpName}}</view>
  14. <view class="ID" v-if="mpData.mpAppId">
  15. <text>书币:{{balanceCount}}</text>
  16. <navigator :url="`../extractBookCurr/extractBookCurr?mpAppId=${mpData.mpAppId}&mpOpenId=${mpData.mpOpenId}`" class="extract" hover-class="none">提取</navigator>
  17. </view>
  18. <view class="ID" v-else>ID:{{userId}}</view>
  19. </view>
  20. </view>
  21. <navigator :url="'../checkInRecord/checkInRecord' + getSerialize({...mpData, openId})" class="right" hover-class="none">
  22. <text>中奖记录</text>
  23. </navigator>
  24. </view>
  25. <!-- 滚动通知 -->
  26. <view class="notice">
  27. <image src="../../static/horn.png" class="horn" mode="widthFix"></image>
  28. <view class="txts">
  29. <u-notice-bar mode="vertical" :volume-icon="false" color="#FFFFFF" type="none" :list="list"></u-notice-bar>
  30. </view>
  31. </view>
  32. <!-- 去抽奖路口 -->
  33. <view class="qLuckDraw" @click="jumpSign">
  34. <image src="../../static/redEnv.png" mode="widthFix"></image>
  35. </view>
  36. <!-- 大转盘 -->
  37. <view class="turntable">
  38. <view class="decorate">
  39. <image src="../../static/decorate.png" class="decorateBack" mode="widthFix"></image>
  40. <image src="../../static/chassis.png" class="decorateChassis" mode="widthFix"></image>
  41. </view>
  42. <view class="turntableContent">
  43. <view class="al">
  44. <almost-lottery
  45. :canvasId="canvasConfig.canvasId"
  46. :canvasWidth="canvasConfig.width"
  47. :canvasHeight="canvasConfig.height"
  48. :outerWidth="canvasConfig.outerWidth"
  49. :outerHeight="canvasConfig.outerHeight"
  50. :colors="canvasConfig.colors"
  51. :ringCount="8"
  52. :duration="5"
  53. :prizeList="prizeList"
  54. :prizeIndex="prizeIndex"
  55. @reset-index="prizeIndex = -1"
  56. @draw-start="handleDrawStart"
  57. @draw-end="handleDrawEnd"
  58. @finish="handleDrawFinish"
  59. v-if="prizeList.length"
  60. />
  61. </view>
  62. <view class="bottom">
  63. <view class="cont">今日剩余抽奖次数:<text>{{freeNum}}</text></view>
  64. </view>
  65. </view>
  66. </view>
  67. <view style="margin: 0 30rpx;" v-if="adConfig.bannerAd">
  68. <ad-view :unitId="adConfig.bannerAd" adIntervals="200"></ad-view>
  69. </view>
  70. <!-- 我的奖品 -->
  71. <view class="myPrize">
  72. <view class="title">我的奖品</view>
  73. <view class="chips">
  74. <view class="chip" v-for="(item, index) in prizeCountDtoList" :key="index">
  75. <image src="../../static/iPhone12Chip.png" mode="widthFix" v-if="item.prizeType === 3"></image>
  76. <image src="../../static/vipChip.png" mode="widthFix" v-else></image>
  77. <view class="text">{{item.prizeName}}</view>
  78. <view class="progress">
  79. <view class="value" :style="{width: item.prizeCount && item.prizeCount > 0 ? (item.prizeCount/item.maxCount*100) + '%' : '0'}"></view>
  80. <text>{{item.prizeCount}}/{{item.maxCount}}</text>
  81. </view>
  82. </view>
  83. </view>
  84. <view class="clearTime" v-if="clearTime">碎片有效期至:{{clearTime | getTimerFilter}} </view>
  85. </view>
  86. <!-- 活动规则模块 -->
  87. <view class="activityRules">
  88. <view class="top" @click="activityRulesHandle">
  89. <text>活动规则</text>
  90. <image :src="!activityRules ? '../../static/unfold.png' : '../../static/retract.png'" mode="widthFix"></image>
  91. </view>
  92. <view class="bottom" v-if="activityRules">
  93. <view>1、每个用户账户每天最多有10次抽奖机会,每天0点刷新。</view>
  94. <view>2、每天前2次可直接领取抽奖奖品,其他8次抽奖机会需要通过观看激励视频来获得。</view>
  95. <view>3、用户必须在对应公众号内登陆抽奖,否则书币将无法顺利领取。</view>
  96. <view>4、书币及7天书城VIP会员抽中后自动发放至书城账号,可在中奖记录中查看,或进入书城的“个人中心-充值记录-赠送”查看。</view>
  97. <view>5、用户可以通过完成本产品抽奖获得碎片,碎片种类由系统随机发放,兑换手机需集满50个碎片, 兑换书城VIP需集满30个碎片。碎片累计有效期为7天,在碎片超出有效期后或用户成功兑换奖品后,此前已获得的该奖品碎片都将清零。</view>
  98. <view>6、实物奖品请联系公众号内客服领取,实物奖品颜色随机寄送,以中奖用户收到的实物为准。</view>
  99. <view>7、若发现用户恶意违规行为,开发者有权取消其获奖资格。</view>
  100. <view>8、本活动解释权由开发者所有,有任何疑问请联系公众号内客服。</view>
  101. </view>
  102. </view>
  103. <!-- 弹窗 -->
  104. <view class="popup" v-if="popupShow">
  105. <view class="popupContent">
  106. <view class="content">
  107. <image src="../../static/popupBack.png"></image>
  108. <view class="textCon">
  109. <text class="ts">恭喜您获得</text> </br>
  110. <text class="reward ts">{{luckyDay.name}}</text> </br>
  111. <image src="../../static/doubleBt.png" class="doubleBt" mode="widthFix" :style="{transform: `scale(${scale})`}" @click="lookVideo"></image> </br>
  112. <text class="bt" @click="receiveGold(false)">不了,单倍领取</text>
  113. </view>
  114. </view>
  115. <image src="../../static/close.png" class="close" mode="widthFix" @click="closeHandle"></image>
  116. </view>
  117. </view>
  118. <!-- 弹窗VIP -->
  119. <view class="popupVIP popup" v-if="popupVIPShow">
  120. <view class="popupContent" style="width: 524rpx;">
  121. <view class="content">
  122. <image src="../../static/vipBack.png"></image>
  123. <view class="textCon" style="display: flex; align-items: flex-end;">
  124. <view class="againLuckDrawBt btVip" @click="againLuckDraw('vip');startAni(2)" :style="{transform: `scale(${scale})`}">再次抽奖</view>
  125. </view>
  126. </view>
  127. <image src="../../static/close.png" class="close" mode="widthFix" @click="popupVIPShow = false;startAni(2); showCpAd()"></image>
  128. </view>
  129. </view>
  130. <!-- 弹窗12 -->
  131. <view class="popup12 popup" v-if="popup12Show">
  132. <view class="popupContent" style="width: 702rpx;">
  133. <view class="content">
  134. <image src="../../static/12Back.png" style="height: 722rpx;"></image>
  135. <view class="textCon" style="display: flex; align-items: flex-end;">
  136. <view class="againLuckDrawBt" @click="againLuckDraw('12'); startAni(3)" :style="{transform: `scale(${scale})`, marginBottom: 0}">再次抽奖</view>
  137. </view>
  138. </view>
  139. <image src="../../static/close.png" class="close" mode="widthFix" @click="popup12Show = false; startAni(3); showCpAd()"></image>
  140. </view>
  141. </view>
  142. <!-- 弹窗金币 -->
  143. <view class="popup12 popup" v-if="popupGoldShow">
  144. <view class="popupContent" style="width: 636rpx;">
  145. <view class="content">
  146. <image src="../../static/goldBack.png" style="height: 790rpx;"></image>
  147. <view class="textCon" style="display: flex; align-items: center; flex-direction: column; justify-content: flex-end;">
  148. <text class="goldText">恭喜您获得</text> </br>
  149. <text class="goldText" style="margin-bottom: 48rpx;">{{luckyDay.name}}</text>
  150. <view class="againLuckDrawBt btGold" @click="againLuckDraw('gold'); startGold(false)" :style="{transform: `translateX(12rpx) scale(${scale})`}">再次抽奖</view>
  151. </view>
  152. </view>
  153. <image src="../../static/close.png" class="close" mode="widthFix" @click="popupGoldShow = false; startGold(false); showCpAd()"></image>
  154. </view>
  155. </view>
  156. <!-- 碎片飞行 -->
  157. <view class="fragmentAni" :animation="animationData">
  158. <image :src="prizeType === 3 ? '../../static/turntable_iPhone12.png' : '../../static/turntable_VIP.png'" mode="widthFix"></image>
  159. </view>
  160. <!-- 金币飞行组 -->
  161. <view class="fragmentGold" :animation="animationDatas[index]" v-for="(item, index) in goldData" :key="index" :style="{top: item.top, left: item.left}">
  162. <image src="../../static/turntable_gold.png" mode="widthFix"></image>
  163. </view>
  164. <!-- 弹窗提示 -->
  165. <view class="receiveTs" :animation="animationDataTs">
  166. {{tsTitle}}
  167. </view>
  168. <!-- 格子广告 -->
  169. <view class="singleLattice" v-if="adConfig.singleLatticeAd">
  170. <ad-custom-view :unit-id="adConfig.singleLatticeAd" adIntervals="200"></ad-custom-view>
  171. </view>
  172. </view>
  173. </view>
  174. </template>
  175. <script>
  176. let timer = null, powerOnTimer = null, adTimer = null, lqTimer = null;
  177. import AlmostLottery from '@/uni_modules/almost-lottery/components/almost-lottery/almost-lottery.vue'
  178. import { config, getHome, getOpenId, getBanner, setDrawGain, getPond, setReceive, getVersion, getBalance } from '@/api/api.js'
  179. import { clearCacheFile } from '@/uni_modules/almost-lottery/utils/almost-utils.js'
  180. import { bannerAd, urgeVideoAd, insertScreenAd, singleLatticeAd } from '@/utils/ad_config.js'
  181. import adView from '@/components/ad-view/ad-view.vue'
  182. import adCustomView from '@/components/ad-custom-view/ad-custom-view.vue'
  183. const systemInfo = uni.getSystemInfoSync()
  184. export default {
  185. components: {
  186. AlmostLottery,
  187. adView,
  188. adCustomView
  189. },
  190. data() {
  191. return {
  192. title: 'Hello',
  193. adConfig: {
  194. bannerAd,
  195. singleLatticeAd
  196. },
  197. list: [
  198. '恭喜用户 “9016” 成功提现 2000书币',
  199. '恭喜用户 “9017” 成功提现 10书币',
  200. '恭喜用户 “9018” 成功提现 20书币',
  201. '恭喜用户 “9019” 成功提现 100书币'
  202. ],
  203. // canvas id、宽、高
  204. canvasConfig: {
  205. canvasId: 'almostLotteryCanvas',
  206. width: 280,
  207. height: 280,
  208. outerWidth: 305,
  209. outerHeight: 305,
  210. colors: [
  211. '#FEE3C6',
  212. '#FFFFFF'
  213. ]
  214. },
  215. // 以下是奖品配置数据
  216. // 奖品数据
  217. prizeList: [],
  218. // 中奖下标
  219. prizeIndex: -1,
  220. // 是否正在抽奖中,避免重复触发
  221. prizeing: false,
  222. // 以下为业务需求有关示例数据
  223. // 当日免费抽奖次数余额
  224. freeNum: 10,
  225. // 以下是
  226. // 活动规则开关控制
  227. activityRules: false,
  228. // 弹窗控制
  229. popupShow: false,
  230. // 抽到VIP碎片弹窗控制
  231. popupVIPShow: false,
  232. // 抽到12碎片弹窗控制
  233. popup12Show: false,
  234. // 抽到金币弹窗控制
  235. popupGoldShow: false,
  236. openId: '',
  237. mpData: {},
  238. prizeCountDtoList: [], // 碎片列表
  239. mpName: null, // 渠道号
  240. userId: 91874, //
  241. luckyDay: {}, // 中奖信息
  242. doubleKey: "", // 领取key
  243. clearTime: "", // 碎片有效期
  244. scale: 1,
  245. animation: null, // 动画实例
  246. animationData: null, // 动画
  247. animationDatas: [null, null, null, null, null, null, null, null], // 动画组
  248. animationDataTs: null,
  249. prizeType: 3, // 奖品类型
  250. durationMath: 20, // 防止动画每次都一样
  251. durationMath1: 20,
  252. durationMath2: 20,
  253. goldData: [
  254. {top: '404rpx', left: '300rpx'},
  255. {top: '434rpx', left: '240rpx'},
  256. {top: '430rpx', left: '398rpx'},
  257. {top: '448rpx', left: '424rpx'},
  258. {top: '380rpx', left: '412rpx'},
  259. {top: '332rpx', left: '332rpx'},
  260. {top: '356rpx', left: '240rpx'},
  261. {top: '474rpx', left: '294rpx'}
  262. ],
  263. tsTitle: '', //提示信息
  264. remoteVersion: null,
  265. loading: false,
  266. _isLoaded: false,
  267. powerOnCount: 0, // 记录开机秒数
  268. powerOnTimer: new Date().getTime(), // 保存当前进入页面的时间挫
  269. videoType: null, // 1 前面两次看视频翻倍 2 后面8次看视频抽奖
  270. // 本地
  271. weightTotal: 0,
  272. // 权重数组
  273. weightArr: [],
  274. balanceCount: 0,
  275. }
  276. },
  277. computed: {
  278. isApple() {
  279. return uni.getSystemInfoSync().platform === 'ios'
  280. }
  281. },
  282. onLoad(options) {
  283. // 请求奖品数据
  284. this.mpData = options
  285. this.getData()
  286. this.animation = uni.createAnimation({ timingFunction: 'ease' })
  287. getVersion({appId: config.appid}).then(res => {
  288. this.remoteVersion = res.data
  289. })
  290. },
  291. onUnload() {
  292. uni.hideLoading()
  293. timer && clearInterval(timer)
  294. lqTimer && clearInterval(lqTimer)
  295. adTimer && clearTimeout(adTimer)
  296. powerOnTimer && clearInterval(powerOnTimer)
  297. this.interstitialAd.destroy()
  298. },
  299. onHide() {
  300. console.log('页面隐藏')
  301. timer && clearInterval(timer)
  302. lqTimer && clearTimeout(lqTimer)
  303. adTimer && clearTimeout(adTimer)
  304. powerOnTimer && clearInterval(powerOnTimer)
  305. },
  306. onShareAppMessage() {},
  307. filters: {
  308. getTimerFilter(value) { // 获取年月日时分秒
  309. if(!value) return ""
  310. let timestamp = Date.parse(new Date(value))
  311. let date = new Date(timestamp)
  312. let Y = date.getFullYear()
  313. let M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1)
  314. let D = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
  315. let H = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
  316. let minute = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
  317. let S = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
  318. return `${Y}-${M}-${D} ${H}:${minute}:${S}`
  319. }
  320. },
  321. async onPullDownRefresh() {
  322. await this.handleInitCanvas()
  323. await this.getList()
  324. uni.stopPullDownRefresh();
  325. },
  326. onReady() {
  327. if(urgeVideoAd) {
  328. this.createInterstitialAd()
  329. this.powerOnShowAd()
  330. }
  331. },
  332. watch: {
  333. // 监听获奖序号的变动
  334. popupShow(newVal, oldVal) {
  335. this.openAniBt(newVal)
  336. },
  337. popupVIPShow(newVal) {
  338. this.openAniBt(newVal)
  339. },
  340. popup12Show(newVal) {
  341. this.openAniBt(newVal)
  342. },
  343. popupGoldShow(newVal) {
  344. this.openAniBt(newVal)
  345. }
  346. },
  347. methods: {
  348. // 获取金币余额
  349. getBookCurr() {
  350. getBalance({appId: config.appid, mpAppId: this.mpData.mpAppId, mpOpenId: this.mpData.mpOpenId}).then(res => {
  351. this.balanceCount = res.data || 0
  352. })
  353. },
  354. powerOnShowAd() {
  355. // 开机25秒调取弹窗广告 以后没5分钟调取
  356. powerOnTimer = setInterval(() => {
  357. this.powerOnCount += 1
  358. if(this.powerOnCount === 25 || this.powerOnCount % 325 === 0) {
  359. this.showInterstitialAd()
  360. }
  361. }, 1000)
  362. },
  363. // 创建插屏广告 激励视频广告
  364. createInterstitialAd() {
  365. // 创建插屏广告
  366. let interstitialAd = this.interstitialAd = uni.createInterstitialAd({adUnitId: insertScreenAd});
  367. interstitialAd.onLoad(() => {
  368. // 插屏 广告加载成功
  369. console.log("插屏 广告加载成功");
  370. this.loading = false;
  371. });
  372. interstitialAd.onClose(() => {
  373. // 用户点击了关闭或返回键(仅Android有返回键)
  374. console.log("插屏 广告关闭");
  375. });
  376. interstitialAd.onError((err) => {
  377. // 插屏 广告加载失败
  378. console.log("插屏 广告加载失败", err);
  379. this.loading = false;
  380. });
  381. // 广告实例创建成功后默认会执行一次 load,加载广告数据
  382. // 如果界面有 "显示广告" 按钮,需要先禁用掉,防止用户点击,等待广告数据加载成功后在放开
  383. this.loading = true;
  384. // 激励视频广告
  385. this._isLoaded = false
  386. let rewardedVideoAd = this._rewardedVideoAd = uni.createRewardedVideoAd({ adUnitId: urgeVideoAd })
  387. rewardedVideoAd.onLoad(() => {
  388. this._isLoaded = true
  389. console.log('onLoad event')
  390. // 加载激励视频成功
  391. // 当激励视频被关闭时,默认预载下一条数据,加载完成时仍然触发 `onLoad` 事件
  392. })
  393. rewardedVideoAd.onError((err) => {
  394. // 加载激励视频失败
  395. this._isLoaded = false
  396. console.log('onError event', err)
  397. })
  398. rewardedVideoAd.onClose((res) => {
  399. // 用户点击了【关闭广告】按钮
  400. console.log('==============>', res)
  401. if (res && res.isEnded) {
  402. // 正常播放结束
  403. if(this.videoType === 1){ // 看视频翻倍领取
  404. this.receiveGold(true)
  405. } else if (this.videoType === 2) { // 看视频抽奖
  406. if (!this.mpName) { // 首次没有重公众号进入
  407. this.localGetPrizeIndex()
  408. return
  409. }
  410. this.remoteGetPrizeIndex()
  411. }
  412. } else {
  413. // 播放中途退出
  414. this.prizeing = false
  415. this.freeNum++
  416. }
  417. })
  418. },
  419. // 抽完奖显示插屏广告
  420. showCpAd () {
  421. lqTimer && clearTimeout(lqTimer)
  422. setTimeout(() => {
  423. this.showInterstitialAd()
  424. }, 10000)
  425. },
  426. // 显示插屏广告广告
  427. showInterstitialAd() {
  428. // 调用 interstitialAd.show(),如果数据正在加载中不会显示广告,加载成功后才显示
  429. // 在数据没有加载成功时,需要防止用户频繁点击显示广告
  430. if(!insertScreenAd) {
  431. console.log('没有插屏广告')
  432. return
  433. }
  434. if(adTimer) {
  435. clearTimeout(adTimer)
  436. }
  437. let newT = new Date().getTime()
  438. if (((newT / 1000) - (this.powerOnTimer / 1000)) < 15) { // 判断是否开机15秒
  439. adTimer = setTimeout(() => {
  440. if (this.loading == true) {
  441. return
  442. }
  443. this.loading = true;
  444. this.interstitialAd.show().then((res) => {
  445. console.log('插屏广告成功---》', res)
  446. this.loading = false;
  447. }).catch(err => {
  448. console.log('插屏广告错误---》', err)
  449. });
  450. clearTimeout(adTimer)
  451. }, newT - this.powerOnTimer + 1000)
  452. return
  453. }
  454. if (this.loading == true) {
  455. return
  456. }
  457. console.log(11111)
  458. this.loading = true;
  459. this.interstitialAd.show().then((res) => {
  460. console.log('插屏广告成功---》', res)
  461. this.loading = false;
  462. }).catch(err => {
  463. console.log('插屏广告错误---》', err)
  464. });
  465. },
  466. // 显示激励视频广告
  467. showVideoAd(type) {
  468. console.log('显示激励视频广告')
  469. this.videoType = type
  470. if (this._isLoaded) {
  471. uni.showLoading({
  472. title: '正在拉取~~',
  473. })
  474. this._rewardedVideoAd.show().then(()=>{
  475. uni.hideLoading()
  476. console.log('拉取视频then')
  477. }).catch((err) => {
  478. console.log('拉取视频catch', err)
  479. uni.hideLoading()
  480. this._rewardedVideoAd && this._rewardedVideoAd.load().then(() => this._rewardedVideoAd && this._rewardedVideoAd.show()).catch(err => {
  481. uni.showToast({
  482. title: '当前无视频广告',
  483. icon: 'none'
  484. })
  485. })
  486. })
  487. } else {
  488. if(this.videoType === 1){ // 看视频翻倍领取
  489. this.receiveGold(true)
  490. } else if (this.videoType === 2) { // 看视频抽奖
  491. if (!this.mpName) { // 首次没有重公众号进入
  492. this.localGetPrizeIndex()
  493. return
  494. }
  495. this.remoteGetPrizeIndex()
  496. }
  497. }
  498. },
  499. // 是否开始呼吸开关动画
  500. openAniBt(val) {
  501. if(val) {
  502. timer = setInterval(() => {
  503. if(this.scale === 1) {
  504. this.scale = 0.92
  505. }else {
  506. this.scale = 1
  507. }
  508. }, 500)
  509. } else {
  510. timer && clearInterval(timer)
  511. }
  512. },
  513. // 开始动画 12 vip 碎片
  514. startAni(prizeType = 3) {
  515. if(prizeType === 3 || prizeType === 2) {
  516. this.prizeType = prizeType
  517. this.startTsAni(false)
  518. let index = this.prizeCountDtoList.findIndex(item => item.prizeType === prizeType)
  519. let left = index !== -1 ? index === 0 ? '150rpx' : '500rpx' : '500rpx'
  520. this.animation.opacity(1).step({ duration: this.durationMath })
  521. if( this.durationMath >= 50 ) {
  522. this.durationMath = 20
  523. } else {
  524. this.durationMath = this.durationMath + 1
  525. }
  526. // this.animation.top('1300rpx').left(left).step({ duration: 1200, delay: 100 })
  527. this.animation.top('76rpx').left('60rpx').step({ duration: 1000, delay: 100 })
  528. this.animation.opacity(0).top('453rpx').left('331rpx').step({ duration: 0 })
  529. this.animationData = this.animation.export()
  530. }
  531. },
  532. startGold(watchVideos) {
  533. this.prizeType = 1
  534. this.startTsAni(watchVideos)
  535. if( this.durationMath1 >= 50 ) {
  536. this.durationMath1 = 20
  537. } else {
  538. this.durationMath1 = this.durationMath1 + 1
  539. }
  540. this.animationDatas = this.goldData.map(item => {
  541. let animation = uni.createAnimation({ timingFunction: 'ease' })
  542. animation.opacity(1).step({ duration: this.durationMath1 })
  543. animation.top('76rpx').left('60rpx').step({ duration: Math.floor(Math.random() * 101) + 1000, delay: 100 }) //
  544. animation.opacity(0).top(item.top).left(item.left).step({ duration: 0 })
  545. return animation.export()
  546. })
  547. },
  548. startTsAni(watchVideos) {
  549. if(this.prizeType === 1) {
  550. if (watchVideos) {
  551. this.tsTitle = '+' + (this.luckyDay.prizeCount * 2) + this.luckyDay.prizeName
  552. } else {
  553. this.tsTitle = '+' + this.luckyDay.name
  554. }
  555. } else {
  556. this.tsTitle = this.luckyDay.prizeName + '+1'
  557. }
  558. if( this.durationMath2 >= 50 ) {
  559. this.durationMath2 = 20
  560. } else {
  561. this.durationMath2 = this.durationMath2 + 1
  562. }
  563. let animation = uni.createAnimation({ timingFunction: 'ease' })
  564. animation.opacity(1).step({ duration: this.durationMath2 })
  565. animation.top('250rpx').step({ duration: 1000, delay: 100 })
  566. animation.opacity(0).top('450rpx').step({ duration: 0 })
  567. this.animationDataTs = animation.export()
  568. },
  569. // 再次抽奖
  570. againLuckDraw(type) {
  571. if (type === 'vip') {
  572. this.popupVIPShow = false
  573. } else if (type === '12') {
  574. this.popup12Show = false
  575. } else {
  576. this.popupGoldShow = false
  577. }
  578. this.handleDrawStart()
  579. },
  580. // 看视频双倍
  581. lookVideo() {
  582. this.showVideoAd(1)
  583. },
  584. // 领取金币
  585. receiveGold(watchVideos = false) {
  586. if (!this.mpName) { // 首次没有重公众号进入
  587. this.startGold(watchVideos)
  588. this.popupShow = false
  589. return
  590. }
  591. if(this.doubleKey) {
  592. setReceive({appId: config.appid, doubleKey: this.doubleKey, openId: this.openId, watchVideos, ...this.mpData }).then(res => {
  593. this.startGold(watchVideos)
  594. this.popupShow = false
  595. this.doubleKey = ""
  596. this.getList()
  597. if(watchVideos) {
  598. } else {
  599. this.showInterstitialAd()
  600. }
  601. })
  602. }
  603. },
  604. //
  605. getData() {
  606. uni.login({
  607. success: async res => {
  608. if (res.code) {
  609. let openIDInfo = await getOpenId({appId: config.appid, code: res.code})
  610. this.openId = openIDInfo.data
  611. let response = await this.getList()
  612. if(response) {
  613. await this.getPrizeList()
  614. getBanner({appId: config.appid, openId: this.openId, mpAppId: this.mpData.mpAppId}).then(res => {
  615. this.list = res.data
  616. })
  617. } else {
  618. this.prizeList = [
  619. {"prizeId":1,"name":"100书币","stock":100,"prizeCount": 100,"prizeName": '书币',"weight":0.1,"prizeType": 1,"prizeImage":"/static/turntable_golds.png"},
  620. {"prizeId":2,"name":"书城VIP碎片","stock":100,"weight":5,"prizeType": 2,"prizeImage":"/static/turntable_VIP.png"},
  621. {"prizeId":3,"name":"30书币","stock":100,"prizeCount": 30,"prizeName": '书币',"weight":1,"prizeType": 1,"prizeImage":"/static/turntable_gold.png"},
  622. {"prizeId":4,"name":"书城VIP碎片","stock":100,"weight":5,"prizeType": 2,"prizeImage":"/static/turntable_VIP.png"},
  623. {"prizeId":5,"name":"10书币","stock":100,"prizeCount": 10,"prizeName": '书币',"weight":10000,"prizeType": 1,"prizeImage":"/static/turntable_gold.png"},
  624. {"prizeId":6,"name":"50书币","stock":100,"weight":1,"prizeCount": 50,"prizeName": '书币',"prizeType": 1,"prizeImage":"/static/turntable_golds.png"},
  625. {"prizeId":7,"name":"iPhone12碎片","stock":100,"weight":5,"prizeType": 3,"prizeImage":"/static/turntable_iPhone12.png"},
  626. {"prizeId":8,"name":"20书币","stock":100,"prizeCount": 20,"prizeName": '书币',"weight":10000,"prizeType": 1,"prizeImage":"/static/turntable_gold.png"}]
  627. this.prizeCountDtoList = [{"prizeType":2,"prizeCount":0,"prizeName":"书城VIP碎片","maxCount":30},{"prizeType":3,"prizeCount":0,"prizeName":"iPhone12碎片","maxCount":50}]
  628. this.prizeList.forEach((item) => this.weightTotal += item.weight)
  629. this.weightArr = this.prizeList.map((item) => item.weight)
  630. }
  631. }
  632. }
  633. })
  634. },
  635. // 跳转小程序
  636. jumpSign() {
  637. let path = 'pages/index/index'
  638. if(Object.keys(this.mpData).length > 0) {
  639. path = path + this.getSerialize(this.mpData)
  640. }
  641. uni.navigateToMiniProgram({
  642. appId: 'wx162370635292eef2',
  643. path,
  644. success(res) {
  645. // 打开成功
  646. }
  647. })
  648. },
  649. // 对象序列化成 a=1&b=2
  650. getSerialize(value) {
  651. if(Object.prototype.toString.call(value) === "[object Object]") {
  652. let path = ""
  653. for (const key in value) {
  654. if (Object.prototype.hasOwnProperty.call(value, key)) {
  655. const element = value[key];
  656. if (path === "") {
  657. path = `?${key}=${element}`
  658. }else {
  659. path = path + `&${key}=${element}`
  660. }
  661. }
  662. }
  663. return path
  664. } else {
  665. return ""
  666. }
  667. },
  668. // 活动规则
  669. activityRulesHandle() {
  670. this.activityRules = !this.activityRules
  671. },
  672. // 关闭弹窗
  673. closeHandle() {
  674. this.receiveGold(false)
  675. this.popupShow = false
  676. },
  677. // 重新生成
  678. handleInitCanvas() {
  679. clearCacheFile()
  680. this.prizeList = []
  681. this.getPrizeList()
  682. },
  683. // 获取首页信息
  684. async getList() {
  685. let res = await getHome({appId: config.appid, openId: this.openId, userSource: 1, ...this.mpData})
  686. let data = res.data
  687. if(data) {
  688. this.userId = data.userId
  689. this.clearTime = data.clearTime
  690. this.prizeCountDtoList = data.prizeCountDtoList
  691. this.mpName = data.mpName
  692. this.freeNum = data.luckDraw
  693. this.mpData = {
  694. mpAppId: data.mpAppId,
  695. mpName: data.mpName,
  696. mpOpenId: data.mpOpenId
  697. }
  698. this.getBookCurr()
  699. return Promise.resolve(true)
  700. } else {
  701. return Promise.resolve(false)
  702. }
  703. },
  704. // 获取奖品列表
  705. async getPrizeList() {
  706. uni.showLoading({
  707. title: '奖品准备中...'
  708. })
  709. let res = await getPond({appId: config.appid, openId: this.openId, mpAppId: this.mpData.mpAppId})
  710. if(res.data && res.data.length > 0) {
  711. this.prizeList = res.data.map(item => {
  712. let prizeImage = ""
  713. if (item.prizeType === 1) {
  714. prizeImage = '/static/turntable_gold.png'
  715. if(item.prizeCount > 30) {
  716. prizeImage = '/static/turntable_golds.png'
  717. }
  718. return {
  719. prizeId: item.id,
  720. name: item.prizeCount + item.prizeName,
  721. stock: 100,
  722. weight: 10,
  723. prizeImage,
  724. prizeType: item.prizeType,
  725. prizeCount: item.prizeCount,
  726. prizeName: item.prizeName,
  727. }
  728. } else {
  729. prizeImage = '/static/turntable_iPhone12.png'
  730. if(item.prizeType === 2){
  731. prizeImage = '/static/turntable_VIP.png'
  732. }
  733. return {
  734. prizeId: item.id,
  735. name: item.prizeName,
  736. stock: 100,
  737. weight: 10,
  738. prizeImage,
  739. prizeType: item.prizeType,
  740. prizeCount: item.prizeCount,
  741. prizeName: item.prizeName,
  742. }
  743. }
  744. })
  745. }else {
  746. uni.hideLoading()
  747. uni.showToast({
  748. title: '获取奖品失败'
  749. })
  750. }
  751. },
  752. // 本次抽奖开始
  753. handleDrawStart() {
  754. console.log('触发抽奖按钮')
  755. if (systemInfo.system.includes('indows')) {
  756. uni.showToast({
  757. title: '请到手机端抽奖!',
  758. icon: 'error',
  759. duration: 4000
  760. })
  761. return
  762. }
  763. if (!this.mpName) { // 首次没有重公众号进入
  764. if(this.remoteVersion !== config.version) {
  765. uni.showToast({
  766. title: '请先关注公众号~~',
  767. icon: 'none'
  768. })
  769. }
  770. // uni.navigateTo({
  771. // url: '../officialAccount/officialAccount'
  772. // })
  773. // 没有公众号本地抽奖
  774. if (this.freeNum > 0) {
  775. // 更新免费次数或金币余额
  776. if (this.freeNum > 0) {
  777. this.freeNum--
  778. }
  779. if(this.freeNum < 8) {
  780. // 看视频
  781. this.showVideoAd(2)
  782. } else {
  783. // 发起抽奖
  784. this.localGetPrizeIndex()
  785. }
  786. }
  787. return
  788. }
  789. if (this.prizeing) return
  790. this.prizeing = true
  791. // 还有免费数次或者剩余金币足够抽一次
  792. if (this.freeNum > 0) {
  793. // 更新免费次数或金币余额
  794. if (this.freeNum > 0) {
  795. this.freeNum--
  796. }
  797. lqTimer && clearTimeout(lqTimer)
  798. if(this.freeNum < 8) {
  799. // 看视频
  800. this.showVideoAd(2)
  801. } else {
  802. // 发起抽奖
  803. this.remoteGetPrizeIndex()
  804. }
  805. } else {
  806. this.prizeing = false
  807. uni.showToast({
  808. title: '抽奖次数不足',
  809. icon:'none'
  810. })
  811. }
  812. },
  813. // 远程请求接口获取中奖下标
  814. remoteGetPrizeIndex() {
  815. console.warn('###当前处于模拟的请求接口,并返回了中奖信息###')
  816. let { mpName, ...mp } = this.mpData
  817. setDrawGain({appId: config.appid, openId: this.openId, ...mp}).then(res => {
  818. let data = res.data
  819. this.doubleKey = data.doubleKey
  820. let prizeIndex = this.prizeList.findIndex(item => item.prizeId === data.id)
  821. if(prizeIndex !== -1){
  822. this.prizeIndex = prizeIndex
  823. } else {
  824. uni.showToast({
  825. title: '抽奖异常,请稍后重试'
  826. })
  827. }
  828. })
  829. },
  830. // 没有公众号模拟抽奖
  831. // 本地获取中奖下标
  832. localGetPrizeIndex() {
  833. console.warn('###当前处于前端控制中奖概率,安全起见,强烈建议由后端控制###')
  834. // 前端控制概率的情况下,需要拿到最接近随机权重且大于随机权重的值
  835. // 后端控制概率的情况下,通常会直接返回 prizeId
  836. if (!this.weightTotal) {
  837. console.warn('###当前已开启前端控制中奖概率,但是奖品数据列表中的 weight 参数似乎配置不正确###')
  838. return
  839. }
  840. console.log('当前权重总和为 =>', this.weightTotal)
  841. // 注意这里使用了 Math.ceil,如果某个权重的值为 0,则始终无法中奖
  842. let weight = Math.ceil(Math.random() * this.weightTotal)
  843. console.log('本次权重随机数 =>', weight)
  844. let list = [...this.prizeList]
  845. // 生成大于等于随机权重的数组
  846. let tempMaxArrs = []
  847. list.forEach((item) => {
  848. if (item.weight >= weight) {
  849. tempMaxArrs.push(item.weight)
  850. }
  851. })
  852. // 如果大于随机权重的数组有值,先对这个数组排序然后取值
  853. // 反之新建一个临时的包含所有权重的已排序数组,然后取值
  854. let tempMaxArrsLen = tempMaxArrs.length
  855. if (tempMaxArrsLen) {
  856. tempMaxArrs.sort((a, b) => a - b)
  857. // 取值时,如果存在多个值,分两种情况
  858. if (tempMaxArrsLen > 1) {
  859. // 值不相等的情况下取最接近的值,也就是第1个值
  860. let sumWeight = tempMaxArrs.reduce((a, b) => a + b)
  861. if ((sumWeight / tempMaxArrsLen) !== tempMaxArrs[0]) {
  862. this.prizeIndex = this.weightArr.indexOf(tempMaxArrs[0])
  863. } else {
  864. // 值相等时,随机取值,当然这里你可以自己决定是否随机取值
  865. let sameWeight = tempMaxArrs[0]
  866. let sameWeightArr = []
  867. let sameWeightItem = {}
  868. this.weightArr.forEach((item, index) => {
  869. if (item === sameWeight) {
  870. sameWeightArr.push({
  871. weight: item,
  872. index
  873. })
  874. }
  875. })
  876. console.log('sameWeightArr', sameWeightArr)
  877. sameWeightItem = sameWeightArr[Math.floor(Math.random() * sameWeightArr.length)]
  878. console.log('sameWeightItem', sameWeightItem)
  879. this.prizeIndex = sameWeightItem.index
  880. }
  881. } else {
  882. this.prizeIndex = this.weightArr.indexOf(tempMaxArrs[0])
  883. }
  884. } else {
  885. let tempWeightArr = [...this.weightArr]
  886. tempWeightArr.sort((a, b) => a - b)
  887. this.prizeIndex = this.weightArr.indexOf(tempWeightArr[tempWeightArr.length - 1])
  888. }
  889. console.log('本次抽中奖品 =>', this.prizeList[this.prizeIndex].name)
  890. },
  891. // 本次抽奖结束
  892. handleDrawEnd() {
  893. console.log('旋转结束,执行拿到结果后到逻辑')
  894. // 旋转结束后,开始处理拿到结果后的逻辑
  895. this.prizeing = false
  896. let prizeName = this.prizeList[this.prizeIndex].name
  897. let { prizeType, prizeCount } = this.prizeList[this.prizeIndex]
  898. console.log('1111->', this.prizeList[this.prizeIndex])
  899. this.luckyDay = this.prizeList[this.prizeIndex]
  900. if (prizeName === '谢谢参与') {
  901. } else if (prizeName.indexOf('碎片') === -1 && this.freeNum >= 8) {
  902. this.popupShow = true
  903. return
  904. } else {
  905. if (prizeType === 1) {
  906. this.popupGoldShow = true
  907. } else if (prizeType === 2) {
  908. this.popupVIPShow = true
  909. } else if (prizeType === 3) {
  910. this.popup12Show = true
  911. }
  912. }
  913. if (!this.mpName) { // 首次没有重公众号进入
  914. console.log("首次没有重公众号进入")
  915. return
  916. }
  917. this.getList()
  918. },
  919. // 抽奖转盘绘制完成
  920. handleDrawFinish(res) {
  921. console.log('抽奖转盘绘制完成', res)
  922. uni.showToast({
  923. title: res.msg,
  924. duration: 800,
  925. mask: true,
  926. icon: 'none'
  927. })
  928. }
  929. }
  930. }
  931. </script>
  932. <style lang="scss">
  933. page{
  934. background-color: #F0524C;
  935. }
  936. .luckyDraw {
  937. position: relative;
  938. &>.back {
  939. width: 100%;
  940. }
  941. }
  942. .luckyDrawContent {
  943. overflow-x: hidden;
  944. position: absolute;
  945. top: 0;
  946. width: 100%;
  947. padding: 28rpx 0;
  948. margin-bottom: 20rpx;
  949. font-family: PingFangSC-Medium, PingFang SC;
  950. // 用户信息
  951. .luckyDrawTop {
  952. padding: 0 28rpx;
  953. height: 104rpx;
  954. display: flex;
  955. justify-content: space-between;
  956. align-items: center;
  957. .left{
  958. display: flex;
  959. justify-content: flex-start;
  960. align-items: center;
  961. &>.avatarView {
  962. overflow: hidden;
  963. width: 104rpx;
  964. height: 104rpx;
  965. background: #D8D8D8;
  966. border-radius: 10px;
  967. &>image {
  968. width: 100%;
  969. height: 100%;
  970. }
  971. }
  972. .userInfo{
  973. margin-left: 28rpx;
  974. &>view{
  975. font-size: 32rpx;
  976. font-weight: 500;
  977. color: #FFFFFF;
  978. &.account {
  979. display: flex;
  980. justify-content: flex-start;
  981. align-items: center;
  982. &>image {
  983. width: 36rpx;
  984. height: 36rpx;
  985. margin-right: 10rpx;
  986. }
  987. }
  988. &.ID{
  989. margin-top: 4rpx;
  990. display: flex;
  991. justify-content: flex-start;
  992. align-items: center;
  993. }
  994. .extract {
  995. font-size: 30rpx;
  996. margin-left: 30rpx;
  997. background-color: rgb(213, 51, 186);
  998. // background-image: linear-gradient(to right, rgb(66, 83, 216), rgb(213, 51, 186));
  999. padding: 6rpx 16rpx;
  1000. border-radius: 26rpx;
  1001. }
  1002. }
  1003. }
  1004. }
  1005. .right{
  1006. width: 180rpx;
  1007. height: 64rpx;
  1008. background: #BA3A11;
  1009. border-radius: 30rpx;
  1010. display: flex;
  1011. justify-content: center;
  1012. align-items: center;
  1013. &>text {
  1014. font-size: 28rpx;
  1015. font-weight: 400;
  1016. color: #FFFFFF;
  1017. }
  1018. }
  1019. }
  1020. // 滚动通知
  1021. .notice {
  1022. width: 656rpx;
  1023. height: 60rpx;
  1024. background: #C7322C;
  1025. box-shadow: 0px 4rpx 8rpx 0rpx rgba(49, 49, 49, 0.08);
  1026. border-radius: 38rpx;
  1027. opacity: 0.53;
  1028. margin: 38rpx auto 0;
  1029. padding: 0 30rpx;
  1030. box-sizing: border-box;
  1031. display: flex;
  1032. justify-content: flex-start;
  1033. align-items: center;
  1034. .horn {
  1035. width: 28rpx;
  1036. height: 28rpx;
  1037. }
  1038. .txts {
  1039. // flex: 1;
  1040. height: 68rpx;
  1041. width: 600rpx;
  1042. }
  1043. }
  1044. // 去签到
  1045. .qLuckDraw {
  1046. position: absolute;
  1047. top: 180rpx;
  1048. right: 10rpx;
  1049. z-index: 200;
  1050. animation: lanimation 1.3s linear infinite;
  1051. &>image {
  1052. width: 120rpx;
  1053. height: 120rpx;
  1054. }
  1055. }
  1056. // 大转盘
  1057. .turntable {
  1058. position: relative;
  1059. margin-top: 20rpx;
  1060. .decorate{
  1061. position: relative;
  1062. width: 100%;
  1063. height: 880rpx;
  1064. &>image {
  1065. width: 100%;
  1066. position: absolute;
  1067. z-index: 10;
  1068. &.decorateBack {
  1069. top: 0;
  1070. }
  1071. &.decorateChassis{
  1072. position: absolute;
  1073. z-index: 1;
  1074. bottom: 0;
  1075. }
  1076. }
  1077. }
  1078. .turntableContent {
  1079. position: absolute;
  1080. top: 0;
  1081. left: 0;
  1082. right: 0;
  1083. bottom: 0;
  1084. width: 100%;
  1085. height: 100%;
  1086. z-index: 20;
  1087. .al {
  1088. width: 100%;
  1089. height: 804rpx;
  1090. display: flex;
  1091. justify-content: center;
  1092. align-items: center;
  1093. padding-bottom: 40rpx;
  1094. }
  1095. .bottom {
  1096. margin-top: 30rpx;
  1097. text-align: center;
  1098. position: absolute;
  1099. bottom: 25rpx;
  1100. left: 50%;
  1101. transform: translateX(-50%);
  1102. .cont{
  1103. font-size: 28rpx;
  1104. font-weight: 400;
  1105. color: #FFFFFF;
  1106. margin-bottom: 12rpx;
  1107. text {
  1108. font-size: 36rpx;
  1109. color: #FEED22;
  1110. font-weight: 500;
  1111. }
  1112. }
  1113. }
  1114. }
  1115. }
  1116. // 我的奖品
  1117. .myPrize {
  1118. margin: 30rpx 26rpx 0;
  1119. min-height: 352rpx;
  1120. background: #F4E2CA;
  1121. border-radius: 20rpx;
  1122. position: relative;
  1123. padding: 40rpx 0 20rpx;
  1124. .title {
  1125. position: absolute;
  1126. width: 232rpx;
  1127. height: 64rpx;
  1128. background: linear-gradient(180deg, #FFEDD1 0%, #FFC954 100%);
  1129. box-shadow: 0 4rpx 8rpx 0 rgba(0, 0, 0, 0.07);
  1130. border-radius: 0 0 24rpx 24rpx;
  1131. font-size: 32rpx;
  1132. font-weight: 500;
  1133. color: #F33938;
  1134. text-align: center;
  1135. line-height: 64rpx;
  1136. left: 50%;
  1137. transform: translateX(-50%);
  1138. top: -12rpx;
  1139. }
  1140. .chips {
  1141. display: flex;
  1142. justify-content: space-between;
  1143. }
  1144. .chip {
  1145. display: flex;
  1146. flex-direction: column;
  1147. align-items: center;
  1148. width: 50%;
  1149. &>image {
  1150. width: 180rpx;
  1151. height: 140rpx;
  1152. }
  1153. .text{
  1154. font-size: 32rpx;
  1155. font-weight: 500;
  1156. color: #F33938;
  1157. line-height: 44rpx;
  1158. margin-top: 12rpx;
  1159. }
  1160. .progress{
  1161. position: relative;
  1162. width: 200rpx;
  1163. height: 38rpx;
  1164. margin-top: 12rpx;
  1165. background: #FFFCF7;
  1166. border-radius: 26rpx;
  1167. overflow: hidden;
  1168. .value{
  1169. position: absolute;
  1170. width: 1%;
  1171. height: 100%;
  1172. top: 0;
  1173. left: 0;
  1174. z-index: 1;
  1175. background: #F37938;
  1176. }
  1177. &>text {
  1178. font-size: 28rpx;
  1179. font-weight: 500;
  1180. color: #333333;
  1181. position: absolute;
  1182. top: 50%;
  1183. left: 50%;
  1184. transform: translate(-50%, -50%);
  1185. z-index: 2;
  1186. }
  1187. }
  1188. }
  1189. .clearTime{
  1190. margin: 20rpx 0 0;
  1191. text-align: center;
  1192. font-size: 24rpx;
  1193. font-weight: 400;
  1194. color: #F33938;
  1195. }
  1196. }
  1197. // 活动规则
  1198. .activityRules {
  1199. margin: 28rpx 28rpx 0;
  1200. background: #F4E2CA;
  1201. border-radius: 20rpx;
  1202. color: #F33938;
  1203. font-size: 32rpx;
  1204. font-weight: 400;
  1205. &>.top {
  1206. height: 92rpx;
  1207. padding: 0 28rpx;
  1208. box-sizing: border-box;
  1209. display: flex;
  1210. justify-content: space-between;
  1211. align-items: center;
  1212. &>image {
  1213. width: 40rpx;
  1214. }
  1215. }
  1216. &>.bottom {
  1217. padding: 0 28rpx 30rpx;
  1218. box-sizing: border-box;
  1219. &> view {
  1220. margin-bottom: 12rpx;
  1221. font-size: 28rpx;
  1222. font-weight: 400;
  1223. color: #666666;
  1224. line-height: 46rpx;
  1225. }
  1226. }
  1227. }
  1228. // 弹窗
  1229. .popup {
  1230. position: fixed;
  1231. width: 100%;
  1232. height: 100vh;
  1233. background: rgba(0, 0, 0, 0.6);
  1234. top: 0;
  1235. left: 0;
  1236. right: 0;
  1237. bottom: 0;
  1238. z-index: 201;
  1239. .popupContent {
  1240. width: 632rpx;
  1241. position: absolute;
  1242. top: 50%;
  1243. left: 50%;
  1244. transform: translate(-50%, -50%);
  1245. text-align: center;
  1246. &>.content {
  1247. position: relative;
  1248. &>image {
  1249. width: 100%;
  1250. height: 652rpx;
  1251. }
  1252. &>.textCon {
  1253. position: absolute;
  1254. width: 100%;
  1255. top: 0;
  1256. left: 0;
  1257. right: 0;
  1258. bottom: 0;
  1259. padding-top: 192rpx;
  1260. .ts {
  1261. font-size: 60rpx;
  1262. font-weight: 500;
  1263. color: #F5631D;
  1264. }
  1265. .reward {
  1266. height: 60rpx;
  1267. // background: #FFD9A2;
  1268. // border-radius: 31rpx;
  1269. font-size: 50rpx;
  1270. font-weight: 400;
  1271. display: inline-block;
  1272. padding: 0 32rpx;
  1273. color: #F5631E;
  1274. line-height: 60rpx;
  1275. margin-top: 20rpx;
  1276. }
  1277. .goldText {
  1278. font-size: 64rpx;
  1279. font-family: FZZZHONGJW--GB1-0, FZZZHONGJW--GB1;
  1280. font-weight: normal;
  1281. color: #FFFFFF;
  1282. margin-bottom: 25rpx;
  1283. transform: translateX(12rpx);
  1284. }
  1285. .doubleBt {
  1286. width: 456rpx;
  1287. height: 104rpx;
  1288. margin-top: 90rpx;
  1289. transition: all linear .5s;
  1290. }
  1291. .bt {
  1292. margin-top: 14rpx;
  1293. font-size: 32rpx;
  1294. font-weight: 400;
  1295. color: #FCE8CD;
  1296. }
  1297. .againLuckDrawBt {
  1298. width: 424rpx;
  1299. height: 86rpx;
  1300. background: linear-gradient(180deg, #FDDEA5 0%, #FFC981 75%, #FFC983 100%);
  1301. border-radius: 43rpx;
  1302. font-size: 36rpx;
  1303. font-family: SourceHanSansCN-Medium, SourceHanSansCN;
  1304. font-weight: 500;
  1305. color: #854007;
  1306. text-align: center;
  1307. line-height: 86rpx;
  1308. margin: 0 auto 40rpx;
  1309. transition: all linear .5s;
  1310. }
  1311. .btGold {
  1312. width: 448rpx;
  1313. height: 104rpx;
  1314. border-radius: 52rpx;
  1315. line-height: 104rpx;
  1316. font-size: 40rpx;
  1317. box-shadow: 0px 2rpx 8rpx 4rpx rgba(183, 2, 2, 0.37);
  1318. background: linear-gradient(180deg, #FFFCBE 0%, #F87527 100%);
  1319. }
  1320. .btVip {
  1321. width: 426rpx;
  1322. height: 88rpx;
  1323. background: linear-gradient(180deg, #F6E5CA 0%, #EDC388 100%);
  1324. box-shadow: 0rpx 6rpx 16rpx 0rpx rgba(162, 58, 20, 0.77);
  1325. border-radius: 44rpx;
  1326. }
  1327. }
  1328. }
  1329. &>.close {
  1330. width: 54rpx;
  1331. height: 54rpx;
  1332. margin-top: 76rpx;
  1333. }
  1334. }
  1335. }
  1336. // 碎片飞行初始样式 // 金币飞行
  1337. .fragmentAni, .fragmentGold {
  1338. position: absolute;
  1339. z-index: 201;
  1340. top: 453rpx;
  1341. left: 330rpx;
  1342. opacity: 0;
  1343. &>image {
  1344. width: 100rpx;
  1345. height: 100rpx;
  1346. }
  1347. }
  1348. .fragmentGold {
  1349. // opacity: 1;
  1350. }
  1351. .receiveTs {
  1352. position: absolute;
  1353. border: 2rpx solid rgb(242, 69, 69);
  1354. top: 450rpx;
  1355. z-index: 201;
  1356. color: #FFFFFF;
  1357. left: 50%;
  1358. transform: translateX(-50%);
  1359. padding: 10rpx 20rpx;
  1360. background-color: rgba(131, 37, 37, 0.6);
  1361. border-radius: 5rpx;
  1362. opacity: 0;
  1363. }
  1364. .singleLattice {
  1365. position: absolute;
  1366. top: 900rpx;
  1367. right: 8rpx;
  1368. z-index: 201;
  1369. }
  1370. }
  1371. @-webkit-keyframes lanimation {
  1372. 0% {
  1373. transform: rotate(0deg);
  1374. }
  1375. 8% {
  1376. transform: rotate(12deg);
  1377. }
  1378. 16% {
  1379. transform: rotate(0deg);
  1380. }
  1381. 24% {
  1382. transform: rotate(-12deg);
  1383. }
  1384. 32% {
  1385. transform: rotate(0deg);
  1386. }
  1387. 100% {
  1388. transform: rotate(0deg);
  1389. }
  1390. }
  1391. </style>