uniapp 九宫格抽奖

复制代码
<template>
  <view class="container">
    <view class="navleft" @click="navback">
      <image src="@/static/cj/left.png" mode=""></image>
    </view>
    <view class="navtitle">抽奖</view>
    <view class="bg">
      <image src="https://szcc.test03.qcw800.com/uploads/images/20240708/kIKHgR1pGuYUwq0D9AhTXcl9ufcKmwsVuXn0lKUp.png" mode=""></image>
    </view>
    <view class="title">幸运大抽奖</view>
    <view class="cont">
      <view
        class="cont_item"
        :class="{ 'no-margin': index % 3 === 2, highlight: index === highlightIndex }"
        v-for="(item, index) in drawList"
        :key="index"
        @click="changeCont(item)"
      >
        <view class="cont_img" v-if="item.text !== '抽奖'">
          <image src="@/static/cj/jp.png" mode=""></image>
        </view>
        <view class="cont_cj" v-if="item.text == '抽奖'">
          {{ item.text }}
        </view>
        <view class="cont_txt" v-if="item.text !== '抽奖'">{{ item.title }}</view>
      </view>
    </view>

    <view class="sycj">
      <view class="sycj_txt">剩余抽奖次数:{{ luck }}</view>
    </view>
    <view class="foot">
      <view class="foot_title">
        <view class="foot_left"></view>
        <view class="foot_title">活动规则</view>
        <view class="foot_right"></view>
      </view>
      <view class="foot_txt">
        活动最终解释权归平台所有,活动最终解释权归平台所有,活动最终解释权归平台所有活动最终解释权归平台所有,活动最终解释权归平台所有,活动最终解释权归平台
      </view>
    </view>
    <view>
      <!-- 弹窗 -->
      <uni-popup ref="popup" background-color="#fff">
        <view class="popup-con" v-if="result.title !== '谢谢惠顾'">
          <view class="con_title">提示</view>
          <view class="con_text">恭喜您本次抽中{{ result.title }},是否需要快递邮寄?</view>
          <view class="title_btns">
            <view class="title_err" @click="popupClose">不需要</view>
            <view class="title_res" @click="goAddress">需要</view>
          </view>
        </view>
        <view class="popup-con" v-else>
          <view class="con_title">提示</view>
          <view class="con_text">您本次抽中谢谢惠顾,继续努力</view>
          <view class="conbut" @click="popupClose">确定</view>
          <!-- <view class="title_btns">
            <view class="title_err" @click="popupClose">不需要</view>
            <view class="title_res" @click="goAddress">需要</view>
          </view> -->
        </view>
      </uni-popup>
    </view>
  </view>
</template>

<script>
import { get, post } from '@/utils/request.js';
export default {
  data() {
    return {
      luck: '', //抽奖次数
      drawList: '', //抽奖列表
      isAnimating: false,
      currentIndex: null, // 用于追踪当前正在高亮的列表项的索引
      isLuckyDrawAnimating: false,
      winningItemId: null, // 存储从服务器返回的中奖ID
      highlightIndex: null, // 初始化 highlightIndex
      result: '' //中奖结果
    };
  },
  created() {
    this.getDrawList();
  },
  onShow() {
    this.getDrawNum();
  },
  // 方法部分
  methods: {
    async getDrawNum() {
      const res = await get('/api/user/luckDrawNum', { api_token: uni.getStorageSync('api_token') });
      console.log('抽奖次数', res.data.num);
      this.luck = res.data.num;
    },
    async getDrawList() {
      const res = await get('/api/public/luckDrawList');
      console.log(res);
      this.drawList = res.data;
      // 抽奖按钮配置
      const drawButton = {
        text: '抽奖',
        image: null
      };
      // 在第5项位置插入抽奖按钮
      if (this.drawList.length >= 5) {
        this.drawList.splice(4, 0, drawButton);
      } else {
        // 如果当前列表长度不足5项,可以考虑直接添加到末尾或不做任何操作
        this.drawList.push(drawButton);
      }
    },
    navback() {
      uni.navigateBack();
    },
    popupOpen() {
      this.$refs.popup.open();
    },
    popupClose() {
      this.$refs.popup.close();
      this.getDrawNum();
    },
    goAddress() {
      this.$refs.popup.close();
      this.getDrawNum();
      uni.navigateTo({
        url: '/pages/draw/address'
      });
    },
    changeCont(item) {
      if (item.text === '抽奖') {
        if (this.luck > 0) {
          this.luckyDraw();
        } else {
          uni.showToast({
            title: '没有抽奖次数了',
            icon: 'none',
            duration: 2000
          });
        }
      }
    },
    startLuckyDrawAnimation() {
      this.highlightIndex = 0; // 在这里重置 highlightIndex
      this.isLuckyDrawAnimating = true;
      this.cycleHighlight();
    },
    cycleHighlight() {
      if (this.isLuckyDrawAnimating && this.highlightIndex < this.drawList.length) {
        if (this.drawList[this.highlightIndex].text === '抽奖') {
          // 直接跳过抽奖按钮,不进行高亮
          this.highlightIndex++;
          // 使用立即执行的函数表达式确保在抽奖按钮跳过后,立即进行下一次高亮处理
          (() => {
            setTimeout(() => {
              this.cycleHighlight();
            }, 200);
          })();
        } else {
          // 应用高亮样式
          this.$nextTick(() => {
            // 更新highlightIndex之后再设置高亮,确保DOM更新完成
            setTimeout(() => {
              this.highlightIndex++;
              this.cycleHighlight();
            }, 200);
          });
        }
      } else {
        this.stopAtWinningItem();
      }
    },
    stopAtWinningItem() {
      if (this.winningItemId !== null) {
        this.highlightIndex = this.drawList.findIndex((item) => item.id === this.winningItemId);
        this.result = this.drawList.find((item) => item.id === this.winningItemId);
        console.log('执行', this.result);
        // 这里可以添加额外的中奖动画效果
        this.isLuckyDrawAnimating = false;
        //获取中奖的那一项数据
        this.popupOpen(); // 显示中奖弹窗
      }
    },
    luckyDraw() {
      this.startLuckyDrawAnimation();
      uni.request({
        url: 'https://szcc.test03.qcw800.com/api/user/LuckDraw',
        method: 'GET',
        data: { api_token: uni.getStorageSync('api_token') },
        success: (res) => {
          console.log(res); //{luck_id: "8", luck_draw_record_id: "4"} luck_draw_record_id是中奖id
          this.winningItemId = res.data.data.luck_id;
          // this.winningItemId = '4';
        }
      });
    }
  }
};
</script>

<style lang="scss" scoped>
.highlight {
  box-shadow: 0 0 10rpx 5rpx rgba(255, 255, 0, 0.8) !important;
}
::v-deep .uni-popup__wrapper {
  width: 662rpx;
  height: 424rpx;
  background: #ffffff;
  border-radius: 16rpx;
}
.popup-con {
  .con_title {
    margin-top: 40rpx;
    font-size: 34rpx;
    font-family: PingFang SC, PingFang SC-Medium;
    font-weight: 500;
    text-align: center;
    color: #1d2129;
    letter-spacing: -0.44rpx;
  }
  .con_text {
    width: 540rpx;
    margin: 62rpx auto;
    font-size: 30rpx;
    font-family: PingFang SC, PingFang SC-Medium;
    font-weight: 500;
    text-align: center;
    color: #1b1b1b;
    line-height: 48rpx;
  }
  .conbut {
    margin: auto;
    width: 286rpx;
    height: 82rpx;
    background: linear-gradient(82deg, #d93624 13%, #f09072 80%);
    border-radius: 16rpx;
    text-align: center;
    line-height: 82rpx;
    color: #fff;
  }
  .title_btns {
    margin: auto;
    width: 602rpx;
    display: flex;
    justify-content: space-between;
    .title_err {
      width: 286rpx;
      height: 82rpx;
      background: #f6f7f9;
      border-radius: 16rpx;
      text-align: center;
      line-height: 82rpx;
      color: #666666;
    }
    .title_res {
      width: 286rpx;
      height: 82rpx;
      background: linear-gradient(82deg, #d93624 13%, #f09072 80%);
      border-radius: 16rpx;
      text-align: center;
      line-height: 82rpx;
      color: #ffffff;
    }
  }
}
.navleft {
  position: absolute;
  top: 108rpx;
  left: 24rpx;
  width: 48rpx;
  height: 48rpx;
  z-index: 2;
  image {
    width: 100%;
    height: 100%;
  }
}
.navtitle {
  z-index: 2;
  position: absolute;
  top: 108rpx;
  left: 342rpx;
  width: 68rpx;
  height: 48rpx;
  font-size: 34rpx;
  font-family: PingFang SC, PingFang SC-Medium;
  font-weight: 500;
  color: #ffffff;
}
.bg {
  position: relative;
  width: 750rpx;
  height: 1624rpx;
  image {
    width: 100%;
    height: 100%;
  }
}
.title {
  position: absolute;
  top: 194rpx;
  left: 126rpx;
  width: 496rpx;
  height: 140rpx;
  font-size: 90rpx;
  font-family: YouSheBiaoTiHei, YouSheBiaoTiHei-Regular;
  font-weight: 400;
  color: #fdf1b8;
}
.cont_cj {
  width: 148rpx;
  height: 148rpx;
  background: radial-gradient(#d94235, #e54f2c 55%, #eb7854);
  border-radius: 12rpx;
  box-shadow: 0rpx 6rpx 16rpx 0rpx rgba(237, 102, 60, 0.56);
  font-size: 48rpx;
  font-family: PingFang SC, PingFang SC-Medium;
  font-weight: 500;
  text-align: center;
  color: #fdf1b8;
  line-height: 148rpx;
  margin-right: 30rpx;
}

.cont {
  position: absolute;
  top: 366rpx;
  left: 66rpx;
  background: url(https://szcc.test03.qcw800.com/uploads/images/20240709/POqESSmKSQmWtm5XekLxwZu9zI0bXIGuIXoEbC8V.png) center;
  width: 504rpx;
  height: 500rpx;
  background-size: 100% 100%;
  padding: 60rpx;
  display: flex;
  flex-wrap: wrap;

  .cont_item {
    width: 148rpx;
    height: 148rpx;
    background: url(https://szcc.test03.qcw800.com/uploads/images/20240709/yIVTR4jIGECShJpwQzOquyntD08ZgshWV2cPAOZK.png);
    background-size: 100% 100%;
    margin-right: 30rpx;
    &.no-margin {
      margin-right: 0;
    }
    .cont_img {
      width: 76rpx;
      height: 76rpx;
      margin: auto;
      image {
        margin-top: 24rpx;
        width: 100%;
        height: 100%;
      }
    }
    .cont_txt {
      margin-top: 24rpx;
      height: 32rpx;
      font-size: 22rpx;
      font-family: PingFang SC, PingFang SC-Medium;
      font-weight: 500;
      text-align: center;
      color: #fd9440;
    }
  }
}
.sycj {
  position: absolute;
  top: 1016rpx;
  left: 66rpx;
  width: 618rpx;
  height: 90rpx;
  background: url(https://szcc.test03.qcw800.com/uploads/images/20240709/d3MRq1bYG9Uy7hdLFvMkk7nvfM7z4jPFj5p97W8E.png) center;
  background-size: 100% 100%;
  .sycj_txt {
    margin-left: 34rpx;
    font-size: 30rpx;
    font-family: PingFang SC, PingFang SC-Semibold;
    font-weight: 600;
    text-align: left;
    line-height: 90rpx;
    color: #ffffff;
  }
}
.foot {
  position: absolute;
  top: 1136rpx;
  left: 66rpx;
  background-color: #fff;
  border-radius: 12rpx;
  width: 572rpx;
  height: 410rpx;
  padding: 24rpx 22rpx 0 24rpx;
  .foot_title {
    display: flex;
    align-items: center;
    justify-content: center;
    .foot_left {
      width: 114rpx;
      height: 6rpx;
      background: linear-gradient(270deg, #eb592b, rgba(240, 144, 114, 0));
    }
    .foot_title {
      margin: 0 24rpx;
      width: 160rpx;
      height: 56rpx;
      font-size: 40rpx;
      font-family: PingFang SC, PingFang SC-Semibold;
      font-weight: 600;
      text-align: left;
      color: #ed581d;
    }
    .foot_right {
      width: 114rpx;
      height: 6rpx;
      background: linear-gradient(90deg, #eb592b, rgba(240, 144, 114, 0));
    }
  }
  .foot_txt {
    margin-top: 22rpx;
    width: 572rpx;
    height: 256rpx;
    font-size: 26rpx;
    font-family: PingFang SC, PingFang SC-Regular;
    font-weight: 400;
    text-align: left;
    color: #333333;
    line-height: 44rpx;
  }
}
</style>
相关推荐
猫猫不是喵喵.几秒前
Vue3 Props 属性
前端·javascript·vue.js
醉城夜风~1 小时前
CSS元素显示模式(display)
前端·css
AI大模型-小华2 小时前
Codex 三方充值快速入门指南
java·前端·数据库·chatgpt·ai编程·codex·chatgpt pro
2601_965798473 小时前
Is Hygia Good for Maid & Janitorial Sites? Technical Audit
服务器·网络·数据库
蚰蜒螟4 小时前
从内核源码看Linux启动:chroot、execve与MS_MOVE的协奏曲
linux·服务器·网络
做前端的娜娜子4 小时前
同一链接实现 PC Web 与移动 H5 自适应
前端·掘金·金石计划
小帅不太帅4 小时前
架构没变、规模没变,DeepSeek V4 Flash 正式版凭什么暴涨 47 分?
前端·aigc·deepseek
jarvisuni5 小时前
DeepSeekFlash前端依旧拉垮,而且变慢了很多!
前端·javascript·算法
来者皆善5 小时前
ZYNQ linux上使用 USB CDC ACM
linux·运维·服务器