award.vue 21 KB

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