当前计时
-{{ isBreak ? '☕ 休息中' : '当前计时' }}
+番茄钟默认 25 分钟,休息计时 5 分钟
+{{ isBreak ? '休息倒计时' : '番茄钟默认 25 分钟,休息计时 5 分钟' }}
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 分钟' }}