index.vue 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249
  1. <template>
  2. <!-- 阳光签到书城 -->
  3. <view class="sign">
  4. <image src="../../static/sign_back.png" class="back" mode="widthFix"></image>
  5. <view class="signCenter">
  6. <!-- 个人信息模块 -->
  7. <view class="signTop">
  8. <view class="left">
  9. <view class="avatarView">
  10. <!-- <open-data type="userAvatarUrl" class="avatar"></open-data> -->
  11. <image src="../../static/avatar.png" mode="widthFix"></image>
  12. </view>
  13. <view class="userInfo">
  14. <view class="account">{{signData.mpName}}</view>
  15. <view class="ID" v-if="mpData.mpAppId">
  16. <text>书币:{{balanceCount}}</text>
  17. <navigator :url="`../extractBookCurr/extractBookCurr?mpAppId=${mpData.mpAppId}&mpOpenId=${mpData.mpOpenId}`" class="extract" hover-class="none">提取</navigator>
  18. </view>
  19. <view class="ID" v-else>ID:{{signData.userId}}</view>
  20. </view>
  21. </view>
  22. <navigator :url="'../checkInRecord/checkInRecord?openId=' + openId + '&mpAppId=' + mpData.mpAppId + '&mpOpenId=' + mpData.mpOpenId" class="right">
  23. <image src="../../static/signRecord.png" mode="widthFix"></image>
  24. <text>签到记录</text>
  25. </navigator>
  26. </view>
  27. <view class="signBottom">
  28. <!-- 滚动通知 -->
  29. <view class="notice">
  30. <image src="../../static/horn.png" class="horn" mode="widthFix"></image>
  31. <view class="txts">
  32. <u-notice-bar mode="vertical" :volume-icon="false" color="#FFFFFF" type="none" :list="list"></u-notice-bar>
  33. </view>
  34. </view>
  35. <!-- 签到展示模块 -->
  36. <view class="exhibitionContent" v-if="signData.signInDayVoList.length > 0">
  37. <view class="ts">已连续签到{{signData.sustainDayCount}}天,有{{signData.canSupplement}}次补签机会</view>
  38. <view class="signinExhibition">
  39. <view v-for="(item, index) in signData.signInDayVoList" :key="index" :class="item.signIn ? 'select' : item.canSupplement ? 'repairSign' : ''">
  40. <template v-if="index < 6">
  41. <view class="repair" v-if="item.canSupplement">看视频补签</view>
  42. <text class="day">{{item.dayDescribe}}</text>
  43. <image src="../../static/goldSelect.png" class="goldCoins" style="width: 68rpx;" mode="heightFix" v-if="item.signIn"></image>
  44. <image src="../../static/clickVideo.png" class="goldCoins" mode="heightFix" style="position: relative; z-index: 101;" @click="signatureHandle(2, item)" v-else-if="item.canSupplement"></image>
  45. <image src="../../static/gold.png" class="goldCoins" style="width: 68rpx;" mode="heightFix" v-else></image>
  46. <text class="reward">{{item.bookCoin}}书币</text>
  47. <image src="../../static/signSub.png" class="signSub" mode="widthFix" v-if="item.signIn"></image>
  48. </template>
  49. <template v-else>
  50. <view class="left">
  51. <text class="day">{{item.dayDescribe}}</text>
  52. <text class="reward">{{item.bookCoin}}书币</text>
  53. </view>
  54. <view class="right">
  55. <image src="../../static/giftBag.png" mode="heightFix" v-if="!item.signIn"></image>
  56. <image src="../../static/giftBagSelect.png" mode="heightFix" v-else></image>
  57. </view>
  58. <image src="../../static/signSub.png" class="signSub" mode="widthFix" v-if="item.signIn"></image>
  59. </template>
  60. </view>
  61. </view>
  62. <!-- <navigator url="../officialAccount/officialAccount" class="gignBt" v-if="!signData.mpName" :animation="btAnimationData">签到领书币</navigator> -->
  63. <view class="gignBt" @click="tsAccount" v-if="!signData.mpName" :animation="btAnimationData">签到领书币</view>
  64. <view class="gignBt" @click="signIn" v-else-if="!isSignIn" :animation="btAnimationData">签到领书币</view>
  65. <!-- <view class="already" v-else>今日已签</view> -->
  66. <view class="gignBt" v-else @click="moreGold" :animation="btAnimationData">去抽奖获更多奖励</view>
  67. </view>
  68. <!-- 签到提醒模块 -->
  69. <view class="signRemind">
  70. <text>签到提醒</text>
  71. <view class="remindSwitch">
  72. <view :class="signRemind ? 'open' : 'close'" @click="signRemindHandle(true)">
  73. <view class="select"></view>
  74. <text>开启</text>
  75. </view>
  76. <view :class="!signRemind ? 'open' : 'close'" @click="signRemindHandle(false)">
  77. <view class="select"></view>
  78. <text>关闭</text>
  79. </view>
  80. </view>
  81. </view>
  82. <ad-view :unitId="adConfig.bannerAd" adIntervals="200" v-if="adConfig.bannerAd"></ad-view>
  83. <!-- 活动规则模块 -->
  84. <view class="activityRules">
  85. <view class="top" @click="activityRulesHandle">
  86. <text>活动规则</text>
  87. <image :src="!activityRules ? '../../static/unfold.png' : '../../static/retract.png'" mode="widthFix"></image>
  88. </view>
  89. <view class="bottom" v-if="activityRules">
  90. <view>
  91. 1.用户进入小程序后,点击签到按钮即可完成一次签到。
  92. </view>
  93. <view>
  94. 2.签到获得的书币奖励,在提取之日即时生效。连续签到所得书币奖励在周期内稍有变化,非均等分布。连续7日完成签到的用户在第7日可获得更多的奖励。
  95. </view>
  96. <view>
  97. 3.用户每个周期(7天),至多拥有2次补签机会(连续签到2天拥有1次补签机会,一天内只允许补签一次空缺天数),可通过观看小视频获得,连续未签到2天,签到重新开始。
  98. </view>
  99. <view>
  100. 4.连续签到:自首日完成签到开始累计,连续7天签到为一个周期。签到中断,则重新开始计算。
  101. </view>
  102. <view>
  103. 5.每日同一注册用户仅可参与一次。
  104. </view>
  105. <view>
  106. 6.本活动解释权由开发者所有,有任何疑问请联系公众号内客服。
  107. </view>
  108. </view>
  109. </view>
  110. </view>
  111. <!-- 金币飞行组 -->
  112. <view class="fragmentGold" :animation="animationDatas[index]" v-for="(item, index) in goldData" :key="index" :style="{top: item.top, left: item.left}">
  113. <image src="../../static/gold.png" mode="widthFix"></image>
  114. </view>
  115. <!-- 去抽奖路口 -->
  116. <view class="qLuckDraw" @click="moreGold">
  117. <image src="../../static/1234.gif" mode="widthFix"></image>
  118. </view>
  119. </view>
  120. <!-- -->
  121. <view class="popup" v-if="popupShow">
  122. <view class="popupContent">
  123. <view class="content">
  124. <image src="../../static/popupBack.png"></image>
  125. <view class="textCon">
  126. <text class="ts">签到成功!</text> </br>
  127. <text class="reward">恭喜您获得{{signInDay.bookCoin}}书币</text> </br>
  128. <image src="../../static/doubleBt.png" class="doubleBt" mode="widthFix" :style="{transform: `scale(${scale})`}" @click="lookVideo"></image> </br>
  129. <text class="bt" @click="signInHandle(false)">不了,单倍领取</text>
  130. </view>
  131. </view>
  132. <image src="../../static/close.png" class="close" mode="widthFix" @click="closeHandle"></image>
  133. </view>
  134. </view>
  135. <!-- 弹窗提示 -->
  136. <view class="receiveTs" :animation="animationDataTs">
  137. {{tsTitle}}
  138. </view>
  139. <!-- 格子广告 -->
  140. <!-- <view class="singleLattice">
  141. <ad-custom-view :unit-id="adConfig.singleLatticeAd" adIntervals="200"></ad-custom-view>
  142. </view> -->
  143. </view>
  144. </template>
  145. <script>
  146. let timer = null, btTimer = null, adTimer = null, powerOnTimer = null
  147. import { config, getHome, getOpenId, signInAjax, getTemplateIDs, setMessage, switchUpdate, getBalance } from '@/api/api.js'
  148. import { bannerAd, urgeVideoAd, insertScreenAd, singleLatticeAd } from '@/utils/ad_config.js'
  149. import adView from '@/components/ad-view/ad-view.vue'
  150. import adCustomView from '@/components/ad-custom-view/ad-custom-view.vue'
  151. export default {
  152. components: {
  153. adView,
  154. adCustomView
  155. },
  156. data() {
  157. return {
  158. adConfig: {
  159. bannerAd,
  160. singleLatticeAd
  161. },
  162. list: [
  163. '恭喜用户 “0016” 成功提现 200书币',
  164. '恭喜用户 “1037” 成功提现 10书币',
  165. '恭喜用户 “9128” 成功提现 20书币',
  166. '恭喜用户 “1873” 成功提现 140书币',
  167. '恭喜用户 “9834” 成功提现 200书币',
  168. '恭喜用户 “5623” 成功提现 10书币',
  169. '恭喜用户 “0934” 成功提现 20书币',
  170. '恭喜用户 “7843” 成功提现 60书币',
  171. '恭喜用户 “1344” 成功提现 20书币',
  172. '恭喜用户 “5464” 成功提现 140书币',
  173. '恭喜用户 “0823” 成功提现 200书币',
  174. '恭喜用户 “8910” 成功提现 10书币',
  175. '恭喜用户 “0714” 成功提现 20书币',
  176. ],
  177. signRemind: false, // 是否开启签到提醒
  178. activityRules: false, // 是否展开活动规则
  179. popupShow: false, // 弹窗控制
  180. signData: {
  181. sustainDayCount: 0,
  182. canSupplement: 0,
  183. userId: null,
  184. mpName: null,
  185. signInDayVoList: [
  186. {
  187. signIn: false,
  188. canSupplement: false,
  189. dayDescribe: '第一天',
  190. bookCoin: 10,
  191. isSignIn: true
  192. },
  193. {
  194. signIn: false,
  195. canSupplement: false,
  196. dayDescribe: '第二天',
  197. bookCoin: 20,
  198. isSignIn: false
  199. },
  200. {
  201. signIn: false,
  202. canSupplement: false,
  203. dayDescribe: '第三天',
  204. bookCoin: 30,
  205. isSignIn: false
  206. },
  207. {
  208. signIn: false,
  209. canSupplement: false,
  210. dayDescribe: '第四天',
  211. bookCoin: 40,
  212. isSignIn: false
  213. },
  214. {
  215. signIn: false,
  216. canSupplement: false,
  217. dayDescribe: '第五天',
  218. bookCoin: 50,
  219. isSignIn: false
  220. },
  221. {
  222. signIn: false,
  223. canSupplement: false,
  224. dayDescribe: '第六天',
  225. bookCoin: 60,
  226. isSignIn: false
  227. },
  228. {
  229. signIn: false,
  230. canSupplement: false,
  231. dayDescribe: '第七天',
  232. bookCoin: 70,
  233. isSignIn: false
  234. },
  235. ]
  236. }, // 签到相关信息
  237. openId: '',
  238. mpData: {}, // 公众号相关
  239. isSignIn: true, // 是否已经签到
  240. userId: undefined, // 用户ID
  241. signIdTemID: [], // 签到提醒模板ID
  242. isMainSwitch: true, // 是否关闭了通知按钮
  243. isAlwaysCancel: false, // 是否点击了总是允许取消
  244. signInDay: {}, // 今天签到信息
  245. scale: 1,
  246. btAnimation: null, // 按钮呼吸动画实例
  247. btAnimationData: {}, // 按钮呼吸动画
  248. btScale: 1,
  249. tsTitle: '+100金币', // 提示文字
  250. durationMath1: 20,
  251. durationMath2: 20,
  252. animationDataTs: {}, // 提示文字动画
  253. goldData: [
  254. {top: '532rpx', left: '82rpx'},
  255. {top: '532rpx', left: '252rpx'},
  256. {top: '532rpx', left: '426rpx'},
  257. {top: '532rpx', left: '600rpx'},
  258. {top: '724rpx', left: '82rpx'},
  259. {top: '724rpx', left: '252rpx'},
  260. {top: '724rpx', left: '426rpx'},
  261. {top: '724rpx', left: '484rpx'}
  262. ],
  263. animationDatas: [null, null, null, null, null, null, null, null], // 金币动画组
  264. getIntoCount: 0,
  265. loading: false,
  266. powerOnTimer: new Date().getTime(), // 保存当前进入页面的时间挫
  267. isVideoType: null, // 1 是否是看视频签到 2 是否是补签
  268. repairSignData: null, // 保存补签的信息
  269. powerOnCount: 0, // 记录开机秒数
  270. balanceCount: 0, // 余额
  271. }
  272. },
  273. watch: {
  274. 'signData.signInDayVoList':{
  275. handler(val, oldVal){
  276. if (val.length > 0) {
  277. let signInDay = val.find(item => item.canSign)
  278. if (signInDay) {
  279. this.isSignIn = signInDay.signIn
  280. }
  281. }
  282. },
  283. deep: true
  284. },
  285. popupShow(newVal, oldVal) {
  286. if(newVal) {
  287. timer = setInterval(() => {
  288. if(this.scale === 1) {
  289. this.scale = 0.92
  290. }else {
  291. this.scale = 1
  292. }
  293. }, 500)
  294. } else {
  295. timer && clearInterval(timer)
  296. }
  297. }
  298. },
  299. onLoad(options) {
  300. this.mpData = options
  301. uni.login({
  302. success: async res => {
  303. if (res.code) {
  304. let openIDInfo = await getOpenId({appId: config.appid, code: res.code})
  305. this.openId = openIDInfo.data
  306. this.getList()
  307. }
  308. }
  309. })
  310. },
  311. onShareAppMessage() {},
  312. onReady() {
  313. if (urgeVideoAd) {
  314. this.createInterstitialAd()
  315. this.powerOnShowAd()
  316. }
  317. this.btAnimation = uni.createAnimation({ timingFunction: 'ease' })
  318. this.btBreathAni()
  319. },
  320. onHide() {
  321. console.log('页面隐藏')
  322. timer && clearInterval(timer)
  323. btTimer && clearInterval(btTimer)
  324. adTimer && clearTimeout(adTimer)
  325. powerOnTimer && clearInterval(powerOnTimer)
  326. },
  327. onUnload() {
  328. console.log('onUnload---->')
  329. timer && clearInterval(timer)
  330. btTimer && clearInterval(btTimer)
  331. this.interstitialAd.destroy()
  332. adTimer && clearTimeout(adTimer)
  333. powerOnTimer && clearInterval(powerOnTimer)
  334. },
  335. methods: {
  336. getBookCurr() {
  337. getBalance({appId: config.appid, mpAppId: this.mpData.mpAppId, mpOpenId: this.mpData.mpOpenId}).then(res => {
  338. this.balanceCount = res.data || 0
  339. })
  340. },
  341. // 提示关注公众号
  342. tsAccount() {
  343. uni.showToast({
  344. title: '请先关注公众号~~',
  345. icon: 'none'
  346. })
  347. },
  348. powerOnShowAd() {
  349. // 开机25秒调取弹窗广告 以后没5分钟调取
  350. powerOnTimer = setInterval(() => {
  351. this.powerOnCount += 1
  352. if(this.powerOnCount === 25 || this.powerOnCount % 325 === 0) {
  353. this.showInterstitialAd()
  354. }
  355. }, 1000)
  356. },
  357. // 创建插屏广告 激励视频广告
  358. createInterstitialAd() {
  359. // 创建插屏广告
  360. let interstitialAd = this.interstitialAd = uni.createInterstitialAd({adUnitId: insertScreenAd});
  361. interstitialAd.onLoad(() => {
  362. // 插屏 广告加载成功
  363. console.log("插屏 广告加载成功");
  364. this.loading = false;
  365. });
  366. interstitialAd.onClose(() => {
  367. // 用户点击了关闭或返回键(仅Android有返回键)
  368. console.log("插屏 广告关闭");
  369. });
  370. interstitialAd.onError((err) => {
  371. // 插屏 广告加载失败
  372. console.log("插屏 广告加载失败", err);
  373. this.loading = false;
  374. });
  375. // 广告实例创建成功后默认会执行一次 load,加载广告数据
  376. // 如果界面有 "显示广告" 按钮,需要先禁用掉,防止用户点击,等待广告数据加载成功后在放开
  377. this.loading = true;
  378. // 激励视频广告
  379. this._isLoaded = false
  380. let rewardedVideoAd = this._rewardedVideoAd = uni.createRewardedVideoAd({ adUnitId: urgeVideoAd }) // 仅用于HBuilder基座调试 adpid: '1507000689'
  381. rewardedVideoAd.onLoad(() => {
  382. this._isLoaded = true
  383. console.log('onLoad event')
  384. // 加载激励视频成功
  385. // 当激励视频被关闭时,默认预载下一条数据,加载完成时仍然触发 `onLoad` 事件
  386. })
  387. rewardedVideoAd.onError((err) => {
  388. // 加载激励视频失败
  389. // console.log('onError event', err)
  390. })
  391. rewardedVideoAd.onClose((res) => {
  392. // 用户点击了【关闭广告】按钮
  393. if (res && res.isEnded) {
  394. // 正常播放结束
  395. if(this.isVideoType === 1){ // 看视频签到
  396. this.signInHandle(true)
  397. } else if (this.isVideoType === 2) { // 看视频补签
  398. this.repairSign(this.repairSignData)
  399. }
  400. } else {
  401. // 播放中途退出
  402. }
  403. })
  404. },
  405. // 显示插屏广告广告
  406. showInterstitialAd() {
  407. // 调用 interstitialAd.show(),如果数据正在加载中不会显示广告,加载成功后才显示
  408. // 在数据没有加载成功时,需要防止用户频繁点击显示广告
  409. if(adTimer) {
  410. clearTimeout(adTimer)
  411. }
  412. if (insertScreenAd) {
  413. let newT = new Date().getTime()
  414. if (((newT / 1000) - (this.powerOnTimer / 1000)) < 15) { // 判断是否开机15秒
  415. adTimer = setTimeout(() => {
  416. if (this.loading == true) {
  417. return
  418. }
  419. this.loading = true;
  420. this.interstitialAd.show().then((res) => {
  421. console.log('插屏广告成功---》', res)
  422. this.loading = false;
  423. }).catch(err => {
  424. console.log('插屏广告错误---》', err)
  425. });
  426. clearTimeout(adTimer)
  427. }, newT - this.powerOnTimer + 1000)
  428. return
  429. }
  430. if (this.loading == true) {
  431. return
  432. }
  433. this.loading = true;
  434. this.interstitialAd.show().then((res) => {
  435. console.log('插屏广告成功---》', res)
  436. this.loading = false;
  437. }).catch(err => {
  438. console.log('插屏广告错误---》', err)
  439. });
  440. }
  441. },
  442. // 补签点击
  443. signatureHandle(type, data) {
  444. if (!urgeVideoAd) { // 判断是否有视频ID
  445. this.repairSign(this.repairSignData)
  446. return
  447. } else {
  448. this.showVideoAd(type, data)
  449. }
  450. },
  451. // 显示激励视频广告
  452. showVideoAd(type, data) {
  453. if (this._isLoaded) {
  454. this.isVideoType = type
  455. this.repairSignData = data
  456. this._rewardedVideoAd.show().catch(() => {
  457. this._rewardedVideoAd && this._rewardedVideoAd.load().then(() => this._rewardedVideoAd && this._rewardedVideoAd.show()).catch(err => {
  458. uni.showToast({
  459. title: '当前无视频广告',
  460. icon: 'none'
  461. })
  462. })
  463. })
  464. }
  465. },
  466. /** 看视频签到 */
  467. lookVideo() {
  468. if (urgeVideoAd) {
  469. this.showVideoAd(1)
  470. } else {
  471. this.signInHandle(true)
  472. }
  473. },
  474. // 按钮呼吸
  475. btBreathAni() {
  476. btTimer = setInterval(() => {
  477. if(this.btScale === 1) {
  478. this.btScale = 0.92
  479. this.btAnimation.scale(0.92).step({ duration: 600 })
  480. this.btAnimationData = this.btAnimation.export()
  481. } else {
  482. this.btScale = 1
  483. this.btAnimation.scale(1).step({ duration: 600 })
  484. this.btAnimationData = this.btAnimation.export()
  485. }
  486. }, 600)
  487. },
  488. // 提示动画
  489. startTsAni(watchVideos) {
  490. if (watchVideos) {
  491. this.tsTitle = '+' + (this.signInDay.bookCoin * 2) + '书币'
  492. } else {
  493. this.tsTitle = '+' + this.signInDay.bookCoin + '书币'
  494. }
  495. if( this.durationMath2 >= 50 ) {
  496. this.durationMath2 = 20
  497. } else {
  498. this.durationMath2 = this.durationMath2 + 1
  499. }
  500. let animation = uni.createAnimation({ timingFunction: 'ease' })
  501. animation.opacity(1).step({ duration: this.durationMath2 })
  502. animation.top('150rpx').step({ duration: 1000, delay: 100 })
  503. animation.opacity(0).top('350rpx').step({ duration: 0 })
  504. this.animationDataTs = animation.export()
  505. },
  506. // 金币组动画
  507. startGold(watchVideos) {
  508. this.startTsAni(watchVideos)
  509. if( this.durationMath1 >= 50 ) {
  510. this.durationMath1 = 20
  511. } else {
  512. this.durationMath1 = this.durationMath1 + 1
  513. }
  514. this.animationDatas = this.goldData.map(item => {
  515. let animation = uni.createAnimation({ timingFunction: 'ease' })
  516. animation.opacity(1).step({ duration: this.durationMath1 })
  517. animation.top('76rpx').left('60rpx').step({ duration: Math.floor(Math.random() * 101) + 650, delay: 100 }) //
  518. animation.opacity(0).top(item.top).left(item.left).step({ duration: 0 })
  519. return animation.export()
  520. })
  521. },
  522. // 更多书币
  523. moreGold() {
  524. let path = 'pages/index/index'
  525. if(Object.keys(this.mpData).length > 0) {
  526. path = path + this.getSerialize(this.mpData)
  527. }
  528. uni.navigateToMiniProgram({
  529. appId: 'wxe1b04d1d8f6df382',
  530. path,
  531. success(res) {
  532. // 打开成功
  533. }
  534. })
  535. },
  536. // 对象序列化成 a=1&b=2
  537. getSerialize(value) {
  538. if(Object.prototype.toString.call(value) === "[object Object]") {
  539. let path = ""
  540. for (const key in value) {
  541. if (Object.prototype.hasOwnProperty.call(value, key)) {
  542. const element = value[key];
  543. if (path === "") {
  544. path = `?${key}=${element}`
  545. }else {
  546. path = path + `&${key}=${element}`
  547. }
  548. }
  549. }
  550. return path
  551. } else {
  552. return ""
  553. }
  554. },
  555. // 判断模板消息是否点击了总是允许
  556. getSetting() {
  557. return new Promise((resolve, reject) => {
  558. uni.getSetting({
  559. withSubscriptions: true,
  560. success: resSetting => {
  561. console.log('订阅消息---->', resSetting)
  562. let { subscriptionsSetting } = resSetting
  563. if (subscriptionsSetting) {
  564. let { mainSwitch, itemSettings, ...data } = subscriptionsSetting
  565. if (data && Object.keys(data).length > 0) {
  566. if (mainSwitch) {
  567. for (const key in data) {
  568. if (Object.prototype.hasOwnProperty.call(data, key)) {
  569. const element = data[key];
  570. if (element === 'accept') {
  571. resolve(200) // 总是允许开启
  572. } else {
  573. resolve(400) // 总是允许取消
  574. }
  575. }
  576. }
  577. } else {
  578. resolve(401) // 后台关闭开关
  579. }
  580. } else {
  581. resolve(402) // 没有点总是允许
  582. }
  583. } else {
  584. resolve(402) // 没有点总是允许
  585. }
  586. }
  587. })
  588. })
  589. },
  590. handleMessage(remindSwitch, allowSwitch = 0) { // 设置签到消息接口
  591. let { mpName, ...mp } = this.mpData
  592. setMessage({appId: config.appid, openId: this.openId, allowSwitch, remindSwitch, ...mp}).then(res => {
  593. this.getList()
  594. this.showInterstitialAd()
  595. })
  596. },
  597. // 获取模板签到ID
  598. getTemplate() {
  599. getTemplateIDs({appId: config.appid, type: 1}).then(res => {
  600. this.signIdTemID = [res.data]
  601. })
  602. },
  603. // 获取首页数据
  604. async getList(signTime) {
  605. let data = {appId: config.appid, userSource: 1, openId: this.openId, ...this.mpData, ...(signTime ? {signTime} : {})}
  606. let res = await getHome(data)
  607. if (res.data) {
  608. this.mpData = {
  609. mpAppId: res.data.mpAppId,
  610. mpName: res.data.mpName,
  611. mpOpenId: res.data.mpOpenId
  612. }
  613. this.signData = res.data
  614. this.signRemind = res.data.loginRemindSwitch === 0 ? false : true
  615. this.getTemplate()
  616. this.getBookCurr()
  617. }
  618. },
  619. /** 补签*/
  620. repairSign(data) {
  621. let { dayTime, dayNum } = data
  622. signInAjax({watchVideo: false, supplement: true, appId: config.appid, openId: this.openId, dayNum, dayTime, ...this.mpData}).then(res => {
  623. this.getList(res.data)
  624. this.startGold(false)
  625. uni.showToast({
  626. title: '补签成功',
  627. icon: 'success'
  628. })
  629. setTimeout(() => {
  630. this.showInterstitialAd()
  631. }, 20000)
  632. })
  633. },
  634. getTimer() { // 获取年月日时分秒
  635. let timestamp = Date.parse(new Date())
  636. let date = new Date(timestamp)
  637. let Y = date.getFullYear()
  638. let M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1)
  639. let D = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
  640. return `${Y}${M}${D}`
  641. },
  642. /** 签到提醒按钮 */
  643. signRemindHandle(state) {
  644. if (!this.signData.mpName) {
  645. uni.navigateTo({
  646. url: '../officialAccount/officialAccount'
  647. })
  648. return
  649. }
  650. if(state) { // 点击开启
  651. if (this.signIdTemID.length > 0) {
  652. uni.requestSubscribeMessage({
  653. tmplIds: this.signIdTemID,
  654. success: async res => {
  655. let { errMsg, ...massageData } = res
  656. console.log('------>', res)
  657. let msg = await this.getSetting()
  658. console.log('----2222---->', msg)
  659. if(msg === 400) {
  660. uni.showToast({
  661. title: '签到消息微信关闭,如要开启通知,请到通知管理开启',
  662. icon: 'none',
  663. duration: 2000
  664. })
  665. return
  666. } else if(msg === 401) {
  667. uni.showToast({
  668. title: '通知管理按钮关闭,如要开启通知,请到通知管理开启',
  669. icon: 'none',
  670. duration: 2000
  671. })
  672. } else {
  673. for (const key in massageData) {
  674. if (Object.prototype.hasOwnProperty.call(massageData, key)) {
  675. const element = massageData[key];
  676. if (element === 'accept') { // 允许
  677. console.log('msg--->', msg)
  678. this.handleMessage(1, msg === 200 ? 1 : 0)
  679. } else if (element === 'reject') { // 取消
  680. }
  681. }
  682. }
  683. }
  684. }
  685. })
  686. } else {
  687. uni.showToast({
  688. title: '模板ID为空',
  689. icon: 'none'
  690. })
  691. }
  692. } else { // 点击关闭
  693. this.handleMessage(0, 0)
  694. }
  695. },
  696. /** 活动规则展开和收起 */
  697. activityRulesHandle() {
  698. this.activityRules = !this.activityRules
  699. },
  700. /** 签到 */
  701. signIn() {
  702. if(!this.signData.mpName) {
  703. uni.showToast({
  704. title: '请先关注公众号',
  705. icon: 'none'
  706. })
  707. return
  708. }
  709. this.signInDay = this.signData.signInDayVoList.find(item => item.canSign)
  710. this.popupShow = true
  711. },
  712. /** 关闭弹窗 */
  713. closeHandle() {
  714. this.popupShow = false
  715. this.signInHandle(false)
  716. },
  717. /** 签到 */
  718. signInHandle(watchVideo) {
  719. let signInDay = this.signData.signInDayVoList.find(item => item.canSign)
  720. console.log(signInDay)
  721. if (signInDay) {
  722. let { dayTime, dayNum, signIn } = signInDay
  723. if (!signIn) {
  724. signInAjax({watchVideo, supplement: false, appId: config.appid, openId: this.openId, dayNum, dayTime, ...this.mpData}).then(res => {
  725. this.getList()
  726. this.startGold(watchVideo)
  727. this.popupShow = false
  728. if(!watchVideo) {
  729. this.showInterstitialAd()
  730. } else {
  731. setTimeout(() => {
  732. this.showInterstitialAd()
  733. }, 20000)
  734. }
  735. })
  736. } else {
  737. uni.showToast({
  738. title: '今日已签!',
  739. icon: 'error'
  740. })
  741. }
  742. } else {
  743. uni.showToast({
  744. title: '数据获取失败!',
  745. icon: 'error'
  746. })
  747. }
  748. }
  749. }
  750. }
  751. </script>
  752. <style lang="scss">
  753. page{
  754. background-color: #FC6E53;
  755. }
  756. .sign {
  757. position: relative;
  758. &>.back {
  759. width: 100%;
  760. margin-top: 104rpx;
  761. }
  762. .signCenter {
  763. position: absolute;
  764. top: 0;
  765. margin: 40rpx 0 60rpx;
  766. font-family: PingFangSC-Medium, PingFang SC;
  767. }
  768. .signTop {
  769. padding: 0 28rpx;
  770. height: 104rpx;
  771. display: flex;
  772. justify-content: space-between;
  773. align-items: center;
  774. .left{
  775. display: flex;
  776. justify-content: flex-start;
  777. align-items: center;
  778. .avatarView{
  779. width: 104rpx;
  780. height: 104rpx;
  781. overflow: hidden;
  782. border-radius: 10px;
  783. .avatar {
  784. width: 104rpx;
  785. height: 104rpx;
  786. background: #D8D8D8;
  787. }
  788. &>image {
  789. width: 100%;
  790. height: 100%;
  791. }
  792. }
  793. .userInfo{
  794. margin-left: 28rpx;
  795. &>view{
  796. font-size: 28rpx;
  797. font-weight: 400;
  798. color: #FFFFFF;
  799. &.ID{
  800. margin-top: 4rpx;
  801. display: flex;
  802. justify-content: flex-start;
  803. align-items: center;
  804. }
  805. .extract {
  806. font-size: 30rpx;
  807. margin-left: 30rpx;
  808. background-color: rgb(213, 51, 186);
  809. // background-image: linear-gradient(to right, rgb(66, 83, 216), rgb(213, 51, 186));
  810. padding: 6rpx 16rpx;
  811. border-radius: 26rpx;
  812. }
  813. }
  814. }
  815. }
  816. .right{
  817. width: 212rpx;
  818. height: 68rpx;
  819. background-color: #FFFFFF;
  820. border-radius: 40rpx;
  821. display: flex;
  822. justify-content: center;
  823. align-items: center;
  824. &>image {
  825. width: 28rpx;
  826. height: 32rpx;
  827. }
  828. &>text {
  829. font-size: 28rpx;
  830. font-weight: 400;
  831. color: #FD9C01;
  832. margin-left: 18rpx;
  833. }
  834. }
  835. }
  836. // 滚动通知
  837. .notice {
  838. width: 656rpx;
  839. height: 68rpx;
  840. background: #C7322C;
  841. box-shadow: 0px 4rpx 8rpx 0rpx rgba(49, 49, 49, 0.08);
  842. border-radius: 38rpx;
  843. opacity: 0.53;
  844. margin: 58rpx auto 0;
  845. padding: 0 30rpx;
  846. box-sizing: border-box;
  847. display: flex;
  848. justify-content: flex-start;
  849. align-items: center;
  850. margin-bottom: 30rpx;
  851. .horn {
  852. width: 28rpx;
  853. height: 28rpx;
  854. }
  855. .txts {
  856. // flex: 1;
  857. height: 68rpx;
  858. width: 600rpx;
  859. }
  860. }
  861. .signBottom{
  862. margin: 0 14rpx;
  863. margin-top: 160rpx;
  864. width: 722rpx;
  865. }
  866. .exhibitionContent{
  867. padding: 26rpx 26rpx 40rpx;
  868. box-sizing: border-box;
  869. background-color: #FFFFFF;
  870. border-radius: 22rpx;
  871. box-shadow: 0px 4rpx 8rpx 0rpx rgba(230, 230, 230, 0.5);
  872. &>.ts {
  873. font-size: 28rpx;
  874. font-weight: 400;
  875. color: #666666;
  876. }
  877. &>.signinExhibition {
  878. margin-top: 18rpx;
  879. display: flex;
  880. justify-content: space-between;
  881. flex-wrap: wrap;
  882. &>view{
  883. width: 152rpx;
  884. height: 168rpx;
  885. background: #FFF7EF;
  886. box-shadow: 0rpx 4rpx 8rpx 0rpx rgba(254, 173, 165, 0.26);
  887. border-radius: 16rpx;
  888. border: 2rpx solid #FFB35C;
  889. margin-bottom: 20rpx;
  890. padding: 12rpx;
  891. box-sizing: border-box;
  892. display: flex;
  893. flex-direction: column;
  894. justify-content: flex-start;
  895. align-items: center;
  896. position: relative;
  897. .day{
  898. font-size: 24rpx;
  899. font-weight: 500;
  900. color: #FF9011;
  901. }
  902. &>.goldCoins {
  903. height: 68rpx;
  904. margin: 5rpx 0;
  905. }
  906. .reward{
  907. font-size: 24rpx;
  908. font-weight: 500;
  909. color: #FE604F;
  910. }
  911. &:last-child{
  912. width: 322rpx;
  913. display: flex;
  914. justify-content: space-between;
  915. flex-direction: row;
  916. &>.left {
  917. display: flex;
  918. flex-direction: column;
  919. align-items: flex-start;
  920. margin-left: 35rpx;
  921. height: 100%;
  922. flex: 1;
  923. .reward{
  924. margin-top: 28rpx;
  925. font-size: 32rpx;
  926. font-weight: 500;
  927. }
  928. }
  929. &>.right {
  930. width: 115rpx;
  931. height: 100%;
  932. display: flex;
  933. justify-content: center;
  934. align-items: center;
  935. &>image{
  936. width: 108rpx;
  937. height: 128rpx;
  938. }
  939. }
  940. }
  941. // 已签到
  942. &.select {
  943. overflow: hidden;
  944. border: 2rpx solid #D2D2D2;
  945. background: #F2F2F2;
  946. .day, .reward{
  947. color: #999999;
  948. }
  949. }
  950. .signSub {
  951. position: absolute;
  952. bottom: 0;
  953. right: 0;
  954. width: 72rpx;
  955. }
  956. // 看视频补签
  957. &.repairSign {
  958. position: relative;
  959. .repair {
  960. position: absolute;
  961. width: calc(100% + 2rpx);
  962. left: -1rpx;
  963. top: -1rpx;
  964. text-align: center;
  965. line-height: 46rpx;
  966. height: 46rpx;
  967. background: #FE604F;
  968. font-size: 24rpx;
  969. font-weight: 500;
  970. color: #FFFFFF;
  971. border-radius: 16rpx 16rpx 0 0;
  972. }
  973. }
  974. }
  975. }
  976. &>.gignBt {
  977. width: 456rpx;
  978. height: 80rpx;
  979. line-height: 80rpx;
  980. text-align: center;
  981. // background-color: #D8D8D8;
  982. background: linear-gradient(180deg, #FDC606 0%, #FF8D12 100%);
  983. box-shadow: 0rpx 4rpx 8rpx 0rpx rgba(241, 139, 11, 0.61);
  984. margin: 40rpx auto 0;
  985. font-size: 32rpx;
  986. font-weight: 500;
  987. color: #FFFFFF;
  988. border-radius: 40rpx;
  989. }
  990. &>.already{
  991. margin: 40rpx auto 0;
  992. width: 456rpx;
  993. height: 80rpx;
  994. background: #D8D8D8;
  995. border-radius: 40rpx;
  996. font-size: 32rpx;
  997. font-weight: 500;
  998. color: #FFFFFF;
  999. line-height: 80rpx;
  1000. text-align: center;
  1001. }
  1002. }
  1003. .signRemind {
  1004. margin-top: 40rpx;
  1005. height: 92rpx;
  1006. background: rgba(255, 255, 255, 0.15);
  1007. border-radius: 20rpx;
  1008. line-height: 92rpx;
  1009. color: #FFFFFF;
  1010. font-size: 32rpx;
  1011. padding: 0 28rpx;
  1012. box-sizing: border-box;
  1013. display: flex;
  1014. font-weight: 400;
  1015. justify-content: space-between;
  1016. .remindSwitch{
  1017. display: flex;
  1018. justify-content: flex-start;
  1019. align-items: center;
  1020. &>view {
  1021. display: flex;
  1022. justify-content: flex-start;
  1023. align-items: center;
  1024. &>text {
  1025. font-weight: 400;
  1026. font-size: 32rpx;
  1027. margin-left: 12rpx;
  1028. }
  1029. &.open > .select {
  1030. width: 24rpx;
  1031. height: 24rpx;
  1032. background: #FFFFFF;
  1033. border-radius: 24rpx;
  1034. }
  1035. &.close > .select {
  1036. width: 24rpx;
  1037. height: 24rpx;
  1038. border: 2rpx solid #FFFFFF;
  1039. box-sizing: border-box;
  1040. border-radius: 24rpx;
  1041. }
  1042. &:first-child {
  1043. margin-right: 38rpx;
  1044. }
  1045. }
  1046. }
  1047. }
  1048. .activityRules {
  1049. margin-top: 40rpx;
  1050. background: rgba(255, 255, 255, 0.15);
  1051. border-radius: 20rpx;
  1052. color: #FFFFFF;
  1053. font-size: 32rpx;
  1054. font-weight: 400;
  1055. &>.top {
  1056. height: 92rpx;
  1057. padding: 0 28rpx;
  1058. box-sizing: border-box;
  1059. display: flex;
  1060. justify-content: space-between;
  1061. align-items: center;
  1062. &>image {
  1063. width: 40rpx;
  1064. }
  1065. }
  1066. &>.bottom {
  1067. padding: 0 28rpx 30rpx;
  1068. box-sizing: border-box;
  1069. &> view {
  1070. margin-bottom: 12rpx;
  1071. font-size: 28rpx;
  1072. font-weight: 400;
  1073. color: #FFFFFF;
  1074. line-height: 46rpx;
  1075. }
  1076. }
  1077. }
  1078. .popup {
  1079. position: fixed;
  1080. width: 100%;
  1081. height: 100vh;
  1082. background: rgba(0, 0, 0, 0.6);
  1083. top: 0;
  1084. left: 0;
  1085. right: 0;
  1086. bottom: 0;
  1087. .popupContent {
  1088. width: 632rpx;
  1089. position: absolute;
  1090. top: 50%;
  1091. left: 50%;
  1092. transform: translate(-50%, -50%);
  1093. text-align: center;
  1094. &>.content {
  1095. position: relative;
  1096. &>image {
  1097. width: 100%;
  1098. height: 652rpx;
  1099. }
  1100. &>.textCon {
  1101. position: absolute;
  1102. width: 100%;
  1103. top: 0;
  1104. left: 0;
  1105. right: 0;
  1106. bottom: 0;
  1107. padding-top: 192rpx;
  1108. .ts {
  1109. font-size: 60rpx;
  1110. font-weight: 500;
  1111. color: #F5631D;
  1112. }
  1113. .reward {
  1114. height: 60rpx;
  1115. background: #FFD9A2;
  1116. border-radius: 31rpx;
  1117. font-size: 32rpx;
  1118. font-weight: 400;
  1119. display: inline-block;
  1120. padding: 0 32rpx;
  1121. color: #F5631E;
  1122. line-height: 60rpx;
  1123. margin-top: 20rpx;
  1124. }
  1125. .doubleBt {
  1126. width: 456rpx;
  1127. height: 104rpx;
  1128. margin-top: 90rpx;
  1129. transition: all linear .5s;
  1130. }
  1131. .bt {
  1132. margin-top: 14rpx;
  1133. font-size: 32rpx;
  1134. font-weight: 400;
  1135. color: #FCE8CD;
  1136. }
  1137. }
  1138. }
  1139. &>.close {
  1140. width: 54rpx;
  1141. height: 54rpx;
  1142. margin-top: 76rpx;
  1143. }
  1144. }
  1145. }
  1146. .fragmentGold {
  1147. position: absolute;
  1148. z-index: 100;
  1149. opacity: 0;
  1150. &>image {
  1151. width: 68rpx;
  1152. height: 68rpx;
  1153. }
  1154. }
  1155. .qLuckDraw {
  1156. position: absolute;
  1157. top: 240rpx;
  1158. right: 8rpx;
  1159. z-index: 200;
  1160. animation: lanimation 1.3s linear infinite;
  1161. &>image {
  1162. width: 150rpx;
  1163. height: 150rpx;
  1164. }
  1165. }
  1166. .receiveTs {
  1167. position: absolute;
  1168. border: 2rpx solid rgb(242, 164, 39);
  1169. top: 350rpx;
  1170. z-index: 100;
  1171. color: #FFFFFF;
  1172. left: 50%;
  1173. transform: translateX(-50%);
  1174. padding: 10rpx 20rpx;
  1175. background-color: rgba(195, 106, 106, 0.6);
  1176. border-radius: 5rpx;
  1177. opacity: 0;
  1178. }
  1179. .singleLattice {
  1180. position: fixed;
  1181. top: 200rpx;
  1182. right: 4rpx;
  1183. }
  1184. }
  1185. @-webkit-keyframes lanimation {
  1186. 0% {
  1187. transform: rotate(0deg);
  1188. }
  1189. 8% {
  1190. transform: rotate(12deg);
  1191. }
  1192. 16% {
  1193. transform: rotate(0deg);
  1194. }
  1195. 24% {
  1196. transform: rotate(-12deg);
  1197. }
  1198. 32% {
  1199. transform: rotate(0deg);
  1200. }
  1201. 100% {
  1202. transform: rotate(0deg);
  1203. }
  1204. }
  1205. </style>