diff --git a/src/api/studySessions.ts b/src/api/studySessions.ts index 084be25..981a3a8 100644 --- a/src/api/studySessions.ts +++ b/src/api/studySessions.ts @@ -37,6 +37,13 @@ export const getReportDraft = (sessionNum: string) => { return request.get(`/study-sessions/${sessionNum}/report-draft`); }; +/** 查询当前是否有活跃会话 */ +export const getActiveSession = (excludeTaskNum?: string) => { + const params: Record = {}; + if (excludeTaskNum) params.excludeTaskNum = excludeTaskNum; + return request.get('/study-sessions/active', params); +}; + /** 分页查询任务的历史残片 */ export const getTaskFragments = (taskNum: string, page: number, size: number, keyword?: string) => { const params: Record = { page, size }; diff --git a/src/components/StartTask.vue b/src/components/StartTask.vue index e4323fc..607bc8a 100644 --- a/src/components/StartTask.vue +++ b/src/components/StartTask.vue @@ -150,6 +150,9 @@ const BREAK_END_KEY = computed(() => `breakEnd_${taskNum}`); const isBreak = ref(false); const breakAudio = new Audio('/resource/notification.mp3'); +// 恢复提示 +const showResumeHint = ref(route.query.resume === "true"); + const progress = computed(() => { const total = isBreak.value ? 5 * 60 : 25 * 60; const remaining = timerMinutes.value * 60 + timerSeconds.value; @@ -303,6 +306,7 @@ const endTimer = async (content: string) => { } clear(); clearBreakState(); + localStorage.removeItem("activeSession"); await router.push("/study"); } catch { ElMessage.error("结束会话失败,请重试"); @@ -389,6 +393,13 @@ const loadTaskSession = async () => { } } + // 持久化活跃会话(用于跨页面恢复 + 阻止多任务) + localStorage.setItem("activeSession", JSON.stringify({ + taskNum: taskInfo.value.taskNum, + sessionNum: taskInfo.value.sessionNum, + taskName: taskInfo.value.taskName, + })); + if (taskInfo.value.sessionState === "ONGOING") { startTimer(); } else { @@ -516,6 +527,14 @@ onUnmounted(() => {