|
|
|
|
@ -1,8 +1,11 @@
|
|
|
|
|
import request from "@/utils/request";
|
|
|
|
|
import { getUserInfo } from "@/utils/auth";
|
|
|
|
|
|
|
|
|
|
// 学生页面和全局“补充步骤”导航会在同一轮路由渲染中读取同一任务配置。
|
|
|
|
|
// 仅合并进行中的请求:教师保存后下一次读取仍会获得最新配置,不引入陈旧缓存。
|
|
|
|
|
const pendingTaskRequests = new Map();
|
|
|
|
|
const pendingStudentTaskListRequests = new Map();
|
|
|
|
|
const STUDENT_TASK_NAVIGATION_CACHE_PREFIX = "student-training-task-navigation:v1:";
|
|
|
|
|
|
|
|
|
|
function notifyStudentTaskConfigLoading(taskKey, loading) {
|
|
|
|
|
if (typeof window === "undefined") return;
|
|
|
|
|
@ -17,6 +20,51 @@ export function listTrainingTasks(params) {
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getStudentTaskNavigationCacheKey() {
|
|
|
|
|
try {
|
|
|
|
|
const userInfo = JSON.parse(getUserInfo() || "{}");
|
|
|
|
|
const userId = userInfo.userId || userInfo.user_id || userInfo.username || userInfo.userName;
|
|
|
|
|
return userId ? `${STUDENT_TASK_NAVIGATION_CACHE_PREFIX}${userId}` : "";
|
|
|
|
|
} catch (error) {
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getCachedStudentTrainingTasks() {
|
|
|
|
|
const cacheKey = getStudentTaskNavigationCacheKey();
|
|
|
|
|
if (!cacheKey || typeof window === "undefined") return [];
|
|
|
|
|
try {
|
|
|
|
|
const cached = JSON.parse(window.sessionStorage.getItem(cacheKey) || "[]");
|
|
|
|
|
return Array.isArray(cached) ? cached : [];
|
|
|
|
|
} catch (error) {
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The navigation and top bar both need the same enabled task list. Reuse one
|
|
|
|
|
* in-flight request and retain the last successful response for immediate menu rendering.
|
|
|
|
|
*/
|
|
|
|
|
export function loadStudentTrainingTasks() {
|
|
|
|
|
const cacheKey = getStudentTaskNavigationCacheKey() || "anonymous";
|
|
|
|
|
if (pendingStudentTaskListRequests.has(cacheKey)) {
|
|
|
|
|
return pendingStudentTaskListRequests.get(cacheKey);
|
|
|
|
|
}
|
|
|
|
|
const requestPromise = listTrainingTasks({ enabledOnly: true }).then((res) => {
|
|
|
|
|
const tasks = Array.isArray(res?.data) ? res.data : [];
|
|
|
|
|
if (cacheKey !== "anonymous" && typeof window !== "undefined") {
|
|
|
|
|
window.sessionStorage.setItem(cacheKey, JSON.stringify(tasks));
|
|
|
|
|
}
|
|
|
|
|
return { ...res, data: tasks };
|
|
|
|
|
});
|
|
|
|
|
pendingStudentTaskListRequests.set(cacheKey, requestPromise);
|
|
|
|
|
requestPromise.then(
|
|
|
|
|
() => pendingStudentTaskListRequests.delete(cacheKey),
|
|
|
|
|
() => pendingStudentTaskListRequests.delete(cacheKey)
|
|
|
|
|
);
|
|
|
|
|
return requestPromise;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getTrainingTaskByKey(taskKey) {
|
|
|
|
|
const normalizedTaskKey = String(taskKey || "").trim();
|
|
|
|
|
if (pendingTaskRequests.has(normalizedTaskKey)) {
|
|
|
|
|
|