award.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804
  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. },
  154. timer: null,
  155. rule: '',
  156. rule_title: '',
  157. is_receipts: 0,
  158. verify_note: {
  159. company_name: '',
  160. verify_name: '',
  161. verify_phone: ''
  162. }
  163. };
  164. },
  165. mounted() {
  166. this.getGiftListEvent()
  167. this.getActiveInfo()
  168. this.getRouteListInfo()
  169. },
  170. onUnload() {
  171. clearTimeout(this.timer)
  172. },
  173. computed: {
  174. getProcess() {
  175. if (!(this.giftList && this.giftList.length > 0)) {
  176. return '0%'
  177. }
  178. let subList = []
  179. for (var i = this.giftList.length - 1; i > 0; i--) {
  180. subList.unshift(this.giftList[i].route_count - this.giftList[i - 1].route_count)
  181. }
  182. subList.unshift(this.giftList[0].route_count)
  183. let process = 0
  184. let count = this.checked
  185. let per_process = 100 / this.giftList.length
  186. subList.forEach(item => {
  187. if (count >= item) {
  188. count -= item
  189. process += per_process
  190. } else {
  191. process += per_process * (count / item)
  192. count = 0
  193. }
  194. })
  195. return process + '%'
  196. },
  197. },
  198. methods: {
  199. onShareTimeline() {
  200. return {
  201. title: '逛展会,领福利!',
  202. path: '/pages/checkIn/index',
  203. imageUrl: 'https://www.productronicachina.com.cn/resources/files/0221/67b7e5190bd22/share.png'
  204. }
  205. }
  206. ,
  207. onShareAppMessage() {
  208. return {
  209. title: '逛展会,领福利!',
  210. path: '/pages/checkIn/index',
  211. imageUrl: 'https://www.productronicachina.com.cn/resources/files/0221/67b7e5190bd22/share.png'
  212. }
  213. }
  214. ,
  215. getRouteListInfo(callback) {
  216. getRouteList().then(res => {
  217. this.is_receipts = res.data.is_receipts
  218. if (callback) {
  219. callback()
  220. }
  221. })
  222. },
  223. getActiveInfo() {
  224. getActivityInfo().then(res => {
  225. this.rule = res.data.gifts_rules_content
  226. this.rule_title = res.data.gifts_rules_name
  227. })
  228. },
  229. getGiftListEvent() {
  230. getGiftList().then(res => {
  231. this.giftList = res.data;
  232. this.getCheckinCount()
  233. })
  234. },
  235. getCheckinCount(callback) {
  236. checkInCount().then(res => {
  237. this.routes = res.data.routes
  238. this.route_count = res.data.route_count
  239. this.checked = res.data.route_checkin_count
  240. console.log(this.checked, 'this.checked')
  241. console.log(this.giftList)
  242. this.giftList.forEach((item, index) => {
  243. if (this.checked >= item.route_count) {
  244. this.activeIndex = index
  245. }
  246. })
  247. if (callback) {
  248. callback()
  249. }
  250. })
  251. },
  252. gotoCheck() {
  253. uni.navigateTo({
  254. url: '/pages/checkIn/checkInRoute'
  255. });
  256. },
  257. closeQR() {
  258. this.show_qr = false;
  259. clearTimeout(this.timer)
  260. },
  261. claimDataEvent() {
  262. //生成二维码方法
  263. claim({
  264. gift_id: this.current_gift.id,
  265. }).then(res => {
  266. if (res.code === 0) {
  267. this.qr_code = res.data.qrcode_url
  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. }
  279. }
  280. })
  281. },
  282. getGift(item, index) {
  283. //获取当前产品信息
  284. if (item.is_receipts > 0 || this.activeIndex !== index) {
  285. return false
  286. }
  287. this.current_gift = item
  288. this.getRouteListInfo(() => {
  289. //获取当前是否生成过奖品二维码 is_receipts
  290. if (this.is_receipts > 0) {
  291. //获取二维码
  292. this.claimDataEvent()
  293. } else {
  294. //确认是否领取奖品
  295. uni.showModal({
  296. title: '确定领取该奖品吗?',
  297. content: '领取该礼品后将无法再领取其它礼品',
  298. success: (res) => {
  299. if (res.confirm) {
  300. //获取二维码
  301. this.claimDataEvent()
  302. }
  303. }
  304. })
  305. }
  306. })
  307. },
  308. checkGiftState(callback) {
  309. getGiftList().then(res => {
  310. this.giftList = res.data;
  311. this.giftList.forEach(item => {
  312. if (item.id === this.current_gift.id) {
  313. if (item.is_receipts) {
  314. console.log('轮询已核销')
  315. clearTimeout(this.timer)
  316. this.checkAnimation()
  317. if (callback) {
  318. callback()
  319. }
  320. } else {
  321. console.log('轮询未核销')
  322. this.timer = setTimeout(() => {
  323. this.checkGiftState(callback)
  324. }, 1000)
  325. }
  326. }
  327. })
  328. })
  329. },
  330. getClass(item, index) {
  331. if (item.is_receipts)
  332. return 'cheked'
  333. if (this.activeIndex !== index)
  334. return 'disable'
  335. },
  336. getText(item, index) {
  337. if (item.is_receipts)
  338. return '已领取奖品'
  339. if (this.activeIndex === index) {
  340. return '立即领取'
  341. } else {
  342. return '不可领取'
  343. }
  344. },
  345. getNow() {
  346. if (this.verify_note.company_name == '' || this.verify_note.verify_name == '' || this.verify_note.verify_phone == '') {
  347. uni.showToast({
  348. title: '请填写完整信息',
  349. icon: 'none'
  350. })
  351. } else {
  352. receiptNote({
  353. id: this.current_gift.form_id,
  354. verify_note: this.verify_note
  355. }).then(res => {
  356. uni.showToast({
  357. title: '提交抽奖信息成功',
  358. icon: 'none'
  359. })
  360. this.pop_up = false
  361. this.show_qr = true
  362. this.checkGiftState(() => {
  363. this.getGiftListEvent()
  364. this.getCheckinCount()
  365. })
  366. })
  367. }
  368. },
  369. checkAnimation() {
  370. this.check_finish = true
  371. setTimeout(() => {
  372. this.show_qr = false
  373. }, 2000)
  374. }
  375. }
  376. }
  377. </script>
  378. <style lang="scss" scoped>
  379. .pop-up-bg {
  380. position: absolute;
  381. left: 0;
  382. top: 0;
  383. width: 100%;
  384. height: 100%;
  385. background-color: #00000066;
  386. display: flex;
  387. flex-direction: column;
  388. align-items: center;
  389. justify-content: center;
  390. .QRcode {
  391. width: 60%;
  392. display: flex;
  393. flex-direction: column;
  394. &.checked {
  395. .tickt-1 {
  396. animation: checked 600ms forwards;
  397. }
  398. @keyframes checked {
  399. 0% {
  400. transform: rotate(0deg);
  401. }
  402. 50% {
  403. transform: rotate(8deg);
  404. }
  405. 100% {
  406. transform: rotate(6deg);
  407. }
  408. }
  409. }
  410. .tickt-1 {
  411. background-image: url('https://www.productronicachina.com.cn/resources/files/0227/67c02d4916542/tickt1.png');
  412. background-size: 100% 100%;
  413. width: 100%;
  414. aspect-ratio: 2/1;
  415. position: relative;
  416. overflow: hidden;
  417. transform-origin: 100% 100%;
  418. .text {
  419. margin-top: 40rpx;
  420. text-align: center;
  421. color: grey;
  422. }
  423. .image {
  424. position: absolute;
  425. left: 50%;
  426. bottom: 0;
  427. transform: translate(-50%, 80%);
  428. width: 70%;
  429. aspect-ratio: 1;
  430. .image-inner {
  431. width: 100%;
  432. height: 100%;
  433. }
  434. }
  435. }
  436. .tickt-2 {
  437. position: relative;
  438. background-image: url('https://www.productronicachina.com.cn/resources/files/0227/67c02d4915cc2/tickt2.png');
  439. background-size: 100% 100%;
  440. width: 100%;
  441. aspect-ratio: 1;
  442. .text {
  443. width: 100%;
  444. position: absolute;
  445. bottom: 50rpx;
  446. text-align: center;
  447. color: grey;
  448. font-size: 24rpx;
  449. }
  450. .image {
  451. position: absolute;
  452. left: 50%;
  453. top: 0;
  454. transform: translate(-50%, -20%);
  455. width: 70%;
  456. aspect-ratio: 1;
  457. .image-inner {
  458. width: 100%;
  459. height: 100%;
  460. }
  461. }
  462. overflow: hidden;
  463. }
  464. }
  465. .close {
  466. margin-top: 60rpx;
  467. display: flex;
  468. justify-content: center;
  469. align-items: center;
  470. width: 80rpx;
  471. height: 80rpx;
  472. border: 4rpx solid white;
  473. color: white;
  474. border-radius: 50%;
  475. }
  476. .pop-up {
  477. display: flex;
  478. flex-direction: column;
  479. grid-gap: 20rpx;
  480. width: 80%;
  481. background-color: #FAFAFA;
  482. border-radius: 20rpx;
  483. padding: 57rpx 38rpx 102rpx;
  484. .button-list {
  485. display: flex;
  486. grid-gap: 13rpx;
  487. justify-content: flex-end;
  488. .button {
  489. padding: 15rpx 0;
  490. width: 144rpx;
  491. text-align: center;
  492. font-weight: bold;
  493. font-size: 14rpx;
  494. border-radius: 6rpx;
  495. &.confime {
  496. background-color: #E57519;
  497. color: white;
  498. }
  499. &.cancel {
  500. border: 1rpx solid #94A3B8;
  501. }
  502. }
  503. }
  504. .title {
  505. font-size: 18rpx;
  506. line-height: 1.5;
  507. }
  508. .description {
  509. font-size: 16rpx;
  510. }
  511. .tips {
  512. font-size: 14rpx;
  513. color: #555555;
  514. }
  515. .input {
  516. padding: 10rpx 18rpx;
  517. display: flex;
  518. align-items: center;
  519. border: 1rpx solid #CBD5E1;
  520. border-radius: 8rpx;
  521. .placeholder {
  522. font-size: 16rpx;
  523. span {
  524. color: red;
  525. }
  526. }
  527. .text-input {
  528. flex: 1;
  529. height: 100%;
  530. font-size: 16rpx;
  531. }
  532. }
  533. }
  534. }
  535. .main-container {
  536. background: linear-gradient(180deg, #015A92 0%, #56A3E9 15%, #3484BD 74%, #106591 98%);
  537. padding: 32rpx;
  538. min-height: 100vh;
  539. .theme-title {
  540. //margin-top: 24rpx;
  541. margin-bottom: 32rpx;
  542. position: relative;
  543. height: 130rpx;
  544. display: flex;
  545. justify-content: center;
  546. align-items: center;
  547. .title {
  548. color: white;
  549. font-size: 55rpx;
  550. font-weight: bold;
  551. }
  552. .title-bg {
  553. position: absolute;
  554. left: 0;
  555. top: 0;
  556. height: 100%;
  557. }
  558. }
  559. .award-index {
  560. background-color: #ffffff;
  561. border-radius: 20rpx 20rpx 0 0;
  562. width: 100%;
  563. padding: 36rpx 40rpx;
  564. .award-title {
  565. flex: 1;
  566. min-width: 1px;
  567. font-size: $fontSize1;
  568. }
  569. .award-head {
  570. display: flex;
  571. align-items: center;
  572. .award-button {
  573. line-height: 1;
  574. background-color: #4085C7;
  575. padding: 16rpx 32rpx;
  576. border-radius: 50rpx;
  577. font-size: 24rpx;
  578. color: #ffffff;
  579. &.disabled {
  580. background: #94A3B8;
  581. }
  582. }
  583. }
  584. .award-body {
  585. .award-list {
  586. display: flex;
  587. flex-direction: column;
  588. grid-gap: 24rpx;
  589. margin-top: 32rpx;
  590. .award-list-item {
  591. display: flex;
  592. background: #FAFAFA;
  593. padding: 30rpx 12rpx;
  594. align-items: center;
  595. border-radius: 20rpx;
  596. image {
  597. width: 128rpx;
  598. //height: 128rpx;
  599. }
  600. .award-info {
  601. flex: 1;
  602. min-width: 1rpx;
  603. .award-info-title {
  604. color: #000000;
  605. font-size: $fontSize2;
  606. }
  607. .award-info-desc {
  608. margin-top: 18rpx;
  609. color: #555555;
  610. font-size: $fontSize0;
  611. text {
  612. color: #015A92;
  613. }
  614. }
  615. }
  616. .award-option-btn {
  617. background: #E57519;
  618. font-size: 20rpx;
  619. color: #ffffff;
  620. width: 136rpx;
  621. height: 56rpx;
  622. border-radius: 6rpx;
  623. display: flex;
  624. align-items: center;
  625. justify-content: center;
  626. line-height: 1;
  627. &.disable {
  628. background: #94A3B8;
  629. }
  630. &.cheked {
  631. background: #015A92;
  632. }
  633. }
  634. .award-option {
  635. }
  636. }
  637. }
  638. }
  639. .award-progress {
  640. margin-top: 30rpx;
  641. display: flex;
  642. align-items: center;
  643. position: relative;
  644. width: 100%;
  645. margin-bottom: 90rpx;
  646. .award-progress-bar {
  647. display: block;
  648. width: 90%;
  649. height: 9rpx;
  650. border-radius: 100rpx;
  651. background-color: #D9CC9D;
  652. }
  653. .award-progress-value {
  654. display: block;
  655. position: absolute;
  656. height: 9rpx;
  657. border-radius: 100rpx;
  658. width: 0%;
  659. transition: width 1s ease-in-out;
  660. background-color: #E57519;
  661. }
  662. .award-progress-point-list {
  663. display: flex;
  664. position: absolute;
  665. align-items: center;
  666. width: 100%;
  667. .award-progress-point-item {
  668. position: absolute;
  669. display: flex;
  670. flex-direction: column;
  671. align-items: center;
  672. top: -12rpx;
  673. transform: translateX(-50%);
  674. & > text {
  675. margin-top: 12rpx;
  676. white-space: nowrap;
  677. font-size: $fontSize1;
  678. }
  679. .point {
  680. height: 24rpx;
  681. width: 24rpx;
  682. border-radius: 50%;
  683. border: 1rpx solid #E57519;
  684. background-color: #ffffff;
  685. &:before {
  686. content: '\e849';
  687. font-family: 'iconfont';
  688. color: #ffffff;
  689. line-height: 1;
  690. transition: 1s ease-in-out;
  691. font-size: 20rpx;
  692. opacity: 0;
  693. transform: scale(0);
  694. }
  695. }
  696. &.active {
  697. .point {
  698. background-color: #E57519;
  699. display: flex;
  700. align-items: center;
  701. justify-content: center;
  702. &:before {
  703. opacity: 1;
  704. transform: scale(1);
  705. }
  706. }
  707. }
  708. }
  709. }
  710. }
  711. }
  712. .award-footer {
  713. padding: 42rpx 48rpx;
  714. background-color: #EEEEEE;
  715. border-radius: 0 0 20rpx 20rpx;
  716. .award-footer-title {
  717. font-size: $fontSize3;
  718. }
  719. .award-footer-desc {
  720. padding-left: unset;
  721. margin-top: 20rpx;
  722. font-size: $fontSize1;
  723. line-height: 1.9;
  724. display: flex;
  725. flex-direction: column;
  726. //text-indent: 22rpx;
  727. list-style: decimal;
  728. padding-left: 22rpx;
  729. & > text {
  730. display: list-item;
  731. }
  732. }
  733. }
  734. }
  735. </style>