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.

184 lines
4.3 KiB

  1. <template>
  2. <div
  3. :id="`card-${id}`"
  4. :class="[
  5. 'element',
  6. { lightitem: isBold, highlight: highlight, prize: prize },
  7. ]"
  8. :style="cardStyle"
  9. >
  10. <!-- <div class="company">{{ company }}</div> -->
  11. <!-- <div class="name">{{ user[1] }}</div> -->
  12. <div class="details">{{ displayText }}</div>
  13. </div>
  14. </template>
  15. <script setup>
  16. import { computed, ref, onMounted, onBeforeUnmount, watch } from "vue";
  17. import { useLotteryStore } from "../../../store/lottery"; // 路径根据实际情况调整
  18. const lotteryStore = useLotteryStore(); // 只获取一次
  19. const lotteryState = computed({
  20. get: () => lotteryStore.lotteryState,
  21. set: (val) => lotteryStore.setLotteryState(val),
  22. });
  23. const props = defineProps({
  24. id: [String, Number],
  25. user: { type: Array, required: true },
  26. isBold: Boolean,
  27. showTable: Boolean,
  28. company: String,
  29. highlight: Boolean,
  30. prize: Boolean,
  31. });
  32. // 添加响应式数据用于文字切换
  33. const displayText = ref("");
  34. const textSwitchInterval = ref(null);
  35. // 从store获取用户列表状态
  36. const allUsers = computed(() => lotteryStore.allUsers);
  37. const isUsersLoaded = computed(() => lotteryStore.isUsersLoaded);
  38. // 随机切换文字
  39. const switchText = () => {
  40. if (isUsersLoaded.value && allUsers.value.length > 0) {
  41. displayText.value = lotteryStore.getRandomUserName();
  42. } else {
  43. displayText.value = props.user[0] || "";
  44. }
  45. };
  46. // 开始文字切换
  47. const startTextSwitch = () => {
  48. // 只有在非抽奖状态下才进行文字切换
  49. if (lotteryState.value === "idle" || lotteryState.value === "ready") {
  50. const scheduleNextSwitch = () => {
  51. // 生成1-4秒之间的随机间隔
  52. const randomInterval = Math.random() * 10000 + 10000; // 10000-20000毫秒
  53. textSwitchInterval.value = setTimeout(() => {
  54. switchText();
  55. // 递归调用,继续下一次随机切换
  56. scheduleNextSwitch();
  57. }, randomInterval);
  58. };
  59. scheduleNextSwitch();
  60. }
  61. };
  62. // 停止文字切换
  63. const stopTextSwitch = () => {
  64. if (textSwitchInterval.value) {
  65. clearTimeout(textSwitchInterval.value);
  66. textSwitchInterval.value = null;
  67. }
  68. };
  69. // 监听抽奖状态变化
  70. const handleLotteryStateChange = () => {
  71. if (lotteryState.value === "rotating" || lotteryState.value === "result") {
  72. // 抽奖过程中停止切换,显示固定内容
  73. stopTextSwitch();
  74. displayText.value = props.user[0] || "";
  75. } else {
  76. // 空闲状态恢复切换
  77. startTextSwitch();
  78. }
  79. };
  80. const cardStyle = computed(() => {
  81. // 基础样式
  82. const baseStyle = {
  83. width: "130px",
  84. height: "170px",
  85. border: "1px solid rgb(255,255,255)",
  86. };
  87. if (props.isBold && props.showTable) {
  88. if (lotteryState.value === "idle") {
  89. return {
  90. ...baseStyle,
  91. background: 'linear-gradient(180deg, rgba(243,153,38,0.7) 0%, rgba(207,56,35,1) 100%)',
  92. };
  93. }
  94. }
  95. // 如果是result状态且有prize类,不设置背景色,让CSS类控制
  96. if (lotteryState.value === "result" && props.prize) {
  97. return baseStyle;
  98. }
  99. // 其他情况都显示默认背景色
  100. return {
  101. ...baseStyle,
  102. backgroundColor: "rgba(254, 177, 48, 100)",
  103. };
  104. });
  105. // 组件挂载时初始化
  106. onMounted(async () => {
  107. // 初始化显示文本
  108. displayText.value = props.user[0] || "";
  109. // 延迟启动文字切换,确保所有卡牌都已加载完成
  110. setTimeout(() => {
  111. startTextSwitch();
  112. }, 1000);
  113. // 监听抽奖状态变化
  114. handleLotteryStateChange();
  115. });
  116. // 监听抽奖状态变化
  117. watch(lotteryState, () => {
  118. handleLotteryStateChange();
  119. });
  120. // 监听用户列表加载状态
  121. watch(isUsersLoaded, (loaded) => {
  122. if (loaded) {
  123. // 用户列表加载完成后,立即切换一次文字
  124. switchText();
  125. }
  126. });
  127. // 组件卸载时清理
  128. onBeforeUnmount(() => {
  129. stopTextSwitch();
  130. });
  131. </script>
  132. <style scoped>
  133. .element {
  134. transition: background 2s;
  135. box-shadow: 0 4px 8px rgba(0, 0, 0, 0.4);
  136. /* 你的基础样式 */
  137. }
  138. .lightitem {
  139. /* 高亮样式 */
  140. }
  141. .highlight {
  142. /* 响应式高亮样式 */
  143. }
  144. .prize {
  145. /* 中奖样式 - 使用更高优先级 */
  146. background: linear-gradient(180deg, #F39B26 0%, #E13A26 100%) !important;
  147. }
  148. .company {
  149. /* ... */
  150. }
  151. .name {
  152. /* ... */
  153. }
  154. .details {
  155. font-size: 26px;
  156. color: white;
  157. text-align: center;
  158. display: flex;
  159. flex-direction: column;
  160. justify-content: center;
  161. height: 100%;
  162. transition: opacity 0.3s ease;
  163. }
  164. </style>