12 KiB
用户手册详情页实施计划
目标:将访客端原有详情弹窗替换为基于 slug 的独立详情页,使 description 可以长期作为 Markdown 用户手册展示,并补齐直达访问、空内容、404 和长文阅读体验。
架构:本次为单一功能子系统改造,不创建纲领文件。后端先补齐按 slug 查询已发布工具的公开详情能力,再由前端新增公开详情页路由和页面组件,最后替换首页详情入口并完善长文阅读样式与测试。前端测试基建当前缺失,因此计划第一步先补齐 Vitest + Vue Test Utils + jsdom,确保后续页面改造遵循测试优先。
技术栈:Vue 3、vue-router、Vite、Vitest、Vue Test Utils、NestJS、Prisma、Jest、Supertest、marked、DOMPurify
文件结构
新建文件
-
client/vitest.config.js- 前端测试配置,提供 Vue SFC 和jsdom运行环境
注释需求:低优先级,配置项仅在非直观处补简短说明
复杂度:低 -
client/src/test/setup.js- 前端测试初始化,挂载全局匹配器、滚动和路由相关基础 mock
注释需求:中优先级,需要说明全局 mock 的用途
复杂度:中 -
client/src/utils/markdown-outline.js- 提取 Markdown 标题、生成稳定锚点和目录结构
注释需求:高优先级,需要为重复标题去重和锚点规范化逻辑添加说明
复杂度:中 -
client/src/utils/markdown-outline.spec.js- 验证目录提取、标题去重和无标题场景
注释需求:低优先级
复杂度:中 -
client/src/pages/ToolDetailPage.vue- 公开详情页,负责按slug拉取详情、渲染摘要和 Markdown 手册、处理空状态/404/返回入口
注释需求:高优先级,需要在状态流转和 launch 复用入口处补说明
复杂度:高 -
client/src/pages/ToolDetailPage.spec.js- 详情页组件测试,覆盖加载态、404、空内容、目录和主操作按钮
注释需求:低优先级
复杂度:高 -
client/src/App.spec.js- 首页交互测试,覆盖详情按钮跳转和旧弹窗移除
注释需求:低优先级
复杂度:中 -
server/src/modules/tools/tools.service.spec.ts- 后端服务单测,覆盖按slug查询详情的业务规则
注释需求:低优先级
复杂度:中 -
server/test/tools-detail.e2e-spec.ts- 公开详情接口 e2e,覆盖成功命中和 404
注释需求:中优先级,需要说明测试数据准备和清理
复杂度:中
修改文件
-
client/package.json- 增加前端测试脚本和测试依赖声明
注释需求:低优先级
复杂度:低 -
client/package-lock.json- 锁定前端测试依赖版本
注释需求:无
复杂度:低 -
client/src/api.js- 新增按slug获取详情的方法,复用现有错误和 launch 行为
注释需求:中优先级,需要说明新接口和旧按id接口的职责差异
复杂度:中 -
client/src/admin/router.js- 增加公开详情页路由/tools/:slug
注释需求:低优先级
复杂度:低 -
client/src/App.vue- 移除详情弹窗状态和模板,将详情入口改为路由跳转
注释需求:中优先级,需要说明首页仅负责列表和跳转,不再持有详情状态
复杂度:高 -
client/src/style.scss- 增加详情页布局、目录、空状态、404 和长文阅读样式
注释需求:低优先级
复杂度:高 -
client/src/admin/components/ToolFormDialog.vue- 微调“工具简介”提示文案,明确其可承载 Markdown 手册内容
注释需求:低优先级
复杂度:低 -
server/src/modules/tools/tools.service.ts- 抽出详情映射逻辑,新增按slug查询已发布工具详情的方法
注释需求:高优先级,需要说明id与slug两套公开查询入口的职责分层
复杂度:中 -
server/src/modules/tools/tools.controller.ts- 新增按slug获取公开详情的接口
注释需求:低优先级
复杂度:低
测试文件
client/src/utils/markdown-outline.spec.js- 验证 Markdown 目录提取和锚点生成规则client/src/pages/ToolDetailPage.spec.js- 验证详情页数据状态和长文阅读体验client/src/App.spec.js- 验证首页详情入口从弹窗切为路由跳转server/src/modules/tools/tools.service.spec.ts- 验证按slug查询的业务规则server/test/tools-detail.e2e-spec.ts- 验证公开详情接口路由行为
任务列表
任务 1:建立前端测试基建和 Markdown 目录工具
文件:
-
创建:
client/vitest.config.js -
创建:
client/src/test/setup.js -
创建:
client/src/utils/markdown-outline.js -
测试:
client/src/utils/markdown-outline.spec.js -
修改:
client/package.json -
修改:
client/package-lock.json -
步骤 1:在
client/package.json中增加test、test:run脚本和vitest、@vue/test-utils、jsdom等依赖声明;创建client/vitest.config.js、client/src/test/setup.js;编写client/src/utils/markdown-outline.spec.js,先描述标题提取、重复标题去重、无标题返回空目录的失败用例。 -
步骤 2:运行
npm --prefix client install;随后运行npm --prefix client run test:run -- client/src/utils/markdown-outline.spec.js,预期输出为测试失败,原因是markdown-outline.js尚未实现或断言不满足。 -
步骤 3:创建
client/src/utils/markdown-outline.js,实现extractMarkdownOutline和稳定锚点生成逻辑,保证只提取正文标题并对重复标题追加序号。 -
步骤 4:再次运行
npm --prefix client run test:run -- client/src/utils/markdown-outline.spec.js,预期输出1 passed,前端测试基建可用。
任务 2:实现后端按 slug 查询详情的服务层能力
文件:
-
创建:
server/src/modules/tools/tools.service.spec.ts -
修改:
server/src/modules/tools/tools.service.ts -
步骤 1:编写
server/src/modules/tools/tools.service.spec.ts,覆盖已发布工具可按slug查询、未发布工具不可见、缺失工具抛出 404、详情映射字段与现有按id详情保持一致的失败测试。 -
步骤 2:运行
npm --prefix server test -- --runTestsByPath src/modules/tools/tools.service.spec.ts,预期输出为编译失败或测试失败,因为getToolDetailBySlug及共享映射尚未存在。 -
步骤 3:在
server/src/modules/tools/tools.service.ts中抽出详情映射方法,新增getToolDetailBySlug(slug: string),查询条件限定为status=published、isDeleted=false,并复用现有详情返回结构。 -
步骤 4:再次运行
npm --prefix server test -- --runTestsByPath src/modules/tools/tools.service.spec.ts,预期输出Test Suites: 1 passed。
任务 3:补齐公开详情 slug 接口和后端 e2e
文件:
-
创建:
server/test/tools-detail.e2e-spec.ts -
修改:
server/src/modules/tools/tools.controller.ts -
步骤 1:编写
server/test/tools-detail.e2e-spec.ts,准备一条已发布工具测试数据,定义GET /tools/slug/:slug成功返回详情和未知slug返回 404 的失败测试。 -
步骤 2:运行
npm --prefix server run test:e2e -- --runTestsByPath test/tools-detail.e2e-spec.ts,预期输出为 404 或断言失败,因为控制器路由尚未暴露该接口。 -
步骤 3:在
server/src/modules/tools/tools.controller.ts中新增GET /tools/slug/:slug路由,调用toolsService.getToolDetailBySlug;按需要调整 e2e 中的测试数据清理,避免污染现有数据。 -
步骤 4:再次运行
npm --prefix server run test:e2e -- --runTestsByPath test/tools-detail.e2e-spec.ts,预期输出1 passed或2 passed,接口直达行为稳定。
任务 4:新增公开详情页路由、API 接入和页面状态
文件:
-
创建:
client/src/pages/ToolDetailPage.vue -
测试:
client/src/pages/ToolDetailPage.spec.js -
修改:
client/src/api.js -
修改:
client/src/admin/router.js -
步骤 1:编写
client/src/pages/ToolDetailPage.spec.js,覆盖按路由slug拉取详情、加载态、404 提示、空内容提示、返回首页入口以及主操作按钮展示的失败测试。 -
步骤 2:运行
npm --prefix client run test:run -- client/src/pages/ToolDetailPage.spec.js,预期输出为模块不存在或多个断言失败,因为详情页组件、路由和新 API 方法尚未实现。 -
步骤 3:在
client/src/api.js中新增fetchToolDetailBySlug(slug);在client/src/admin/router.js中增加公开路由/tools/:slug;创建client/src/pages/ToolDetailPage.vue,完成按slug加载数据、页面级加载/错误/404/空内容状态和返回入口,并复用现有 launch 行为。 -
步骤 4:再次运行
npm --prefix client run test:run -- client/src/pages/ToolDetailPage.spec.js,预期输出1 passed,详情页基础行为成立。
任务 5:替换首页详情弹窗为路由跳转
文件:
-
创建:
client/src/App.spec.js -
修改:
client/src/App.vue -
步骤 1:编写
client/src/App.spec.js,覆盖“详情”按钮改为跳转到/tools/:slug、旧详情弹窗 DOM 不再渲染、首页仍保留概览弹窗的失败测试。 -
步骤 2:运行
npm --prefix client run test:run -- client/src/App.spec.js,预期输出为断言失败,因为首页仍然保留openDetailModal流程和旧弹窗模板。 -
步骤 3:修改
client/src/App.vue,移除detailModalOpen/detailLoading/detailError/detail等状态及弹窗模板,将详情按钮改为router.push或RouterLink跳转,并保留列表、筛选和概览弹窗逻辑不变。 -
步骤 4:再次运行
npm --prefix client run test:run -- client/src/App.spec.js client/src/pages/ToolDetailPage.spec.js,预期输出全部通过,首页到详情页的主链路打通。
任务 6:完善长文阅读体验、后台提示文案和整体验证
文件:
-
修改:
client/src/style.scss -
修改:
client/src/pages/ToolDetailPage.vue -
修改:
client/src/pages/ToolDetailPage.spec.js -
修改:
client/src/admin/components/ToolFormDialog.vue -
步骤 1:扩展
client/src/pages/ToolDetailPage.spec.js,新增目录渲染、无标题时不显示目录、长文时保留清晰段落层级和返回入口的失败测试。 -
步骤 2:运行
npm --prefix client run test:run -- client/src/pages/ToolDetailPage.spec.js,预期输出为目录相关断言失败,因为页面尚未接入目录工具和阅读态样式。 -
步骤 3:修改
client/src/pages/ToolDetailPage.vue和client/src/style.scss,接入extractMarkdownOutline、渲染目录导航、优化正文宽度/标题层级/锚点区块;同步修改client/src/admin/components/ToolFormDialog.vue的简介提示文案,明确其支持 Markdown 手册内容。 -
步骤 4:依次运行
npm --prefix client run test:run -- client/src/utils/markdown-outline.spec.js client/src/pages/ToolDetailPage.spec.js client/src/App.spec.js、npm --prefix client run build、npm --prefix server test -- --runTestsByPath src/modules/tools/tools.service.spec.ts、npm --prefix server run test:e2e -- --runTestsByPath test/tools-detail.e2e-spec.ts,预期输出均为通过,且客户端构建成功无报错。
执行顺序说明
- 先补前端测试基建,否则后续页面任务无法按 TDD 执行。
- 后端先做服务层,再做控制器和 e2e,可减少路由级调试成本。
- 前端先完成详情页自身状态,再替换首页入口,避免“按钮先改了但页面未就绪”。
- 长文阅读体验放在最后收口,避免样式和目录逻辑反复返工。
风险提示
- 前端当前没有测试依赖,任务 1 会同时引入测试脚手架和锁文件变更。
App.vue体量较大,任务 5 需要谨慎删除旧弹窗状态,避免误伤概览弹窗和列表筛选逻辑。slug接口与按id接口将同时存在,任务 2 和任务 3 需要确保两者返回结构一致,避免前端出现双标准。- e2e 测试需要自行准备和清理工具数据,避免依赖现有 seed 内容导致测试不稳定。