index.vue 32 KB

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