# 模块设计 > 版本: v0.4.0 | 作者: Arch AI | 基于 PRD v0.4.0 + 旧架构合并 --- ## 1. 模块总览 ``` ErrLens ├── P01_errlens_app (小程序 + 后端) │ ├── 小程序端 (Taro + React) │ │ ├── pages/auth # 登录/注册 │ │ ├── pages/home # 首页(错题概览) │ │ ├── pages/capture # 拍照录入 │ │ ├── pages/error-detail # 错题详情+分析 │ │ ├── pages/error-list # 错题列表 │ │ ├── pages/weak-points # 薄弱点分析 │ │ ├── pages/practice # 练习推荐 (P1) │ │ ├── pages/print # PDF 输出 (P0) │ │ └── pages/profile # 个人中心 │ │ │ └── 后端 (NestJS) │ ├── modules/auth # 鉴权模块 │ ├── modules/user # 用户模块(含邀请链) │ ├── modules/invitation # 邀请模块 │ ├── modules/error-item # 错题模块 │ ├── modules/ai # AI 分析模块 │ ├── modules/image # 图像预处理模块 │ ├── modules/subject # 学科模块 │ ├── modules/question-bank # 题库模块 │ ├── modules/recommend # 推荐模块 (P1) │ ├── modules/print # 打印/PDF 输出模块 (P0) │ └── modules/upload # 文件上传 │ ├── P02_errlens_training (Phase 3) │ └── AI 模型训练管线 │ └── P03_errlens_web (Phase 3) └── Web 管理后台 ``` ## 2. 小程序页面路由 | 路由 | 页面 | 说明 | MVP | |------|------|------|-----| | `/pages/index/index` | 首页 | 错题统计概览 + 快捷入口 | ✅ | | `/pages/auth/login` | 登录 | 微信授权登录 | ✅ | | `/pages/capture/index` | 拍照录入 | 拍照 → AI 识别 → 确认 | ✅ | | `/pages/error-list/index` | 错题列表 | 筛选 + 搜索 | ✅ | | `/pages/error-detail/index` | 错题详情 | 题目 + AI 分析 | ✅ | | `/pages/weak-points/index` | 薄弱点 | 知识点薄弱项汇总 | ✅ | | `/pages/practice/index` | 练习推荐 | 智能组题 | P1 | | `/pages/practice/result` | 练习结果 | 对错反馈 | P1 | | `/pages/print/index` | 错题选择 | 选题→生成 PDF | ✅ | | `/pages/print/preview` | 打印预览 | PDF 预览+下载 | ✅ | | `/pages/profile/index` | 个人中心 | 资料 + 设置 | ✅ | ## 3. 后端模块设计 ### 3.1 Auth 模块 ``` modules/auth/ ├── auth.module.ts ├── auth.controller.ts # POST /auth/login (微信 code → JWT) ├── auth.service.ts # 微信 code2session + JWT 签发 ├── auth.guard.ts # JWT 鉴权守卫 └── dto/ └── login.dto.ts ``` **API**: | 方法 | 路径 | 说明 | |------|------|------| | POST | /auth/login | 微信 code 换取 JWT token | | POST | /auth/refresh | 刷新 token | ### 3.2 User 模块 ``` modules/user/ ├── user.module.ts ├── user.controller.ts # GET/PATCH /user/profile ├── user.service.ts ├── user.entity.ts # Drizzle schema └── dto/ └── update-profile.dto.ts ``` **API**: | 方法 | 路径 | 说明 | |------|------|------| | GET | /user/profile | 获取个人信息 | | PATCH | /user/profile | 更新年级、学科 | | GET | /user/invitation-code | 获取个人邀请码和二维码 | | GET | /user/tree | 获取邀请树(直接下级列表) | ### 3.3 Invitation 模块 ``` modules/invitation/ ├── invitation.module.ts ├── invitation.controller.ts # POST /invitation/register ├── invitation.service.ts # 邀请码生成 + 邀请链管理 ├── user-relation.entity.ts # Drizzle schema └── dto/ ├── register-by-invite.dto.ts └── tree-query.dto.ts ``` **API**: | 方法 | 路径 | 说明 | |------|------|------| | POST | /invitation/register | 通过邀请码注册(携带 inviter_code) | | GET | /invitation/tree | 获取当前用户的邀请树(一级+递归) | | GET | /invitation/tree/:userId | 获取指定用户的邀请统计(子节点数、活跃用户数) | **邀请码生成规则**: - 用户注册时自动生成 6 位字母数字邀请码 - 格式: `[A-Z0-9]{6}`,排除易混淆字符 (0/O, 1/I/L) - 唯一约束,冲突时重试生成 **注册流程**: ``` 1. 老用户 A 分享小程序 → 携带邀请码参数 (pages/auth/login?invite=ABC123) 2. 新用户 B 打开 → 微信授权登录 3. 后端创建 B 用户 → 生成 B 的邀请码 4. 创建 user_relation (inviter=A, invitee=B) 5. B 进入首页 → 关系建立完成 ``` ### 3.4 ErrorItem 模块(核心) ``` modules/error-item/ ├── error-item.module.ts ├── error-item.controller.ts # CRUD /error-items ├── error-item.service.ts # 错题业务逻辑 + 校验状态管理 ├── error-item.entity.ts # Drizzle schema ├── correction-log.service.ts # 修正记录管理 └── dto/ ├── create-error.dto.ts ├── update-error.dto.ts ├── query-error.dto.ts # 筛选参数(含 verification_status) └── batch-confirm.dto.ts # 批量确认 ``` **API**: | 方法 | 路径 | 说明 | |------|------|------| | POST | /error-items | 创建错题(AI 识别结果,状态=raw) | | GET | /error-items | 列表查询(分页+筛选,含 verification_status 筛选) | | GET | /error-items/:id | 错题详情(含 AI 分析 + 置信度) | | PATCH | /error-items/:id | 修正错题信息(字段修正时记录 CorrectionLog) | | POST | /error-items/batch-confirm | 批量确认(raw → reviewed) | | DELETE | /error-items/:id | 删除错题 | **校验状态机**: ``` raw → (用户查看+确认) → reviewed → (用户修正字段) → corrected ↓ stale (30天未确认,系统标记,可恢复为 raw) ``` **AnalysisReport 数据过滤**: 查询时加 `WHERE verification_status != 'raw'`,确保分析只使用已确认数据。 ### 3.5 AI 模块 ``` modules/ai/ ├── ai.module.ts ├── ai.controller.ts # POST /ai/analyze ├── ai.service.ts # Coze SDK 调用封装 ├── strategies/ │ ├── ocr.strategy.ts # OCR 识别策略 │ ├── classify.strategy.ts # 学科/知识点分类策略 │ └── diagnose.strategy.ts # 错误原因诊断策略 └── dto/ ├── analyze-request.dto.ts └── analyze-response.dto.ts ``` **API**: | 方法 | 路径 | 说明 | |------|------|------| | POST | /ai/analyze | 分析错题图片 → 返回结构化结果 | | GET | /ai/report | 获取薄弱点分析报告 | **AI 分析流程**: ``` 图片 URL → OCR 文字提取 ──→ question_text (confidence: 0.5-0.95) ├─ 学科分类 ──────────→ subject_id (confidence: 0.7-0.95) ├─ 知识点标注 ────────→ knowledge_points[] (confidence 各 0.5-0.9) ├─ 题目结构提取 ──────→ wrong_answer/correct_answer (confidence 各 0.5-0.9) └─ 错误原因诊断 ──────→ error_type + diagnosis (confidence: 0.5-0.9) → 每个字段附带 confidence 分数 → 低置信(<0.7)字段标记 requires_review=true,前端红色高亮 → 汇总返回 { result, confidences, requires_review_fields[] } ``` ### 3.6 Image 模块(图像预处理) ``` modules/image/ ├── image.module.ts ├── image.service.ts # 图像预处理编排 ├── pipelines/ │ ├── perspective.service.ts # 透视校正(手动框 4 角) │ ├── enhance.service.ts # CLAHE + Gamma + 对比度增强 │ └── pen-removal.service.ts # 笔迹去除(红/蓝 HSV 自动,黑笔手动圈选) ├── sharp.config.ts # Sharp 图像处理参数配置 └── dto/ └── preprocess.dto.ts ``` **处理管线**: ``` 原始图片 → 透视校正 → CLAHE 增强 → 笔迹去除 → 输出增强图片 URL ↓ ↓ ↓ ↓ 原图保留 手动框角 光照归一化 红/蓝自动去除 黑笔可选手动圈选 ``` **降级策略**: 任何模块失败不阻塞整体流程。校正失败 → 用原图;增强失败 → 跳过增强;笔迹去除失败 → 保留原图。始终保证图片能进入 AI 识别。 **Spike 验证结论**(来自旧架构,Coze 沙盒中重新调优): - 自动透视校正不可用(整页裁成碎片),以手动框 4 角为主方案 - CLAHE 增强 10/10 达到清晰度标准 - 红笔批改可靠去除、蓝笔可用、黑笔无法自动去除(需用户圈选) ### 3.8 Subject 模块 ``` modules/subject/ ├── subject.module.ts ├── subject.controller.ts # GET /subjects ├── subject.service.ts └── subject.entity.ts ``` **API**: | 方法 | 路径 | 说明 | |------|------|------| | GET | /subjects | 获取学科列表 | | GET | /subjects/:id/knowledge-points | 获取学科下知识点树 | ### 3.7 Print 模块(PDF 输出)[P0] ``` modules/print/ ├── print.module.ts ├── print.controller.ts # POST /print/generate, GET /print/download/:id ├── print.service.ts # PDF 生成 + S3 存储 + 过期清理 ├── pdf-layout.service.ts # PDFKit A4/300DPI 排版 └── dto/ ├── generate-print.dto.ts └── print-task.dto.ts ``` **API**: | 方法 | 路径 | 说明 | |------|------|------| | POST | /print/generate | 提交错题 ID 列表,生成 PDF 任务 | | GET | /print/task/:id | 查询生成进度 | | GET | /print/download/:id | 下载 PDF 文件(24h 有效) | **排版优先级**: 题库匹配的结构化内容 > 经图像预处理的增强图片 > 原始图片 **清理策略**: 定时任务每天清理 expires_at < NOW() 的临时文件。 ### 3.9 Upload 模块 ``` modules/upload/ ├── upload.module.ts ├── upload.controller.ts # POST /upload/image ├── upload.service.ts # S3 上传 + 缩略图 └── upload.config.ts # S3/MinIO 配置 ``` **API**: | 方法 | 路径 | 说明 | |------|------|------| | POST | /upload/image | 上传图片 → 返回 URL | ### 3.10 Recommend 模块 (P1) ``` modules/recommend/ ├── recommend.module.ts ├── recommend.controller.ts # GET /recommend ├── recommend.service.ts # 推荐编排 └── strategies/ ├── coarse-recall.strategy.ts # 粗筛:关键词搜索 + Jaccard 相似度(本地,免费) ├── ai-rerank.strategy.ts # 精排:AI 语义匹配(候选集不足时启用,付费) ├── weak-point.strategy.ts # 薄弱点权重排序 └── similar-difficulty.strategy.ts # 难度匹配 ``` **两阶段推荐策略**: 1. **粗筛**(关键词 + Jaccard 相似度)→ 快速召回候选集,零成本、低延迟 2. **精排**(AI 语义匹配)→ 候选集为空或不满足阈值时启用,语义理解泛化 3. 排序: 薄弱点权重 > 难度匹配度 > 去重(已做过的不推) ### 3.11 QuestionBank 模块(题库抽象层) ``` modules/question-bank/ ├── question-bank.module.ts ├── question-bank.controller.ts # CRUD /questions ├── question-bank.service.ts # 多源题库路由 ├── adapters/ │ ├── base-adapter.ts # 题库适配器接口 │ ├── self-built.adapter.ts # 自有题库适配器 │ ├── zuoyebang.adapter.ts # 作业帮 API 适配器 │ └── adapter.factory.ts # 按 source 路由到对应适配器 ├── pdf-import/ │ ├── pdf-parser.service.ts # PDF → 文本 │ ├── ai-extractor.service.ts # AI 结构化提取题目 │ └── import-review.service.ts # 人工审核流程 └── dto/ ├── create-question.dto.ts ├── query-question.dto.ts └── pdf-import.dto.ts ``` **API**: | 方法 | 路径 | 说明 | |------|------|------| | GET | /questions | 题目列表查询(分页+筛选) | | GET | /questions/:id | 题目详情 | | POST | /questions | 手动创建题目(自有题库录入) | | POST | /questions/search | 跨源搜索(自有 + 作业帮,结果合并) | | POST | /questions/pdf-import | 上传 PDF 启动导入任务 | | GET | /questions/pdf-import/:taskId | 查询 PDF 导入进度 | **适配器接口**: ```typescript interface QuestionBankAdapter { source: string; search(params: SearchParams): Promise; getById(id: string): Promise; healthCheck(): Promise; } ``` **题库路由策略**: 请求时并行查询自有题库 + 作业帮 API,合并去重后返回。自有题库优先排序。 ## 4. 前端状态管理 (Zustand) ``` stores/ ├── auth.store.ts # 登录态、token、用户信息 ├── error-item.store.ts # 错题列表、筛选条件、分页 ├── capture.store.ts # 拍照流程状态机 └── ai-analysis.store.ts # AI 分析结果缓存 ``` **capture 状态机**: ``` IDLE → CAMERA → PREVIEW → UPLOADING → ANALYZING → REVIEW → SAVING → DONE ↓ ↓ ↓ ERROR ERROR ERROR ``` ## 5. MVP 开发顺序 ``` Phase 2a (Week 1-2): 基础设施 - 数据库 Schema + 迁移 - Auth 模块(微信登录) - User 模块 - Image 模块(图像预处理管线) Phase 2b (Week 3-4): 核心闭环 - Upload 模块 - AI 模块(Coze SDK 集成) - ErrorItem CRUD - 拍照录入页 + 错题列表页 Phase 2c (Week 5-6): 分析+打印+打磨 - 错题详情 + AI 分析展示 - 薄弱点汇总 - Print 模块(PDF 输出) - Subject 模块 + 筛选 - 交互打磨、异常处理 ``` --- *关联: 总体架构.md → 技术选型.md → 数据模型.md*