award.vue 19 KB

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