You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

185 lines
6.9 KiB

  1. import { ref, computed, watch } from 'vue';
  2. import { useLotteryStore } from '../../../store/lottery' // 路径根据实际情况调整
  3. import { drawLottery } from '../../../api/API'; // 导入新的抽奖接口
  4. function getRandomInt(max) {
  5. return Math.floor(Math.random() * max);
  6. }
  7. const lotteryStore = useLotteryStore();
  8. const winners = computed({
  9. get: () => lotteryStore.winners,
  10. set: (val) => lotteryStore.setWinners(val),
  11. });
  12. // 用watch监听winners的变化
  13. // watch(winners, (newVal) => {
  14. // console.log('winners', newVal);
  15. // winners.value = newVal;
  16. // });
  17. export function useLotteryEngine(dataManager, renderer3D) {
  18. const isLotting = ref(false);
  19. const lotteryStore = useLotteryStore(); // 只获取一次
  20. async function executeLottery() {
  21. if (isLotting.value) return;
  22. isLotting.value = true;
  23. dataManager.setLotteryStatus(true);
  24. await dataManager.saveData();
  25. changePrize();
  26. // 重置卡片动画
  27. await renderer3D.resetCard([]);
  28. // 计算本次应该抽奖的人数
  29. const currentPrizeIndex = dataManager.state.currentPrizeIndex;
  30. const prize = dataManager.state.basicData.prizes[currentPrizeIndex];
  31. const luckyUsers = dataManager.state.basicData.luckyUsers[currentPrizeIndex] || [];
  32. const remainingPrizeCount = prize.count - luckyUsers.length; // 奖品剩余数量
  33. const basePerCount = dataManager.state.config.EACH_COUNT[currentPrizeIndex] || 1;
  34. const actualPerCount = Math.min(basePerCount, remainingPrizeCount); // 取最小值
  35. console.log('executeLottery - currentPrizeIndex:', currentPrizeIndex, 'prize:', prize, 'basePerCount:', basePerCount, 'remainingPrizeCount:', remainingPrizeCount, 'actualPerCount:', actualPerCount);
  36. // 请求后端进行抽奖
  37. try {
  38. const lotteryData = {
  39. gradeId: prize.gradeId,
  40. prizeId: prize.prizeId,
  41. perWin: basePerCount,
  42. remainNum: prize.remainNum
  43. };
  44. console.log('请求后端抽奖,参数:', lotteryData);
  45. const response = await drawLottery(lotteryData);
  46. console.log('response', response);
  47. winners.value = response.data.data;
  48. console.log('抽奖的winners', winners.value);
  49. // winners.value = response.data;
  50. console.log('后端抽奖返回结果:', response);
  51. if (response && response.data.data && Array.isArray(response.data.data)) {
  52. // 后端返回中奖用户数据
  53. const currentLuckys = response.data.data.map(item => ({
  54. jwcode: item.jwcode,
  55. username: item.username
  56. }));
  57. console.log('后端返回的中奖用户:', currentLuckys);
  58. // 生成随机卡片索引用于显示
  59. const totalCards = dataManager.getTotalCards();
  60. let selectedCardIndex = [];
  61. for (let i = 0; i < currentLuckys.length; i++) {
  62. let cardIndex = getRandomInt(totalCards);
  63. while (selectedCardIndex.includes(cardIndex)) {
  64. cardIndex = getRandomInt(totalCards);
  65. }
  66. selectedCardIndex.push(cardIndex);
  67. }
  68. console.log('executeLottery - selectedCardIndex:', selectedCardIndex, 'currentLuckys:', currentLuckys);
  69. dataManager.state.currentLuckys = currentLuckys;
  70. // 保存中奖用户到对应奖品
  71. if (!dataManager.state.basicData.luckyUsers[currentPrizeIndex]) {
  72. dataManager.state.basicData.luckyUsers[currentPrizeIndex] = [];
  73. }
  74. dataManager.state.basicData.luckyUsers[currentPrizeIndex].push(...currentLuckys);
  75. // 更新轮次信息
  76. dataManager.updateCurrentRound();
  77. // 展示中奖动画
  78. console.log('executeLottery - calling selectCard');
  79. await renderer3D.selectCard?.(selectedCardIndex, currentLuckys);
  80. console.log('executeLottery - selectCard completed');
  81. } else {
  82. console.error('后端抽奖返回数据格式错误:', response);
  83. throw new Error('抽奖失败:后端返回数据格式错误');
  84. }
  85. } catch (error) {
  86. console.error('抽奖请求失败:', error);
  87. // 如果后端请求失败,可以回退到前端随机抽奖逻辑
  88. console.log('回退到前端随机抽奖逻辑');
  89. const totalCards = dataManager.getTotalCards();
  90. const leftUsers = dataManager.state.basicData.leftUsers;
  91. let selectedCardIndex = [];
  92. let currentLuckys = [];
  93. let leftCount = leftUsers.length;
  94. // 随机抽取中奖用户和卡片索引
  95. for (let i = 0; i < actualPerCount && leftCount > 0; i++) {
  96. const luckyId = getRandomInt(leftCount);
  97. const selectedUser = leftUsers.splice(luckyId, 1)[0];
  98. // 确保数据格式一致
  99. currentLuckys.push({
  100. jwcode: selectedUser.jwcode || selectedUser[0] || "",
  101. username: selectedUser.username || selectedUser[1] || "",
  102. company: selectedUser.company || selectedUser[2] || "PSST"
  103. });
  104. leftCount--;
  105. let cardIndex = getRandomInt(totalCards);
  106. while (selectedCardIndex.includes(cardIndex)) {
  107. cardIndex = getRandomInt(totalCards);
  108. }
  109. selectedCardIndex.push(cardIndex);
  110. }
  111. console.log('executeLottery - selectedCardIndex:', selectedCardIndex, 'currentLuckys:', currentLuckys);
  112. dataManager.state.currentLuckys = currentLuckys;
  113. // 保存中奖用户到对应奖品
  114. if (!dataManager.state.basicData.luckyUsers[currentPrizeIndex]) {
  115. dataManager.state.basicData.luckyUsers[currentPrizeIndex] = [];
  116. }
  117. dataManager.state.basicData.luckyUsers[currentPrizeIndex].push(...currentLuckys);
  118. // 更新轮次信息
  119. dataManager.updateCurrentRound();
  120. // 展示中奖动画
  121. console.log('executeLottery - calling selectCard');
  122. await renderer3D.selectCard?.(selectedCardIndex, currentLuckys);
  123. console.log('executeLottery - selectCard completed');
  124. }
  125. // 抽奖完成后更新奖品列表数据
  126. try {
  127. await dataManager.updatePrizeList();
  128. console.log('抽奖完成后奖品列表已更新');
  129. } catch (error) {
  130. console.error('更新奖品列表失败:', error);
  131. }
  132. dataManager.setLotteryStatus(false);
  133. isLotting.value = false;
  134. }
  135. function performLottery() {
  136. // 已合并到 executeLottery
  137. }
  138. function changePrize() {
  139. // 可根据中奖情况切换奖品
  140. dataManager.updateCurrentPrize();
  141. }
  142. async function resetLottery() {
  143. if (isLotting.value) return;
  144. dataManager.resetAllData();
  145. renderer3D.addHighlight && renderer3D.addHighlight();
  146. lotteryStore.setLotteryState('idle'); // 直接用
  147. await renderer3D.resetCard([]);
  148. await dataManager.resetData();
  149. // 重置轮次
  150. dataManager.state.currentRound = 1;
  151. renderer3D.switchScreen && renderer3D.switchScreen('enter');
  152. }
  153. return {
  154. isLotting,
  155. executeLottery,
  156. performLottery,
  157. changePrize,
  158. resetLottery
  159. };
  160. }