uniapp 九宫格抽奖

打印 上一主题 下一主题

主题 982|帖子 982|积分 2946

  1. <template>
  2.   <view class="container">
  3.     <view class="navleft" @click="navback">
  4.       <image src="@/static/cj/left.png" mode=""></image>
  5.     </view>
  6.     <view class="navtitle">抽奖</view>
  7.     <view class="bg">
  8.       <image src="https://szcc.test03.qcw800.com/uploads/images/20240708/kIKHgR1pGuYUwq0D9AhTXcl9ufcKmwsVuXn0lKUp.png" mode=""></image>
  9.     </view>
  10.     <view class="title">幸运大抽奖</view>
  11.     <view class="cont">
  12.       <view
  13.         class="cont_item"
  14.         :class="{ 'no-margin': index % 3 === 2, highlight: index === highlightIndex }"
  15.         v-for="(item, index) in drawList"
  16.         :key="index"
  17.         @click="changeCont(item)"
  18.       >
  19.         <view class="cont_img" v-if="item.text !== '抽奖'">
  20.           <image src="@/static/cj/jp.png" mode=""></image>
  21.         </view>
  22.         <view class="cont_cj" v-if="item.text == '抽奖'">
  23.           {{ item.text }}
  24.         </view>
  25.         <view class="cont_txt" v-if="item.text !== '抽奖'">{{ item.title }}</view>
  26.       </view>
  27.     </view>
  28.     <view class="sycj">
  29.       <view class="sycj_txt">剩余抽奖次数:{{ luck }}</view>
  30.     </view>
  31.     <view class="foot">
  32.       <view class="foot_title">
  33.         <view class="foot_left"></view>
  34.         <view class="foot_title">活动规则</view>
  35.         <view class="foot_right"></view>
  36.       </view>
  37.       <view class="foot_txt">
  38.         活动最终解释权归平台所有,活动最终解释权归平台所有,活动最终解释权归平台所有活动最终解释权归平台所有,活动最终解释权归平台所有,活动最终解释权归平台
  39.       </view>
  40.     </view>
  41.     <view>
  42.       <!-- 弹窗 -->
  43.       <uni-popup ref="popup" background-color="#fff">
  44.         <view class="popup-con" v-if="result.title !== '谢谢惠顾'">
  45.           <view class="con_title">提示</view>
  46.           <view class="con_text">恭喜您本次抽中{{ result.title }},是否需要快递邮寄?</view>
  47.           <view class="title_btns">
  48.             <view class="title_err" @click="popupClose">不需要</view>
  49.             <view class="title_res" @click="goAddress">需要</view>
  50.           </view>
  51.         </view>
  52.         <view class="popup-con" v-else>
  53.           <view class="con_title">提示</view>
  54.           <view class="con_text">您本次抽中谢谢惠顾,继续努力</view>
  55.           <view class="conbut" @click="popupClose">确定</view>
  56.           <!-- <view class="title_btns">
  57.             <view class="title_err" @click="popupClose">不需要</view>
  58.             <view class="title_res" @click="goAddress">需要</view>
  59.           </view> -->
  60.         </view>
  61.       </uni-popup>
  62.     </view>
  63.   </view>
  64. </template>
  65. <script>
  66. import { get, post } from '@/utils/request.js';
  67. export default {
  68.   data() {
  69.     return {
  70.       luck: '', //抽奖次数
  71.       drawList: '', //抽奖列表
  72.       isAnimating: false,
  73.       currentIndex: null, // 用于追踪当前正在高亮的列表项的索引
  74.       isLuckyDrawAnimating: false,
  75.       winningItemId: null, // 存储从服务器返回的中奖ID
  76.       highlightIndex: null, // 初始化 highlightIndex
  77.       result: '' //中奖结果
  78.     };
  79.   },
  80.   created() {
  81.     this.getDrawList();
  82.   },
  83.   onShow() {
  84.     this.getDrawNum();
  85.   },
  86.   // 方法部分
  87.   methods: {
  88.     async getDrawNum() {
  89.       const res = await get('/api/user/luckDrawNum', { api_token: uni.getStorageSync('api_token') });
  90.       console.log('抽奖次数', res.data.num);
  91.       this.luck = res.data.num;
  92.     },
  93.     async getDrawList() {
  94.       const res = await get('/api/public/luckDrawList');
  95.       console.log(res);
  96.       this.drawList = res.data;
  97.       // 抽奖按钮配置
  98.       const drawButton = {
  99.         text: '抽奖',
  100.         image: null
  101.       };
  102.       // 在第5项位置插入抽奖按钮
  103.       if (this.drawList.length >= 5) {
  104.         this.drawList.splice(4, 0, drawButton);
  105.       } else {
  106.         // 如果当前列表长度不足5项,可以考虑直接添加到末尾或不做任何操作
  107.         this.drawList.push(drawButton);
  108.       }
  109.     },
  110.     navback() {
  111.       uni.navigateBack();
  112.     },
  113.     popupOpen() {
  114.       this.$refs.popup.open();
  115.     },
  116.     popupClose() {
  117.       this.$refs.popup.close();
  118.       this.getDrawNum();
  119.     },
  120.     goAddress() {
  121.       this.$refs.popup.close();
  122.       this.getDrawNum();
  123.       uni.navigateTo({
  124.         url: '/pages/draw/address'
  125.       });
  126.     },
  127.     changeCont(item) {
  128.       if (item.text === '抽奖') {
  129.         if (this.luck > 0) {
  130.           this.luckyDraw();
  131.         } else {
  132.           uni.showToast({
  133.             title: '没有抽奖次数了',
  134.             icon: 'none',
  135.             duration: 2000
  136.           });
  137.         }
  138.       }
  139.     },
  140.     startLuckyDrawAnimation() {
  141.       this.highlightIndex = 0; // 在这里重置 highlightIndex
  142.       this.isLuckyDrawAnimating = true;
  143.       this.cycleHighlight();
  144.     },
  145.     cycleHighlight() {
  146.       if (this.isLuckyDrawAnimating && this.highlightIndex < this.drawList.length) {
  147.         if (this.drawList[this.highlightIndex].text === '抽奖') {
  148.           // 直接跳过抽奖按钮,不进行高亮
  149.           this.highlightIndex++;
  150.           // 使用立即执行的函数表达式确保在抽奖按钮跳过后,立即进行下一次高亮处理
  151.           (() => {
  152.             setTimeout(() => {
  153.               this.cycleHighlight();
  154.             }, 200);
  155.           })();
  156.         } else {
  157.           // 应用高亮样式
  158.           this.$nextTick(() => {
  159.             // 更新highlightIndex之后再设置高亮,确保DOM更新完成
  160.             setTimeout(() => {
  161.               this.highlightIndex++;
  162.               this.cycleHighlight();
  163.             }, 200);
  164.           });
  165.         }
  166.       } else {
  167.         this.stopAtWinningItem();
  168.       }
  169.     },
  170.     stopAtWinningItem() {
  171.       if (this.winningItemId !== null) {
  172.         this.highlightIndex = this.drawList.findIndex((item) => item.id === this.winningItemId);
  173.         this.result = this.drawList.find((item) => item.id === this.winningItemId);
  174.         console.log('执行', this.result);
  175.         // 这里可以添加额外的中奖动画效果
  176.         this.isLuckyDrawAnimating = false;
  177.         //获取中奖的那一项数据
  178.         this.popupOpen(); // 显示中奖弹窗
  179.       }
  180.     },
  181.     luckyDraw() {
  182.       this.startLuckyDrawAnimation();
  183.       uni.request({
  184.         url: 'https://szcc.test03.qcw800.com/api/user/LuckDraw',
  185.         method: 'GET',
  186.         data: { api_token: uni.getStorageSync('api_token') },
  187.         success: (res) => {
  188.           console.log(res); //{luck_id: "8", luck_draw_record_id: "4"} luck_draw_record_id是中奖id
  189.           this.winningItemId = res.data.data.luck_id;
  190.           // this.winningItemId = '4';
  191.         }
  192.       });
  193.     }
  194.   }
  195. };
  196. </script>
  197. <style lang="scss" scoped>
  198. .highlight {
  199.   box-shadow: 0 0 10rpx 5rpx rgba(255, 255, 0, 0.8) !important;
  200. }
  201. ::v-deep .uni-popup__wrapper {
  202.   width: 662rpx;
  203.   height: 424rpx;
  204.   background: #ffffff;
  205.   border-radius: 16rpx;
  206. }
  207. .popup-con {
  208.   .con_title {
  209.     margin-top: 40rpx;
  210.     font-size: 34rpx;
  211.     font-family: PingFang SC, PingFang SC-Medium;
  212.     font-weight: 500;
  213.     text-align: center;
  214.     color: #1d2129;
  215.     letter-spacing: -0.44rpx;
  216.   }
  217.   .con_text {
  218.     width: 540rpx;
  219.     margin: 62rpx auto;
  220.     font-size: 30rpx;
  221.     font-family: PingFang SC, PingFang SC-Medium;
  222.     font-weight: 500;
  223.     text-align: center;
  224.     color: #1b1b1b;
  225.     line-height: 48rpx;
  226.   }
  227.   .conbut {
  228.     margin: auto;
  229.     width: 286rpx;
  230.     height: 82rpx;
  231.     background: linear-gradient(82deg, #d93624 13%, #f09072 80%);
  232.     border-radius: 16rpx;
  233.     text-align: center;
  234.     line-height: 82rpx;
  235.     color: #fff;
  236.   }
  237.   .title_btns {
  238.     margin: auto;
  239.     width: 602rpx;
  240.     display: flex;
  241.     justify-content: space-between;
  242.     .title_err {
  243.       width: 286rpx;
  244.       height: 82rpx;
  245.       background: #f6f7f9;
  246.       border-radius: 16rpx;
  247.       text-align: center;
  248.       line-height: 82rpx;
  249.       color: #666666;
  250.     }
  251.     .title_res {
  252.       width: 286rpx;
  253.       height: 82rpx;
  254.       background: linear-gradient(82deg, #d93624 13%, #f09072 80%);
  255.       border-radius: 16rpx;
  256.       text-align: center;
  257.       line-height: 82rpx;
  258.       color: #ffffff;
  259.     }
  260.   }
  261. }
  262. .navleft {
  263.   position: absolute;
  264.   top: 108rpx;
  265.   left: 24rpx;
  266.   width: 48rpx;
  267.   height: 48rpx;
  268.   z-index: 2;
  269.   image {
  270.     width: 100%;
  271.     height: 100%;
  272.   }
  273. }
  274. .navtitle {
  275.   z-index: 2;
  276.   position: absolute;
  277.   top: 108rpx;
  278.   left: 342rpx;
  279.   width: 68rpx;
  280.   height: 48rpx;
  281.   font-size: 34rpx;
  282.   font-family: PingFang SC, PingFang SC-Medium;
  283.   font-weight: 500;
  284.   color: #ffffff;
  285. }
  286. .bg {
  287.   position: relative;
  288.   width: 750rpx;
  289.   height: 1624rpx;
  290.   image {
  291.     width: 100%;
  292.     height: 100%;
  293.   }
  294. }
  295. .title {
  296.   position: absolute;
  297.   top: 194rpx;
  298.   left: 126rpx;
  299.   width: 496rpx;
  300.   height: 140rpx;
  301.   font-size: 90rpx;
  302.   font-family: YouSheBiaoTiHei, YouSheBiaoTiHei-Regular;
  303.   font-weight: 400;
  304.   color: #fdf1b8;
  305. }
  306. .cont_cj {
  307.   width: 148rpx;
  308.   height: 148rpx;
  309.   background: radial-gradient(#d94235, #e54f2c 55%, #eb7854);
  310.   border-radius: 12rpx;
  311.   box-shadow: 0rpx 6rpx 16rpx 0rpx rgba(237, 102, 60, 0.56);
  312.   font-size: 48rpx;
  313.   font-family: PingFang SC, PingFang SC-Medium;
  314.   font-weight: 500;
  315.   text-align: center;
  316.   color: #fdf1b8;
  317.   line-height: 148rpx;
  318.   margin-right: 30rpx;
  319. }
  320. .cont {
  321.   position: absolute;
  322.   top: 366rpx;
  323.   left: 66rpx;
  324.   background: url(https://szcc.test03.qcw800.com/uploads/images/20240709/POqESSmKSQmWtm5XekLxwZu9zI0bXIGuIXoEbC8V.png) center;
  325.   width: 504rpx;
  326.   height: 500rpx;
  327.   background-size: 100% 100%;
  328.   padding: 60rpx;
  329.   display: flex;
  330.   flex-wrap: wrap;
  331.   .cont_item {
  332.     width: 148rpx;
  333.     height: 148rpx;
  334.     background: url(https://szcc.test03.qcw800.com/uploads/images/20240709/yIVTR4jIGECShJpwQzOquyntD08ZgshWV2cPAOZK.png);
  335.     background-size: 100% 100%;
  336.     margin-right: 30rpx;
  337.     &.no-margin {
  338.       margin-right: 0;
  339.     }
  340.     .cont_img {
  341.       width: 76rpx;
  342.       height: 76rpx;
  343.       margin: auto;
  344.       image {
  345.         margin-top: 24rpx;
  346.         width: 100%;
  347.         height: 100%;
  348.       }
  349.     }
  350.     .cont_txt {
  351.       margin-top: 24rpx;
  352.       height: 32rpx;
  353.       font-size: 22rpx;
  354.       font-family: PingFang SC, PingFang SC-Medium;
  355.       font-weight: 500;
  356.       text-align: center;
  357.       color: #fd9440;
  358.     }
  359.   }
  360. }
  361. .sycj {
  362.   position: absolute;
  363.   top: 1016rpx;
  364.   left: 66rpx;
  365.   width: 618rpx;
  366.   height: 90rpx;
  367.   background: url(https://szcc.test03.qcw800.com/uploads/images/20240709/d3MRq1bYG9Uy7hdLFvMkk7nvfM7z4jPFj5p97W8E.png) center;
  368.   background-size: 100% 100%;
  369.   .sycj_txt {
  370.     margin-left: 34rpx;
  371.     font-size: 30rpx;
  372.     font-family: PingFang SC, PingFang SC-Semibold;
  373.     font-weight: 600;
  374.     text-align: left;
  375.     line-height: 90rpx;
  376.     color: #ffffff;
  377.   }
  378. }
  379. .foot {
  380.   position: absolute;
  381.   top: 1136rpx;
  382.   left: 66rpx;
  383.   background-color: #fff;
  384.   border-radius: 12rpx;
  385.   width: 572rpx;
  386.   height: 410rpx;
  387.   padding: 24rpx 22rpx 0 24rpx;
  388.   .foot_title {
  389.     display: flex;
  390.     align-items: center;
  391.     justify-content: center;
  392.     .foot_left {
  393.       width: 114rpx;
  394.       height: 6rpx;
  395.       background: linear-gradient(270deg, #eb592b, rgba(240, 144, 114, 0));
  396.     }
  397.     .foot_title {
  398.       margin: 0 24rpx;
  399.       width: 160rpx;
  400.       height: 56rpx;
  401.       font-size: 40rpx;
  402.       font-family: PingFang SC, PingFang SC-Semibold;
  403.       font-weight: 600;
  404.       text-align: left;
  405.       color: #ed581d;
  406.     }
  407.     .foot_right {
  408.       width: 114rpx;
  409.       height: 6rpx;
  410.       background: linear-gradient(90deg, #eb592b, rgba(240, 144, 114, 0));
  411.     }
  412.   }
  413.   .foot_txt {
  414.     margin-top: 22rpx;
  415.     width: 572rpx;
  416.     height: 256rpx;
  417.     font-size: 26rpx;
  418.     font-family: PingFang SC, PingFang SC-Regular;
  419.     font-weight: 400;
  420.     text-align: left;
  421.     color: #333333;
  422.     line-height: 44rpx;
  423.   }
  424. }
  425. </style>
复制代码
 

 


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

宝塔山

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表