This commit is contained in:
zpc 2025-05-15 20:47:39 +08:00
parent 47899ec619
commit 758198ec71
7 changed files with 2346 additions and 298 deletions

View File

@ -0,0 +1,164 @@
# 老虎机抽奖组件使用指南
## 组件简介
本组件是一个整合了1列、3列和5列老虎机功能的抽奖组件可根据传入的参数动态切换不同列数的老虎机模式。
## 使用方法
### 1. 引入组件
```vue
import DetailLucky from "@/components/detail-lucky/detail-lucky.vue";
export default {
components: {
DetailLucky
}
}
```
### 2. 在模板中使用
```vue
<template>
<DetailLucky ref="luckySlot" :mode="3"></DetailLucky>
</template>
```
### 3. 组件属性
| 属性名 | 类型 | 默认值 | 说明 |
|-------|------|-------|------|
| mode | Number/String | 1 | 老虎机模式可选值1, 3, 5 |
### 4. 组件方法
#### 初始化老虎机
```js
// 初始化老虎机,传入奖品列表和模式
this.$refs.luckySlot.init(prizeList, mode);
// 例如初始化3列老虎机
this.$refs.luckySlot.init(myPrizes, 3);
// 也可以仅传入奖品列表,使用组件默认的模式
this.$refs.luckySlot.init(myPrizes);
```
#### 开始抽奖
```js
// 开始抽奖,可选传入回调函数
this.$refs.luckySlot.startDraw(() => {
console.log('老虎机开始旋转');
});
```
#### 停止抽奖并指定中奖结果
```js
// 停止抽奖,传入中奖索引数组
// 对于1列老虎机传入1个索引
this.$refs.luckySlot.stopDraw([5]);
// 对于3列老虎机传入3个索引
this.$refs.luckySlot.stopDraw([3, 2, 8]);
// 对于5列老虎机传入5个索引
this.$refs.luckySlot.stopDraw([1, 2, 3, 4, 5]);
// 也可以不传入索引,组件会随机生成
this.$refs.luckySlot.stopDraw();
```
#### 其他方法
```js
// 强制结束抽奖
this.$refs.luckySlot.forceEndDraw();
// 隐藏老虎机
this.$refs.luckySlot.hide();
// 显示老虎机
this.$refs.luckySlot.show();
// 重置组件状态
this.$refs.luckySlot.reset();
```
### 5. 组件事件
| 事件名 | 说明 | 返回值 |
|-------|------|-------|
| start | 开始抽奖时触发 | - |
| end | 结束抽奖时触发 | 中奖信息对象 |
### 使用示例
```vue
<template>
<view>
<button @click="startLottery">开始抽奖</button>
<DetailLucky ref="luckySlot" :mode="slotMode"></DetailLucky>
</view>
</template>
<script>
import DetailLucky from "@/components/detail-lucky/detail-lucky.vue";
export default {
components: { DetailLucky },
data() {
return {
slotMode: 3,
prizeList: [] // 奖品列表
}
},
mounted() {
// 获取奖品列表
this.getPrizeList();
},
methods: {
// 获取奖品列表
async getPrizeList() {
// 这里可以从API获取奖品列表
this.prizeList = [...]; // 示例奖品列表
},
// 开始抽奖
startLottery() {
// 初始化老虎机
this.$refs.luckySlot.init(this.prizeList, this.slotMode);
// 开始抽奖
this.$refs.luckySlot.startDraw();
// 模拟3秒后停止抽奖
setTimeout(() => {
// 这里可以调用API获取中奖结果
const winIndex = Math.floor(Math.random() * this.prizeList.length);
// 停止抽奖并指定中奖索引
if (this.slotMode === 1) {
this.$refs.luckySlot.stopDraw([winIndex]);
} else if (this.slotMode === 3) {
this.$refs.luckySlot.stopDraw([winIndex, winIndex, winIndex]);
} else {
this.$refs.luckySlot.stopDraw([winIndex, winIndex, winIndex, winIndex, winIndex]);
}
}, 3000);
}
}
}
</script>
```
## 注意事项
1. 使用前必须先调用`init`方法初始化组件
2. 中奖索引数组的长度应与当前模式的列数匹配,如果不匹配会自动补足或截取
3. 组件高度会根据模式自动调整
4. 如果不传入奖品列表,将使用默认的奖品列表

View File

@ -1,7 +1,570 @@
<template></template>
<script>
<template>
<view class="content-container" v-if="isVisible && isInitialized">
<view class="slot-container">
<view class="slot-icon">
<image
src="https://image.zfunbox.cn/static/image/lucky/icon.png"
mode="widthFix"
style="height: 90rpx; width: 249rpx"
></image>
</view>
<view class="slot-view" :class="'slot-view-' + currentMode">
<!-- 老虎机组件 -->
<SlotMachine
ref="myLucky"
:width="windowWidth"
:height="slotHeight"
:blocks="blocks"
:slots="slots"
:prizes="prizes"
:defaultConfig="defaultConfig"
@start="startCallBack"
@end="endCallBack"
>
</SlotMachine>
</view>
<view style="color: #484848;font-size: 19rpx;text-align: center;padding-top: 20rpx;">动画结果因设备差异可能会显示异常获得赏品以恭喜获得结果为准</view>
<view style="color: #249073;font-size: 21rpx;text-align: center;padding-top: 20rpx;">跳过动画</view>
</view>
</view>
</template>
<script>
//
import SlotMachine from "@/components/@lucky-canvas/uni/slot-machine";
function shuffle(array) {
for (let i = array.length - 1; i > 0; i--) {
// 0 i
const j = Math.floor(Math.random() * (i + 1));
// array[i] array[j]
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
export default {
components: { SlotMachine },
props: {
// : 1, 3, 5 (135)
mode: {
type: [Number, String],
default: 1,
validator: function(value) {
return [1, 3, 5, '1', '3', '5'].includes(value);
}
}
},
data() {
return {
isVisible: false, // /
isInitialized: false, //
windowWidth: "0px",
blocks: [],
slots: [],
prizes: [],
prizeList: [], // data
defaultConfig: {
mode: "horizontal", //
rowSpacing: "10px", //
colSpacing: "10px", //
accelerationTime: 1500,
},
luckyMessage: "恭喜您获得奖品",
luckyPrize: null,
currentPrizeIndex: -1,
internalMode: 1, //
};
},
computed: {
//
lotteryItemSize() {
let height = uni.upx2px(220);
let width = uni.upx2px(170);
return [width, height];
},
//
currentMode() {
return parseInt(this.internalMode);
},
//
slotHeight() {
const modeMap = {
1: "160rpx",
3: "480rpx",
5: "800rpx"
};
return modeMap[this.currentMode] || "480rpx";
},
//
backgroundImage() {
const modeMap = {
1: "di_5.png",
3: "di_3.png",
5: "di_5.png"
};
return modeMap[this.currentMode] || "di_3.png";
}
},
methods: {
//
init(prizeList, mode) {
//
if (mode !== undefined && [1, 3, 5].includes(parseInt(mode))) {
this.internalMode = parseInt(mode);
} else {
// 使propsmode
this.internalMode = parseInt(this.mode);
}
//
if (prizeList && Array.isArray(prizeList) && prizeList.length > 0) {
this.prizeList = prizeList;
} else {
this.prizeList = this.getDefaultPrizes();
}
let windowWidth = uni.getSystemInfoSync().windowWidth;
let t = this.prizeList;
let prizes = [];
for (let i = 0; i < t.length; i++) {
prizes.push({
imgs: [
{
src: t[i].imgurl,
width: "152.78rpx",
height: "152.78rpx",
},
],
background: "#ffffff",
data: t[i], // prize便使
});
}
// slots
const arr = Array.from({ length: t.length }, (_, i) => i);
let slots = [];
//
for (let i = 0; i < this.currentMode; i++) {
slots.push({ order: shuffle([...arr]), speed: 20 });
}
this.windowWidth = windowWidth + "px";
this.slots = slots;
this.prizes = prizes;
//
this.isInitialized = true;
return this; // this
},
//
show() {
if (!this.isInitialized) {
console.error("老虎机尚未初始化请先调用init方法");
return this;
}
this.isVisible = true;
return this;
},
//
hide() {
this.isVisible = false;
return this;
},
//
getDefaultPrizes() {
return [
{
id: 1128,
title: "兹琪露娜提亚斯",
imgurl:
"https://image.zfunbox.cn/topic/20250515/2986e27e673ef675e02771cdebd9b822.jpg",
price: "350.00",
real_pro: "0.02000",
goods_type: 1,
doubling: 1,
is_lingzhu: 0,
},
{
id: 1129,
title: "月岗恋钟",
imgurl:
"https://image.zfunbox.cn/topic/20250515/2c5ed2097716db6bef01da718bc3c091.jpg",
price: "132.00",
real_pro: "0.02000",
goods_type: 1,
doubling: 3,
is_lingzhu: 0,
},
{
id: 1130,
title: "BANDAI万代拼装模型 1/100 MG 机动战士高达 倒A 逆A-15岁以上",
imgurl:
"https://image.zfunbox.cn/topic/20250515/e35da49b4976f156f2f98dec002274a5.png",
price: "305.00",
real_pro: "0.03000",
goods_type: 1,
doubling: 1,
is_lingzhu: 0,
},
{
id: 1131,
title: "BANDAI 万代拼装模型 MG 主天使-15岁以上",
imgurl:
"https://image.zfunbox.cn/topic/20250515/77302c6f1ea9ea6a8516cc1208174aee.png",
price: "289.00",
real_pro: "0.03000",
goods_type: 1,
doubling: 1,
is_lingzhu: 0,
},
{
id: 1132,
title: "BANDAI万代 HG00 09 1/144 座天使高达一型-15岁以上",
imgurl:
"https://image.zfunbox.cn/topic/20250515/55e816c93b5e4103a30682c586816b11.jpg",
price: "114.00",
real_pro: "0.50000",
goods_type: 1,
doubling: 3,
is_lingzhu: 0,
},
{
id: 1133,
title: "BANDAI万代拼装模型 HGUC 130 机动战士高达 杰斯塔-15岁以上",
imgurl:
"https://image.zfunbox.cn/topic/20250515/aeb6bfb8b4aa8a29796b242e4f5d56d9.png",
price: "113.00",
real_pro: "1.50000",
goods_type: 1,
doubling: 1,
is_lingzhu: 0,
},
{
id: 1134,
title: "BANDAI万代拼装模型HG26 1/144 凯列班高达 异灵高达-15岁以上",
imgurl:
"https://image.zfunbox.cn/topic/20250515/329e3a7e21772a63cea03d31f948345d.png",
price: "112.00",
real_pro: "1.00000",
goods_type: 1,
doubling: 2,
is_lingzhu: 0,
},
{
id: 1135,
title: "梦幻",
imgurl:
"https://image.zfunbox.cn/topic/20250515/d2c7e48515d393084000595074209042.jpg",
price: "41.00",
real_pro: "2.50000",
goods_type: 1,
doubling: 2,
is_lingzhu: 0,
},
{
id: 1136,
title: "谜拟丘",
imgurl:
"https://image.zfunbox.cn/topic/20250515/6031827bc455cbf86ff778d74ddffbd3.jpg",
price: "38.00",
real_pro: "1.50000",
goods_type: 1,
doubling: 1,
is_lingzhu: 0,
},
{
id: 1137,
title: "小提琴模型1个",
imgurl:
"https://image.zfunbox.cn/topic/20250515/22846dea5a933ab314998afc51abb7bb.jpg",
price: "13.80",
real_pro: "92.90000",
goods_type: 1,
doubling: 1,
is_lingzhu: 0,
},
];
},
//
startCallBack() {
console.log("开始抽奖");
this.$emit("start");
},
//
endCallBack(prize) {
//
console.log("抽奖结束", prize);
try {
//
const prizeData =
this.prizes[this.currentPrizeIndex]?.data || this.prizes[0]?.data;
if (!prizeData) {
console.error("无法获取奖品数据");
return;
}
//
let allPrizes = [];
// prize使map使prize
if (Array.isArray(prize)) {
allPrizes = prize
.map((item) => {
const index = typeof item.index === "number" ? item.index : 0;
return this.prizes[index]?.data || this.prizes[0]?.data;
})
.filter((item) => !!item);
} else if (prize && typeof prize.index === "number") {
// prize
const index = prize.index;
const itemData = this.prizes[index]?.data;
if (itemData) {
allPrizes.push(itemData);
}
} else {
// 使
allPrizes.push(prizeData);
}
//
this.$emit("end", {
prize: prize,
prizeData: prizeData, //
allPrizes: allPrizes, //
message: `恭喜您获得 ${prizeData.title}`,
prizeInfo: {
name: prizeData.title,
image: prizeData.imgurl,
description: `价值:${prizeData.price}`,
data: prizeData,
},
});
// //
// setTimeout(() => {
// this.hide();
// }, 2000);
} catch (error) {
console.error("处理抽奖结果时出错:", error);
this.hide();
}
},
//
startDraw(callback) {
//
if (!this.isInitialized) {
console.error("老虎机尚未初始化请先调用init方法");
return this;
}
// init
this.show();
setTimeout(() => {
// DOMplay
this.$nextTick(() => {
//
if (this.$refs.myLucky) {
//
this.$refs.myLucky.play();
if (this.bgmCtx && this.bgmCtx.slotBgm) {
this.bgmCtx.slotBgm.play();
}
if (typeof callback === "function") {
callback();
}
} else {
console.error("老虎机组件未初始化");
}
});
}, 100);
return this; // this
},
//
stopDraw(prizeIndices) {
//
if (!this.isInitialized) {
console.error("老虎机尚未初始化请先调用init方法");
return this;
}
if (!this.$refs.myLucky) {
console.error("老虎机组件未初始化");
return this;
}
//
if (
!prizeIndices ||
!Array.isArray(prizeIndices) ||
prizeIndices.length === 0
) {
//
const randomIndices = [];
for (let i = 0; i < this.currentMode; i++) {
randomIndices.push(Math.floor(Math.random() * this.prizes.length));
}
this.currentPrizeIndex = randomIndices[0]; // 使
this.$refs.myLucky.stop(randomIndices);
return this;
}
//
let indices = [...prizeIndices];
while (indices.length < this.currentMode) {
indices.push(indices[indices.length - 1] || 0);
}
//
indices = indices.map((index) => {
if (index < 0 || index >= this.prizes.length) {
return Math.floor(Math.random() * this.prizes.length);
}
return index;
});
//
this.currentPrizeIndex = indices[0];
// 使currentMode
if(indices.length > this.currentMode){
indices=indices.slice(0,this.currentMode)
}
// // 33使3
// if (this.currentMode === 3 && indices.length > 3) {
// indices = indices.slice(0, 3);
// }
// stop
this.$refs.myLucky.stop(indices);
return this;
},
//
forceEndDraw() {
if (!this.isInitialized) {
console.error("老虎机尚未初始化请先调用init方法");
return this;
}
this.hide();
return this; // this
},
//
reset() {
this.isInitialized = false;
this.isVisible = false;
this.slots = [];
this.prizes = [];
this.prizeList = [];
this.currentPrizeIndex = -1;
return this;
},
},
mounted() {
//
},
watch: {
// mode
mode: {
immediate: true,
handler(newVal) {
if ([1, 3, 5, '1', '3', '5'].includes(newVal)) {
this.internalMode = parseInt(newVal);
}
}
}
}
};
</script>
<style lang="scss" scoped>
</style>
<style lang="scss" scoped>
//
.content-container {
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
box-sizing: border-box;
background-image: url($imgurl + "common/slot_bg.webp");
background-size: cover;
background-position: center;
position: fixed;
top: 0;
left: 0;
z-index: 999;
}
//
.slot-container {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
position: relative;
}
.slot-icon {
padding-bottom: 25rpx;
}
//
.slot-view {
background-size: 100% 100%;
width: 100%;
padding-top: 80rpx;
padding-bottom: 80rpx;
display: flex;
justify-content: center;
align-items: center;
}
//
.slot-view-1 {
background: url("https://image.zfunbox.cn/static/image/lucky/di_5.png") no-repeat;
background-size: 100% 100%;
}
.slot-view-3 {
background: url("https://image.zfunbox.cn/static/image/lucky/di_3.png") no-repeat;
background-size: 100% 100%;
}
.slot-view-5 {
background: url("https://image.zfunbox.cn/static/image/lucky/di_5.png") no-repeat;
background-size: 100% 100%;
}
//
.item-lottry {
height: 152.78rpx;
width: 152.78rpx;
display: flex;
justify-content: center;
align-items: center;
font-size: 30rpx;
border-radius: 16rpx;
color: black;
box-sizing: border-box;
background-color: rgba(255, 255, 255, 1);
}
</style>

View File

@ -0,0 +1,489 @@
<template>
<view class="content-container" v-if="isVisible && isInitialized">
<view class="slot-container">
<view class="slot-icon">
<image
src="https://image.zfunbox.cn/static/image/lucky/icon.png"
mode="widthFix"
style="height: 90rpx; width: 249rpx"
></image>
</view>
<view class="slot-view">
<!-- 老虎机组件 -->
<SlotMachine
ref="myLucky"
:width="windowWidth"
height="160rpx"
:blocks="blocks"
:slots="slots"
:prizes="prizes"
:defaultConfig="defaultConfig"
@start="startCallBack"
@end="endCallBack"
>
</SlotMachine>
</view>
</view>
</view>
</template>
<script>
//
import SlotMachine from "@/components/@lucky-canvas/uni/slot-machine";
function shuffle(array) {
for (let i = array.length - 1; i > 0; i--) {
// 0 i
const j = Math.floor(Math.random() * (i + 1));
// array[i] array[j]
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
export default {
components: { SlotMachine },
props: {
// prizeList props
},
data() {
return {
isVisible: false, // /
isInitialized: false, //
windowWidth: "0px",
blocks: [],
slots: [],
prizes: [],
prizeList: [], // data
defaultConfig: {
mode: "horizontal", //
rowSpacing: "10px", //
colSpacing: "10px", //
accelerationTime: 1500,
},
luckyMessage: "恭喜您获得奖品",
luckyPrize: null,
currentPrizeIndex: -1,
};
},
computed: {
//
lotteryItemSize() {
let height = uni.upx2px(220);
let width = uni.upx2px(170);
return [width, height];
},
},
methods: {
//
init(prizeList) {
//
if (prizeList && Array.isArray(prizeList) && prizeList.length > 0) {
this.prizeList = prizeList;
} else {
this.prizeList = this.getDefaultPrizes();
}
let windowWidth = uni.getSystemInfoSync().windowWidth;
let t = this.prizeList;
let prizes = [];
for (let i = 0; i < t.length; i++) {
prizes.push({
imgs: [
{
src: t[i].imgurl,
width: "152.78rpx",
height: "152.78rpx",
},
],
background: "#ffffff",
data: t[i], // prize便使
});
}
const arr = Array.from({ length: t.length }, (_, i) => i);
let slots = [
{ order: shuffle([...arr]), speed: 20 }, //
];
this.windowWidth = windowWidth + "px";
this.slots = slots;
this.prizes = prizes;
//
this.isInitialized = true;
return this; // this
},
//
show() {
if (!this.isInitialized) {
console.error("老虎机尚未初始化请先调用init方法");
return this;
}
this.isVisible = true;
return this;
},
//
hide() {
this.isVisible = false;
return this;
},
//
getDefaultPrizes() {
return [
{
id: 1128,
title: "兹琪露娜提亚斯",
imgurl:
"https://image.zfunbox.cn/topic/20250515/2986e27e673ef675e02771cdebd9b822.jpg",
price: "350.00",
real_pro: "0.02000",
goods_type: 1,
doubling: 1,
is_lingzhu: 0,
},
{
id: 1129,
title: "月岗恋钟",
imgurl:
"https://image.zfunbox.cn/topic/20250515/2c5ed2097716db6bef01da718bc3c091.jpg",
price: "132.00",
real_pro: "0.02000",
goods_type: 1,
doubling: 3,
is_lingzhu: 0,
},
{
id: 1130,
title: "BANDAI万代拼装模型 1/100 MG 机动战士高达 倒A 逆A-15岁以上",
imgurl:
"https://image.zfunbox.cn/topic/20250515/e35da49b4976f156f2f98dec002274a5.png",
price: "305.00",
real_pro: "0.03000",
goods_type: 1,
doubling: 1,
is_lingzhu: 0,
},
{
id: 1131,
title: "BANDAI 万代拼装模型 MG 主天使-15岁以上",
imgurl:
"https://image.zfunbox.cn/topic/20250515/77302c6f1ea9ea6a8516cc1208174aee.png",
price: "289.00",
real_pro: "0.03000",
goods_type: 1,
doubling: 1,
is_lingzhu: 0,
},
{
id: 1132,
title: "BANDAI万代 HG00 09 1/144 座天使高达一型-15岁以上",
imgurl:
"https://image.zfunbox.cn/topic/20250515/55e816c93b5e4103a30682c586816b11.jpg",
price: "114.00",
real_pro: "0.50000",
goods_type: 1,
doubling: 3,
is_lingzhu: 0,
},
{
id: 1133,
title: "BANDAI万代拼装模型 HGUC 130 机动战士高达 杰斯塔-15岁以上",
imgurl:
"https://image.zfunbox.cn/topic/20250515/aeb6bfb8b4aa8a29796b242e4f5d56d9.png",
price: "113.00",
real_pro: "1.50000",
goods_type: 1,
doubling: 1,
is_lingzhu: 0,
},
{
id: 1134,
title: "BANDAI万代拼装模型HG26 1/144 凯列班高达 异灵高达-15岁以上",
imgurl:
"https://image.zfunbox.cn/topic/20250515/329e3a7e21772a63cea03d31f948345d.png",
price: "112.00",
real_pro: "1.00000",
goods_type: 1,
doubling: 2,
is_lingzhu: 0,
},
{
id: 1135,
title: "梦幻",
imgurl:
"https://image.zfunbox.cn/topic/20250515/d2c7e48515d393084000595074209042.jpg",
price: "41.00",
real_pro: "2.50000",
goods_type: 1,
doubling: 2,
is_lingzhu: 0,
},
{
id: 1136,
title: "谜拟丘",
imgurl:
"https://image.zfunbox.cn/topic/20250515/6031827bc455cbf86ff778d74ddffbd3.jpg",
price: "38.00",
real_pro: "1.50000",
goods_type: 1,
doubling: 1,
is_lingzhu: 0,
},
{
id: 1137,
title: "小提琴模型1个",
imgurl:
"https://image.zfunbox.cn/topic/20250515/22846dea5a933ab314998afc51abb7bb.jpg",
price: "13.80",
real_pro: "92.90000",
goods_type: 1,
doubling: 1,
is_lingzhu: 0,
},
];
},
//
startCallBack() {
console.log("开始抽奖");
this.$emit("start");
},
//
endCallBack(prize) {
//
console.log("抽奖结束", prize);
try {
//
const prizeData =
this.prizes[this.currentPrizeIndex]?.data || this.prizes[0]?.data;
if (!prizeData) {
console.error("无法获取奖品数据");
return;
}
//
let allPrizes = [];
// prize使map使prize
if (Array.isArray(prize)) {
allPrizes = prize
.map((item) => {
const index = typeof item.index === "number" ? item.index : 0;
return this.prizes[index]?.data || this.prizes[0]?.data;
})
.filter((item) => !!item);
} else if (prize && typeof prize.index === "number") {
// prize
const index = prize.index;
const itemData = this.prizes[index]?.data;
if (itemData) {
allPrizes.push(itemData);
}
} else {
// 使
allPrizes.push(prizeData);
}
//
this.$emit("end", {
prize: prize,
prizeData: prizeData, //
allPrizes: allPrizes, //
message: `恭喜您获得 ${prizeData.title}`,
prizeInfo: {
name: prizeData.title,
image: prizeData.imgurl,
description: `价值:${prizeData.price}`,
data: prizeData,
},
});
//
setTimeout(() => {
this.hide();
}, 2000);
} catch (error) {
console.error("处理抽奖结果时出错:", error);
this.hide();
}
},
//
startDraw(callback) {
//
if (!this.isInitialized) {
console.error("老虎机尚未初始化请先调用init方法");
return this;
}
// init
this.show();
setTimeout(() => {
// DOMplay
this.$nextTick(() => {
//
if (this.$refs.myLucky) {
//
this.$refs.myLucky.play();
if (this.bgmCtx && this.bgmCtx.slotBgm) {
this.bgmCtx.slotBgm.play();
}
if (typeof callback === "function") {
callback();
}
} else {
console.error("老虎机组件未初始化");
}
});
}, 100);
return this; // this
},
//
stopDraw(prizeIndices) {
//
if (!this.isInitialized) {
console.error("老虎机尚未初始化请先调用init方法");
return this;
}
if (!this.$refs.myLucky) {
console.error("老虎机组件未初始化");
return this;
}
//
if (
!prizeIndices ||
!Array.isArray(prizeIndices) ||
prizeIndices.length === 0
) {
// 5
const randomIndices = [];
for (let i = 0; i < 5; i++) {
randomIndices.push(Math.floor(Math.random() * this.prizes.length));
}
this.currentPrizeIndex = randomIndices[0]; // 使
this.$refs.myLucky.stop(randomIndices);
return this;
}
// 55
let indices = [...prizeIndices];
while (indices.length < 5) {
indices.push(indices[indices.length - 1] || 0);
}
//
indices = indices.map((index) => {
if (index < 0 || index >= this.prizes.length) {
return Math.floor(Math.random() * this.prizes.length);
}
return index;
});
//
this.currentPrizeIndex = indices[0];
// stop
this.$refs.myLucky.stop(indices[0]);
return this;
},
//
forceEndDraw() {
if (!this.isInitialized) {
console.error("老虎机尚未初始化请先调用init方法");
return this;
}
this.hide();
return this; // this
},
//
reset() {
this.isInitialized = false;
this.isVisible = false;
this.slots = [];
this.prizes = [];
this.prizeList = [];
this.currentPrizeIndex = -1;
return this;
},
},
mounted() {
//
},
};
</script>
<style lang="scss" scoped>
//
.content-container {
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
box-sizing: border-box;
background-image: url($imgurl + "common/slot_bg.webp");
background-size: cover;
background-position: center;
position: fixed;
top: 0;
left: 0;
z-index: 999;
}
//
.slot-container {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
position: relative;
}
.slot-icon {
padding-bottom: 25rpx;
}
//
.slot-view {
background: url("https://image.zfunbox.cn/static/image/lucky/di_5.png")
no-repeat;
background-size: 100% 100%;
width: 100%;
padding-top: 80rpx;
padding-bottom: 80rpx;
display: flex;
justify-content: center;
align-items: center;
}
//
.item-lottry {
height: 152.78rpx;
width: 152.78rpx;
display: flex;
justify-content: center;
align-items: center;
font-size: 30rpx;
border-radius: 16rpx;
color: black;
box-sizing: border-box;
background-color: rgba(255, 255, 255, 1);
}
</style>

View File

@ -0,0 +1,493 @@
<template>
<view class="content-container" v-if="isVisible && isInitialized">
<view class="slot-container">
<view class="slot-icon">
<image
src="https://image.zfunbox.cn/static/image/lucky/icon.png"
mode="widthFix"
style="height: 90rpx; width: 249rpx"
></image>
</view>
<view class="slot-view">
<!-- 老虎机组件 -->
<SlotMachine
ref="myLucky"
:width="windowWidth"
height="480rpx"
:blocks="blocks"
:slots="slots"
:prizes="prizes"
:defaultConfig="defaultConfig"
@start="startCallBack"
@end="endCallBack"
>
</SlotMachine>
</view>
</view>
</view>
</template>
<script>
//
import SlotMachine from "@/components/@lucky-canvas/uni/slot-machine";
function shuffle(array) {
for (let i = array.length - 1; i > 0; i--) {
// 0 i
const j = Math.floor(Math.random() * (i + 1));
// array[i] array[j]
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
export default {
components: { SlotMachine },
props: {
// prizeList props
},
data() {
return {
isVisible: false, // /
isInitialized: false, //
windowWidth: "0px",
blocks: [],
slots: [],
prizes: [],
prizeList: [], // data
defaultConfig: {
mode: "horizontal", //
rowSpacing: "10px", //
colSpacing: "10px", //
accelerationTime: 1500,
},
luckyMessage: "恭喜您获得奖品",
luckyPrize: null,
currentPrizeIndex: -1,
};
},
computed: {
//
lotteryItemSize() {
let height = uni.upx2px(220);
let width = uni.upx2px(170);
return [width, height];
},
},
methods: {
//
init(prizeList) {
//
if (prizeList && Array.isArray(prizeList) && prizeList.length > 0) {
this.prizeList = prizeList;
} else {
this.prizeList = this.getDefaultPrizes();
}
let windowWidth = uni.getSystemInfoSync().windowWidth;
let t = this.prizeList;
let prizes = [];
for (let i = 0; i < t.length; i++) {
prizes.push({
imgs: [
{
src: t[i].imgurl,
width: "152.78rpx",
height: "152.78rpx",
},
],
background: "#ffffff",
data: t[i], // prize便使
});
}
const arr = Array.from({ length: t.length }, (_, i) => i);
let slots = [
{ order: shuffle([...arr]), speed: 20 }, //
{ order: shuffle([...arr]), speed: 20 }, //
{ order: shuffle([...arr]), speed: 20 }, //
];
this.windowWidth = windowWidth + "px";
this.slots = slots;
this.prizes = prizes;
//
this.isInitialized = true;
return this; // this
},
//
show() {
if (!this.isInitialized) {
console.error("老虎机尚未初始化请先调用init方法");
return this;
}
this.isVisible = true;
return this;
},
//
hide() {
this.isVisible = false;
return this;
},
//
getDefaultPrizes() {
return [
{
id: 1128,
title: "兹琪露娜提亚斯",
imgurl:
"https://image.zfunbox.cn/topic/20250515/2986e27e673ef675e02771cdebd9b822.jpg",
price: "350.00",
real_pro: "0.02000",
goods_type: 1,
doubling: 1,
is_lingzhu: 0,
},
{
id: 1129,
title: "月岗恋钟",
imgurl:
"https://image.zfunbox.cn/topic/20250515/2c5ed2097716db6bef01da718bc3c091.jpg",
price: "132.00",
real_pro: "0.02000",
goods_type: 1,
doubling: 3,
is_lingzhu: 0,
},
{
id: 1130,
title: "BANDAI万代拼装模型 1/100 MG 机动战士高达 倒A 逆A-15岁以上",
imgurl:
"https://image.zfunbox.cn/topic/20250515/e35da49b4976f156f2f98dec002274a5.png",
price: "305.00",
real_pro: "0.03000",
goods_type: 1,
doubling: 1,
is_lingzhu: 0,
},
{
id: 1131,
title: "BANDAI 万代拼装模型 MG 主天使-15岁以上",
imgurl:
"https://image.zfunbox.cn/topic/20250515/77302c6f1ea9ea6a8516cc1208174aee.png",
price: "289.00",
real_pro: "0.03000",
goods_type: 1,
doubling: 1,
is_lingzhu: 0,
},
{
id: 1132,
title: "BANDAI万代 HG00 09 1/144 座天使高达一型-15岁以上",
imgurl:
"https://image.zfunbox.cn/topic/20250515/55e816c93b5e4103a30682c586816b11.jpg",
price: "114.00",
real_pro: "0.50000",
goods_type: 1,
doubling: 3,
is_lingzhu: 0,
},
{
id: 1133,
title: "BANDAI万代拼装模型 HGUC 130 机动战士高达 杰斯塔-15岁以上",
imgurl:
"https://image.zfunbox.cn/topic/20250515/aeb6bfb8b4aa8a29796b242e4f5d56d9.png",
price: "113.00",
real_pro: "1.50000",
goods_type: 1,
doubling: 1,
is_lingzhu: 0,
},
{
id: 1134,
title: "BANDAI万代拼装模型HG26 1/144 凯列班高达 异灵高达-15岁以上",
imgurl:
"https://image.zfunbox.cn/topic/20250515/329e3a7e21772a63cea03d31f948345d.png",
price: "112.00",
real_pro: "1.00000",
goods_type: 1,
doubling: 2,
is_lingzhu: 0,
},
{
id: 1135,
title: "梦幻",
imgurl:
"https://image.zfunbox.cn/topic/20250515/d2c7e48515d393084000595074209042.jpg",
price: "41.00",
real_pro: "2.50000",
goods_type: 1,
doubling: 2,
is_lingzhu: 0,
},
{
id: 1136,
title: "谜拟丘",
imgurl:
"https://image.zfunbox.cn/topic/20250515/6031827bc455cbf86ff778d74ddffbd3.jpg",
price: "38.00",
real_pro: "1.50000",
goods_type: 1,
doubling: 1,
is_lingzhu: 0,
},
{
id: 1137,
title: "小提琴模型1个",
imgurl:
"https://image.zfunbox.cn/topic/20250515/22846dea5a933ab314998afc51abb7bb.jpg",
price: "13.80",
real_pro: "92.90000",
goods_type: 1,
doubling: 1,
is_lingzhu: 0,
},
];
},
//
startCallBack() {
console.log("开始抽奖");
this.$emit("start");
},
//
endCallBack(prize) {
//
console.log("抽奖结束", prize);
try {
//
const prizeData =
this.prizes[this.currentPrizeIndex]?.data || this.prizes[0]?.data;
if (!prizeData) {
console.error("无法获取奖品数据");
return;
}
//
let allPrizes = [];
// prize使map使prize
if (Array.isArray(prize)) {
allPrizes = prize
.map((item) => {
const index = typeof item.index === "number" ? item.index : 0;
return this.prizes[index]?.data || this.prizes[0]?.data;
})
.filter((item) => !!item);
} else if (prize && typeof prize.index === "number") {
// prize
const index = prize.index;
const itemData = this.prizes[index]?.data;
if (itemData) {
allPrizes.push(itemData);
}
} else {
// 使
allPrizes.push(prizeData);
}
//
this.$emit("end", {
prize: prize,
prizeData: prizeData, //
allPrizes: allPrizes, //
message: `恭喜您获得 ${prizeData.title}`,
prizeInfo: {
name: prizeData.title,
image: prizeData.imgurl,
description: `价值:${prizeData.price}`,
data: prizeData,
},
});
//
setTimeout(() => {
this.hide();
}, 2000);
} catch (error) {
console.error("处理抽奖结果时出错:", error);
this.hide();
}
},
//
startDraw(callback) {
//
if (!this.isInitialized) {
console.error("老虎机尚未初始化请先调用init方法");
return this;
}
// init
this.show();
setTimeout(() => {
// DOMplay
this.$nextTick(() => {
//
if (this.$refs.myLucky) {
//
this.$refs.myLucky.play();
if (this.bgmCtx && this.bgmCtx.slotBgm) {
this.bgmCtx.slotBgm.play();
}
if (typeof callback === "function") {
callback();
}
} else {
console.error("老虎机组件未初始化");
}
});
}, 100);
return this; // this
},
//
stopDraw(prizeIndices) {
//
if (!this.isInitialized) {
console.error("老虎机尚未初始化请先调用init方法");
return this;
}
if (!this.$refs.myLucky) {
console.error("老虎机组件未初始化");
return this;
}
//
if (
!prizeIndices ||
!Array.isArray(prizeIndices) ||
prizeIndices.length === 0
) {
// 5
const randomIndices = [];
for (let i = 0; i < 5; i++) {
randomIndices.push(Math.floor(Math.random() * this.prizes.length));
}
this.currentPrizeIndex = randomIndices[0]; // 使
this.$refs.myLucky.stop(randomIndices);
return this;
}
// 55
let indices = [...prizeIndices];
while (indices.length < 5) {
indices.push(indices[indices.length - 1] || 0);
}
//
indices = indices.map((index) => {
if (index < 0 || index >= this.prizes.length) {
return Math.floor(Math.random() * this.prizes.length);
}
return index;
});
//
this.currentPrizeIndex = indices[0];
if (indices.length > 3) {
indices = indices.slice(0, 3);
}
// stop
this.$refs.myLucky.stop(indices);
return this;
},
//
forceEndDraw() {
if (!this.isInitialized) {
console.error("老虎机尚未初始化请先调用init方法");
return this;
}
this.hide();
return this; // this
},
//
reset() {
this.isInitialized = false;
this.isVisible = false;
this.slots = [];
this.prizes = [];
this.prizeList = [];
this.currentPrizeIndex = -1;
return this;
},
},
mounted() {
//
},
};
</script>
<style lang="scss" scoped>
//
.content-container {
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
box-sizing: border-box;
background-image: url($imgurl + "common/slot_bg.webp");
background-size: cover;
background-position: center;
position: fixed;
top: 0;
left: 0;
z-index: 999;
}
.slot-icon {
padding-bottom: 25rpx;
}
//
.slot-container {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
position: relative;
}
//
.slot-view {
background: url("https://image.zfunbox.cn/static/image/lucky/di_3.png")
no-repeat;
background-size: 100% 100%;
width: 100%;
padding-top: 80rpx;
padding-bottom: 80rpx;
display: flex;
justify-content: center;
align-items: center;
}
//
.item-lottry {
height: 152.78rpx;
width: 152.78rpx;
display: flex;
justify-content: center;
align-items: center;
font-size: 30rpx;
border-radius: 16rpx;
color: black;
box-sizing: border-box;
background-color: rgba(255, 255, 255, 1);
}
</style>

View File

@ -0,0 +1,485 @@
<template>
<view class="content-container" v-if="isVisible && isInitialized">
<view class="slot-container">
<view class="slot-icon">
<image
src="https://image.zfunbox.cn/static/image/lucky/icon.png"
mode="widthFix"
style="height: 90rpx; width: 249rpx"
></image>
</view>
<view class="slot-view">
<!-- 老虎机组件 -->
<SlotMachine
ref="myLucky"
:width="windowWidth"
height="800rpx"
:blocks="blocks"
:slots="slots"
:prizes="prizes"
:defaultConfig="defaultConfig"
@start="startCallBack"
@end="endCallBack"
>
</SlotMachine>
</view>
</view>
</view>
</template>
<script>
//
import SlotMachine from "@/components/@lucky-canvas/uni/slot-machine";
function shuffle(array) {
for (let i = array.length - 1; i > 0; i--) {
// 0 i
const j = Math.floor(Math.random() * (i + 1));
// array[i] array[j]
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
export default {
components: { SlotMachine },
props: {
// prizeList props
},
data() {
return {
isVisible: false, // /
isInitialized: false, //
windowWidth: "0px",
blocks: [],
slots: [],
prizes: [],
prizeList: [], // data
defaultConfig: {
mode: "horizontal", //
rowSpacing: "10px", //
colSpacing: "10px", //
accelerationTime: 1500,
},
luckyMessage: "恭喜您获得奖品",
luckyPrize: null,
currentPrizeIndex: -1,
};
},
computed: {
//
lotteryItemSize() {
let height = uni.upx2px(220);
let width = uni.upx2px(170);
return [width, height];
},
},
methods: {
//
init(prizeList) {
//
if (prizeList && Array.isArray(prizeList) && prizeList.length > 0) {
this.prizeList = prizeList;
} else {
this.prizeList = this.getDefaultPrizes();
}
let windowWidth = uni.getSystemInfoSync().windowWidth;
let t = this.prizeList;
let prizes = [];
for (let i = 0; i < t.length; i++) {
prizes.push({
imgs: [
{
src: t[i].imgurl,
width: "152.78rpx",
height: "152.78rpx",
},
],
background: "#ffffff",
data: t[i], // prize便使
});
}
const arr = Array.from({ length: t.length }, (_, i) => i);
let slots = [
{ order: shuffle([...arr]), speed: 20 }, //
{ order: shuffle([...arr]), speed: 20 }, //
{ order: shuffle([...arr]), speed: 20 }, //
{ order: shuffle([...arr]), speed: 20 }, //
{ order: shuffle([...arr]), speed: 20 }, //
];
this.windowWidth = windowWidth + "px";
this.slots = slots;
this.prizes = prizes;
//
this.isInitialized = true;
return this; // this
},
//
show() {
if (!this.isInitialized) {
console.error('老虎机尚未初始化请先调用init方法');
return this;
}
this.isVisible = true;
return this;
},
//
hide() {
this.isVisible = false;
return this;
},
//
getDefaultPrizes() {
return [
{
id: 1128,
title: "兹琪露娜提亚斯",
imgurl:
"https://image.zfunbox.cn/topic/20250515/2986e27e673ef675e02771cdebd9b822.jpg",
price: "350.00",
real_pro: "0.02000",
goods_type: 1,
doubling: 1,
is_lingzhu: 0,
},
{
id: 1129,
title: "月岗恋钟",
imgurl:
"https://image.zfunbox.cn/topic/20250515/2c5ed2097716db6bef01da718bc3c091.jpg",
price: "132.00",
real_pro: "0.02000",
goods_type: 1,
doubling: 3,
is_lingzhu: 0,
},
{
id: 1130,
title: "BANDAI万代拼装模型 1/100 MG 机动战士高达 倒A 逆A-15岁以上",
imgurl:
"https://image.zfunbox.cn/topic/20250515/e35da49b4976f156f2f98dec002274a5.png",
price: "305.00",
real_pro: "0.03000",
goods_type: 1,
doubling: 1,
is_lingzhu: 0,
},
{
id: 1131,
title: "BANDAI 万代拼装模型 MG 主天使-15岁以上",
imgurl:
"https://image.zfunbox.cn/topic/20250515/77302c6f1ea9ea6a8516cc1208174aee.png",
price: "289.00",
real_pro: "0.03000",
goods_type: 1,
doubling: 1,
is_lingzhu: 0,
},
{
id: 1132,
title: "BANDAI万代 HG00 09 1/144 座天使高达一型-15岁以上",
imgurl:
"https://image.zfunbox.cn/topic/20250515/55e816c93b5e4103a30682c586816b11.jpg",
price: "114.00",
real_pro: "0.50000",
goods_type: 1,
doubling: 3,
is_lingzhu: 0,
},
{
id: 1133,
title: "BANDAI万代拼装模型 HGUC 130 机动战士高达 杰斯塔-15岁以上",
imgurl:
"https://image.zfunbox.cn/topic/20250515/aeb6bfb8b4aa8a29796b242e4f5d56d9.png",
price: "113.00",
real_pro: "1.50000",
goods_type: 1,
doubling: 1,
is_lingzhu: 0,
},
{
id: 1134,
title: "BANDAI万代拼装模型HG26 1/144 凯列班高达 异灵高达-15岁以上",
imgurl:
"https://image.zfunbox.cn/topic/20250515/329e3a7e21772a63cea03d31f948345d.png",
price: "112.00",
real_pro: "1.00000",
goods_type: 1,
doubling: 2,
is_lingzhu: 0,
},
{
id: 1135,
title: "梦幻",
imgurl:
"https://image.zfunbox.cn/topic/20250515/d2c7e48515d393084000595074209042.jpg",
price: "41.00",
real_pro: "2.50000",
goods_type: 1,
doubling: 2,
is_lingzhu: 0,
},
{
id: 1136,
title: "谜拟丘",
imgurl:
"https://image.zfunbox.cn/topic/20250515/6031827bc455cbf86ff778d74ddffbd3.jpg",
price: "38.00",
real_pro: "1.50000",
goods_type: 1,
doubling: 1,
is_lingzhu: 0,
},
{
id: 1137,
title: "小提琴模型1个",
imgurl:
"https://image.zfunbox.cn/topic/20250515/22846dea5a933ab314998afc51abb7bb.jpg",
price: "13.80",
real_pro: "92.90000",
goods_type: 1,
doubling: 1,
is_lingzhu: 0,
},
];
},
//
startCallBack() {
console.log("开始抽奖");
this.$emit('start');
},
//
endCallBack(prize) {
//
console.log("抽奖结束", prize);
try {
//
const prizeData = this.prizes[this.currentPrizeIndex]?.data || this.prizes[0]?.data;
if (!prizeData) {
console.error('无法获取奖品数据');
return;
}
//
let allPrizes = [];
// prize使map使prize
if (Array.isArray(prize)) {
allPrizes = prize.map(item => {
const index = typeof item.index === 'number' ? item.index : 0;
return this.prizes[index]?.data || this.prizes[0]?.data;
}).filter(item => !!item);
} else if (prize && typeof prize.index === 'number') {
// prize
const index = prize.index;
const itemData = this.prizes[index]?.data;
if (itemData) {
allPrizes.push(itemData);
}
} else {
// 使
allPrizes.push(prizeData);
}
//
this.$emit('end', {
prize: prize,
prizeData: prizeData, //
allPrizes: allPrizes, //
message: `恭喜您获得 ${prizeData.title}`,
prizeInfo: {
name: prizeData.title,
image: prizeData.imgurl,
description: `价值:${prizeData.price}`,
data: prizeData,
}
});
//
setTimeout(() => {
this.hide();
}, 2000);
} catch (error) {
console.error('处理抽奖结果时出错:', error);
this.hide();
}
},
//
startDraw(callback) {
//
if (!this.isInitialized) {
console.error('老虎机尚未初始化请先调用init方法');
return this;
}
// init
this.show();
setTimeout(() => {
// DOMplay
this.$nextTick(() => {
//
if (this.$refs.myLucky) {
//
this.$refs.myLucky.play();
if (this.bgmCtx && this.bgmCtx.slotBgm) {
this.bgmCtx.slotBgm.play();
}
if (typeof callback === 'function') {
callback();
}
} else {
console.error('老虎机组件未初始化');
}
});
}, 100);
return this; // this
},
//
stopDraw(prizeIndices) {
//
if (!this.isInitialized) {
console.error('老虎机尚未初始化请先调用init方法');
return this;
}
if (!this.$refs.myLucky) {
console.error('老虎机组件未初始化');
return this;
}
//
if (!prizeIndices || !Array.isArray(prizeIndices) || prizeIndices.length === 0) {
// 5
const randomIndices = [];
for (let i = 0; i < 5; i++) {
randomIndices.push(Math.floor(Math.random() * this.prizes.length));
}
this.currentPrizeIndex = randomIndices[0]; // 使
this.$refs.myLucky.stop(randomIndices);
return this;
}
// 55
let indices = [...prizeIndices];
while (indices.length < 5) {
indices.push(indices[indices.length - 1] || 0);
}
//
indices = indices.map(index => {
if (index < 0 || index >= this.prizes.length) {
return Math.floor(Math.random() * this.prizes.length);
}
return index;
});
//
this.currentPrizeIndex = indices[0];
// stop
this.$refs.myLucky.stop(indices);
return this;
},
//
forceEndDraw() {
if (!this.isInitialized) {
console.error('老虎机尚未初始化请先调用init方法');
return this;
}
this.hide();
return this; // this
},
//
reset() {
this.isInitialized = false;
this.isVisible = false;
this.slots = [];
this.prizes = [];
this.prizeList = [];
this.currentPrizeIndex = -1;
return this;
}
},
mounted() {
//
},
};
</script>
<style lang="scss" scoped>
//
.content-container {
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
box-sizing: border-box;
background-image: url($imgurl + "common/slot_bg.webp");
background-size: cover;
background-position: center;
position: fixed;
top: 0;
left: 0;
z-index: 999;
}
.slot-icon {
padding-bottom: 25rpx;
}
//
.slot-container {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
position: relative;
}
//
.slot-view {
background: url("https://image.zfunbox.cn/static/image/lucky/di_5.png") no-repeat;
background-size: 100% 100%;
width: 100%;
padding-top: 80rpx;
padding-bottom: 80rpx;
display: flex;
justify-content: center;
align-items: center;
}
//
.item-lottry {
height: 152.78rpx;
width: 152.78rpx;
display: flex;
justify-content: center;
align-items: center;
font-size: 30rpx;
border-radius: 16rpx;
color: black;
box-sizing: border-box;
background-color: rgba(255, 255, 255, 1);
}
</style>

View File

@ -264,7 +264,8 @@
</view>
</uni-popup>
<!-- 使用抽取的老虎机组件 -->
<DetailLucky ref="detailLucky" @end="onLuckyEnd" />
</page-container>
</template>
@ -278,7 +279,8 @@ import DetailPreviewPopup from '@/components/detail-preview-popup/detail-preview
import preview from '@/components/detail-preview-popup/index.js'
import DetailWuxianLingzhu from '@/components/detail-wuxian-lingzhu/detail-wuxian-lingzhu.vue'
import DetailWuxianRage from '@/components/detail-wuxian-rage/detail-wuxian-rage.vue'
//
import DetailLucky from "@/components/detail-lucky/detail-lucky.vue";
export default {
components: {
PageContainer,
@ -287,7 +289,8 @@ export default {
DetailButton,
DetailPreviewPopup,
DetailWuxianLingzhu,
DetailWuxianRage //
DetailWuxianRage, //
DetailLucky
},
data() {
return {
@ -415,6 +418,14 @@ export default {
},
methods: {
//
onLuckyEnd(data) {
console.log("抽奖结束", data);
//
console.log("所有中奖奖品:", data.allPrizes);
this.$refs.detailLucky.hide();
},
previewDetail(item, a) {
const obj = {
@ -545,7 +556,7 @@ export default {
return
}
// console.log(' res.data.prize_num', res.data.prize_num);
if (that.buyNum == 0 || that.buyNum == null) {
if (res.data.prize_num != null) {
that.buyNum = res.data.prize_num;
@ -657,8 +668,9 @@ export default {
})
if (status == 'success') {
this.getPrize(res.data.order_num)
this.getPrize(res.data.order_num);
this.doRefresh()
// this.$refs.detailLucky.init([], this.buyNum);
}
} else {
this.$c.toast({

View File

@ -1,312 +1,154 @@
<template>
<page-container title="抽奖特效" :showBack="true">
<view class="content-container">
<view>
<view class="slot-view">
<!-- 老虎机组件 -->
<SlotMachine
ref="myLucky"
:width="windowWidth"
height="800rpx"
:blocks="blocks"
:slots="slots"
:prizes="prizes"
:defaultConfig="defaultConfig"
@start="startCallBack"
@end="endCallBack"
>
</SlotMachine>
</view>
</view>
</view>
<!-- 使用抽取的老虎机组件 -->
<DetailLucky ref="detailLucky" @start="onLuckyStart" @end="onLuckyEnd" />
<!-- 开始抽奖按钮 -->
<button
style="
margin-top: 20rpx;
position: absolute;
bottom: 20rpx;
left: 50%;
transform: translateX(-50%);
"
@click="onStartDraw"
>
开始抽奖
</button>
<!-- 页面上的开始抽奖按钮 -->
<button class="start-draw-btn" @click="startDrawing">开始抽奖</button>
</page-container>
</template>
<script>
//
import SlotMachine from "@/components/@lucky-canvas/uni/slot-machine";
function shuffle(array) {
for (let i = array.length - 1; i > 0; i--) {
// 0 i
const j = Math.floor(Math.random() * (i + 1));
// array[i] array[j]
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
// import SlotMachine from '@lucky-canvas/uni/slot-machine' //
//
import DetailLucky from "@/components/detail-lucky/detail-lucky.vue";
export default {
components: { SlotMachine },
components: { DetailLucky },
data() {
let windowWidth = uni.getSystemInfoSync().windowWidth;
console.log(windowWidth);
let t = [
{
id: 1128,
title: "兹琪露娜提亚斯",
imgurl:
"https://image.zfunbox.cn/topic/20250515/2986e27e673ef675e02771cdebd9b822.jpg",
price: "350.00",
real_pro: "0.02000",
goods_type: 1,
doubling: 1,
is_lingzhu: 0,
},
{
id: 1129,
title: "月岗恋钟",
imgurl:
"https://image.zfunbox.cn/topic/20250515/2c5ed2097716db6bef01da718bc3c091.jpg",
price: "132.00",
real_pro: "0.02000",
goods_type: 1,
doubling: 3,
is_lingzhu: 0,
},
{
id: 1130,
title: "BANDAI万代拼装模型 1/100 MG 机动战士高达 倒A 逆A-15岁以上",
imgurl:
"https://image.zfunbox.cn/topic/20250515/e35da49b4976f156f2f98dec002274a5.png",
price: "305.00",
real_pro: "0.03000",
goods_type: 1,
doubling: 1,
is_lingzhu: 0,
},
{
id: 1131,
title: "BANDAI 万代拼装模型 MG 主天使-15岁以上",
imgurl:
"https://image.zfunbox.cn/topic/20250515/77302c6f1ea9ea6a8516cc1208174aee.png",
price: "289.00",
real_pro: "0.03000",
goods_type: 1,
doubling: 1,
is_lingzhu: 0,
},
{
id: 1132,
title: "BANDAI万代 HG00 09 1/144 座天使高达一型-15岁以上",
imgurl:
"https://image.zfunbox.cn/topic/20250515/55e816c93b5e4103a30682c586816b11.jpg",
price: "114.00",
real_pro: "0.50000",
goods_type: 1,
doubling: 3,
is_lingzhu: 0,
},
{
id: 1133,
title: "BANDAI万代拼装模型 HGUC 130 机动战士高达 杰斯塔-15岁以上",
imgurl:
"https://image.zfunbox.cn/topic/20250515/aeb6bfb8b4aa8a29796b242e4f5d56d9.png",
price: "113.00",
real_pro: "1.50000",
goods_type: 1,
doubling: 1,
is_lingzhu: 0,
},
{
id: 1134,
title: "BANDAI万代拼装模型HG26 1/144 凯列班高达 异灵高达-15岁以上",
imgurl:
"https://image.zfunbox.cn/topic/20250515/329e3a7e21772a63cea03d31f948345d.png",
price: "112.00",
real_pro: "1.00000",
goods_type: 1,
doubling: 2,
is_lingzhu: 0,
},
{
id: 1135,
title: "梦幻",
imgurl:
"https://image.zfunbox.cn/topic/20250515/d2c7e48515d393084000595074209042.jpg",
price: "41.00",
real_pro: "2.50000",
goods_type: 1,
doubling: 2,
is_lingzhu: 0,
},
{
id: 1136,
title: "谜拟丘",
imgurl:
"https://image.zfunbox.cn/topic/20250515/6031827bc455cbf86ff778d74ddffbd3.jpg",
price: "38.00",
real_pro: "1.50000",
goods_type: 1,
doubling: 1,
is_lingzhu: 0,
},
{
id: 1137,
title: "小提琴模型1个",
imgurl:
"https://image.zfunbox.cn/topic/20250515/22846dea5a933ab314998afc51abb7bb.jpg",
price: "13.80",
real_pro: "92.90000",
goods_type: 1,
doubling: 1,
is_lingzhu: 0,
},
];
let prizes = [];
for (let i = 0; i < t.length; i++) {
prizes.push({
imgs: [
{
src: t[i].imgurl,
width: "152.78rpx",
height: "152.78rpx",
},
],
background: "#ffffff",
});
}
const arr = Array.from({ length: t.length }, (_, i) => i);
let slots = [
{ order:shuffle([...arr]), speed: 20 }, //
{ order:shuffle([...arr]), speed: 20 }, //
{ order:shuffle([...arr]), speed: 20 }, //
{ order:shuffle([...arr]), speed: 20 }, //
{ order:shuffle([...arr]), speed: 20 }, //
]
console.log(slots);
return {
windowWidth: windowWidth + "px",
//
blocks: [
// { padding: "100px 0px 0px 0px", imgs:[{src:"https://image.zfunbox.cn/di.png",width:"100%",height:"100%"}]},
//https://image.zfunbox.cn/di.png
// {background:"#238E71"},
// { padding: "0px", background: "transparent" }, //
// { padding: "0px", background: "transparent" }, //
//
prizeList: [
{
id: 1001,
title: "iPhone 15 Pro Max",
imgurl:
"https://image.zfunbox.cn/topic/20250515/2986e27e673ef675e02771cdebd9b822.jpg",
price: "9999.00",
real_pro: "0.01000",
goods_type: 1,
doubling: 1,
is_lingzhu: 0,
},
{
id: 1002,
title: "AirPods Pro",
imgurl:
"https://image.zfunbox.cn/topic/20250515/2c5ed2097716db6bef01da718bc3c091.jpg",
price: "1999.00",
real_pro: "0.05000",
goods_type: 1,
doubling: 1,
is_lingzhu: 0,
},
// ...
],
//
slots: slots,
//
prizes: prizes,
//
defaultConfig: {
mode: "horizontal", //
rowSpacing: "10px", //
colSpacing: "10px", //
accelerationTime:1500
},
//
luckyMessage: "恭喜您获得奖品",
luckyPrize: null,
};
},
computed: {
//
lotteryItemSize() {
let height = uni.upx2px(220);
let width = uni.upx2px(170);
return [width, height];
},
mounted() {
//
this.initLuckyMachine();
},
methods: {
//
startCallBack() {
console.log("开始抽奖");
//
initLuckyMachine() {
try {
// 使
this.$refs.detailLucky.init([], 1);
console.log("老虎机初始化完成");
} catch (error) {
console.error("初始化老虎机时出错:", error);
}
},
//
endCallBack(prize) {
//
console.log("抽奖结束", prize);
},
//
onStartDraw() {
let windowWidth = uni.getSystemInfoSync().windowWidth;
console.log(windowWidth);
//
this.$refs.myLucky.play();
this.bgmCtx.slotBgm.play()
// 使
setTimeout(() => {
//
const index = Math.floor(Math.random() * this.prizes.length);
// stop
this.$refs.myLucky.stop([0, 1, 2,3,4]);
}, 2000); // 3
//
startDrawing() {
try {
// ->->
//
this.$refs.detailLucky.startDraw(() => {
console.log("抽奖开始了");
// 2
setTimeout(() => {
try {
// 5
// 1 -
// this.$refs.detailLucky.stopDraw();
// 2 -
// this.$refs.detailLucky.stopDraw([0, 0, 0, 0, 0]);
// 3 -
const prizeIndices = [0, 1, 0, 1, 0]; //
this.$refs.detailLucky.stopDraw(prizeIndices);
} catch (error) {
console.error("停止抽奖时出错:", error);
uni.showToast({
title: "抽奖异常,请重试",
icon: "none",
});
}
}, 2000);
});
} catch (error) {
console.error("开始抽奖时出错:", error);
uni.showToast({
title: "抽奖异常,请重试",
icon: "none",
});
}
},
//
onLuckyStart() {
console.log("父组件接收到开始抽奖事件");
},
//
onLuckyEnd(data) {
console.log("抽奖结束", data);
//
console.log("所有中奖奖品:", data.allPrizes);
this.$refs.detailLucky.hide();
//
this.luckyMessage = data.message;
this.luckyPrize = data.prizeInfo;
//
this.$refs.luckyPopup && this.$refs.luckyPopup.open();
},
//
onPrizeConfirm(prize) {
uni.showToast({
title: "奖品已领取",
icon: "success",
});
},
//
onPrizeCancel() {
uni.showToast({
title: "已关闭弹窗",
icon: "none",
});
},
},
};
</script>
<style lang="scss">
//
.content-container {
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
box-sizing: border-box;
background-image: url($imgurl + "common/slot_bg.webp");
background-size: cover;
background-position: center;
}
.slot-title{
background: url('https://image.zfunbox.cn/di.png') no-repeat;
background-size: 100% 100%;
width: 100vw;
height: 100rpx;
}
//
.slot-view {
// background: linear-gradient(to right, #0c1b21, #218c78, #0c1b21);
background: url('https://image.zfunbox.cn/di.png') no-repeat;
background-size: 100% 100%;
// background-size: cover;
// background-position: center;
width: 100vw;
padding-top: 200rpx;
padding-bottom: 80rpx;
// height: 520rpx;
display: flex;
justify-content: center;
align-items: center;
// padding: 0rpx;
}
// 线
.view-center-line {
position: absolute;
width: 1rpx;
background-color: red;
height: 300rpx;
z-index: 10;
}
//
.item-lottry {
height: 152.78rpx;
width: 152.78rpx;
display: flex;
justify-content: center;
align-items: center;
font-size: 30rpx;
border-radius: 16rpx;
color: black;
box-sizing: border-box;
background-color: rgba(255, 255, 255, 1);
//
.start-draw-btn {
margin: 20rpx;
background-color: #ff6b6b;
color: #fff;
border-radius: 50rpx;
padding: 20rpx 40rpx;
}
</style>