示例:
使用的是一个插件可以在多种环境下运行的插件:九宫格 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.dataconsole.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"><LuckyGridref="myLucky"width="7.7rem"height="7.7rem":prizes="prizes":blocks="blocks":buttons="buttons"rowscols: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-itemv-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-tabsv-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>