award.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810
  1. <template>
  2. <page-layout class="award-container">
  3. <nav-bar title="我的奖品" @init="onInitNavbar"></nav-bar>
  4. <u-scroll-view :tabbar-conflict="false">
  5. <view class="main-container">
  6. <view class="theme-title">
  7. <text class="title">我的奖品</text>
  8. <image mode="aspectFit" class="title-bg"
  9. src="https://www.productronicachina.com.cn/resources/files/0221/67b7dd27b30b7/标题星星.png"></image>
  10. </view>
  11. <view class="award-index">
  12. <view class="award-head">
  13. <view class="award-title">
  14. 路线进度
  15. </view>
  16. <view v-if="is_receipts === 0" @click="gotoCheck()" class="award-button">
  17. 继续打卡
  18. </view>
  19. <view class="award-button disabled" v-else>
  20. 已完成打卡
  21. </view>
  22. </view>
  23. <view class="award-progress">
  24. <view class="award-progress-bar"></view>
  25. <view class="award-progress-value" :style="{width: getProcess}"></view>
  26. <view class="award-progress-point-list">
  27. <view v-for="(item,index) in giftList" :style="{left:((index+1)/giftList.length)*90+'%'}" :key="item.id"
  28. :class="['award-progress-point-item',checked>=item.route_count?'active':'']">
  29. <view class="point"></view>
  30. <text>已满{{ item.route_count }}条</text>
  31. </view>
  32. </view>
  33. </view>
  34. <view class="award-body">
  35. <view class="award-title">
  36. 您目前的奖品
  37. </view>
  38. <view class="award-list">
  39. <view v-for="(item,index) in giftList" :key="item.id" class="award-list-item">
  40. <image :src="item.picture_url" alt="image" mode="widthFix"></image>
  41. <view class="award-info">
  42. <view class="award-info-title">
  43. {{ item.name }}
  44. </view>
  45. <view class="award-info-desc">
  46. 成功打卡
  47. <text>{{ item.route_count }}条路线</text>
  48. 即可获取
  49. </view>
  50. <mp-html class="award-info-desc" :content="item.description"></mp-html>
  51. </view>
  52. <view class="award-option">
  53. <view @click="getGift(item,index)" :class="['award-option-btn',getClass(item,index)]">
  54. {{ getText(item, index) }}
  55. </view>
  56. </view>
  57. </view>
  58. </view>
  59. </view>
  60. </view>
  61. <view class="award-footer">
  62. <view class="award-footer-title">
  63. {{ rule_title }}
  64. </view>
  65. <mp-html :content="rule" class="award-footer-desc"></mp-html>
  66. </view>
  67. </view>
  68. </u-scroll-view>
  69. <view v-if="show_qr" class="pop-up-bg">
  70. <view :class="['QRcode',check_finish?'checked':'']">
  71. <view class="tickt-1">
  72. <view :style="{textDecoration:check_finish?'line-through':''}" class="text">
  73. {{ check_finish ? current_gift.name + '已核销' : current_gift.name + '核销券' }}
  74. </view>
  75. <view class="image">
  76. <image class="image-inner" mode="aspectFit" :src="qr_code"></image>
  77. </view>
  78. </view>
  79. <view class="tickt-2">
  80. <view class="image">
  81. <image class="image-inner" mode="aspectFit" :src="qr_code"></image>
  82. </view>
  83. <view class="text">
  84. 请将此二维码交由工作人员核销
  85. </view>
  86. </view>
  87. </view>
  88. <view @click="closeQR()" class="iconfont icon-Cancel-copy close"></view>
  89. </view>
  90. <view v-if="pop_up" class="pop-up-bg">
  91. <view class="pop-up">
  92. <view class="title">
  93. <view>这是您专属的幸运时刻,请填写以下信息参与抽奖:</view>
  94. <view>恭喜您获得本年度大满贯抽奖资格!</view>
  95. </view>
  96. <view class="input">
  97. <view class="placeholder">您的公司名称<span>*</span> :</view>
  98. <input v-model="verify_note.company_name" class="text-input"/>
  99. </view>
  100. <view class="input">
  101. <view class="placeholder">您的姓名<span>*</span> :</view>
  102. <input v-model="verify_note.verify_name" class="text-input"/>
  103. </view>
  104. <view class="input">
  105. <view class="placeholder">您的手机号<span>*</span> :</view>
  106. <input v-model="verify_note.verify_phone" class="text-input"/>
  107. </view>
  108. <view class="description">
  109. 温馨提示:本次抽奖奖品丰厚,机会难得,请确保信息真实有效。填写完毕后,点击"立即抽奖"按钮,即可开启您的幸运之旅!
  110. </view>
  111. <view class="description">祝你好运!</view>
  112. <view class="tips">注:本活动真实有效,最终解释权归主办方所有</view>
  113. <view class="button-list">
  114. <view @click="pop_up=false" class="button cancel">取消</view>
  115. <view @click="getNow()" class="button confime">立即抽奖</view>
  116. </view>
  117. </view>
  118. </view>
  119. </page-layout>
  120. </template>
  121. <script>
  122. import PageLayout from "@/components/layout/page-layout";
  123. import NavBar from "@/components/layout/nav-bar";
  124. import UTabs from "@/components/common/u-tabs";
  125. import UScrollView from "@/components/common/u-scroll-view";
  126. import NewsItem from "@/pages/news/components/news-item";
  127. import DisclaimerText from "@/components/disclaimer-text";
  128. import floatButton from "@/components/layout/float-button";
  129. import {checkInCount, claim, receiptNote, getActivityInfo, getRouteList, getGiftList} from "@/api/checkIn";
  130. export default {
  131. components: {
  132. PageLayout,
  133. NavBar,
  134. UTabs,
  135. UScrollView,
  136. NewsItem,
  137. DisclaimerText,
  138. floatButton
  139. },
  140. data() {
  141. return {
  142. activeIndex: null,
  143. awardProgressValue: '0%',
  144. giftList: [],
  145. routes: [],
  146. route_count: 1,
  147. checked: 0,
  148. pop_up: false,
  149. show_qr: false,
  150. qr_code: '',
  151. check_finish: false,
  152. current_gift: {},
  153. timer: null,
  154. rule: '',
  155. rule_title: '',
  156. is_receipts: 0,
  157. verify_note: {
  158. company_name: '',
  159. verify_name: '',
  160. verify_phone: ''
  161. }
  162. };
  163. },
  164. mounted() {
  165. this.getGiftListEvent()
  166. this.getActiveInfo()
  167. this.getRouteListInfo()
  168. },
  169. onUnload() {
  170. clearTimeout(this.timer)
  171. },
  172. computed: {
  173. getProcess() {
  174. if (!(this.giftList && this.giftList.length > 0)) {
  175. return '0%'
  176. }
  177. let subList = []
  178. for (var i = this.giftList.length - 1; i > 0; i--) {
  179. subList.unshift(this.giftList[i].route_count - this.giftList[i - 1].route_count)
  180. }
  181. subList.unshift(this.giftList[0].route_count)
  182. let process = 0
  183. let count = this.checked
  184. let per_process = 100 / this.giftList.length
  185. subList.forEach(item => {
  186. if (count >= item) {
  187. count -= item
  188. process += per_process
  189. } else {
  190. process += per_process * (count / item)
  191. count = 0
  192. }
  193. })
  194. return process + '%'
  195. },
  196. },
  197. methods: {
  198. onShareTimeline() {
  199. return {
  200. title: '逛展会,领福利!',
  201. path: '/pages/checkIn/index',
  202. imageUrl: 'https://www.productronicachina.com.cn/resources/files/0221/67b7e5190bd22/share.png'
  203. }
  204. }
  205. ,
  206. onShareAppMessage() {
  207. return {
  208. title: '逛展会,领福利!',
  209. path: '/pages/checkIn/index',
  210. imageUrl: 'https://www.productronicachina.com.cn/resources/files/0221/67b7e5190bd22/share.png'
  211. }
  212. }
  213. ,
  214. getRouteListInfo(callback) {
  215. getRouteList().then(res => {
  216. this.is_receipts = res.data.is_receipts
  217. if (callback) {
  218. callback()
  219. }
  220. })
  221. },
  222. getActiveInfo() {
  223. getActivityInfo().then(res => {
  224. this.rule = res.data.gifts_rules_content
  225. this.rule_title = res.data.gifts_rules_name
  226. })
  227. },
  228. getGiftListEvent() {
  229. getGiftList().then(res => {
  230. this.giftList = res.data;
  231. this.getCheckinCount()
  232. })
  233. },
  234. getCheckinCount(callback) {
  235. checkInCount().then(res => {
  236. this.routes = res.data.routes
  237. this.route_count = res.data.route_count
  238. this.checked = res.data.route_checkin_count
  239. console.log(this.checked, 'this.checked')
  240. console.log(this.giftList)
  241. this.giftList.forEach((item, index) => {
  242. if (this.checked >= item.route_count) {
  243. this.activeIndex = index
  244. }
  245. })
  246. if (callback) {
  247. callback()
  248. }
  249. })
  250. },
  251. gotoCheck() {
  252. uni.navigateTo({
  253. url: '/pages/checkIn/checkInRoute'
  254. });
  255. },
  256. closeQR() {
  257. this.show_qr = false;
  258. clearTimeout(this.timer)
  259. },
  260. claimDataEvent() {
  261. //生成二维码方法
  262. claim({
  263. gift_id: this.current_gift.id,
  264. }).then(res => {
  265. if (res.code === 0) {
  266. this.qr_code = res.data.qrcode_url
  267. this.is_receipts = 1
  268. if (res.data.verify_note) {
  269. this.verify_note.company_name = res.data.verify_note.company_name
  270. this.verify_note.verify_name = res.data.verify_note.verify_name
  271. this.verify_note.verify_phone = res.data.verify_note.verify_phone
  272. }
  273. this.current_gift.form_id = res.data.id
  274. //展示二维码
  275. if (this.current_gift.route_count === 9) {
  276. //轮询确认核销后,展示抽奖环节
  277. this.pop_up = true
  278. } else {
  279. this.show_qr = true
  280. this.checkGiftState(() => {
  281. this.getGiftListEvent()
  282. this.getCheckinCount()
  283. })
  284. }
  285. }
  286. })
  287. },
  288. getGift(item, index) {
  289. //获取当前产品信息
  290. if (item.is_receipts > 0 || this.activeIndex !== index) {
  291. return false
  292. }
  293. this.current_gift = item
  294. this.getRouteListInfo(() => {
  295. //获取当前是否生成过奖品二维码 is_receipts
  296. if (this.is_receipts > 0) {
  297. //获取二维码
  298. this.claimDataEvent()
  299. } else {
  300. //确认是否领取奖品
  301. uni.showModal({
  302. title: '确定领取该奖品吗?',
  303. content: '领取该礼品后将无法再领取其它礼品',
  304. success: (res) => {
  305. if (res.confirm) {
  306. //获取二维码
  307. this.claimDataEvent()
  308. }
  309. }
  310. })
  311. }
  312. })
  313. },
  314. checkGiftState(callback) {
  315. getGiftList().then(res => {
  316. this.giftList = res.data;
  317. this.giftList.forEach(item => {
  318. if (item.id === this.current_gift.id) {
  319. if (item.is_receipts) {
  320. console.log('轮询已核销')
  321. clearTimeout(this.timer)
  322. this.checkAnimation()
  323. if (callback) {
  324. callback()
  325. }
  326. } else {
  327. console.log('轮询未核销')
  328. this.timer = setTimeout(() => {
  329. this.checkGiftState(callback)
  330. }, 1000)
  331. }
  332. }
  333. })
  334. })
  335. },
  336. getClass(item, index) {
  337. if (item.is_receipts)
  338. return 'cheked'
  339. if (this.activeIndex !== index)
  340. return 'disable'
  341. },
  342. getText(item, index) {
  343. if (item.is_receipts)
  344. return '已领取奖品'
  345. if (this.activeIndex === index) {
  346. return '立即领取'
  347. } else {
  348. return '不可领取'
  349. }
  350. },
  351. getNow() {
  352. if (this.verify_note.company_name == '' || this.verify_note.verify_name == '' || this.verify_note.verify_phone == '') {
  353. uni.showToast({
  354. title: '请填写完整信息',
  355. icon: 'none'
  356. })
  357. } else {
  358. receiptNote({
  359. id: this.current_gift.form_id,
  360. verify_note: this.verify_note
  361. }).then(res => {
  362. uni.showToast({
  363. title: '提交抽奖信息成功',
  364. icon: 'none'
  365. })
  366. this.pop_up = false
  367. this.show_qr = true
  368. this.checkGiftState(() => {
  369. this.getGiftListEvent()
  370. this.getCheckinCount()
  371. })
  372. })
  373. }
  374. },
  375. checkAnimation() {
  376. this.check_finish = true
  377. setTimeout(() => {
  378. this.show_qr = false
  379. }, 2000)
  380. }
  381. }
  382. }
  383. </script>
  384. <style lang="scss" scoped>
  385. .pop-up-bg {
  386. position: absolute;
  387. left: 0;
  388. top: 0;
  389. width: 100%;
  390. height: 100%;
  391. background-color: #00000066;
  392. display: flex;
  393. flex-direction: column;
  394. align-items: center;
  395. justify-content: center;
  396. .QRcode {
  397. width: 60%;
  398. display: flex;
  399. flex-direction: column;
  400. &.checked {
  401. .tickt-1 {
  402. animation: checked 600ms forwards;
  403. }
  404. @keyframes checked {
  405. 0% {
  406. transform: rotate(0deg);
  407. }
  408. 50% {
  409. transform: rotate(8deg);
  410. }
  411. 100% {
  412. transform: rotate(6deg);
  413. }
  414. }
  415. }
  416. .tickt-1 {
  417. background-image: url('https://www.productronicachina.com.cn/resources/files/0227/67c02d4916542/tickt1.png');
  418. background-size: 100% 100%;
  419. width: 100%;
  420. aspect-ratio: 2/1;
  421. position: relative;
  422. overflow: hidden;
  423. transform-origin: 100% 100%;
  424. .text {
  425. margin-top: 40rpx;
  426. text-align: center;
  427. color: grey;
  428. }
  429. .image {
  430. position: absolute;
  431. left: 50%;
  432. bottom: 0;
  433. transform: translate(-50%, 80%);
  434. width: 70%;
  435. aspect-ratio: 1;
  436. .image-inner {
  437. width: 100%;
  438. height: 100%;
  439. }
  440. }
  441. }
  442. .tickt-2 {
  443. position: relative;
  444. background-image: url('https://www.productronicachina.com.cn/resources/files/0227/67c02d4915cc2/tickt2.png');
  445. background-size: 100% 100%;
  446. width: 100%;
  447. aspect-ratio: 1;
  448. .text {
  449. width: 100%;
  450. position: absolute;
  451. bottom: 50rpx;
  452. text-align: center;
  453. color: grey;
  454. font-size: 24rpx;
  455. }
  456. .image {
  457. position: absolute;
  458. left: 50%;
  459. top: 0;
  460. transform: translate(-50%, -20%);
  461. width: 70%;
  462. aspect-ratio: 1;
  463. .image-inner {
  464. width: 100%;
  465. height: 100%;
  466. }
  467. }
  468. overflow: hidden;
  469. }
  470. }
  471. .close {
  472. margin-top: 60rpx;
  473. display: flex;
  474. justify-content: center;
  475. align-items: center;
  476. width: 80rpx;
  477. height: 80rpx;
  478. border: 4rpx solid white;
  479. color: white;
  480. border-radius: 50%;
  481. }
  482. .pop-up {
  483. display: flex;
  484. flex-direction: column;
  485. grid-gap: 20rpx;
  486. width: 80%;
  487. background-color: #FAFAFA;
  488. border-radius: 20rpx;
  489. padding: 57rpx 38rpx 102rpx;
  490. .button-list {
  491. display: flex;
  492. grid-gap: 13rpx;
  493. justify-content: flex-end;
  494. .button {
  495. padding: 15rpx 0;
  496. width: 144rpx;
  497. text-align: center;
  498. font-weight: bold;
  499. font-size: 14rpx;
  500. border-radius: 6rpx;
  501. &.confime {
  502. background-color: #E57519;
  503. color: white;
  504. }
  505. &.cancel {
  506. border: 1rpx solid #94A3B8;
  507. }
  508. }
  509. }
  510. .title {
  511. font-size: 18rpx;
  512. line-height: 1.5;
  513. }
  514. .description {
  515. font-size: 16rpx;
  516. }
  517. .tips {
  518. font-size: 14rpx;
  519. color: #555555;
  520. }
  521. .input {
  522. padding: 10rpx 18rpx;
  523. display: flex;
  524. align-items: center;
  525. border: 1rpx solid #CBD5E1;
  526. border-radius: 8rpx;
  527. .placeholder {
  528. font-size: 16rpx;
  529. span {
  530. color: red;
  531. }
  532. }
  533. .text-input {
  534. flex: 1;
  535. height: 100%;
  536. font-size: 16rpx;
  537. }
  538. }
  539. }
  540. }
  541. .main-container {
  542. background: linear-gradient(180deg, #015A92 0%, #56A3E9 15%, #3484BD 74%, #106591 98%);
  543. padding: 32rpx;
  544. min-height: 100vh;
  545. .theme-title {
  546. //margin-top: 24rpx;
  547. margin-bottom: 32rpx;
  548. position: relative;
  549. height: 130rpx;
  550. display: flex;
  551. justify-content: center;
  552. align-items: center;
  553. .title {
  554. color: white;
  555. font-size: 55rpx;
  556. font-weight: bold;
  557. }
  558. .title-bg {
  559. position: absolute;
  560. left: 0;
  561. top: 0;
  562. height: 100%;
  563. }
  564. }
  565. .award-index {
  566. background-color: #ffffff;
  567. border-radius: 20rpx 20rpx 0 0;
  568. width: 100%;
  569. padding: 36rpx 40rpx;
  570. .award-title {
  571. flex: 1;
  572. min-width: 1px;
  573. font-size: $fontSize1;
  574. }
  575. .award-head {
  576. display: flex;
  577. align-items: center;
  578. .award-button {
  579. line-height: 1;
  580. background-color: #4085C7;
  581. padding: 16rpx 32rpx;
  582. border-radius: 50rpx;
  583. font-size: 24rpx;
  584. color: #ffffff;
  585. &.disabled {
  586. background: #94A3B8;
  587. }
  588. }
  589. }
  590. .award-body {
  591. .award-list {
  592. display: flex;
  593. flex-direction: column;
  594. grid-gap: 24rpx;
  595. margin-top: 32rpx;
  596. .award-list-item {
  597. display: flex;
  598. background: #FAFAFA;
  599. padding: 30rpx 12rpx;
  600. align-items: center;
  601. border-radius: 20rpx;
  602. image {
  603. width: 128rpx;
  604. //height: 128rpx;
  605. }
  606. .award-info {
  607. flex: 1;
  608. min-width: 1rpx;
  609. .award-info-title {
  610. color: #000000;
  611. font-size: $fontSize2;
  612. }
  613. .award-info-desc {
  614. margin-top: 18rpx;
  615. color: #555555;
  616. font-size: $fontSize0;
  617. text {
  618. color: #015A92;
  619. }
  620. }
  621. }
  622. .award-option-btn {
  623. background: #E57519;
  624. font-size: 20rpx;
  625. color: #ffffff;
  626. width: 136rpx;
  627. height: 56rpx;
  628. border-radius: 6rpx;
  629. display: flex;
  630. align-items: center;
  631. justify-content: center;
  632. line-height: 1;
  633. &.disable {
  634. background: #94A3B8;
  635. }
  636. &.cheked {
  637. background: #015A92;
  638. }
  639. }
  640. .award-option {
  641. }
  642. }
  643. }
  644. }
  645. .award-progress {
  646. margin-top: 30rpx;
  647. display: flex;
  648. align-items: center;
  649. position: relative;
  650. width: 100%;
  651. margin-bottom: 90rpx;
  652. .award-progress-bar {
  653. display: block;
  654. width: 90%;
  655. height: 9rpx;
  656. border-radius: 100rpx;
  657. background-color: #D9CC9D;
  658. }
  659. .award-progress-value {
  660. display: block;
  661. position: absolute;
  662. height: 9rpx;
  663. border-radius: 100rpx;
  664. width: 0%;
  665. transition: width 1s ease-in-out;
  666. background-color: #E57519;
  667. }
  668. .award-progress-point-list {
  669. display: flex;
  670. position: absolute;
  671. align-items: center;
  672. width: 100%;
  673. .award-progress-point-item {
  674. position: absolute;
  675. display: flex;
  676. flex-direction: column;
  677. align-items: center;
  678. top: -12rpx;
  679. transform: translateX(-50%);
  680. & > text {
  681. margin-top: 12rpx;
  682. white-space: nowrap;
  683. font-size: $fontSize1;
  684. }
  685. .point {
  686. height: 24rpx;
  687. width: 24rpx;
  688. border-radius: 50%;
  689. border: 1rpx solid #E57519;
  690. background-color: #ffffff;
  691. &:before {
  692. content: '\e849';
  693. font-family: 'iconfont';
  694. color: #ffffff;
  695. line-height: 1;
  696. transition: 1s ease-in-out;
  697. font-size: 20rpx;
  698. opacity: 0;
  699. transform: scale(0);
  700. }
  701. }
  702. &.active {
  703. .point {
  704. background-color: #E57519;
  705. display: flex;
  706. align-items: center;
  707. justify-content: center;
  708. &:before {
  709. opacity: 1;
  710. transform: scale(1);
  711. }
  712. }
  713. }
  714. }
  715. }
  716. }
  717. }
  718. .award-footer {
  719. padding: 42rpx 48rpx;
  720. background-color: #EEEEEE;
  721. border-radius: 0 0 20rpx 20rpx;
  722. .award-footer-title {
  723. font-size: $fontSize3;
  724. }
  725. .award-footer-desc {
  726. padding-left: unset;
  727. margin-top: 20rpx;
  728. font-size: $fontSize1;
  729. line-height: 1.9;
  730. display: flex;
  731. flex-direction: column;
  732. //text-indent: 22rpx;
  733. list-style: decimal;
  734. padding-left: 22rpx;
  735. & > text {
  736. display: list-item;
  737. }
  738. }
  739. }
  740. }
  741. </style>