diff --git a/docs/开发计划.md b/docs/开发计划.md new file mode 100644 index 0000000..f303278 --- /dev/null +++ b/docs/开发计划.md @@ -0,0 +1,171 @@ +# 备考通|开发计划 + +版本:v1.0 · 2026-08-27 +说明:这是最终版本的实施顺序,不代表功能分期;所有工作完成后才视为项目交付。 + +## 1. 执行方式 + +采用“基础设施先行、纵向功能闭环、最后统一验收”的顺序。每项工作必须同时具备代码、可运行结果和验证记录,避免只完成页面而没有接口或持久化。 + +执行约束: + +- 后端接口 Schema 先于前端 API 生成。 +- 数据模型先于业务 Service,业务 Service 先于页面联调。 +- 每完成一个业务闭环,立即验证刷新后的 JSON 持久化结果。 +- PC 与 Mobile 从第一张页面开始同步适配,不集中到末尾处理。 +- 生成代码不手工修改,接口变更必须重新生成并检查差异。 + +## 2. 任务顺序 + +### 任务 01|项目初始化与目录确定 + +工作:创建前后端目录、TypeScript 配置、包管理脚本、环境变量模板、基础 Git 忽略规则。 + +产出:前后端分别可以启动;开发、构建、类型检查命令可执行。 + +完成标准:新环境按 README 操作可以启动前端和后端,启动失败时有明确错误。 + +### 任务 02|JSON Store 与演示数据 + +工作:实现 `readData`、`writeData`、`updateData`,建立数据文件路径常量和缺失文件初始化;录入演示题、用户档案、计划、模考和要闻数据。 + +产出:`server/data/` 可独立运行;写入使用临时文件后原子替换。需要兼容开发/生产两套环境。 + +完成标准:服务重启后数据仍然存在;任一 JSON 文件缺失不会导致服务崩溃;非法 JSON 有可定位错误。 + +### 任务 03|后端路由 Schema 与 OpenAPI + +工作:注册 Fastify、统一错误处理、请求日志、Zod 校验;为每个业务接口补齐请求和响应 Schema;导出静态 OpenAPI 文档。 + +产出:`/api/openapi.json`、Swagger UI、错误响应格式、OpenAPI 导出脚本。 + +完成标准:所有已登记接口都出现在文档中;请求参数错误能返回统一错误;`openapi:export` 可重复执行。 + +### 任务 04|前端 API 自动生成与基础壳层 + +工作:接入 OpenAPI 代码生成;建立请求客户端、路由、Pinia 基础 store、设计 Token、全局布局、PC 侧栏和 Mobile TabBar。 + +产出:`client/src/api/generated/`;页面可在桌面和移动断点切换;统一加载、空数据、错误提示组件。 + +完成标准:前端业务代码不直接写 URL 和 `fetch`;修改后端 Schema 能重新生成类型;首页路由能通过真实接口加载。 + +### 任务 05|数据中枢纵向闭环 + +工作:实现概览、趋势、掌握度、今日任务和薄弱考点接口及页面;接入统计计算。 + +产出:PC 数据看板和 Mobile 首页均使用同一份后端数据。 + +完成标准:存在演示数据时指标、图表和任务可见;清空数据时显示合理空状态;刷新后结果一致。 + +### 任务 06|计划、个人中心、设置与要闻 + +工作:实现计划任务创建/切换、个人档案、设置修改、要闻列表/详情;接入 Markdown 渲染和 JSON 要闻数据。 + +产出:计划、个人、设置和要闻页面的接口、页面和持久化。 + +完成标准:任务状态变更能影响首页统计;设置刷新后保留;要闻详情支持 Markdown;RSS/API/URL 入口返回明确占位反馈。 + +### 任务 07|题库管理与导入导出 + +工作:实现题目列表筛选、JSON 导入、内容指纹去重、后台 UUID 生成、导出和删除确认。 + +产出:题库管理页面、导入结果报告、导出文件。 + +完成标准:导入文件不含 ID 也能成功;重复题目被跳过;错误题目不影响有效题目导入;导出的数据可再次导入。 + +### 任务 08|刷题与结果闭环 + +工作:实现模块选题、5/10/15 分钟组卷、自定义组卷、会话、计时、作答、提交、结果和标准解析。 + +产出:可从首页或刷题中心开始一套题并完成提交;记录写入 JSON。 + +完成标准:答案、正确率、耗时和完成状态准确;中途刷新按设计处理;提交后不能重复计入同一题。 + +### 任务 09|错题复习闭环 + +工作:答错自动沉淀错题;实现待复习筛选、复习提交、+1/+3/+7 天安排、连续答对后标记掌握、再次答错回到当天。 + +产出:错题本、错题详情、复习操作和数据中枢联动。 + +完成标准:修改系统日期或使用测试时间可验证每个复习节点;复习结果影响掌握度和待复习数量。 + +### 任务 10|模考分析 + +工作:实现行测模考录入、列表、趋势、模块分数、目标分差和较上次变化;补充无数据空状态。 + +产出:模考分析页和成绩录入页。 + +完成标准:只出现行测字段;至少两条记录能生成趋势;删除或修改记录后分析同步更新。 + +### 任务 11|AI 讲解与申论占位 + +工作:实现 OpenAI 兼容客户端、Token 配置读取、结构化讲解、超时处理和题库解析回退;完成申论占位页面。 + +产出:AI 讲解接口、前端结果展示、未配置和失败提示。 + +完成标准:配置有效 Token 能完成一次讲解;未配置或超时不会阻塞刷题结果;Token 不出现在前端和日志中。 + +### 任务 12|联调与异常收口 + +工作:逐接口联调;补齐空数据、非法导入、重复提交、文件写入失败、AI 失败和网络断开处理;统一按钮禁用和提示文案。 + +产出:接口检查清单、边界场景记录、修复提交。 + +完成标准:主要用户流程无未处理异常;所有错误都能被用户理解;服务端日志能定位问题但不泄露敏感配置。 + +### 任务 13|原型视觉验收与响应式修正 + +工作:对照原型逐页校准尺寸、间距、字号、颜色、图标、卡片层级和交互状态;检查 390px 手机宽度、平板宽度和桌面宽度。 + +产出:视觉差异修复、页面截图检查记录。 + +完成标准:导航、主要卡片、按钮和核心数据层级与原型一致;无横向溢出;触控目标可操作。 + +### 任务 14|交付整理 + +工作:整理 README、环境变量示例、启动命令、题库格式说明、AI 配置说明和数据目录说明;执行生产构建。 + +产出:可交付代码、运行文档、最终 OpenAPI 文件和验收清单。 + +完成标准:清空依赖缓存后可重新安装并构建;生产构建成功;文档中的命令与实际脚本一致。 + +## 3. 关键依赖关系 + +```text +初始化 + ↓ +JSON Store ───────┐ + ↓ │ +数据模型/Schema │ + ↓ │ +OpenAPI ─→ 前端 API 生成 + ↓ ↓ +业务 Service ─→ 页面联调 + ↓ +统计、错题、AI + ↓ +双端验收与交付 +``` + +以下事项不得提前绕过依赖: + +- 页面不得在接口未定时自行定义重复类型。 +- 统计页面不得使用仅存在于前端的模拟计算。 +- 错题复习必须基于真实作答记录,不能单独维护一套展示数字。 +- AI 页面必须复用刷题结果中的题目和用户答案。 + +## 4. 每项任务的完成检查 + +完成一项任务前,按以下顺序检查: + +1. 启动前端并使用浏览器打开对应页面,在与原型图一致的视口尺寸下截图;将实现截图与对应原型逐项对比,记录布局、尺寸、间距、颜色、字体、图标和内容差异,修正明显偏差后再继续。 +2. 使用浏览器实际操作一遍本任务涉及的核心流程,确认页面反馈、路由跳转和数据变化符合预期。 +3. 正常流程是否可运行。 +4. 空数据是否可展示。 +5. 非法输入是否有反馈。 +6. 写入后重启服务是否仍然正确。 +7. PC 与 Mobile 是否都可操作。 +8. OpenAPI、生成 API 和实际实现是否一致。 +9. 是否引入了需求之外的抽象或依赖。 + +全部任务完成后,再执行一次从“首次启动 → 开始刷题 → 提交 → 错题复习 → 录入模考 → 查看数据中枢”的完整验收流程。 diff --git a/docs/开发需求说明.md b/docs/开发需求说明.md new file mode 100644 index 0000000..e890ae8 --- /dev/null +++ b/docs/开发需求说明.md @@ -0,0 +1,331 @@ +# 备考通|开发需求说明 + +版本:v1.0 · 2026-08-27 +定位:个人本地部署的公务员考试备考工具 +依据:`deliverables/prototype/` 原型图与 `deliverables/design/` 设计规范 + +## 1. 项目边界 + +备考通服务单一用户,围绕行测备考形成“计划—刷题—错题复习—模考分析”的闭环,并提供时政要闻和申论入口。 + +本版本包含: + +- PC 与 Mobile 响应式界面。 +- 行测内置演示题库、题目 JSON 导入与导出。 +- 行测按模块刷题、计时、提交、结果和解析。 +- 错题沉淀、间隔复习和错题详情。 +- 学习计划、每日任务、周报复盘。 +- 行测模考成绩录入、趋势与模块分析。 +- 要闻列表、详情及 JSON/RSS/API/URL 导入入口。 +- AI 行测题目讲解,后端通过 OpenAI 兼容接口调用。 +- 申论占位页,不实现写作编辑、批改和评分。 + +明确不包含:登录注册、权限系统、多用户、云同步、数据库、备份恢复、深色模式、行测以外的模考、完整申论系统。 + +## 2. 技术方案 + +### 2.1 技术栈 + +- 前端:Vue 3、Vite、TypeScript、Vue Router、Pinia、ECharts、Lucide Vue。 +- 后端:Node.js、TypeScript、Fastify(Express 可替代,但项目内只选一种)。 +- 存储:后端本地 `data/*.json` 文件。 +- 校验:Zod。 +- AI:OpenAI 兼容的 Chat Completions 接口,Token 只在后端配置。 + +### 2.2 OpenAPI 约定 + +后端接口必须提供 OpenAPI 3.0 文档,作为前后端接口契约的唯一来源。接口仍采用语义化路径,不因引入 OpenAPI 改为传统 REST 资源风格。 + +- Fastify 使用 `@fastify/swagger` 根据路由 schema 生成 OpenAPI 文档。 +- 开发环境提供 `/api/openapi.json`,便于查看和调试。 +- 前端使用 `openapi-typescript` 生成接口类型,使用 `openapi-fetch` 封装请求客户端。 +- 生成文件放在 `client/src/api/generated/`,不手工修改,加入 `.gitignore`。 +- 前端通过 `pnpm api:generate`(或项目选定的包管理器命令)从后端 OpenAPI 文档重新生成 API 文件。 +- `dev` 与 `build` 前执行生成检查;若 OpenAPI 文档无法获取或生成失败,命令应直接失败。 +- 后端每个接口必须声明请求参数、请求体、成功响应和错误响应 schema;禁止出现只有实现没有 schema 的接口。 + +推荐配置: + +```text +server: @fastify/swagger + @fastify/swagger-ui +client: openapi-typescript + openapi-fetch +document: /api/openapi.json +generated: client/src/api/generated/ +``` + +前端业务代码只调用生成后的 API 方法或类型,不直接在页面中写 `fetch`、URL 字符串和重复的请求类型。生成客户端统一处理基础 URL、JSON headers、错误响应和超时;AI Token 等敏感配置不进入 OpenAPI 文档或前端代码。 + +### 2.2 后端分层 + +后端保持三层,不引入 Repository、ORM、领域层或消息系统: + +```text +请求 → Handler → Service → JSON Store + ↘ AI / 导入解析器 +``` + +```text +server/ +├── src/ +│ ├── server.ts +│ ├── routes.ts +│ ├── handlers/ # 参数读取、调用 service、响应格式化 +│ ├── services/ # 业务规则和统计计算 +│ ├── data/ +│ │ ├── store.ts # readData / writeData / updateData +│ │ └── files.ts +│ ├── importers/ # JSON、RSS、API、URL 解析入口 +│ ├── ai/ # AI 客户端与响应整理 +│ ├── utils/ # id、日期、内容指纹 +│ └── types/ +└── data/ +``` + +`store.ts` 负责 JSON 读写。所有写操作先写临时文件,再原子替换目标文件;不提供数据备份和恢复能力。 + +### 2.3 前端目录规划 + +前端按页面、业务组件、状态、接口、基础组件分离,页面组件负责组合,不直接承担数据计算和请求细节。 + + client/ + └── src/ + ├── main.ts、App.vue + ├── router/index.ts + ├── api/ + │ ├── client.ts # 生成客户端的统一配置 + │ ├── index.ts # 对业务暴露 API + │ └── generated/ # OpenAPI 自动生成,禁止手工修改 + ├── stores/ # app、profile、practice + ├── layouts/ # Desktop、Mobile、Navigation + ├── views/ # 按 dashboard、practice、review、plan、mock、news、questions、profile、settings、essay 划分 + ├── components/ + │ ├── base/ # Button、Card、Badge、Modal + │ ├── feedback/ # Loading、Error、Toast、Confirm + │ ├── charts/ + │ └── dashboard、practice、review、plan、mock、news、questions/ + ├── composables/ # useResponsive、useRequest、useToast + ├── styles/ # main、tokens、reset、responsive + ├── types/view-models.ts # 页面组合类型,不复制接口类型 + └── utils/ # 格式化、日期、前端校验 + +目录规则:views 对应路由页面;components 放跨页面复用组件;stores 只保存跨页面共享状态;api/generated 只由 OpenAPI 脚本生成;页面不复制桌面和移动两套业务逻辑,通过 Layout、CSS 断点和少量条件渲染适配。 + +## 3. 页面与导航 + +### 3.1 PC 导航 + +左侧固定导航:数据中枢、刷题中心、模考分析、备考计划、要闻、我的、题库管理、设置。 + +### 3.2 Mobile 导航 + +底部 TabBar:首页、刷题、要闻、分析、我的。二级页面通过页面内返回按钮进入。 + +### 3.3 页面清单 + +| 页面 | 主要内容 | +|---|---| +| 数据中枢 | 备考数据卡、模考趋势、今日任务、掌握度、薄弱考点 | +| 刷题中心 | 行测模块、组卷时长、自定义组卷、错因分布、待复习入口 | +| 作答页 | 题干、选项、进度、计时、提交 | +| 结果页 | 得分、正确率、错题、标准解析、AI 讲解入口 | +| AI 讲解 | 结论、分步解析、考点、常见错误、答案 | +| 错题本 | 待复习列表、模块/错因筛选、复习状态 | +| 错题详情 | 题目、用户答案、正确答案、解析、复习操作 | +| 申论占位 | 功能说明与后续入口,不保存写作内容 | +| 备考计划 | 今日/本周任务、完成状态、计划操作、周报入口 | +| 周报复盘 | 周学习时长、刷题数、正确率、薄弱模块、建议 | +| 模考分析 | 行测成绩趋势、目标分差、模块得分、模考记录 | +| 成绩录入 | 模考名称、日期、总分、五个行测模块分数、备注 | +| 要闻 | 分类列表、详情、导入入口 | +| 我的 | 学习档案、累计数据、成就 | +| 题库管理 | 题目列表、筛选、JSON 导入/导出、删除 | +| 设置 | 目标分、考试日期、每日提醒、刷题偏好、AI 配置状态 | + +每个数据页面必须处理加载、空数据、错误和成功反馈四种状态;空状态需要给出下一步操作。 + +## 4. 业务规则 + +### 4.1 行测模块 + +固定模块:言语理解、数量关系、判断推理、资料分析、常识判断。题目支持单选题;每道题包含题干、A-D 选项、答案、解析、难度、标签和来源。 + +### 4.2 刷题会话 + +用户选择模块和 5/10/15 分钟时长,系统按模块随机组卷并创建会话。会话保存开始时间、题目顺序、答题记录和结束状态。提交后计算答对数、正确率、用时,并将答错题写入错题数据。 + +### 4.3 错题复习 + +错题首次答错当天可复习;复习答对后依次安排 +1 天、+3 天、+7 天,连续四次复习答对后标记已掌握;任意阶段答错则回到当天。用户可以手动标记待复习、复习中或已掌握。 + +模块掌握度默认使用最近 30 天作答记录计算: + +```text +正确作答数 ÷ 有效作答总数 × 100% +``` + +### 4.4 计划与打卡 + +任务包含日期、类型、模块、目标数量或时长、状态和备注。完成一道题、一次错题复习、一个计划任务或一次模考录入,均可计为当日学习行为。连续打卡按自然日计算,缺失一天即归零。 + +### 4.5 模考 + +只支持行测成绩,字段为名称、日期、总分、言语理解、数量关系、判断推理、资料分析、常识判断和备注。系统展示最近成绩、目标分差、较上次变化、趋势和模块对比。 + +### 4.6 要闻 + +内部统一字段:标题、分类、摘要、Markdown 正文、来源、发布时间、标签、导入来源。JSON 为首要维护方式,RSS、API、URL 仅需保留入口、请求结构和未配置提示,解析器可暂为空实现。 + +### 4.7 AI 讲解 + +后端从环境变量读取: + +```text +AI_BASE_URL= +AI_API_KEY= +AI_MODEL= +``` + +前端只传题目 ID、用户答案和请求类型。后端组装题干、选项、标准答案、解析和用户答案后请求 AI,并整理为摘要、步骤、考点、常见错误和答案。AI 超时或未配置时回退到题库解析并返回可识别的提示。 + +## 5. 数据文件与字段 + +```text +data/ +├── profile.json +├── settings.json +├── questions.json +├── practice-sessions.json +├── practice-records.json +├── wrong-questions.json +├── study-plans.json +├── mock-exams.json +└── news.json +``` + +### 5.1 题目导入格式 + +导入文件不提供 `id`: + +```json +{ + "version": "1.0", + "questions": [ + { + "type": "行测", + "module": "数量关系", + "subModule": "行程问题", + "difficulty": "中等", + "stem": "题干内容", + "options": [ + { "key": "A", "text": "选项一" }, + { "key": "B", "text": "选项二" }, + { "key": "C", "text": "选项三" }, + { "key": "D", "text": "选项四" } + ], + "answer": "C", + "analysis": "标准解析", + "tags": ["相遇问题"], + "source": "演示题库" + } + ] +} +``` + +导入流程:校验字段 → 规范化文本 → 使用题型、模块、题干、选项和答案计算内容指纹 → 跳过重复项 → 生成 UUID → 写入文件。导入结果返回总数、成功数、跳过数、失败数和逐条错误。 + +### 5.2 其他实体最小字段 + +- `profile`:昵称、考试日期、目标分、备考开始日期。 +- `settings`:每日目标、提醒时间、AI 配置状态、刷题偏好。 +- `practice-session`:会话 ID、题目 ID 列表、模式、开始/结束时间、状态。 +- `practice-record`:题目 ID、会话 ID、用户答案、是否正确、耗时、作答时间。 +- `wrong-question`:题目 ID、错因、状态、复习次数、下次复习时间、更新时间。 +- `study-plan`:任务 ID、日期、类型、模块、目标、状态、备注。 +- `mock-exam`:模考字段、创建时间。 +- `news`:要闻字段及导入来源。 + +## 6. 语义化接口 + +接口统一前缀 `/api`,成功响应返回业务数据,失败响应格式为: + +```json +{ "error": { "code": "VALIDATION_ERROR", "message": "说明", "details": [] } } +``` + +核心接口: + +```text +GET /api/dashboard/overview +GET /api/dashboard/trends + +GET /api/practice/modules +POST /api/practice/start +GET /api/practice/:sessionId/question +POST /api/practice/:sessionId/answer +POST /api/practice/:sessionId/finish + +GET /api/review/list +POST /api/review/:id/submit +POST /api/review/:id/mark-mastered + +GET /api/plans/today +GET /api/plans/week +POST /api/plans/tasks +PATCH /api/plans/tasks/:id/toggle + +GET /api/mock-exams/analysis +POST /api/mock-exams/record + +GET /api/news/list +GET /api/news/:id +POST /api/news/import/json +POST /api/news/import/rss +POST /api/news/import/api +POST /api/news/import/url + +GET /api/questions/list +POST /api/questions/import +GET /api/questions/export +DELETE /api/questions/:id + +POST /api/ai/explain-question +GET /api/profile +PATCH /api/profile +GET /api/settings +PATCH /api/settings +``` + +## 7. 前端实现约束 + +- 使用 Vue Router 管理页面;Pinia 只保存用户档案、设置、当前会话和必要的缓存,不把所有接口数据做成全局状态。 +- 请求封装统一处理加载、错误和响应解包;页面不直接调用 `fetch`。 +- 以设计 Token 为唯一颜色、字号、间距和圆角来源,沿用 `deliverables/design/design-tokens.css`。 +- PC 使用侧栏和多列卡片;小于 768px 切换为移动布局和底部 TabBar;移动端内容宽度、触控区域和安全边距遵循原型。 +- 图表只展示可解释的真实数据;无数据时使用空状态,不绘制虚假趋势。 +- 所有破坏性操作需要二次确认;导入操作必须显示结果摘要。 + +## 8. 运行与配置 + +前端和后端分别提供开发启动与生产构建命令。后端通过环境变量配置端口、数据目录和 AI 参数: + +```text +PORT=3000 +DATA_DIR=./data +AI_BASE_URL= +AI_API_KEY= +AI_MODEL= +``` + +本地部署要求:首次启动自动创建数据目录并写入演示数据;数据文件不存在时使用空数组或默认档案,不因单个文件缺失导致服务崩溃。 + +## 9. 验收标准 + +- PC 和 Mobile 均能完成首页浏览、开始刷题、提交答案、查看解析、进入错题复习和查看模考分析。 +- 刷题结果会正确更新作答记录、正确率、错题和数据中枢统计。 +- 错题能按规则进入下一次复习,并能手动标记已掌握。 +- 题目 JSON 导入不要求 ID;后台自动生成 ID,重复题目被跳过并可追溯原因;可导出当前题库。 +- 模考仅出现行测字段,录入后趋势和模块分析同步更新。 +- AI Token 配置后可完成一次真实讲解;未配置或失败时能回退到题库解析。 +- 要闻 JSON 列表和详情可用,其他导入入口有明确的占位反馈。 +- 页面具备空、加载、错误和成功反馈;刷新页面后数据仍从 JSON 文件恢复。 +- 不存在登录、权限、数据库、备份恢复和多用户相关界面或接口。