- {{ prizes[lastRevealedIdx].title }}
- {{ prizes[lastRevealedIdx].text }}
+ {{
+ prizes[lastRevealedIdx].title
+ }}
+ {{
+ prizes[lastRevealedIdx].text
+ }}
- {{ prizes[lastRevealedIdx].count - getLeftCount(prizes[lastRevealedIdx]) }}/{{ prizes[lastRevealedIdx].count }}
+ {{ getLeftCount(prizes[lastRevealedIdx]) }}/{{
+ prizes[lastRevealedIdx].count
+ }}
@@ -159,16 +182,27 @@
@@ -501,10 +577,37 @@ function getProgressPercent(prize) {
border-radius: 8px 8px 8px 8px;
}
.prize-panel-item.revealed-highlight {
- border: 3px solid #ff9800;
+ /* border: 3px solid #ff9800; */
box-shadow: 0 0 16px 4px #ff9800aa;
transform: scale(1.05);
z-index: 2;
transition: all 0.3s;
}
+
+.prize-panel-item.disabled {
+ cursor: not-allowed !important;
+ position: relative;
+}
+
+.prize-panel-item.disabled::after {
+ content: "请先抽完上一个奖品";
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ background: rgba(0, 0, 0, 0.8);
+ color: white;
+ padding: 8px 12px;
+ border-radius: 6px;
+ font-size: 14px;
+ white-space: nowrap;
+ z-index: 10;
+ opacity: 0;
+ transition: opacity 0.3s;
+ pointer-events: none;
+}
+
+.prize-panel-item.disabled:hover::after {
+ opacity: 1;
+}
\ No newline at end of file
diff --git a/src/views/choujiang/lottery/dataManager.js b/src/views/choujiang/lottery/dataManager.js
index 6737279..0634555 100644
--- a/src/views/choujiang/lottery/dataManager.js
+++ b/src/views/choujiang/lottery/dataManager.js
@@ -1,5 +1,5 @@
import { reactive } from 'vue';
-
+import { getPrizeList, getUserList } from '../../../api/API';
export function useDataManager() {
const state = reactive({
basicData: {
@@ -12,94 +12,56 @@ export function useDataManager() {
currentPrize: null,
currentLuckys: [],
isLotting: false,
+ // 新增:轮次管理
+ currentRound: 1,
config: {
prizes: [],
EACH_COUNT: [],
COMPANY: '',
HIGHLIGHT_CELL: [],
- Resolution: 1
+ Resolution: 1,
+ ROW_COUNT: 7,
+ COLUMN_COUNT: 20
}
});
async function getBasicData() {
- // 假数据,后续可替换为接口
- const fakePrizes = [
- { type: 0, title: '特别奖', text: 'iPad', count: 10, img: '/src/assets/lottery/ipad.jpg' },
- { type: 1, title: '一等奖', text: 'Kindle', count: 20, img: '/src/assets/lottery/kindle.jpg' },
- { type: 2, title: '二等奖', text: 'MacBook Pro', count: 10, img: '/src/assets/lottery/mbp.jpg' }
- ];
- const fakeEachCount = [15, 17, 36];
+ // 获取奖品列表
+ const prizeList = await getPrizeList();
+ const fakePrizes = prizeList.data.map((item, index) => ({
+ type: index, // 使用索引作为type
+ title: item.gradeName,
+ text: item.prizeName,
+ count: item.amount,
+ img: item.imageUrl
+ }));
+
+ const fakeEachCount = prizeList.data.map(item => item.perWin);
+ console.log("fakeEachCount", fakeEachCount);
const fakeCompany = '前端假公司';
const fakeLuckyData = {};
- fakePrizes.forEach(prize => {
- fakeLuckyData[prize.type] = [];
+ fakePrizes.forEach((prize, index) => {
+ fakeLuckyData[index] = [];
});
- const fakeLeftUsers = [
- [0, "张三"],
- [1, "李四"],
- [2, "王五"],
- [3, "赵六"],
- [4, "孙七"],
- [5, "周八"],
- [6, "吴九"],
- [7, "郑十"],
- [8, "钱十一"],
- [9, "孙十二"],
- [10, "李十三"],
- [11, "周十四"],
- [12, "吴十五"],
- [13, "郑十六"],
- [14, "钱十七"],
- [15, "孙十八"],
- [16, "李十九"],
- [17, "周二十"],
- [18, "吴二一"],
- [19, "郑二二"], [0, "张三"],
- [1, "李四"],
- [2, "王五"],
- [3, "赵六"],
- [4, "孙七"],
- [5, "周八"],
- [6, "吴九"],
- [7, "郑十"],
- [8, "钱十一"],
- [9, "孙十二"],
- [10, "李十三"],
- [11, "周十四"],
- [12, "吴十五"],
- [13, "郑十六"],
- [14, "钱十七"],
- [15, "孙十八"],
- [16, "李十九"],
- [17, "周二十"],
- [18, "吴二一"],
- [19, "郑二二"], [0, "张三"],
- [1, "李四"],
- [2, "王五"],
- [3, "赵六"],
- [4, "孙七"],
- [5, "周八"],
- [6, "吴九"],
- [7, "郑十"],
- [8, "钱十一"],
- [9, "孙十二"],
- [10, "李十三"],
- [11, "周十四"],
- [12, "吴十五"],
- [13, "郑十六"],
- [14, "钱十七"],
- [15, "孙十八"],
- [16, "李十九"],
- [17, "周二十"],
- [18, "吴二一"],
- [19, "郑二二"],
- ];
+
+ // 获取真实用户数据
+ const userListResponse = await getUserList();
+ console.log("userList", userListResponse);
+
+ // 将后端返回的用户数据转换为兼容格式
+ const realUsers = userListResponse.data.map(item => ({
+ jwcode: item.jwcode,
+ username: item.username,
+ company: fakeCompany // 使用默认公司名称
+ }));
+
state.config.prizes = fakePrizes;
state.config.EACH_COUNT = fakeEachCount;
state.config.COMPANY = fakeCompany;
state.config.HIGHLIGHT_CELL = [];
state.basicData.prizes = fakePrizes;
- state.basicData.leftUsers = fakeLeftUsers.slice();
+ state.basicData.users = realUsers; // 使用真实用户数据
+ state.basicData.leftUsers = realUsers.slice(); // 初始化剩余用户为所有用户
state.basicData.luckyUsers = fakeLuckyData;
determineCurrentPrize();
return Promise.resolve({
@@ -108,74 +70,24 @@ export function useDataManager() {
EACH_COUNT: fakeEachCount,
COMPANY: fakeCompany
},
- leftUsers: fakeLeftUsers.slice(),
+ leftUsers: realUsers.slice(),
luckyData: fakeLuckyData
});
}
async function getUsers() {
- const fakeUsers = [
- [0, "张三"],
- [1, "李四"],
- [2, "王五"],
- [3, "赵六"],
- [4, "孙七"],
- [5, "周八"],
- [6, "吴九"],
- [7, "郑十"],
- [8, "钱十一"],
- [9, "孙十二"],
- [10, "李十三"],
- [11, "周十四"],
- [12, "吴十五"],
- [13, "郑十六"],
- [14, "钱十七"],
- [15, "孙十八"],
- [16, "李十九"],
- [17, "周二十"],
- [18, "吴二一"],
- [19, "郑二二"], [0, "张三"],
- [1, "李四"],
- [2, "王五"],
- [3, "赵六"],
- [4, "孙七"],
- [5, "周八"],
- [6, "吴九"],
- [7, "郑十"],
- [8, "钱十一"],
- [9, "孙十二"],
- [10, "李十三"],
- [11, "周十四"],
- [12, "吴十五"],
- [13, "郑十六"],
- [14, "钱十七"],
- [15, "孙十八"],
- [16, "李十九"],
- [17, "周二十"],
- [18, "吴二一"],
- [19, "郑二二"], [0, "张三"],
- [1, "李四"],
- [2, "王五"],
- [3, "赵六"],
- [4, "孙七"],
- [5, "周八"],
- [6, "吴九"],
- [7, "郑十"],
- [8, "钱十一"],
- [9, "孙十二"],
- [10, "李十三"],
- [11, "周十四"],
- [12, "吴十五"],
- [13, "郑十六"],
- [14, "钱十七"],
- [15, "孙十八"],
- [16, "李十九"],
- [17, "周二十"],
- [18, "吴二一"],
- [19, "郑二二"],
- ];
- state.basicData.users = fakeUsers;
- return Promise.resolve(fakeUsers);
+ const userList = await getUserList();
+ console.log("userList", userList);
+
+ // 将后端返回的用户数据转换为兼容格式
+ const realUsers = userList.data.map(item => ({
+ jwcode: item.jwcode,
+ username: item.username,
+ company: state.config.COMPANY || '前端假公司'
+ }));
+
+ state.basicData.users = realUsers;
+ return Promise.resolve(userList);
}
function determineCurrentPrize() {
@@ -213,6 +125,35 @@ export function useDataManager() {
}
function updateCurrentPrize() { determineCurrentPrize(); }
+ // 新增:计算当前奖品的总轮次
+ function getTotalRounds(prizeIndex) {
+ const prize = state.basicData.prizes[prizeIndex];
+ const eachCount = state.config.EACH_COUNT[prizeIndex];
+ if (!prize || !eachCount) return 0;
+ return Math.ceil(prize.count / eachCount);
+ }
+
+ // 新增:计算当前轮次
+ function getCurrentRound(prizeIndex) {
+ const luckyUsers = state.basicData.luckyUsers[prizeIndex] || [];
+ const eachCount = state.config.EACH_COUNT[prizeIndex];
+ if (!eachCount) return 1;
+ return Math.floor(luckyUsers.length / eachCount) + 1;
+ }
+
+ // 新增:计算剩余数量
+ function getLeftCount(prizeIndex) {
+ const prize = state.basicData.prizes[prizeIndex];
+ const luckyUsers = state.basicData.luckyUsers[prizeIndex] || [];
+ if (!prize) return 0;
+ return prize.count - luckyUsers.length;
+ }
+
+ // 新增:更新当前轮次
+ function updateCurrentRound() {
+ state.currentRound = getCurrentRound(state.currentPrizeIndex);
+ }
+
return {
state,
getBasicData,
@@ -224,6 +165,10 @@ export function useDataManager() {
getTotalCards,
setLotteryStatus,
resetAllData,
- updateCurrentPrize
+ updateCurrentPrize,
+ getTotalRounds,
+ getCurrentRound,
+ getLeftCount,
+ updateCurrentRound
};
}
\ No newline at end of file
diff --git a/src/views/choujiang/lottery/lotteryEngine.js b/src/views/choujiang/lottery/lotteryEngine.js
index 1b07618..9adf8db 100644
--- a/src/views/choujiang/lottery/lotteryEngine.js
+++ b/src/views/choujiang/lottery/lotteryEngine.js
@@ -1,5 +1,6 @@
import { ref } from 'vue';
import { useLotteryStore } from '../../../store/lottery' // 路径根据实际情况调整
+import { drawLottery } from '../../../api/API'; // 导入新的抽奖接口
function getRandomInt(max) {
return Math.floor(Math.random() * max);
@@ -17,35 +18,113 @@ export function useLotteryEngine(dataManager, renderer3D) {
changePrize();
// 重置卡片动画
await renderer3D.resetCard([]);
- // 生成中奖卡片索引和中奖用户
- const perCount = dataManager.state.config.EACH_COUNT[dataManager.state.currentPrizeIndex] || 1;
- const totalCards = renderer3D.getTotalCards ? renderer3D.getTotalCards() : 50;
- const leftUsers = dataManager.state.basicData.leftUsers;
- let selectedCardIndex = [];
- let currentLuckys = [];
- let leftCount = leftUsers.length;
- console.log('executeLottery - perCount:', perCount, 'leftCount:', leftCount, 'totalCards:', totalCards);
+ // 计算本次应该抽奖的人数
+ const currentPrizeIndex = dataManager.state.currentPrizeIndex;
+ const prize = dataManager.state.basicData.prizes[currentPrizeIndex];
+ const luckyUsers = dataManager.state.basicData.luckyUsers[currentPrizeIndex] || [];
+ const remainingPrizeCount = prize.count - luckyUsers.length; // 奖品剩余数量
+ const basePerCount = dataManager.state.config.EACH_COUNT[currentPrizeIndex] || 1;
+ const actualPerCount = Math.min(basePerCount, remainingPrizeCount); // 取最小值
- // 随机抽取中奖用户和卡片索引
- for (let i = 0; i < perCount && leftCount > 0; i++) {
- const luckyId = getRandomInt(leftCount);
- currentLuckys.push(leftUsers.splice(luckyId, 1)[0]);
- leftCount--;
- let cardIndex = getRandomInt(totalCards);
- while (selectedCardIndex.includes(cardIndex)) {
- cardIndex = getRandomInt(totalCards);
+ console.log('executeLottery - currentPrizeIndex:', currentPrizeIndex, 'prize:', prize, 'basePerCount:', basePerCount, 'remainingPrizeCount:', remainingPrizeCount, 'actualPerCount:', actualPerCount);
+
+ // 请求后端进行抽奖
+ try {
+ const lotteryData = {
+ gradeName: prize.title,
+ prizeName: prize.text,
+ perWin: basePerCount,
+ round: dataManager.state.currentRound
+ };
+
+ console.log('请求后端抽奖,参数:', lotteryData);
+ const response = await drawLottery(lotteryData);
+ console.log('后端抽奖返回结果:', response);
+
+ if (response && response.data && Array.isArray(response.data)) {
+ // 后端返回中奖用户数据
+ const currentLuckys = response.data.map(item => ({
+ jwcode: item.jwcode,
+ username: item.username
+ }));
+
+ console.log('后端返回的中奖用户:', currentLuckys);
+
+ // 生成随机卡片索引用于显示
+ const totalCards = dataManager.getTotalCards();
+ let selectedCardIndex = [];
+ for (let i = 0; i < currentLuckys.length; i++) {
+ let cardIndex = getRandomInt(totalCards);
+ while (selectedCardIndex.includes(cardIndex)) {
+ cardIndex = getRandomInt(totalCards);
+ }
+ selectedCardIndex.push(cardIndex);
+ }
+
+ console.log('executeLottery - selectedCardIndex:', selectedCardIndex, 'currentLuckys:', currentLuckys);
+
+ dataManager.state.currentLuckys = currentLuckys;
+ // 保存中奖用户到对应奖品
+ if (!dataManager.state.basicData.luckyUsers[currentPrizeIndex]) {
+ dataManager.state.basicData.luckyUsers[currentPrizeIndex] = [];
+ }
+ dataManager.state.basicData.luckyUsers[currentPrizeIndex].push(...currentLuckys);
+ // 更新轮次信息
+ dataManager.updateCurrentRound();
+ // 展示中奖动画
+ console.log('executeLottery - calling selectCard');
+ await renderer3D.selectCard?.(selectedCardIndex, currentLuckys);
+ console.log('executeLottery - selectCard completed');
+ } else {
+ console.error('后端抽奖返回数据格式错误:', response);
+ throw new Error('抽奖失败:后端返回数据格式错误');
+ }
+ } catch (error) {
+ console.error('抽奖请求失败:', error);
+ // 如果后端请求失败,可以回退到前端随机抽奖逻辑
+ console.log('回退到前端随机抽奖逻辑');
+
+ const totalCards = dataManager.getTotalCards();
+ const leftUsers = dataManager.state.basicData.leftUsers;
+ let selectedCardIndex = [];
+ let currentLuckys = [];
+ let leftCount = leftUsers.length;
+
+ // 随机抽取中奖用户和卡片索引
+ for (let i = 0; i < actualPerCount && leftCount > 0; i++) {
+ const luckyId = getRandomInt(leftCount);
+ const selectedUser = leftUsers.splice(luckyId, 1)[0];
+ // 确保数据格式一致
+ currentLuckys.push({
+ jwcode: selectedUser.jwcode || selectedUser[0] || "",
+ username: selectedUser.username || selectedUser[1] || "",
+ company: selectedUser.company || selectedUser[2] || "PSST"
+ });
+ leftCount--;
+ let cardIndex = getRandomInt(totalCards);
+ while (selectedCardIndex.includes(cardIndex)) {
+ cardIndex = getRandomInt(totalCards);
+ }
+ selectedCardIndex.push(cardIndex);
+ }
+
+ console.log('executeLottery - selectedCardIndex:', selectedCardIndex, 'currentLuckys:', currentLuckys);
+
+ dataManager.state.currentLuckys = currentLuckys;
+ // 保存中奖用户到对应奖品
+ if (!dataManager.state.basicData.luckyUsers[currentPrizeIndex]) {
+ dataManager.state.basicData.luckyUsers[currentPrizeIndex] = [];
}
- selectedCardIndex.push(cardIndex);
+ dataManager.state.basicData.luckyUsers[currentPrizeIndex].push(...currentLuckys);
+ // 更新轮次信息
+ dataManager.updateCurrentRound();
+ // 展示中奖动画
+ console.log('executeLottery - calling selectCard');
+ await renderer3D.selectCard?.(selectedCardIndex, currentLuckys);
+ console.log('executeLottery - selectCard completed');
}
- console.log('executeLottery - selectedCardIndex:', selectedCardIndex, 'currentLuckys:', currentLuckys);
-
- dataManager.state.currentLuckys = currentLuckys;
- // 展示中奖动画
- console.log('executeLottery - calling selectCard');
- await renderer3D.selectCard?.(selectedCardIndex, currentLuckys);
- console.log('executeLottery - selectCard completed');
dataManager.setLotteryStatus(false);
isLotting.value = false;
}
@@ -66,6 +145,8 @@ export function useLotteryEngine(dataManager, renderer3D) {
lotteryStore.setLotteryState('idle'); // 直接用
await renderer3D.resetCard([]);
await dataManager.resetData();
+ // 重置轮次
+ dataManager.state.currentRound = 1;
renderer3D.switchScreen && renderer3D.switchScreen('enter');
}