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
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() * 20000 + 1000; // 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: 30px;
|
|
color: white;
|
|
text-align: center;
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
height: 100%;
|
|
transition: opacity 0.3s ease;
|
|
}
|
|
</style>
|