diff --git a/frontend/src/views/TaskHall.vue b/frontend/src/views/TaskHall.vue index 3f62ce2..efeed63 100644 --- a/frontend/src/views/TaskHall.vue +++ b/frontend/src/views/TaskHall.vue @@ -103,7 +103,7 @@
(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 = (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') || '{}')