如何实现h5的抽奖功能

发布时间:2023年12月29日

示例:

使用的是一个插件可以在多种环境下运行的插件:九宫格 LuckyGrid | 基于 Js / TS / Vue / React / 微信小程序 / uni-app / Taro 的【大转盘 & 九宫格 & 老虎机】抽奖插件

安装插件

# npm 安装
npm install @lucky-canvas/vue@latest

# 或者 yarn 安装
yarn add @lucky-canvas/vue@latest

按需引入(就当前文件使用)

import { LuckyWheel, LuckyGrid } from 'vue-luck-draw'

?仅供参考,基础样式修改可以查看官网文档修改在 Vue 中使用 | 基于 Js / TS / Vue / React / 微信小程序 / uni-app / Taro 的【大转盘 & 九宫格 & 老虎机】抽奖插件

<script>

import { LuckyWheel, LuckyGrid } from "vue-luck-draw";//引入
import turntable from "../../../api/turntable";//api
import Card from "./common/card.vue";//封装的卡券列表
import tipPop from "../common/tipPop.vue";//封装的弹窗
export default {
  components: {
    tipPop,
    Head,
    LuckyWheel,
    LuckyGrid,
    Card,
  },
  data() {
    return {
      dataList: [
        { telephone: "157xxxx5554", offerName: "商品xxx" },
        { telephone: "177xxxx5434", offerName: "商品xxx" },
      ],
      blocks: [
        {
          padding: "10px",
        },
      ],

      prizes: [],
      buttons: [
        {
          x: 1,
          y: 1,
          imgs: [
            {
              src: require("../../../assets/img/turntable/djcj.png"), // 转盘中心开始图片
              width: "100%",
              top: "-2%",
            },
          ],
        },
      ],
      // shop1:'0',
      defaultConfig: {
        accelerationTime: 2000,
        decelerationTime: 2000,
      },
      timeNums: 3, //剩余次数
      activeName: "a",//卡券类型
      showAll: false,
      serviceClose: false, //权益服务弹窗关闭按钮
      popShow: false, // 弹窗控制
      safeguardShow: false,
      prizeLists: [],
      prizeName: "", //抽中的奖品
    };
  },
  async mounted() {
    await this.getPrizeLists();
    this.getPrizeCounts();
    this.getAllPrizeOrderLists();
    //顺序没有规律,是按九宫格顺时针执行
    const arr1 = [
      {
        x: 0,
        y: 0,
        background: "#E8FCFF",
      },
      {
        x: 1,
        y: 0,
        background: "#E8FCFF",
      },
      {
        x: 2,
        y: 0,
        background: "#E8FCFF",
      },
      {
        x: 2,
        y: 1,
        background: "#E8FCFF",
      },
      {//开始抽奖的位置
        x: 1,
        y: 1,
        background: "#E8FCFF",
      },
      {
        x: 2,
        y: 2,
        background: "#E8FCFF",
      },
      {
        x: 1,
        y: 2,
        background: "#E8FCFF",
      },
      {
        x: 0,
        y: 2,
        background: "#E8FCFF",
      },
      {
        x: 0,
        y: 1,
        background: "#E8FCFF",
      },
    ];
    // 将接口请求到的奖品结果填充到固定顺序的内容 
    const arr = this.prizeLists.map((item, index) => {
      return {
        ...arr1[index],
        fonts: [
          {
            text: item.offerName,
            top: "30%",
            fontColor: "#474747",
            fontSize: "14px",
          },
        ],
      };
    });
    // 将中间的坐标为(1,1)的点击抽奖删除
    if (arr.length > 4) {
      arr.splice(4, 1);
    }
    this.prizes = arr;
    console.log(this.prizes);
  },
  computed: {},
  methods: {
    startCallback() {
      if (this.timeNums == 0) {
        return this.$dialog
          .alert({
            message: `本月剩余${this.timeNums}次,次月刷新`,
            theme: "round-button",
          })
          .then(() => {
          });
      }
      // 调用抽奖组件的play方法开始游戏
      this.$refs.myLucky.play();
      // 模拟调用接口异步抽奖
      setTimeout(() => {
        // 可以由后端返回的中奖索引控制,暂定随机数
        const randomNum = parseInt(Math.floor(Math.random() * 8));
        // 调用stop停止旋转并传递中奖索引
        this.$refs.myLucky.stop(randomNum);
      }, 3000);
    },
    // 抽奖结束会触发end回调
    endCallback(prize) {
      console.log(prize);
      this.prizeName = prize.fonts[0].text;
      this.popShow = true;
      this.serviceClose = true;
      const name = this.prizeName;
      if (name =='谢谢惠顾') {
        return
      }else{
      const datas = this.prizeLists.find((item) => item.offerName === name);
      console.log(this.prizeLists, this.prizeName, datas);
      delete datas.id;
      const res = turntable.createPrizeOrder({
        ...datas,
        telephone: sessionStorage.getItem("mobileNumber"),
      });
      console.log(res);
      }
      
    },
    //关闭弹窗
    handleMessageClose() {
      this.popShow = false;
      this.serviceClose = false;
      this.getPrizeLists();
      this.getPrizeCounts();
      this.getAllPrizeOrderLists();
      this.$refs.carda.onRefresh();
    },
    //查询奖池列表数据
    async getPrizeLists() {
      const res = await turntable.getPrizeList({
        telephone: sessionStorage.getItem("mobileNumber"),
      });
      this.prizeLists = res.data
      console.log(this.prizeLists,121);
      if (this.prizeLists.length > 4) {
        //将中间的坐标为(1,1)的点击抽奖赋值为空
        this.prizeLists.splice(4, 0, {});
      }
    },
    //查询当月抽奖总数
    async getPrizeCounts() {
      const res = await turntable.getPrizeCount({
        telephone: sessionStorage.getItem("mobileNumber"),
      });
      this.timeNums = res.data;
    },
    //查询所有抽奖订单数据
    async getAllPrizeOrderLists() {
      const res = await turntable.getAllPrizeOrderList();
      if (res.data.length !==0) {
        this.dataList = res.data.map((item) => ({
          telephone: item.telephone,
          offerName: item.offerName,
        }));
      }
    },
    //切换卡券类型
    changeTitle(name, title) {
      console.log(name, title);
      // 根据名字来区分类型刷新对应的卡券类型
        this.$nextTick(() => {
          this.$refs["card" + name].onRefresh();
        });
    },
    //号码脱敏
    desensitizePhoneNumber(phoneNumber) {
      return phoneNumber.replace(/(\d{3})\d{4}(\d{4})/, "$1****$2");
    },
  },
};
</script>
<template>
  <div class="app-cantent">
    
    <div class="turntable">
      <div class="turntable-top">
        
        <div class="turntable-num">剩余{{ timeNums }}次抽奖机会</div>
        <div class="turntable-main">
          <img src="../../../assets/img/turntable/bg1.png" alt="" />
          <div class="prizeDraw" v-if="prizes.length > 0">
            <LuckyGrid
              ref="myLucky"
              width="7.7rem"
              height="7.7rem"
              :prizes="prizes"
              :blocks="blocks"
              :buttons="buttons"
              rows
              cols
              :default-config="defaultConfig"
              @start="startCallback"
              @end="endCallback"
            />
          </div>
          <div class="prizeMsg">
            <div class="fl">
              <van-swipe
                :touchable="false"
                :show-indicators="false"
                vertical
                :autoplay="3000"
                class="fl-swiper"
              >
                <van-swipe-item
                  v-for="(item, index) in dataList"
                  :key="index + 1"
                >
                  恭喜用户{{
                    item.telephone.replace(/(\d{3})\d{4}(\d{4})/, "$1****$2")
                  }}获取{{ item.offerName }}</van-swipe-item
                >
              </van-swipe>
            </div>
          </div>
        </div>
      </div>
      <div class="turntable-bottom">
        <div class="tab-content">
          <div class="my-prize">
            <div class="title-img">
              <img src="../../../assets/img/turntable/table-title.png" alt="" />
            </div>
            <div class="title-header">
              <div class="content-title">我的奖品</div>
            </div>
          </div>

          <div>
            <van-tabs
              v-model="activeName"
              line-width="20px"
              @click="changeTitle"
            >
              <van-tab title="可使用" name="a">
                <card :activeName="activeName" ref="carda"></card>
              </van-tab>
              <van-tab title="已使用" name="b">
                <card :activeName="activeName" ref="cardb"></card>
              </van-tab>
              <van-tab title="已过期" name="c">
                <card :activeName="activeName" ref="cardc"></card>
              </van-tab>
            </van-tabs>
          </div>
        </div>
        <tipPop class="" v-show="popShow">
          <div class="IDBox">
            <div class="ids-title">提示</div>
            <div class="ids-top" v-if="prizeName!=='谢谢惠顾'">恭喜您抽到了{{ prizeName }}</div>
            <div class="ids-top" v-else>{{ prizeName }},下次再来</div>
            <div class="toCopy">
              <van-button round type="info" block @click="handleMessageClose()"
                >{{prizeName=='谢谢惠顾'? '确认':"收下"}}</van-button
              >
            </div>
          </div>
        </tipPop>
      </div>
    </div>
  </div>
</template>
<style scoped lang='less'>
.app-cantent {
  // width: 100vw;
  height: 100%;
  .turntable {
    height: 100%;
    padding: 0 10px;
    background-color: #2892ff;
    background: url("@/assets/img/turntable/bg.png") no-repeat center/cover;
    .turntable-top {
      padding-top: 30px;
      // padding-bottom: 20px;
      .turntable-num {
        // width: 100%;
        height: 30px;
        margin-top: 10px;
        border-radius: 10px;
        line-height: 30px;
        text-align: center;
        background: url("@/assets/img/turntable/yy.png") no-repeat center/cover;
      }
      .turntable-main {
      
        height: 450px;
        
        display: flex;
        justify-content: center;
        align-items: center;
        position: relative;
        
        .prizeDraw {
          position: absolute;
          top: 23vw;
          left: 9vw;
          
        }
        .prizeMsg {
          width: 300px;
          position: absolute;
          top: 7vw;
          left: 10vw;
          display: flex;
          justify-content: center;
          .fl {
            
            margin-top: 0px;
            display: flex;
            align-items: center;
            justify-content: center;
            height: 30px;
            text-align: center;
            .fl-swiper {
              margin-left: 5px;
              height: 22px;
              line-height: 23px;
              font-size: 11px;
            }
          }
        }
        .time {
          position: absolute;
          top: 55%;
          left: 50%;
          margin-left: -70px;
          color: #fff;
        
          width: 140px !important;
          text-align: center;
        }
      }
    }
    .turntable-bottom {
      border: 2px solid #81d3f8;
      .tab-content {
      
        width: 100%;
        
        background-color: #fff;
        .my-prize {
          position: relative;
        }
        .title-img {
        
          position: absolute;
          width: 60%;
          top: -10%;
          left: 20%;
          z-index: 99;
         
        }
        .title-header {
          position: relative;
          height: 35px;
        }

        .content-title {
          position: absolute;
          width: 20%;
          top: 0;
          left: 40%;
          z-index: 99;
          text-align: center;
          color: #fff;
          font-size: 16px;
          font-weight: 700;
        }
      }
    }
  }
  .IDBox {
    .ids-title {
      text-align: center;
      padding: 10px 0;
      font-size: 18px;
      font-weight: 700;
    }
    .ids-top {
      margin-top: 5px;
      text-align: center;
      padding: 10px 0;
      font-size: 16px;
    }
    .toCopy {
      margin-top: 15px;
      text-align: center;
      font-size: 16px;
    }
  }
}
</style>


文章来源:https://blog.csdn.net/weixin_53818172/article/details/135287254
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。