feat: 盲盒模式每次刷新都重新混淆任务顺序,防止通过序号分辨任务

This commit is contained in:
Your Name 2026-02-02 15:39:01 +08:00
parent 1c58431788
commit 9da1153554

View File

@ -103,7 +103,7 @@
<div v-else class="task-grid">
<div
v-for="(task, index) in taskList"
v-for="(task, index) in displayTaskList"
:key="task.id"
:class="['task-card', 'chart-card', { 'blind-box-card': showBlindBox }]"
@click="handleTaskClick(task)"
@ -2672,6 +2672,8 @@ const selectedTask = ref<TaskOrSubTask | null>(null)
// 盲盒模式相关
const blindBoxMode = ref(false)
const blindBoxSeed = ref(Date.now()) // 用于混淆任务顺序的随机种子
const isDeptLeader = computed(() => {
const userInfo = JSON.parse(localStorage.getItem('userInfo') || '{}')
// 部门负责人或管理员不受盲盒模式影响
@ -2683,6 +2685,34 @@ const showBlindBox = computed(() => {
return blindBoxMode.value && !isDeptLeader.value
})
// 基于种子的伪随机数生成器(确保同一种子产生相同的随机序列)
const seededRandom = (seed: number) => {
const x = Math.sin(seed) * 10000
return x - Math.floor(x)
}
// 使用Fisher-Yates算法基于种子打乱数组
const shuffleWithSeed = <T>(array: T[], seed: number): T[] => {
const result = [...array]
let currentSeed = seed
for (let i = result.length - 1; i > 0; i--) {
currentSeed = currentSeed * 1103515245 + 12345
const j = Math.floor(Math.abs(currentSeed % (i + 1)))
;[result[i], result[j]] = [result[j], result[i]]
}
return result
}
// 盲盒模式下混淆后的任务列表(与部门负责人看到的顺序不同)
const displayTaskList = computed(() => {
if (showBlindBox.value && taskList.value.length > 0) {
// 盲盒模式:使用种子打乱顺序
return shuffleWithSeed(taskList.value, blindBoxSeed.value)
}
// 正常模式:原始顺序
return taskList.value
})
// 加载盲盒模式配置
const loadBlindBoxMode = async () => {
try {
@ -2691,6 +2721,10 @@ const loadBlindBoxMode = async () => {
const config = response.data.find((c: any) => c.configKey === 'task.blind_box_mode')
if (config) {
blindBoxMode.value = config.configValue === 'true'
// 每次加载盲盒配置时更新随机种子,确保每次刷新页面顺序都不同
if (blindBoxMode.value) {
blindBoxSeed.value = Date.now()
}
console.log('盲盒模式:', blindBoxMode.value, '是否显示盲盒:', showBlindBox.value)
}
}
@ -3404,6 +3438,13 @@ let allAvailableTasks: any[] = []
// 任务大厅对所有用户开放(包括需求部门和一级需求部门)
const loadTasks = async (forceReload = false) => {
loading.value = true
// 🔀 每次加载任务时更新盲盒随机种子,确保顺序每次都不同
// 防止有人根据排队序号分辨任务
if (blindBoxMode.value) {
blindBoxSeed.value = Date.now() + Math.random() * 1000
}
try {
// 获取用户部门类型(使用部门视角切换后的有效类型)
const userInfo = JSON.parse(localStorage.getItem('userInfo') || '{}')