From 59180fa498ed86aea2e6d46d114c10801cbe8a6c Mon Sep 17 00:00:00 2001 From: root Date: Fri, 26 Jun 2026 14:32:51 +0000 Subject: [PATCH] feat: refine mdtodo project workspace --- .../scripts/workbench-e2e-server.ts | 48 ++- web/hwlab-cloud-web/src/router/index.ts | 3 + .../src/views/projects/MdtodoView.vue | 384 +++++++++++++----- .../specs/project-management.spec.ts | 34 +- 4 files changed, 370 insertions(+), 99 deletions(-) diff --git a/web/hwlab-cloud-web/scripts/workbench-e2e-server.ts b/web/hwlab-cloud-web/scripts/workbench-e2e-server.ts index 4dd9c1bb..f79ab697 100644 --- a/web/hwlab-cloud-web/scripts/workbench-e2e-server.ts +++ b/web/hwlab-cloud-web/scripts/workbench-e2e-server.ts @@ -382,7 +382,8 @@ function projectManagementSourceFromBody(body: JsonRecord, base: JsonRecord): Js function projectManagementFiles(): JsonRecord[] { return [ { sourceId: "hwlab-v03-mdtodo", fileRef: "file_plan", projectId: "project_hwlab_v03", relativePath: "docs/MDTODO/hwlab-v03-mdtodo-web-sample.md", title: "项目管理任务", taskCount: 3, parseError: null, revision: 3, fingerprint: "sha256:e2e-plan", updatedAt: "2026-06-25T09:00:00.000Z" }, - { sourceId: "hwlab-v03-mdtodo", fileRef: "file_rollout", projectId: "project_hwlab_v03", relativePath: "docs/MDTODO/D601-v03-rollout.md", title: "D601 发布任务", taskCount: 1, parseError: null, revision: 1, fingerprint: "sha256:e2e-rollout", updatedAt: "2026-06-25T09:00:00.000Z" } + { sourceId: "hwlab-v03-mdtodo", fileRef: "file_rollout", projectId: "project_hwlab_v03", relativePath: "docs/MDTODO/D601-v03-rollout.md", title: "D601 发布任务", taskCount: 1, parseError: null, revision: 1, fingerprint: "sha256:e2e-rollout", updatedAt: "2026-06-25T09:00:00.000Z" }, + { sourceId: "hwlab-v03-mdtodo", fileRef: "file_feedback", projectId: "project_hwlab_v03", relativePath: "docs/MDTODO/20260609_频率判断_用户反馈.md", title: "这是用户的反馈,你分析原因:", taskCount: 1, parseError: null, revision: 1, fingerprint: "sha256:e2e-feedback", updatedAt: "2026-06-26T13:00:00.000Z" } ]; } @@ -397,11 +398,13 @@ function projectManagementSeedTasks(links: JsonRecord[] = []): JsonRecord[] { const r11 = "mdtodo:hwlab-v03-mdtodo:file_plan:R1.1"; const r111 = "mdtodo:hwlab-v03-mdtodo:file_plan:R1.1.1"; const r2 = "mdtodo:hwlab-v03-mdtodo:file_rollout:R2"; + const feedbackR1 = "mdtodo:hwlab-v03-mdtodo:file_feedback:R1"; return [ { taskRef: r1, projectId: "project_hwlab_v03", sourceId: "hwlab-v03-mdtodo", fileRef: "file_plan", taskId: "R1", title: "实现项目根导航", status: "done", parentTaskRef: null, depth: 0, lineNumber: 4, ordinal: 1, linkCount: linkCount(r1), sourceFingerprint: "sha256:e2e-plan", bodyPreview: "Root notes", body: "Root notes\n\n参考报告 [R1.1](./20260110_LOG/R1.1_log_implementation.md)", updatedAt: "2026-06-25T09:00:00.000Z" }, { taskRef: r11, projectId: "project_hwlab_v03", sourceId: "hwlab-v03-mdtodo", fileRef: "file_plan", taskId: "R1.1", title: "展示 MDTODO 任务详情", status: "open", parentTaskRef: r1, depth: 1, lineNumber: 8, ordinal: 2, linkCount: linkCount(r11), sourceFingerprint: "sha256:e2e-plan", bodyPreview: "Detail body", body: "Detail body", updatedAt: "2026-06-25T09:00:00.000Z" }, { taskRef: r111, projectId: "project_hwlab_v03", sourceId: "hwlab-v03-mdtodo", fileRef: "file_plan", taskId: "R1.1.1", title: "Source 顶部控制", status: "in_progress", parentTaskRef: r11, depth: 2, lineNumber: 12, ordinal: 3, linkCount: linkCount(r111), sourceFingerprint: "sha256:e2e-plan", bodyPreview: "Toolbar body", body: "Toolbar body", updatedAt: "2026-06-25T09:00:00.000Z" }, - { taskRef: r2, projectId: "project_hwlab_v03", sourceId: "hwlab-v03-mdtodo", fileRef: "file_rollout", taskId: "R2", title: "D601 v03 页面验收", status: "blocked", parentTaskRef: null, depth: 0, lineNumber: 3, ordinal: 4, linkCount: linkCount(r2), sourceFingerprint: "sha256:e2e-rollout", bodyPreview: "Rollout body", body: "Rollout body", updatedAt: "2026-06-25T09:00:00.000Z" } + { taskRef: r2, projectId: "project_hwlab_v03", sourceId: "hwlab-v03-mdtodo", fileRef: "file_rollout", taskId: "R2", title: "D601 v03 页面验收", status: "blocked", parentTaskRef: null, depth: 0, lineNumber: 3, ordinal: 4, linkCount: linkCount(r2), sourceFingerprint: "sha256:e2e-rollout", bodyPreview: "Rollout body", body: "Rollout body", updatedAt: "2026-06-25T09:00:00.000Z" }, + { taskRef: feedbackR1, projectId: "project_hwlab_v03", sourceId: "hwlab-v03-mdtodo", fileRef: "file_feedback", taskId: "R1", title: "这是用户的反馈,你分析原因:", status: "open", parentTaskRef: null, depth: 0, lineNumber: 4, ordinal: 5, linkCount: linkCount(feedbackR1), sourceFingerprint: "sha256:e2e-feedback", bodyPreview: "我 reset sys_trip 后,返回 sys_trip=false,但万用表测量端子还是通的。", body: "我 reset sys_trip 后,返回的代码中 sys_trip 已经 false 了,但万用表测量端子还是通的。是因为 int_trip:true 吗?\n\n完成任务后将详细报告写入 [R1](details/20260609_频率判断_用户反馈/20260609_161845_Task_Report.md)。", updatedAt: "2026-06-26T13:00:00.000Z" } ]; } @@ -445,7 +448,7 @@ function projectManagementReportPreview(response: ServerResponse, url: URL): voi report: { sourceId: task.sourceId, relativePath: link.relativePath, - content: "# R1.1 implementation report\n\nReport body from fake server.", + content: reportContentForLink(link), fingerprint: "sha256:e2e-report", revision: "sha256:e2e-report", byteCount: 56, @@ -460,7 +463,19 @@ function projectManagementReportPreview(response: ServerResponse, url: URL): voi } function projectManagementTaskLinks(task: JsonRecord, body: string): JsonRecord[] { - if (String(task.taskId) !== "R1" || !body.includes("R1.1_log_implementation.md")) return []; + if (String(task.taskId) !== "R1") return []; + if (body.includes("20260609_161845_Task_Report.md")) { + return [{ + linkId: "lnk_feedback_r1_report", + label: "R1", + href: "details/20260609_频率判断_用户反馈/20260609_161845_Task_Report.md", + kind: "markdown-report", + relativePath: "details/20260609_频率判断_用户反馈/20260609_161845_Task_Report.md", + ordinal: 1, + valuesRedacted: true + }]; + } + if (!body.includes("R1.1_log_implementation.md")) return []; return [{ linkId: "lnk_r11_report", label: "R1.1", @@ -472,6 +487,31 @@ function projectManagementTaskLinks(task: JsonRecord, body: string): JsonRecord[ }]; } +function reportContentForLink(link: JsonRecord): string { + if (String(link.relativePath ?? "").includes("20260609_161845_Task_Report.md")) { + return [ + "# R1 用户反馈分析报告", + "", + "停机继电器仍然动作时,需要同时确认外部 sys_trip 和内部 int_trip 的输出投票。", + "", + "```json", + "{", + " \"result\": {", + " \"sys_reset\": true,", + " \"int_trip\": true,", + " \"sys_trip\": false,", + " \"sys_alarm\": false", + " },", + " \"id\": 222", + "}", + "```", + "", + "如果 `int_trip` 仍为 true,理论上停机继电器仍可能保持动作。" + ].join("\n"); + } + return "# R1.1 implementation report\n\nReport body from fake server."; +} + function projectManagementUpdateTask(response: ServerResponse, taskRef: string, body: JsonRecord): void { const task = state.projectTasks.find((item) => item.taskRef === taskRef); if (!task) return json(response, 404, { ok: false, contractVersion: "project-management-v1", serviceId: "hwlab-project-management", error: { code: "task_not_found" }, valuesRedacted: true }); diff --git a/web/hwlab-cloud-web/src/router/index.ts b/web/hwlab-cloud-web/src/router/index.ts index d565b331..32f93e5a 100644 --- a/web/hwlab-cloud-web/src/router/index.ts +++ b/web/hwlab-cloud-web/src/router/index.ts @@ -17,6 +17,9 @@ const routes: RouteRecordRaw[] = [ { path: "/workbench", alias: ["/workspace"], name: "CodeWorkbench", component: CodeWorkbenchView, meta: { requiresAuth: true, navId: "workbench.code", title: "Code 工作台", section: "workbench" } }, { path: "/projects", name: "Projects", component: ProjectsView, meta: { requiresAuth: true, navId: "project.overview", title: "项目", section: "project" } }, { path: "/projects/mdtodo", name: "ProjectMdtodo", component: ProjectMdtodoView, meta: { requiresAuth: true, navId: "project.mdtodo", title: "MDTODO", section: "project" } }, + { path: "/projects/mdtodo/sources/:sourceId/files/:fileRef", name: "ProjectMdtodoFile", component: ProjectMdtodoView, meta: { requiresAuth: true, navId: "project.mdtodo", title: "MDTODO", section: "project" } }, + { path: "/projects/mdtodo/sources/:sourceId/files/:fileRef/tasks/:taskId", name: "ProjectMdtodoTask", component: ProjectMdtodoView, meta: { requiresAuth: true, navId: "project.mdtodo", title: "MDTODO", section: "project" } }, + { path: "/projects/mdtodo/sources/:sourceId/files/:fileRef/tasks/:taskId/reports/:linkId", name: "ProjectMdtodoReport", component: ProjectMdtodoView, meta: { requiresAuth: true, navId: "project.mdtodo", title: "MDTODO", section: "project" } }, { path: "/api-keys", name: "ApiKeys", component: () => import("@/views/user/ApiKeysView.vue"), meta: { requiresAuth: true, navId: "user.apiKeys", title: "API Keys", section: "user" } }, { path: "/usage", name: "Usage", component: () => import("@/views/user/UsageView.vue"), meta: { requiresAuth: true, navId: "user.usage", title: "用量与性能", section: "user" } }, { path: "/billing", name: "Billing", component: () => import("@/views/user/BillingView.vue"), meta: { requiresAuth: true, navId: "user.billing", title: "充值与订阅", section: "user" } }, diff --git a/web/hwlab-cloud-web/src/views/projects/MdtodoView.vue b/web/hwlab-cloud-web/src/views/projects/MdtodoView.vue index 1eb38bb1..f981d83e 100644 --- a/web/hwlab-cloud-web/src/views/projects/MdtodoView.vue +++ b/web/hwlab-cloud-web/src/views/projects/MdtodoView.vue @@ -4,15 +4,15 @@