From 9bba684fb223d5c4cebc4b610411b7c6c9c9df64 Mon Sep 17 00:00:00 2001 From: cat-shark <1716967236@qq.com> Date: Mon, 3 Aug 2026 22:21:13 +0800 Subject: [PATCH 1/7] =?UTF-8?q?feat:=20=E9=A6=96=E9=A1=B5=E6=BB=9A?= =?UTF-8?q?=E5=8A=A8=E6=9D=A1=E5=B1=95=E7=A4=BA=E5=AD=A6=E4=B9=A0=E6=AE=8B?= =?UTF-8?q?=E7=89=87=E5=B9=B6=E6=94=AF=E6=8C=81=E6=BB=9A=E8=BD=AE=E6=89=8B?= =?UTF-8?q?=E5=8A=A8=E6=BB=9A=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- e2e/welcome.spec.ts | 40 +++++ src/components/Welcome.vue | 297 +++++++++++++++++++++---------------- 2 files changed, 208 insertions(+), 129 deletions(-) diff --git a/e2e/welcome.spec.ts b/e2e/welcome.spec.ts index 00de01a..68154b8 100644 --- a/e2e/welcome.spec.ts +++ b/e2e/welcome.spec.ts @@ -31,4 +31,44 @@ test.describe('Welcome page', () => { await page.locator('.quick-card').nth(1).locator('button').click(); await expect(page).toHaveURL(/\/review/); }); + + test('wheel scrolls review ticker manually while hovering', async ({ page }) => { + const items = Array.from({ length: 10 }, (_, i) => ({ + id: i + 1, + sessionNum: `S${i + 1}`, + taskNum: `T${i + 1}`, + taskName: `任务 ${i + 1}`, + sourceType: 'FRAGMENT', + content: `第 ${i + 1} 条学习残片内容,用来撑起首页滚动区域。`, + createdTime: `2026-08-01 10:00:${String(i).padStart(2, '0')}`, + })); + + await page.route('**/api/review/feed**', (route) => + route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify({ code: 200, data: items }), + }), + ); + await page.goto('/welcome'); + + const track = page.locator('.review-scroll-track'); + const content = page.locator('.review-scroll-content'); + await expect(track).toBeVisible(); + await track.hover(); + + const readTime = () => + content.evaluate((el) => { + const anim = el.getAnimations()[0]; + return anim && typeof anim.currentTime === 'number' ? anim.currentTime : -1; + }); + + const before = await readTime(); + await page.mouse.wheel(0, 200); + await expect.poll(readTime).toBeGreaterThan(before); + + await page.mouse.move(10, 10); + const after = await readTime(); + await expect.poll(readTime).toBeGreaterThan(after); + }); }); diff --git a/src/components/Welcome.vue b/src/components/Welcome.vue index 0c252d9..65bf771 100644 --- a/src/components/Welcome.vue +++ b/src/components/Welcome.vue @@ -1,63 +1,39 @@ @@ -139,26 +182,27 @@ onMounted(() => {
- 这次学习共有 {{ recallSessionItems.length }} 条记录。看着下面这个片段,先试着回忆:当时还学了什么? + 看着下面这个残片,先试着回忆:当时还学了什么?
-{{ recallCard.group.content }}+
{{ recallCard.fragment.content }}+
{{ recallCard.loadError }}
点击导图节点即可选择复习起点,选好后凭记忆在上方补全知识点。
From e82a87d104a57b2c453967ac973e68edfae5093a Mon Sep 17 00:00:00 2001
From: cat-shark <1716967236@qq.com>
Date: Mon, 3 Aug 2026 23:08:31 +0800
Subject: [PATCH 6/7] =?UTF-8?q?docs:=20=E8=A1=A5=E5=85=85=E5=89=8D?=
=?UTF-8?q?=E7=AB=AF=E7=94=A8=E6=88=B7=E6=8F=90=E7=A4=BA=E8=A7=84=E8=8C=83?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
AGENTS.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/AGENTS.md b/AGENTS.md
index 25c33ff..82a2685 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -97,6 +97,7 @@ lpt-fe/src/
- Markdown 渲染统一使用 `src/utils/markdown.ts` 的 `renderMarkdown`,禁止在组件内复制实现。
- 应用场景状态常量统一使用 `src/utils/taskApplication.ts` 的 `applicationStatusOptions`。
+- 用户可见错误提示必须口语化、可理解,不要直接展示接口原始 message、JSON、参数名或“服务器返回”等技术信息;技术细节留在日志。
- 不保留无消费者代码:未使用的 import、prop、事件、API 封装、CSS class、组件文件与依赖应及时删除。
- 组件公开 props/events 只在有实际消费者时保留,例如 MindMapViewer 通过 `toOutline()` 导出编辑内容,不依赖无人监听的 change 事件。
- Vite 模板遗留文件(示例组件、icon、logo)不进入业务代码。
From 2a36e28f7466c167e2c7144a6d486362e0229638 Mon Sep 17 00:00:00 2001
From: cat-shark <1716967236@qq.com>
Date: Mon, 3 Aug 2026 23:08:36 +0800
Subject: [PATCH 7/7] =?UTF-8?q?refactor:=20=E4=BC=98=E5=8C=96=E5=89=8D?=
=?UTF-8?q?=E7=AB=AF=E9=94=99=E8=AF=AF=E6=8F=90=E7=A4=BA?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/__tests__/utils/request.spec.ts | 2 +-
src/components/TaskForm.vue | 2 +-
src/utils/request.ts | 14 +++++++-------
3 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/src/__tests__/utils/request.spec.ts b/src/__tests__/utils/request.spec.ts
index 11e0139..507fd1d 100644
--- a/src/__tests__/utils/request.spec.ts
+++ b/src/__tests__/utils/request.spec.ts
@@ -116,7 +116,7 @@ describe('request utility', () => {
})
it('should throw for unsupported method', () => {
- expect(() => request.request('patch', '/test', null)).toThrow('请求方法 patch 未实现')
+ expect(() => request.request('patch', '/test', null)).toThrow('该功能暂不可用,请刷新后重试')
})
})
})
diff --git a/src/components/TaskForm.vue b/src/components/TaskForm.vue
index e7341af..21e04c9 100644
--- a/src/components/TaskForm.vue
+++ b/src/components/TaskForm.vue
@@ -249,7 +249,7 @@ const submitTask = () => {
updateTask();
break;
default:
- ElMessage.error("未知操作类型");
+ ElMessage.error("该功能暂不可用,请刷新后重试");
}
};
diff --git a/src/utils/request.ts b/src/utils/request.ts
index c7aedee..1c94872 100644
--- a/src/utils/request.ts
+++ b/src/utils/request.ts
@@ -32,14 +32,14 @@ const handleError = (error: any) => {
}
if (error.response) {
- const backendMessage = error.response?.data?.message || JSON.stringify(error.response?.data);
- ElMessage.error(`请求失败,服务器返回: ${backendMessage}`);
+ const backendMessage = error.response?.data?.message;
+ ElMessage.error(backendMessage || "请求失败了,请稍后再试");
} else if (error.request) {
- ElMessage.error("请求未收到响应,请检查接口运行状态");
+ ElMessage.error("请求失败了,请检查网络后重试");
} else {
- ElMessage.error(error.message || "请求失败");
+ ElMessage.error("请求失败了,请稍后再试");
}
- throw new Error("网络不通畅,请检查您的网络连接或服务器状态");
+ throw new Error("请求失败了,请稍后再试");
};
const validateResponse = (res: any) => {
@@ -88,8 +88,8 @@ const del = (url: string, params: Record