diff --git a/src/components/ReviewRecall.vue b/src/components/ReviewRecall.vue index 1f7accd..eca1cb6 100644 --- a/src/components/ReviewRecall.vue +++ b/src/components/ReviewRecall.vue @@ -20,6 +20,8 @@ const taskNum = computed(() => route.params.taskNum as string); const loading = ref(false); const standard = ref(null); const comparing = ref(false); +const comparingSeconds = ref(0); +let comparingTimer: ReturnType | null = null; const lastResult = ref(null); const hasCompared = ref(false); @@ -139,6 +141,8 @@ const handleRecallCompare = async () => { return; } comparing.value = true; + comparingSeconds.value = 0; + comparingTimer = setInterval(() => { comparingSeconds.value++; }, 1000); try { const res = await recallCompare(taskNum.value, outline); standard.value = res?.data || null; @@ -162,6 +166,7 @@ const handleRecallCompare = async () => { ElMessage.error(e.message || "对比失败"); } finally { comparing.value = false; + if (comparingTimer) { clearInterval(comparingTimer); comparingTimer = null; } } }; @@ -328,6 +333,10 @@ onMounted(() => { 清空重写 +

+ AI 正在对比分析中,已等待 {{ comparingSeconds }} 秒… + +

凭记忆在导图上补全该任务的知识点:选中节点后 Tab 加子节点、Enter 加同级节点、双击修改文字。 @@ -530,6 +539,29 @@ onMounted(() => { line-height: 1.5; } +.ai-waiting { + font-size: 13px; + color: #e6a23c; + margin: 4px 0 0; + display: flex; + align-items: center; + gap: 6px; +} + +.ai-waiting::before { + content: ""; + width: 14px; + height: 14px; + border: 2px solid #f3d19e; + border-top-color: #e6a23c; + border-radius: 50%; + animation: spin 0.8s linear infinite; +} + +@keyframes spin { + to { transform: rotate(360deg); } +} + .standard-meta { display: flex; gap: 12px; diff --git a/src/components/StartTask.vue b/src/components/StartTask.vue index 327019b..39194b1 100644 --- a/src/components/StartTask.vue +++ b/src/components/StartTask.vue @@ -25,6 +25,8 @@ const { const summaryDialogVisible = ref(false); const summaryContent = ref(""); const summaryLoading = ref(false); +const summaryLoadingSeconds = ref(0); +let summaryLoadingTimer: ReturnType | null = null; // 学习预期 const expectationDialogVisible = ref(false); @@ -240,6 +242,8 @@ const openSummaryDialog = async () => { // 有残片且未填写过总结时,用 AI 聚合草稿作为编辑起点 if (!summaryContent.value.trim() && fragmentsList.value.length > 0) { summaryLoading.value = true; + summaryLoadingSeconds.value = 0; + summaryLoadingTimer = setInterval(() => { summaryLoadingSeconds.value++; }, 1000); try { const res = await getReportDraft(taskInfo.value.sessionNum); if (res?.code === 200 && res.data) { @@ -249,12 +253,14 @@ const openSummaryDialog = async () => { // 草稿失败不阻塞手写 } finally { summaryLoading.value = false; + if (summaryLoadingTimer) { clearInterval(summaryLoadingTimer); summaryLoadingTimer = null; } } } }; const closeSummaryDialog = () => { summaryDialogVisible.value = false; + if (summaryLoadingTimer) { clearInterval(summaryLoadingTimer); summaryLoadingTimer = null; } }; const restTimer = async () => { @@ -586,6 +592,9 @@ onUnmounted(() => { 本次预期 {{ expectationSaved }} +

+ AI 正在聚合残片生成草稿,已等待 {{ summaryLoadingSeconds }} 秒… +

{ color: var(--text-secondary); } +.ai-waiting { + font-size: 13px; + color: #e6a23c; + margin: 0 0 8px; + display: flex; + align-items: center; + gap: 6px; +} + +.ai-waiting::before { + content: ""; + width: 14px; + height: 14px; + border: 2px solid #f3d19e; + border-top-color: #e6a23c; + border-radius: 50%; + animation: spin 0.8s linear infinite; +} + +@keyframes spin { + to { transform: rotate(360deg); } +} + .summary-expectation { display: flex; align-items: flex-start; diff --git a/src/utils/request.ts b/src/utils/request.ts index 3fc35dc..7b64b5c 100644 --- a/src/utils/request.ts +++ b/src/utils/request.ts @@ -6,7 +6,7 @@ const basic_url = import.meta.env.VITE_BASE_URL; const axiosInstance = axios.create({ baseURL: basic_url, - timeout: 5000, + timeout: 180000, withCredentials: true });