重构(学习页): 前端仅展示并修复运行稳定性问题

This commit is contained in:
2026-04-12 10:36:59 +08:00
parent 4c73991d64
commit 0f2f0460df
3 changed files with 60 additions and 45 deletions
+21 -30
View File
@@ -1,12 +1,11 @@
<!-- src/views/StudyTimer.vue -->
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue';
import { ref, computed, onMounted, onUnmounted } from 'vue';
import { useRoute } from 'vue-router';
import {ElMessage, ElMessageBox} from 'element-plus';
import { useTimer } from '@/components/composables/useTimer';
import { continueSession, pauseSession, endSession, startOrContinueStudySession } from '@/api/studySessions';
import { useStudyFragment } from '@/components/composables/fragment';
import {routes} from "vue-router/auto-routes";
import router from "@/router";
const {
@@ -49,27 +48,6 @@ const {
requestAudioPermission
} = useTimer();
const globalTimer = ref(Date.now());
const currentCycle = computed(() =>
Math.floor(taskInfo.value.effectiveTime / 60 / 25) + 1
);
const elapsedTime = computed(() => {
if (!taskInfo.value.startTime || !timerRunning.value) return { hours: 0, minutes: 0, seconds: 0 };
const start = new Date(taskInfo.value.startTime).getTime();
const now = globalTimer.value;
const diff = Math.max(Math.floor((now - start) / 1000), 0);
return {
hours: Math.floor(diff / 3600),
minutes: Math.floor((diff % 3600) / 60),
seconds: diff % 60,
};
});
const formatTime = (t: { hours: number; minutes: number; seconds: number }) =>
`${t.hours}${t.minutes}${t.seconds}`;
const progress = computed(() =>
((timerMinutes.value * 60 + timerSeconds.value) / (25 * 60)) * 100
);
@@ -152,24 +130,33 @@ const initPage = async () => {
}
}
await loadTaskSession();
setInterval(() => {
globalTimer.value = Date.now();
}, 1000);
};
onMounted(() => {
initPage();
});
onUnmounted(() => {
clear();
});
</script>
<template>
<div class="task-container">
<el-alert
v-if="taskInfo.systemMessage"
:title="taskInfo.systemMessage"
type="warning"
show-icon
:closable="false"
class="session-alert"
/>
<div class="task-info">
<p>当前任务{{ taskInfo.taskName }}</p>
<p>当前循环{{ currentCycle }}</p>
<p>有效时间{{ taskInfo.effectiveTime / 60 }}分钟</p>
<p>本次运行时间{{ formatTime(elapsedTime) }}</p>
<p>会话状态{{ taskInfo.sessionState }}</p>
<p>实际用时{{ taskInfo.actualTime }}</p>
<p>有效学习时长{{ taskInfo.effectiveTime }}</p>
<p>有效时间比{{ taskInfo.effectivenessRatio }}</p>
</div>
<div class="timer-section">
<el-progress type="circle" :percentage="progress" :width="200">
@@ -225,6 +212,10 @@ onMounted(() => {
justify-content: center;
margin: 20px;
}
.session-alert {
margin-bottom: 16px;
max-width: 500px;
}
.task-info {
font-size: 18px;
margin-bottom: 30px;
+28 -13
View File
@@ -15,8 +15,9 @@ const fetchTasks = () => {
tasks.splice(0, tasks.length, ...res.data.records.map((record: any) => ({
title: record.taskName,
description: record.taskDescription || '',
materialURL: record.materialURL || record.materialUrl || "",
lastLearningStatus: record.lastLearningStatus || '未开始',
priority: Math.round(record.taskPriority),
priority: Number.isFinite(record.taskPriority) ? Math.round(record.taskPriority) : "-",
taskNum: record.taskNum,
taskId: record.id,
})));
@@ -25,8 +26,11 @@ const fetchTasks = () => {
};
const startTask = () => {
if (!selectedTask.value) {
ElMessage.warning("请先选择一个任务");
return;
}
router.push({name:'start-task',params:{taskNum:selectedTask.value.taskNum}});
console.log('任务已开始:', selectedTask.value);
};
const addTask = () => {
@@ -34,21 +38,28 @@ const addTask = () => {
};
const changeTask = () =>{
if (!selectedTask.value) {
ElMessage.warning("请先选择一个任务");
return;
}
router.push({name:"update-task",params:{"taskId":selectedTask.value.taskId}})
};
const removeTask = () => {
if (!selectedTask.value) {
ElMessage.warning("请先选择一个任务");
return;
}
request.del(`/tasks/${selectedTask.value.taskId}`,{}).then(res=>{
if (res.code == '200'){
if (res.code === 200){
ElMessage.success(`任务${selectedTask.value.title}删除成功`)
const index = tasks.indexOf(selectedTask.value);
if (index > -1) {
tasks.splice(index, 1);
selectedTask.value = tasks[0] || null;
}
}
});
const index = tasks.indexOf(selectedTask.value);
if (index > -1) {
tasks.splice(index, 1);
selectedTask.value = tasks[0] || null;
}
};
const selectTask = (task: any) => {
@@ -84,12 +95,16 @@ onMounted(() => {
<el-card class="task-card">
<div v-if="selectedTask">
<h3>任务描述</h3>
<el-input type="textarea" v-model="selectedTask.description" :rows="4" />
<el-input type="textarea" :model-value="selectedTask.description" :rows="4" readonly />
<h3 class="section-title">学习材料</h3>
<el-link v-if="selectedTask.materialURL" :href="selectedTask.materialURL" type="primary" target="_blank">
{{ selectedTask.materialURL }}
</el-link>
<span v-else>未填写材料地址</span>
<h3 class="section-title">任务优先级</h3>
<el-radio-group v-model="selectedTask.priority">
<el-radio-button v-for="i in 6" :label="i - 1" :key="i">{{ i - 1 }}</el-radio-button>
</el-radio-group>
<el-tag type="info">综合优先级{{ selectedTask.priority }}</el-tag>
<h3 class="section-title">上次该任务学习情况</h3>
<el-descriptions border column="1">
+11 -2
View File
@@ -11,10 +11,19 @@ const axiosInstance = axios.create({
const handleError = (error: any) => {
console.log(error);
// 业务异常由 validateResponse 负责提示,这里透传,避免被网络错误文案覆盖。
if (error && typeof error === "object" && "code" in error) {
return Promise.reject(error);
}
if (error.response) {
ElMessage.error(`请求失败,服务器返回: ${error.response.data}`);
const backendMessage = error.response?.data?.message || JSON.stringify(error.response?.data);
ElMessage.error(`请求失败,服务器返回: ${backendMessage}`);
} else if (error.request) {
ElMessage.error("请求未收到响应,请检查接口运行状态");
} else {
ElMessage.error(error.message || "请求失败");
}
throw new Error("网络不通畅,请检查您的网络连接或服务器状态");
};
@@ -61,7 +70,7 @@ const put = (url: string, data: any, config: any = {}) => {
.catch(handleError);
};
const del = (url: string, params: {}, config: any = {}) => {
const del = (url: string, params: Record<string, any> = {}, config: any = {}) => {
console.log("开始DELETE请求", basic_url + url, "参数:", params);
return axiosInstance.delete(url, { params, ...config })
.then(validateResponse)