当前计时
-{{ isBreak ? '☕ 休息中' : '当前计时' }}
+番茄钟默认 25 分钟,休息计时 5 分钟
+{{ isBreak ? '休息倒计时' : '番茄钟默认 25 分钟,休息计时 5 分钟' }}
From ae796308a637e7be874b4d8d29bba4217026c008 Mon Sep 17 00:00:00 2001 From: cat_shark <1716967236@qq.com> Date: Sat, 4 Jul 2026 10:27:38 +0800 Subject: [PATCH] =?UTF-8?q?fix(=E5=AD=A6=E4=B9=A0=E4=BC=9A=E8=AF=9D)?= =?UTF-8?q?=EF=BC=9A=E4=BC=91=E6=81=AF=E5=80=92=E8=AE=A1=E6=97=B6=E5=88=B7?= =?UTF-8?q?=E6=96=B0=E5=90=8E=E4=B8=A2=E5=A4=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根因:休息倒计时完全存在浏览器内存中(runCountdown), 刷新页面后 loadTaskSession() 读取会话为 PAUSED 状态, 走 else 分支 syncDisplay(pointerPosition) 重置为工作钟, 休息状态和剩余时间全部丢失。 修复方案(纯前端): - restTimer() 将休息结束时间戳写入 localStorage - loadTaskSession() 启动时检查 localStorage, 若休息未到期则恢复 runCountdown 继续倒计时 - startTimer()/stopTimer()/endTimer() 清除休息状态 - 休息期间 UI:倒计时数字橙色、进度环金色、 按钮区替换为休息中标签(隐藏开始/暂停/残片) --- src/components/StartTask.vue | 99 ++++++++++++++++++++++++++++++++---- 1 file changed, 88 insertions(+), 11 deletions(-) diff --git a/src/components/StartTask.vue b/src/components/StartTask.vue index 4a4eb09..3815cc0 100644 --- a/src/components/StartTask.vue +++ b/src/components/StartTask.vue @@ -72,7 +72,15 @@ const { requestAudioPermission, } = useTimer(); -const progress = computed(() => ((timerMinutes.value * 60 + timerSeconds.value) / (25 * 60)) * 100); +// 休息状态持久化(刷新后恢复) +const BREAK_END_KEY = computed(() => `breakEnd_${taskNum}`); +const isBreak = ref(false); +const breakAudio = new Audio('/resource/notification.mp3'); + +const progress = computed(() => { + const total = isBreak.value ? 5 * 60 : 25 * 60; + return ((timerMinutes.value * 60 + timerSeconds.value) / total) * 100; +}); const nowTimestamp = ref(Date.now()); let displayInterval: number | undefined; @@ -170,6 +178,9 @@ const startTimer = async () => { if (res.code === 200) ElMessage.success("任务继续"); await loadTaskSession(); } + // 手动开始 → 清除休息状态 + localStorage.removeItem(BREAK_END_KEY.value); + isBreak.value = false; const duration = taskInfo.value.pointerPosition || 25 * 60 * 1000; runCountdown(duration); }; @@ -181,6 +192,12 @@ const stopTimer = async () => { taskInfo.value.sessionState = "PAUSED"; } clear(); + clearBreakState(); +}; + +const clearBreakState = () => { + localStorage.removeItem(BREAK_END_KEY.value); + isBreak.value = false; }; const endTimer = async (content: string) => { @@ -211,6 +228,7 @@ const endTimer = async (content: string) => { ElMessage.error(res.message || "结束会话失败"); } clear(); + clearBreakState(); await router.push("/study"); } catch { ElMessage.error("结束会话失败,请重试"); @@ -241,7 +259,23 @@ const closeSummaryDialog = () => { const restTimer = async () => { await stopTimer(); - runCountdown(5 * 60 * 1000); + const breakMs = 5 * 60 * 1000; + localStorage.setItem(BREAK_END_KEY.value, String(Date.now() + breakMs)); + isBreak.value = true; + runCountdown(breakMs, () => { + localStorage.removeItem(BREAK_END_KEY.value); + isBreak.value = false; + breakAudio.loop = true; + breakAudio.play(); + ElMessageBox.alert('休息结束!点击"开始"继续学习', '休息结束', { + confirmButtonText: '关闭铃声', + callback: () => { + breakAudio.pause(); + breakAudio.currentTime = 0; + ElMessage.success('铃声已关闭'); + }, + }); + }); }; const loadTaskSession = async () => { @@ -249,6 +283,34 @@ const loadTaskSession = async () => { const res = await startOrContinueStudySession(taskNum); Object.assign(taskInfo.value, res.data); await loadExpectation(); + + // 检查是否有未结束的休息 + const storedEnd = localStorage.getItem(BREAK_END_KEY.value); + if (storedEnd) { + const remaining = parseInt(storedEnd, 10) - Date.now(); + if (remaining > 0) { + isBreak.value = true; + runCountdown(remaining, () => { + localStorage.removeItem(BREAK_END_KEY.value); + isBreak.value = false; + breakAudio.loop = true; + breakAudio.play(); + ElMessageBox.alert('休息结束!点击"开始"继续学习', '休息结束', { + confirmButtonText: '关闭铃声', + callback: () => { + breakAudio.pause(); + breakAudio.currentTime = 0; + ElMessage.success('铃声已关闭'); + }, + }); + }); + loadFragments(); + return; + } else { + localStorage.removeItem(BREAK_END_KEY.value); + } + } + if (taskInfo.value.sessionState === "ONGOING") { startTimer(); } else { @@ -404,13 +466,19 @@ onUnmounted(() => {
当前计时
-{{ isBreak ? '☕ 休息中' : '当前计时' }}
+番茄钟默认 25 分钟,休息计时 5 分钟
+{{ isBreak ? '休息倒计时' : '番茄钟默认 25 分钟,休息计时 5 分钟' }}