From 3f0493452b67ef54e33051a9ad81d53ef2f33cfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=B2=85?= <907037276@qq.com> Date: Tue, 8 Sep 2026 17:03:28 +0800 Subject: [PATCH] fix: prevent cached task loading mask from sticking --- src/api/trainingTask.js | 2 ++ src/layout/components/AppMain.vue | 4 +++- ...ent-task-loading-lifecycle.static.test.cjs | 23 +++++++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 tests/student-task-loading-lifecycle.static.test.cjs diff --git a/src/api/trainingTask.js b/src/api/trainingTask.js index df9776e..d1e8816 100644 --- a/src/api/trainingTask.js +++ b/src/api/trainingTask.js @@ -79,6 +79,8 @@ export function getTrainingTaskByKey(taskKey) { return Promise.resolve({ code: 200, data: preview.taskConfig }); } if (pendingTaskRequests.has(normalizedTaskKey)) { + // 页面切回时可能复用仍在进行的请求;重新通知当前路由显示加载状态。 + notifyStudentTaskConfigLoading(normalizedTaskKey, true); return pendingTaskRequests.get(normalizedTaskKey); } notifyStudentTaskConfigLoading(normalizedTaskKey, true); diff --git a/src/layout/components/AppMain.vue b/src/layout/components/AppMain.vue index 2241ae6..1113a2a 100644 --- a/src/layout/components/AppMain.vue +++ b/src/layout/components/AppMain.vue @@ -63,7 +63,9 @@ function handleStudentTaskConfigLoading(event) { studentTaskLoading.value = Boolean(detail.loading); } watch(currentStudentTaskKey, (taskKey) => { - studentTaskLoading.value = Boolean(taskKey); + // 已缓存的实训页重新激活时不会再次执行 onMounted 请求,不能仅因路由 + // 切换而保留遮罩;真实请求会通过 student-task-config-loading 事件重新打开。 + studentTaskLoading.value = false; }, { immediate: true }); onMounted(() => window.addEventListener("student-task-config-loading", handleStudentTaskConfigLoading)); onBeforeUnmount(() => window.removeEventListener("student-task-config-loading", handleStudentTaskConfigLoading)); diff --git a/tests/student-task-loading-lifecycle.static.test.cjs b/tests/student-task-loading-lifecycle.static.test.cjs new file mode 100644 index 0000000..d2d0ef6 --- /dev/null +++ b/tests/student-task-loading-lifecycle.static.test.cjs @@ -0,0 +1,23 @@ +const assert = require("assert"); +const fs = require("fs"); +const path = require("path"); + +const root = path.join(__dirname, ".."); +const appMain = fs.readFileSync(path.join(root, "src", "layout", "components", "AppMain.vue"), "utf8"); +const trainingTaskApi = fs.readFileSync(path.join(root, "src", "api", "trainingTask.js"), "utf8"); + +assert( + appMain.includes("studentTaskLoading.value = false;"), + "切回已缓存的学生实训页时,旧加载遮罩必须先清除" +); +assert( + !appMain.includes("studentTaskLoading.value = Boolean(taskKey);"), + "路由切换不能在没有真实请求时强制显示实训加载遮罩" +); +assert.match( + trainingTaskApi, + /if \(pendingTaskRequests\.has\(normalizedTaskKey\)\) \{[\s\S]*?notifyStudentTaskConfigLoading\(normalizedTaskKey, true\);[\s\S]*?return pendingTaskRequests\.get\(normalizedTaskKey\);/, + "复用进行中的任务配置请求时,必须重新广播加载状态" +); + +console.log("student task loading lifecycle static checks passed");