detail.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766
  1. <template>
  2. <view class="ticket-wrap">
  3. <!-- #ifdef MP-ALIPAY -->
  4. <view v-if="pagesNum > 1">
  5. <u-navbar :placeholder="true" bgColor="#fff" :autoBack="true" :border="true" title="盲票详情" leftIconSize="0"></u-navbar>
  6. </view>
  7. <view v-else>
  8. <u-navbar leftIconSize="0" :placeholder="true" bgColor="#fff" title="盲票详情">
  9. <view class="nav-left flex" slot="left" @click="toIndex">
  10. <u-icon name="home" size="20" color="#333"></u-icon>
  11. <view class="nav-left__code">首页</view>
  12. </view>
  13. </u-navbar>
  14. </view>
  15. <!-- #endif -->
  16. <!-- #ifndef MP-ALIPAY -->
  17. <view v-if="pagesNum > 1">
  18. <u-navbar :placeholder="true" bgColor="#fff" :autoBack="true" :border="true" title="盲票详情"></u-navbar>
  19. </view>
  20. <view v-else>
  21. <u-navbar leftIconSize="0" :placeholder="true" bgColor="#fff" title="盲票详情">
  22. <view class="nav-left flex" slot="left" @click="toIndex">
  23. <u-icon name="home" size="20" color="#333"></u-icon>
  24. <view class="nav-left__code">首页</view>
  25. </view>
  26. </u-navbar>
  27. </view>
  28. <!-- #endif -->
  29. <!-- 奖品轮播 -->
  30. <view class="prize">
  31. <!-- 查看规则 -->
  32. <view class="prize-rule" @click="toRule">
  33. <view class="prize-rule-content flex">
  34. <image src="../../static/index/index_tip.png" mode="scaleToFill"></image>
  35. <text>查看规则</text>
  36. </view>
  37. </view>
  38. <!-- 奖品 -->
  39. <swiper class="prize-swiper" previous-margin="100px" next-margin="100px" :interval="4000" :autoplay="true" :circular="true" @change="changePrizeSwiper">
  40. <swiper-item :class="prizeIndex == index ? 'swiper-item' : 'swiper-item-side'" v-for="(item, index) in prizeList.slice(0, 10)" :key="index">
  41. <view class="prize-swiper-item flex" @click="toPrizeGoods(item)">
  42. <image :class="prizeIndex == index ? 'img' : 'img-side'" :src="item.picUrl" mode="aspectFit"></image>
  43. </view>
  44. </swiper-item>
  45. </swiper>
  46. <!-- 奖品价格 -->
  47. <view class="prize-price flex">
  48. <view class="prize-price-present" v-if="prizeInfo.prizeType != 'coin'">¥{{ $numberFormat(prizeInfo.value) }}</view>
  49. <view class="prize-price-present" v-else>{{ prizeInfo.value }}个</view>
  50. <view class="prize-price-txt ells-one">{{ prizeInfo.title }}</view>
  51. <view class="prize-price__ticket-price flex">
  52. <image src="../../static/ticketBox/ticket_block.png" mode="scaleToFill"></image>
  53. <view class="txt">¥{{ $numberFormat(info.salePrice) }}</view>
  54. </view>
  55. <view class="prize-price-past" v-if="info.originPrice != 0">原价:¥{{ $numberFormat(info.originPrice) }}</view>
  56. </view>
  57. <!-- 开启盲票 -->
  58. <view class="ticket-btn flex">
  59. <image class="ticket-btn-game" src="../../static/ticketBox/ticket_game.png" mode="scaleToFill" @click="toRollingGame"></image>
  60. <view class="ticket-btn-center flex" @click="exchange">
  61. <image src="../../static/ticketBox/ticket_btn_center.png" mode="scaleToFill"></image>
  62. <view class="ticket-btn-center-txt">刮开盲票</view>
  63. </view>
  64. <view class="ticket-btn-share flex">
  65. <!-- #ifdef MP-WEIXIN -->
  66. <image src="../../static/ticketBox/ticket_share.png" mode="scaleToFill" @click="toShare"></image>
  67. <button type="default" open-type="share" v-if="loginState"></button>
  68. <!-- #endif -->
  69. </view>
  70. </view>
  71. </view>
  72. <!-- 盲票奖品说明 -->
  73. <view class="explain flex">
  74. <image class="image-left" src="../../static/ticketBox/ticket_explain_left.png" mode="aspectFit"></image>
  75. <view class="explain-title">刮开必出以下宝贝之一</view>
  76. <image class="image-right" src="../../static/ticketBox/ticket_explain_right.png" mode="aspectFit"></image>
  77. </view>
  78. <!-- 盲票奖品数量、概率 -->
  79. <view class="prize-total">
  80. <view class="prize-total-num">共{{ total }}款</view>
  81. <!-- 中奖概率 -->
  82. <view class="prize-total-chance flex">
  83. <view class="prize-total-chance-content flex" v-for="(item, index) in info.ticketAwardsLabelList">
  84. <image :src="item.picUrl" mode="scaleToFill"></image>
  85. <text>{{ item.hitRate }}%</text>
  86. </view>
  87. </view>
  88. <!-- 文字说明 -->
  89. <view class="prize-total-txt">因概率对小数点后三位进行四舍五入处理,故存在总值不为100%的可能。商品抽奖存在概率性,付费请谨慎!未成年人请在家长监督下使用。</view>
  90. </view>
  91. <!-- 盲票奖品列表 -->
  92. <view class="prize-list">
  93. <view class="prize-list-item flex" v-for="(item, index) in prizeList" :key="index" @click="toPrizeGoods(item)">
  94. <image :src="item.picUrl" mode="aspectFit"></image>
  95. <view class="prize-list-item-info flex">
  96. <view class="title ells">{{ item.title }}</view>
  97. <view class="price" v-if="item.prizeType != 'coin'">¥{{ $numberFormat(item.value) }}</view>
  98. <view class="price" v-else>{{ item.value }}个</view>
  99. </view>
  100. <view class="prize-list-item-grade">
  101. <image :src="item.awardsLabelPicUrl" />
  102. </view>
  103. </view>
  104. <u-loadmore :line="true" v-if="prizeList.length>10" :status="status" :loading-text="'努力加载中'" :nomore-text="'已经到底了'" />
  105. </view>
  106. <view class="footer-fixed" v-if="btnFixed">
  107. <view class="footer-fixed-btn flex">
  108. <view class="footer-fixed-btn-center flex" @click="exchange">
  109. <image src="../../static/ticketBox/ticket_btn_center.png" mode="scaleToFill"></image>
  110. <view class="footer-fixed-btn-center-txt">刮开盲票</view>
  111. </view>
  112. </view>
  113. </view>
  114. <!-- 支付弹层 -->
  115. <pay-popup :pay-show="payShow" :pay-info="payInfo" @close="close" @success="toProcess" v-if="payShow" />
  116. </view>
  117. </template>
  118. <script>
  119. import env from '../../config/env.js'
  120. import $http from '@/utils/request.js'
  121. import PayPopup from '../../components/pay-popup/pay-popup.vue'
  122. export default {
  123. components: {
  124. PayPopup
  125. },
  126. data() {
  127. return {
  128. boxId: '',
  129. picUrlArr: [],
  130. info: {},
  131. status: 'nomore',//上拉刷新状态
  132. pageNum: 1,
  133. total: 0,
  134. prizeList: [],
  135. payShow: false,
  136. payInfo: {},
  137. pagesNum: null,
  138. sceneArr: null,
  139. prizeIndex: 0,
  140. contnetHeight: 0,
  141. btnFixed: false,
  142. prizeInfo: {},
  143. userInfo: {},
  144. loginState: false,
  145. };
  146. },
  147. onLoad(opthios) {
  148. if (opthios.boxId) {
  149. this.boxId = opthios.boxId
  150. }
  151. if (opthios.scene) {
  152. let sceneStr = decodeURIComponent(opthios.scene)
  153. this.sceneArr = sceneStr.split('&')
  154. this.boxId = this.sceneArr[0]
  155. uni.setStorageSync('shareUid', this.sceneArr[1])
  156. uni.setStorageSync('shareType', this.sceneArr[2])
  157. }
  158. if (opthios.userId) {
  159. uni.setStorageSync('shareUid', opthios.userId)
  160. }
  161. if (opthios.type) {
  162. uni.setStorageSync('shareType', opthios.type)
  163. }
  164. /**
  165. * 外部app跳转接受的参数
  166. * shareUid: 用户ID
  167. * shareType: 分享类型
  168. * */
  169. if(opthios.uid) {
  170. uni.setStorageSync('shareUid', opthios.uid)
  171. uni.setStorageSync('shareType', opthios.t)
  172. }
  173. },
  174. mounted() {
  175. let _this = this;
  176. let info = uni.createSelectorQuery().select(".prize");
  177. info.boundingClientRect(function(data) { //data - 各种参数
  178. _this.contnetHeight = data.height
  179. }).exec()
  180. },
  181. onPageScroll: function(e) {
  182. let _this = this;
  183. _this.btnFixed = _this.contnetHeight <= e.scrollTop;
  184. },
  185. onShow() {
  186. this.loginState = uni.getStorageSync('token') ? true : false
  187. if(this.loginState) {
  188. this.getBaseInfo()
  189. }
  190. this.pagesNum = getCurrentPages().length
  191. if (this.boxId) {
  192. this.getDetail()
  193. }
  194. },
  195. methods: {
  196. changePrizeSwiper({ detail }) {
  197. this.prizeIndex = detail.current
  198. this.prizeInfo = this.prizeList[detail.current]
  199. },
  200. getDetail() {
  201. uni.showLoading({
  202. title: '加载中'
  203. });
  204. $http.post('/api/v1/mp/user/mall/ticket/detail/new', {
  205. boxId: this.boxId,
  206. noToken: true
  207. }).then(res => {
  208. uni.hideLoading();
  209. if (res.code == 0) {
  210. this.info = {
  211. ...res.data,
  212. picUrl: res.data.picUrl.split(',').map(item => env.filePublic + item + '?imageView2/2/w/375'),
  213. ticketAwardsLabelList: res.data.ticketAwardsLabelList.map(item => {
  214. return { ...item, picUrl: env.filePublic + item.picUrl }
  215. })
  216. }
  217. this.pageNum = 1
  218. this.total = 0
  219. this.prizeList = []
  220. this.getPrizeList()
  221. }
  222. }).catch(() => {
  223. uni.hideLoading();
  224. })
  225. },
  226. getPrizeList() {
  227. $http.post(`/api/v1/mp/user/ticket/prize/list/${this.boxId}?pageNum=${this.pageNum}&pageSize=10`,{}).then(res => {
  228. if (res.code == 0) {
  229. let prizeList = res.rows
  230. prizeList.forEach(item => {
  231. item.picUrl = env.filePublic + item.picUrl.split(',')[0] + '?imageView2/2/w/375'
  232. item.awardsLabelPicUrl = env.filePublic + item.awardsLabelPicUrl
  233. })
  234. this.total = res.total
  235. this.prizeList = this.prizeList.concat(prizeList)
  236. this.prizeInfo = this.prizeList[this.prizeIndex]
  237. }
  238. })
  239. },
  240. getPageNum() {
  241. let pages = getCurrentPages();
  242. },
  243. close() {
  244. this.payShow = false
  245. },
  246. toProcess(id) {
  247. this.payShow = false
  248. uni.navigateTo({
  249. url: `/packagePrize/rolling/index?boxId=${ this.info.boxId }&orderId=${ id }&isTry=0`
  250. })
  251. },
  252. exchange() {
  253. let data = {
  254. userCouponIds: [],
  255. autoCoupon: 1,
  256. boxId: this.info.boxId,
  257. orderNum: 1
  258. }
  259. $http.post('/api/v1/mp/user/ticket/order/settle', data).then(res => {
  260. if (res.code == 0) {
  261. let info = {
  262. ...res.data,
  263. ...this.info,
  264. picUrl: this.info.picUrl[0],
  265. couponTitle: res.data && res.data.couponList && res.data.couponList.length && res
  266. .data.couponList[0].title,
  267. couponId: res.data && res.data.couponList && res.data.couponList.length && res.data
  268. .couponList[0].id
  269. }
  270. this.payInfo = info
  271. this.payShow = true
  272. }
  273. })
  274. },
  275. toRollingGame() {
  276. if (!uni.getStorageSync('token')) {
  277. uni.navigateTo({
  278. url: '/pages/login/index'
  279. })
  280. return
  281. }
  282. uni.navigateTo({
  283. url: `/packagePrize/rolling/index?boxId=${ this.info.boxId }&isTry=1`
  284. })
  285. },
  286. toShare() {
  287. this.getBaseInfo()
  288. // if (!uni.getStorageSync('token')) {
  289. // uni.navigateTo({
  290. // url: "/pages/login/index"
  291. // })
  292. // return
  293. // }
  294. // uni.navigateTo({
  295. // url: `/packageOperate/share/index?boxId=${ this.info.boxId }`
  296. // })
  297. },
  298. toIndex() {
  299. uni.switchTab({
  300. url: '/pages/index/index'
  301. })
  302. },
  303. // 点击规则说明
  304. toRule() {
  305. uni.navigateTo({
  306. url: '/packageOther/rule/index'
  307. })
  308. },
  309. toPrizeGoods(item) {
  310. if (item.prizeType == "goods") {
  311. uni.navigateTo({
  312. url: `/packagePrize/goods/detail?id=${ item.refId }`
  313. })
  314. }
  315. //门店优惠券
  316. if (item.prizeType == "coupon" || item.prizeType == "coupon_pkg") {
  317. uni.navigateTo({
  318. url: `/packagePrize/goods/detail?id=425`
  319. })
  320. }
  321. // 盲豆
  322. if (item.prizeType == "coin") {
  323. uni.navigateTo({
  324. url: `/packagePrize/goods/detail?id=424`
  325. })
  326. }
  327. },
  328. getBaseInfo() {
  329. $http.post('/api/v1/mp/user/getLoginUserinfo', {}).then(res => {
  330. uni.hideLoading();
  331. if (res.code == 0) {
  332. this.userInfo = res.data
  333. }
  334. })
  335. },
  336. },
  337. onShareAppMessage(res) {
  338. return {
  339. title: '一起来刮盲票吧',
  340. path: `/pages/ticketBox/detail?boxId=${ this.info.boxId }&userId=${ this.userInfo.userId }&type=1`,
  341. type: 2,
  342. }
  343. },
  344. //分享朋友圈
  345. onShareTimeline() {
  346. return {
  347. title: '一起来刮盲票吧',
  348. // query: { userId: this.userInfo.userId,
  349. // type: 1, },
  350. query: `boxId=${ this.info.boxId }&userId=${ this.userInfo.userId?this.userInfo.userId:null }&type=1`
  351. }
  352. },
  353. onReachBottom() {
  354. if(this.total < this.pageNum * 10) return ;
  355. this.status = 'loading';
  356. // setTimeout(() => {
  357. ++this.pageNum
  358. if(this.total < this.pageNum * 10) this.status = 'nomore';
  359. else this.status = 'loading';
  360. this.getPrizeList()
  361. // }, 2000)
  362. },
  363. }
  364. </script>
  365. <style lang="scss" scoped>
  366. .ticket-wrap {
  367. background: #FFF3EB;
  368. padding-bottom: 100rpx;
  369. }
  370. .nav-left {
  371. &__code {
  372. margin-left: 10rpx;
  373. }
  374. }
  375. // 奖品轮播
  376. .prize {
  377. // height: 71vh;
  378. background: url(https://mp-public-1310078123.cos.ap-shanghai.myqcloud.com/v2/detail_3.png) center center no-repeat;
  379. background-size: 100vw 71vh;
  380. margin-bottom: 14rpx;
  381. // 查看规则
  382. &-rule {
  383. display: flex;
  384. align-items: center;
  385. height: 34rpx;
  386. padding: 44rpx 0 0 34rpx;
  387. margin-bottom: 60rpx;
  388. &-content {
  389. image {
  390. width: 34rpx;
  391. height: 34rpx;
  392. margin-right: 14rpx;
  393. }
  394. text {
  395. font-size: 40rpx;
  396. font-family: 'YouSheBiaoTiHei';
  397. font-weight: 400;
  398. color: #FFFFFF;
  399. }
  400. }
  401. }
  402. // 奖品轮播
  403. &-swiper {
  404. height: 534rpx;
  405. .swiper-item {
  406. width: 100%;
  407. height: 100%;
  408. // 80
  409. }
  410. .swiper-item-side {
  411. width: 100%;
  412. height: 100%;
  413. margin: 0;
  414. }
  415. &-item {
  416. height: 267px;
  417. .img {
  418. position: absolute;
  419. width: 100%;
  420. height: 100%;
  421. animation: prizeBig .3s;
  422. }
  423. .img-side {
  424. width: 60%;
  425. height: 60%;
  426. animation: prizeMini .3s;
  427. opacity: .5;
  428. }
  429. }
  430. }
  431. // 奖品价格
  432. &-price {
  433. flex-direction: column;
  434. justify-content: space-between;
  435. height: 14vh;
  436. margin-bottom: 30rpx;
  437. &-present {
  438. font-size: 26rpx;
  439. font-weight: bold;
  440. }
  441. &-txt {
  442. padding: 0 34rpx;
  443. font-size: 30rpx;
  444. font-weight: bold;
  445. }
  446. &__ticket-price {
  447. position: relative;
  448. height: 66rpx;
  449. image {
  450. width: 276rpx;
  451. height: 66rpx;
  452. }
  453. .txt {
  454. position: absolute;
  455. font-size: 40rpx;
  456. line-height: 66rpx;
  457. font-family: YouSheBiaoTiHei;
  458. font-weight: 400;
  459. color: #FFFFFF;
  460. }
  461. }
  462. &-past {
  463. font-size: 26rpx;
  464. font-weight: bold;
  465. text-decoration: line-through;
  466. color: #5E3909;
  467. }
  468. }
  469. // 开启盲票
  470. .ticket-btn {
  471. justify-content: space-between;
  472. height: 10vh;
  473. padding: 0 34rpx;
  474. &-game {
  475. width: 110rpx;
  476. height: 110rpx;
  477. }
  478. &-center {
  479. position: relative;
  480. height: 100%;
  481. image {
  482. height: 100%;
  483. width: 55vw;
  484. }
  485. &-txt {
  486. position: absolute;
  487. top: 30rpx;
  488. font-size: 72rpx;
  489. line-height: 72rpx;
  490. font-family: YouSheBiaoTiHei;
  491. font-weight: 400;
  492. color: #FFFFFF;
  493. }
  494. }
  495. &-share {
  496. position: relative;
  497. width: 110rpx;
  498. height: 110rpx;
  499. image {
  500. position: absolute;
  501. width: 110rpx;
  502. height: 110rpx;
  503. }
  504. ::v-deep button {
  505. position: absolute;
  506. z-index: 5;
  507. width: 110rpx;
  508. height: 110rpx;
  509. background: none;
  510. border: none !important;
  511. }
  512. ::v-deep uni-button:after {
  513. border: none !important;
  514. }
  515. ::v-deep button:after {
  516. border: none !important;
  517. }
  518. }
  519. }
  520. }
  521. // 盲票奖品说明
  522. .explain {
  523. width: 100vw;
  524. position: relative;
  525. height: 40rpx;
  526. margin-bottom: 32rpx;
  527. .image-left {
  528. width: 18vw;
  529. height: 40rpx;
  530. }
  531. .image-right {
  532. width: 18vw;
  533. height: 40rpx;
  534. }
  535. &-title {
  536. font-size: 46rpx;
  537. line-height: 46rpx;
  538. font-family: YouSheBiaoTiHei;
  539. font-weight: 400;
  540. color: #5E3909;
  541. padding: 0 8rpx;
  542. }
  543. }
  544. // 盲票奖品数量、概率
  545. .prize-total {
  546. margin-bottom: 34rpx;
  547. &-num {
  548. font-size: 26rpx;
  549. text-align: center;
  550. font-weight: bold;
  551. color: #744111;
  552. margin-bottom: 24rpx;
  553. }
  554. &-chance {
  555. margin-bottom: 32rpx;
  556. &-content {
  557. margin-right: 40rpx;
  558. image {
  559. width: 56rpx;
  560. height: 50rpx;
  561. }
  562. text {
  563. font-size: 28rpx;
  564. font-family: YouSheBiaoTiHei;
  565. font-weight: 400;
  566. color: #622C06;
  567. }
  568. }
  569. &-content:last-child {
  570. margin: 0;
  571. }
  572. }
  573. &-txt {
  574. padding: 0 100rpx;
  575. font-size: 26rpx;
  576. font-weight: 500;
  577. color: #956B33;
  578. line-height: 42rpx;
  579. text-align: center;
  580. }
  581. }
  582. // 盲票奖品列表
  583. .prize-list {
  584. padding: 0 34rpx 70rpx;
  585. &-item {
  586. position: relative;
  587. padding: 0 110rpx 0 84rpx;
  588. justify-content: flex-start;
  589. height: 264rpx;
  590. background: #FFFFFF;
  591. border-radius: 22rpx;
  592. margin-bottom: 26rpx;
  593. image {
  594. width: 166rpx;
  595. height: 166rpx;
  596. margin-right: 34rpx;
  597. }
  598. &-info {
  599. height: 166rpx;
  600. flex: 1;
  601. flex-direction: column;
  602. align-items: flex-start;
  603. justify-content: space-between;
  604. .title {
  605. font-size: 30rpx;
  606. font-weight: bold;
  607. line-height: 42rpx;
  608. }
  609. .price {
  610. font-size: 36rpx;
  611. font-weight: bold;
  612. color: #FF4208;
  613. line-height: 42rpx;
  614. }
  615. }
  616. &-grade {
  617. position: absolute;
  618. top: -12rpx;
  619. left: 0;
  620. image {
  621. width: 66rpx;
  622. height: 60rpx;
  623. }
  624. }
  625. }
  626. }
  627. // 滚动固定按钮
  628. .footer-fixed {
  629. position: fixed;
  630. bottom: var(--window-bottom);
  631. left: 0;
  632. right: 0;
  633. &-btn {
  634. height: 10vh;
  635. &-center {
  636. position: relative;
  637. height: 100%;
  638. image {
  639. height: 100%;
  640. width: 55vw;
  641. }
  642. &-txt {
  643. position: absolute;
  644. top: 30rpx;
  645. font-size: 72rpx;
  646. line-height: 72rpx;
  647. font-family: YouSheBiaoTiHei;
  648. font-weight: 400;
  649. color: #FFFFFF;
  650. }
  651. }
  652. }
  653. }
  654. // 奖品缩小动画
  655. @keyframes prizeMini
  656. {
  657. from {
  658. width: 100%;
  659. height: 100%;
  660. }
  661. to {
  662. width: 60%;
  663. height: 60%;
  664. }
  665. }
  666. // 奖品放大动画
  667. @keyframes prizeBig
  668. {
  669. from {
  670. width: 60%;
  671. height: 60%;
  672. }
  673. to {
  674. width: 100%;
  675. height: 100%;
  676. }
  677. }
  678. </style>