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
4.3 KiB

<template>
<div
:id="`card-${id}`"
:class="[
'element',
{ lightitem: isBold, highlight: highlight, prize: prize },
]"
:style="cardStyle"
>
<!-- <div class="company">{{ company }}</div> -->
<!-- <div class="name">{{ user[1] }}</div> -->
<div class="details">{{ displayText }}</div>
</div>
</template>
<script setup>
import { computed, ref, onMounted, onBeforeUnmount, watch } from "vue";
import { useLotteryStore } from "../../../store/lottery"; // 路径根据实际情况调整
const lotteryStore = useLotteryStore(); // 只获取一次
const lotteryState = computed({
get: () => lotteryStore.lotteryState,
set: (val) => lotteryStore.setLotteryState(val),
});
const props = defineProps({
id: [String, Number],
user: { type: Array, required: true },
isBold: Boolean,
showTable: Boolean,
company: String,
highlight: Boolean,
prize: Boolean,
});
// 添加响应式数据用于文字切换
const displayText = ref("");
const textSwitchInterval = ref(null);
// 从store获取用户列表状态
const allUsers = computed(() => lotteryStore.allUsers);
const isUsersLoaded = computed(() => lotteryStore.isUsersLoaded);
// 随机切换文字
const switchText = () => {
if (isUsersLoaded.value && allUsers.value.length > 0) {
displayText.value = lotteryStore.getRandomUserName();
} else {
displayText.value = props.user[0] || "";
}
};
// 开始文字切换
const startTextSwitch = () => {
// 只有在非抽奖状态下才进行文字切换
if (lotteryState.value === "idle" || lotteryState.value === "ready") {
const scheduleNextSwitch = () => {
// 生成1-4秒之间的随机间隔
const randomInterval = Math.random() * 10000 + 10000; // 10000-20000毫秒
textSwitchInterval.value = setTimeout(() => {
switchText();
// 递归调用,继续下一次随机切换
scheduleNextSwitch();
}, randomInterval);
};
scheduleNextSwitch();
}
};
// 停止文字切换
const stopTextSwitch = () => {
if (textSwitchInterval.value) {
clearTimeout(textSwitchInterval.value);
textSwitchInterval.value = null;
}
};
// 监听抽奖状态变化
const handleLotteryStateChange = () => {
if (lotteryState.value === "rotating" || lotteryState.value === "result") {
// 抽奖过程中停止切换,显示固定内容
stopTextSwitch();
displayText.value = props.user[0] || "";
} else {
// 空闲状态恢复切换
startTextSwitch();
}
};
const cardStyle = computed(() => {
// 基础样式
const baseStyle = {
width: "130px",
height: "170px",
border: "1px solid rgb(255,255,255)",
};
if (props.isBold && props.showTable) {
if (lotteryState.value === "idle") {
return {
...baseStyle,
background: 'linear-gradient(180deg, rgba(243,153,38,0.7) 0%, rgba(207,56,35,1) 100%)',
};
}
}
// 如果是result状态且有prize类,不设置背景色,让CSS类控制
if (lotteryState.value === "result" && props.prize) {
return baseStyle;
}
// 其他情况都显示默认背景色
return {
...baseStyle,
backgroundColor: "rgba(254, 177, 48, 100)",
};
});
// 组件挂载时初始化
onMounted(async () => {
// 初始化显示文本
displayText.value = props.user[0] || "";
// 延迟启动文字切换,确保所有卡牌都已加载完成
setTimeout(() => {
startTextSwitch();
}, 1000);
// 监听抽奖状态变化
handleLotteryStateChange();
});
// 监听抽奖状态变化
watch(lotteryState, () => {
handleLotteryStateChange();
});
// 监听用户列表加载状态
watch(isUsersLoaded, (loaded) => {
if (loaded) {
// 用户列表加载完成后,立即切换一次文字
switchText();
}
});
// 组件卸载时清理
onBeforeUnmount(() => {
stopTextSwitch();
});
</script>
<style scoped>
.element {
transition: background 2s;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.4);
/* 你的基础样式 */
}
.lightitem {
/* 高亮样式 */
}
.highlight {
/* 响应式高亮样式 */
}
.prize {
/* 中奖样式 - 使用更高优先级 */
background: linear-gradient(180deg, #F39B26 0%, #E13A26 100%) !important;
}
.company {
/* ... */
}
.name {
/* ... */
}
.details {
font-size: 26px;
color: white;
text-align: center;
display: flex;
flex-direction: column;
justify-content: center;
height: 100%;
transition: opacity 0.3s ease;
}
</style>