# 阶段 2:方案设计技能书 ## A. 元数据 (Metadata) **name**: `phase2-design` **description**: 在 Datai 项目中,基于已创建的需求文档,进行技术方案设计、架构设计、数据模型设计和接口设计,生成标准化的设计文档,并更新索引和会话记录。此技能是连接需求与实现的关键桥梁。 --- ## B. 触发与定位 (Triggers & Scope) ### 触发关键词 当用户输入包含以下关键词时,必须觉醒此技能: - "设计方案"、"设计文档"、"技术方案" - "架构设计"、"系统设计" - "接口设计"、"API 设计" - "数据模型设计"、"数据库设计" - "进入阶段 2"、"下一阶段" - "设计"、"设计图"、"设计稿" ### 触发场景 - 用户确认阶段 1 完成,要求进入阶段 2 - 用户要求创建设计文档 - 用户询问如何设计某个功能的技术方案 - 用户提到"按照项目规则"或"SSOT 流程"进行设计 ### 操作路径 此技能涉及以下文件和目录的操作: - **读取**: `docs/requirements/YYYY-MM-DD-00X-需求名.md` (阶段 1 创建的需求文档) - **创建**: `docs/design/YYYY-MM-DD-00X-设计名.md` - **更新**: `docs/index.md` - **更新**: `docs/requirements/YYYY-MM-DD-00X-需求名.md` (添加设计文档引用) - **更新**: `docs/sessions/YYYY-MM-DD-00X-session.md` - **读取**: `.trae/rules/project_rules.md` (项目规则) - **读取**: `docs/Prompt/0004-单一真源文档驱动架构师.md` (SSOT 架构师提示词) ### SSOT 依赖 必须参考以下"唯一真源": - [需求文档](file:///d:\idea_demo\datai\docs\requirements\YYYY-MM-DD-00X-需求名.md) - 阶段 1 创建的需求文档 - [project_rules.md](file:///d:\idea_demo\datai\.trae\rules\project_rules.md) - 项目规则和阶段定义 - [0004-单一真源文档驱动架构师.md](file:///d:\idea_demo\datai\docs\Prompt\0004-单一真源文档驱动架构师.md) - SSOT 架构师提示词 - `docs/design/` 目录下的现有设计文档(作为格式参考) - `datai-modules-*/src/main/java/` 目录下的现有代码(作为架构参考) --- ## C. 核心指令集 (Instructions) ### 架构约束 #### 1. 文档命名规范(强制) - 必须使用格式:`YYYY-MM-DD-00X-设计名.md` - `YYYY-MM-DD`:当前日期(如 2026-01-21) - `00X`:需求编号(与阶段 1 保持一致) - `设计名`:简洁描述,使用中文,如"用户登录功能-设计"、"订单导出优化-设计" - **严禁**使用英文、拼音或无意义的文件名 #### 2. 文档结构约束(强制) 设计文档必须包含以下章节,顺序不能改变: ```markdown # 设计文档 ## 元数据 - 需求编号:001 - 创建时间:YYYY-MM-DD - 创建人:AI Assistant - 状态:进行中 ## 设计概述 [设计概述] ## 架构设计 [架构设计] ## 技术方案 [技术方案] ## 数据模型 [数据模型] ## 接口设计 [接口设计] ## 实现要点 [实现要点] ## 相关文档 - [需求文档](../requirements/YYYY-MM-DD-00X-需求名.md) - [决策记录](../decisions/YYYY-MM-DD-00X-ADR-决策名.md) ``` #### 3. 设计原则约束(强制) - **必须**遵循 Spring Boot 最佳实践 - **必须**遵循若依(RuoYi Geek)框架规范 - **必须**遵循 MyBatis Plus 使用规范 - **必须**考虑 Salesforce API 集成规范(如果涉及) - **必须**遵循 RESTful API 设计规范 - **必须**考虑数据安全和权限控制 - **必须**考虑性能优化和可扩展性 #### 4. 索引更新约束(强制) - 必须在创建设计文档后立即更新 `docs/index.md` - 必须更新需求文档,添加设计文档引用 - 采用增量更新策略,**严禁**删除现有内容 - 索引链接格式:`[文档名](./相对路径/文件名.md)` - 必须在 `docs/index.md` 中添加到"设计文档"部分 #### 5. 会话记录约束(强制) - 必须更新 `docs/sessions/YYYY-MM-DD-00X-session.md` - 必须更新当前阶段为"阶段 2:方案设计" - 必须记录关键设计决策 - 必须记录设计文档链接 ### 业务逻辑 SOP(标准操作流程) #### 步骤 1:需求分析(Let's think step by step) 在创建设计文档前,必须执行以下分析: 1. **分析需求的技术要求** - 读取阶段 1 创建的需求文档 - 识别需求中的功能需求和非功能需求 - 识别需求中的技术约束 - 识别需求中的成功标准 2. **确定技术栈和架构方案** - **框架层**:Spring Boot 版本、Spring Security、Spring Cloud(如果需要) - **数据层**:MyBatis Plus、数据库类型(MySQL/PostgreSQL) - **业务层**:若依框架模块(如 `datai-modules-system`、`datai-modules-salesforce`) - **集成层**:Salesforce API、其他第三方服务 - **前端层**:Vue 3、Element Plus(如果涉及) 3. **识别关键设计决策点** - 是否需要引入新的技术组件 - 是否需要设计新的数据表 - 是否需要调用外部 API - 是否需要考虑分布式事务 - 是否需要考虑缓存策略 - 是否需要考虑消息队列 #### 步骤 2:架构设计 1. **系统架构设计** - 绘制系统架构图(使用 Mermaid 或文字描述) - 识别系统分层(Controller、Service、Mapper、Entity) - 识别模块划分(若依框架模块) - 识别依赖关系 2. **模块架构设计** - 确定涉及的若依模块(如 `datai-modules-system`、`datai-modules-salesforce`) - 确定涉及的包结构(如 `controller`、`service`、`mapper`、`domain`) - 确定涉及的类(如 `XxxController`、`XxxService`、`XxxMapper`、`Xxx`) 3. **数据流设计** - 描述数据从输入到输出的完整流程 - 识别数据转换点 - 识别数据验证点 - 识别数据持久化点 #### 步骤 3:技术方案设计 1. **技术选型** - 列出使用的技术组件(如 Spring Security、JWT、Redis) - 说明选择理由(性能、安全性、可维护性) - 说明版本要求 2. **核心算法设计**(如果涉及) - 描述核心算法的逻辑 - 描述算法的复杂度 - 描述算法的优化点 3. **集成方案设计**(如果涉及) - 描述与外部系统的集成方式 - 描述数据交换格式(JSON、XML) - 描述错误处理机制 - 描述重试机制 #### 步骤 4:数据模型设计 1. **数据库表设计**(如果涉及) - 列出需要创建或修改的表 - 列出表的字段(字段名、类型、长度、是否必填、默认值) - 列出表的索引(主键索引、唯一索引、普通索引) - 列出表的关系(一对一、一对多、多对多) 2. **实体类设计** - 列出需要创建的实体类 - 列出实体类的属性 - 列出实体类的注解(`@TableName`、`@TableId`、`@TableField`) - 列出实体类的基类(如 `BaseEntity`) 3. **数据字典设计**(如果涉及) - 列出需要添加的数据字典 - 列出字典类型和字典数据 #### 步骤 5:接口设计 1. **RESTful API 设计** - 列出需要创建的接口(Controller 方法) - 确定接口的 HTTP 方法(GET、POST、PUT、DELETE) - 确定接口的 URL 路径(如 `/api/system/user/login`) - 确定接口的请求参数(路径参数、查询参数、请求体) - 确定接口的响应格式(成功响应、错误响应) 2. **接口权限设计** - 确定接口的权限要求(如 `@PreAuthorize("@ss.hasPermi('system:user:list')")`) - 确定接口的数据权限(如 `@DataScope`) - 确定接口的角色要求 3. **接口文档设计** - 描述接口的功能 - 描述接口的请求参数 - 描述接口的响应参数 - 提供接口示例 #### 步骤 6:实现要点设计 1. **关键实现逻辑** - 描述核心功能的实现逻辑 - 描述关键算法的实现步骤 - 描述关键数据的处理流程 2. **异常处理设计** - 列出可能出现的异常 - 描述异常的处理方式 - 描述异常的提示信息 3. **性能优化设计** - 描述性能优化策略(如缓存、索引、分页) - 描述性能优化目标(如响应时间、并发数) 4. **安全设计** - 描述数据加密方式 - 描述权限控制方式 - 描述防注入方式(SQL 注入、XSS 攻击) #### 步骤 7:创建设计文档 1. **确定文档路径** - 路径:`docs/design/YYYY-MM-DD-00X-设计名.md` - 使用 Write 工具创建文件 - 确保目录存在(使用 LS 工具检查) 2. **填充文档内容** - **元数据**:填写需求编号、创建时间、状态 - **设计概述**:用 2-3 句话描述设计的核心内容 - **架构设计**:包含系统架构图、模块架构图、数据流图 - **技术方案**:包含技术选型、核心算法、集成方案 - **数据模型**:包含数据库表设计、实体类设计、数据字典设计 - **接口设计**:包含 RESTful API 设计、接口权限设计、接口文档 - **实现要点**:包含关键实现逻辑、异常处理、性能优化、安全设计 - **相关文档**:添加需求文档链接,决策记录链接暂时为空 3. **文档质量检查** - 使用 Read 工具读取刚创建的文档 - 检查是否符合文档结构约束 - 检查是否有遗漏的章节 - 检查设计是否合理、可行 #### 步骤 8:更新索引和需求文档 1. **读取现有索引** - 使用 Read 工具读取 `docs/index.md` - 找到"设计文档"部分 - 如果不存在,则创建该部分 2. **添加新设计链接** - 在"设计文档"部分追加新设计 - 格式:`- [设计名](./design/YYYY-MM-DD-00X-设计名.md) - [状态]` - 示例:`- [用户登录功能-设计](./design/2026-01-21-001-用户登录功能-设计.md) - 进行中` 3. **更新需求文档** - 使用 Read 工具读取需求文档 - 在"相关文档"部分添加设计文档链接 - 格式:`- [设计文档](../design/YYYY-MM-DD-00X-设计名.md)` - 使用 Write 工具更新需求文档 4. **保存索引** - 使用 Write 工具更新 `docs/index.md` - **严禁**删除现有内容,只追加新内容 #### 步骤 9:更新会话记录 1. **读取现有会话记录** - 使用 Read 工具读取 `docs/sessions/YYYY-MM-DD-00X-session.md` 2. **更新阶段 2 信息** - 更新"当前阶段"为"阶段 2:方案设计" - 更新"阶段 2:方案设计"的状态为"已完成" - 添加生成文档链接 - 添加关键设计决策 3. **保存会话记录** - 使用 Write 工具更新会话记录 #### 步骤 10:确认与询问 1. **向用户确认** - 显示设计文档的链接 - 询问:"设计方案是否合理?" - 询问:"是否进入下一阶段(方案决策)?" 2. **等待用户反馈** - 如果用户不满意,询问具体需要修改的地方 - 如果用户要求回退,执行回退机制(见错误陷阱部分) - 如果用户确认,标记阶段 2 为已完成,准备进入阶段 3 ### 工具调用 #### 必须使用的工具 1. **Read 工具**:读取现有文件 - 使用场景:读取需求文档、读取索引、读取会话记录 - 命令:`Read(file_path="d:\\idea_demo\\datai\\docs\\requirements\\2026-01-21-001-用户登录功能.md")` 2. **Write 工具**:创建或更新文件 - 使用场景:创建设计文档、更新索引、更新需求文档、更新会话记录 - 命令:`Write(file_path="d:\\idea_demo\\datai\\docs\\design\\2026-01-21-001-用户登录功能-设计.md", content="...")` 3. **LS 工具**:检查目录是否存在 - 使用场景:创建文档前检查 `docs/design/` 目录 - 命令:`LS(path="d:\\idea_demo\\datai\\docs")` 4. **SearchCodebase 工具**:搜索现有代码 - 使用场景:查找现有的 Controller、Service、Mapper 类作为参考 - 命令:`SearchCodebase(information_request="查找 datai-modules-system 模块下的 Controller 类")` #### 可选使用的工具 1. **Glob 工具**:查找文件 - 使用场景:查找所有设计文档 - 命令:`Glob(pattern="docs/design/*.md")` 2. **TodoWrite 工具**:管理任务 - 使用场景:跟踪阶段执行进度 - 命令:`TodoWrite(todos=[...])` --- ## D. 错误陷阱与验证 (Anti-Patterns & Checklist) ### 常见错误(Anti-Patterns) #### 错误 1:不读取需求文档直接设计 **错误示例**: ``` 用户:进入阶段 2 AI:直接创建设计文档,不读取需求文档 ``` **正确示例**: ``` 用户:进入阶段 2 AI:让我先读取需求文档,分析技术要求... AI:读取需求文档:[链接] AI:分析需求的技术要求、技术栈、关键设计决策点... AI:基于需求分析,开始创建设计文档... ``` #### 错误 2:设计文档缺少关键章节 **错误示例**: ```markdown # 设计文档 ## 设计概述 用户登录功能设计 ## 技术方案 使用 Spring Security ``` **问题**: - 缺少元数据 - 缺少架构设计 - 缺少数据模型设计 - 缺少接口设计 - 缺少实现要点 **正确示例**: ```markdown # 设计文档 ## 元数据 - 需求编号:001 - 创建时间:2026-01-21 - 创建人:AI Assistant - 状态:进行中 ## 设计概述 基于 Spring Security 和若依框架,实现用户登录功能的设计,包括认证、授权、会话管理等核心功能。 ## 架构设计 [系统架构图] [模块架构图] [数据流图] ## 技术方案 [技术选型] [核心算法] [集成方案] ## 数据模型 [数据库表设计] [实体类设计] [数据字典设计] ## 接口设计 [RESTful API 设计] [接口权限设计] [接口文档] ## 实现要点 [关键实现逻辑] [异常处理] [性能优化] [安全设计] ## 相关文档 - [需求文档](../requirements/2026-01-21-001-用户登录功能.md) - [决策记录](../decisions/2026-01-21-001-ADR-用户登录功能-技术选型.md) ``` #### 错误 3:不更新需求文档的设计文档引用 **错误示例**: ``` AI:创建设计文档 AI:更新 docs/index.md AI:完成(忘记更新需求文档) ``` **正确示例**: ``` AI:创建设计文档 AI:更新 docs/index.md,添加设计文档链接 AI:更新需求文档,添加设计文档引用 AI:完成 ``` #### 错误 4:接口设计不符合 RESTful 规范 **错误示例**: ``` POST /api/system/user/getUser GET /api/system/user/createUser DELETE /api/system/user/deleteUser ``` **问题**: - HTTP 方法使用错误 - URL 路径不符合 RESTful 规范 **正确示例**: ``` GET /api/system/user/{userId} POST /api/system/user PUT /api/system/user/{userId} DELETE /api/system/user/{userId} ``` #### 错误 5:数据模型设计不考虑若依框架规范 **错误示例**: ```java public class User { private Long id; private String username; private String password; } ``` **问题**: - 没有继承若依的基类 - 没有使用 MyBatis Plus 的注解 - 没有包含审计字段 **正确示例**: ```java @Data @EqualsAndHashCode(callSuper = true) @TableName("sys_user") public class SysUser extends BaseEntity { @TableId(value = "user_id", type = IdType.AUTO) private Long userId; @TableField("user_name") private String userName; @TableField("password") private String password; @TableField("dept_id") private Long deptId; @TableField("status") private String status; } ``` #### 错误 6:不询问用户确认就进入下一阶段 **错误示例**: ``` AI:创建设计文档 AI:进入阶段 3:方案决策(未询问用户) ``` **正确示例**: ``` AI:创建设计文档 AI:设计文档已创建:[链接] AI:设计方案是否合理? AI:是否进入下一阶段(方案决策)? ``` ### 验收清单(Checklist) 在完成阶段 2 前,必须检查以下项目: #### 文档完整性检查 - [ ] 设计文档已创建在 `docs/design/` 目录下 - [ ] 文档命名符合 `YYYY-MM-DD-00X-设计名.md` 格式 - [ ] 文档包含所有必需章节(元数据、设计概述、架构设计、技术方案、数据模型、接口设计、实现要点、相关文档) - [ ] 元数据已正确填写(需求编号、创建时间、状态) - [ ] 设计概述清晰、无歧义 - [ ] 架构设计包含系统架构图、模块架构图、数据流图 - [ ] 技术方案包含技术选型、核心算法、集成方案 - [ ] 数据模型包含数据库表设计、实体类设计、数据字典设计 - [ ] 接口设计包含 RESTful API 设计、接口权限设计、接口文档 - [ ] 实现要点包含关键实现逻辑、异常处理、性能优化、安全设计 #### 设计合理性检查 - [ ] 架构设计符合若依框架规范 - [ ] 技术选型合理,有充分的理由 - [ ] 数据模型设计符合数据库规范 - [ ] 接口设计符合 RESTful 规范 - [ ] 接口权限设计符合若依权限系统 - [ ] 实现要点考虑了性能优化 - [ ] 实现要点考虑了安全性 #### 索引更新检查 - [ ] `docs/index.md` 已更新 - [ ] 新设计链接已添加到"设计文档"部分 - [ ] 索引链接格式正确:`[文档名](./相对路径/文件名.md)` - [ ] 索引更新采用增量策略,未删除现有内容 #### 需求文档更新检查 - [ ] 需求文档已更新 - [ ] 需求文档的"相关文档"部分已添加设计文档链接 - [ ] 设计文档链接格式正确:`[设计文档](../design/YYYY-MM-DD-00X-设计名.md)` #### 会话记录更新检查 - [ ] 会话记录已更新 - [ ] 会话记录的"当前阶段"已更新为"阶段 2:方案设计" - [ ] 会话记录的"阶段 2:方案设计"状态已更新为"已完成" - [ ] 会话记录包含设计文档链接 - [ ] 会话记录包含关键设计决策 #### 用户确认检查 - [ ] 已向用户显示设计文档链接 - [ ] 已询问用户"设计方案是否合理?" - [ ] 已询问用户"是否进入下一阶段?" - [ ] 已等待用户反馈 #### 回退机制检查(如果需要) - [ ] 如果用户不满意,已询问具体需要修改的地方 - [ ] 如果用户要求回退,已删除设计文档 - [ ] 如果用户要求回退,已撤销索引更新 - [ ] 如果用户要求回退,已撤销需求文档更新 - [ ] 如果用户要求回退,已更新会话记录 ### Correct vs Incorrect 代码对比 #### Incorrect(错误示例) ```markdown # 设计文档 ## 设计概述 用户登录功能设计 ## 技术方案 使用 Spring Security ## 接口设计 POST /api/system/user/login ``` **问题**: - 缺少元数据 - 缺少架构设计 - 缺少数据模型设计 - 技术方案过于简单 - 接口设计不完整 #### Correct(正确示例) ```markdown # 设计文档 ## 元数据 - 需求编号:001 - 创建时间:2026-01-21 - 创建人:AI Assistant - 状态:进行中 ## 设计概述 基于 Spring Security 和若依框架,实现用户登录功能的设计,包括认证、授权、会话管理等核心功能。 ## 架构设计 ### 系统架构 ``` 用户 -> 前端 -> Controller -> Service -> Mapper -> 数据库 -> Security -> 认证中心 ``` ### 模块架构 - **Controller 层**:`SysLoginController`,处理登录请求 - **Service 层**:`SysLoginService`,处理登录业务逻辑 - **Mapper 层**:`SysUserMapper`,查询用户信息 - **Entity 层**:`SysUser`,用户实体类 ### 数据流 ``` 用户输入 -> 前端验证 -> Controller -> Service -> 查询用户 -> 验证密码 -> 生成 Token -> 返回 Token ``` ## 技术方案 ### 技术选型 - **认证框架**:Spring Security 6.x - **Token 生成**:JWT (JSON Web Token) - **密码加密**:BCrypt - **会话管理**:Redis 存储 Token - **权限框架**:若依权限系统 ### 核心算法 1. **密码验证算法**: - 使用 BCrypt 加密算法 - 加密强度:10 - 验证流程:用户输入密码 -> BCrypt 加密 -> 与数据库密码比对 2. **Token 生成算法**: - 使用 JWT 生成 Token - Token 有效期:2 小时 - Token 包含:用户 ID、用户名、角色、权限 ### 集成方案 - **与若依权限系统集成**:使用 `@PreAuthorize` 注解控制权限 - **与 Redis 集成**:使用 Redis 存储 Token,实现单点登录 - **与 Salesforce 集成**:如果需要,通过 Salesforce API 获取用户信息 ## 数据模型 ### 数据库表设计 #### sys_user 表(已存在,需要修改) | 字段名 | 类型 | 长度 | 必填 | 默认值 | 说明 | |--------|------|------|------|--------|------| | user_id | bigint | - | 是 | - | 用户 ID(主键) | | user_name | varchar | 30 | 是 | - | 用户名 | | password | varchar | 100 | 是 | - | 密码(BCrypt 加密) | | dept_id | bigint | - | 否 | - | 部门 ID | | status | char | 1 | 是 | 0 | 状态(0 正常 1 停用) | | login_ip | varchar | 128 | 否 | - | 最后登录 IP | | login_date | datetime | - | 否 | - | 最后登录时间 | ### 实体类设计 #### SysUser.java ```java @Data @EqualsAndHashCode(callSuper = true) @TableName("sys_user") public class SysUser extends BaseEntity { @TableId(value = "user_id", type = IdType.AUTO) private Long userId; @TableField("user_name") private String userName; @TableField("password") private String password; @TableField("dept_id") private Long deptId; @TableField("status") private String status; @TableField("login_ip") private String loginIp; @TableField("login_date") private Date loginDate; } ``` ### 数据字典设计 #### sys_dict_type 表(已存在,需要添加) | 字典类型 | 字典名称 | 状态 | |----------|----------|------| | sys_user_status | 用户状态 | 0 | #### sys_dict_data 表(已存在,需要添加) | 字典类型 | 字典键值 | 字典标签 | 状态 | |----------|----------|----------|------| | sys_user_status | 0 | 正常 | 0 | | sys_user_status | 1 | 停用 | 0 | ## 接口设计 ### RESTful API 设计 #### 1. 用户登录 - **请求方式**:POST - **请求路径**:`/api/system/auth/login` - **请求参数**: ```json { "username": "admin", "password": "123456", "code": "1234", "uuid": "abc123" } ``` - **响应参数**: ```json { "code": 200, "msg": "操作成功", "token": "eyJhbGciOiJIUzUxMiJ9..." } ``` #### 2. 用户登出 - **请求方式**:POST - **请求路径**:`/api/system/auth/logout` - **请求参数**:无 - **响应参数**: ```json { "code": 200, "msg": "退出成功" } ``` #### 3. 获取用户信息 - **请求方式**:GET - **请求路径**:`/api/system/auth/getInfo` - **请求参数**:无(从 Token 中获取用户 ID) - **响应参数**: ```json { "code": 200, "msg": "操作成功", "user": { "userId": 1, "userName": "admin", "deptId": 103 }, "roles": ["admin"], "permissions": ["*:*:*"] } ``` ### 接口权限设计 #### 1. 用户登录 - **权限要求**:无需登录即可访问 - **注解**:`@Anonymous` #### 2. 用户登出 - **权限要求**:需要登录 - **注解**:`@PreAuthorize("@ss.hasPermi('system:auth:logout')")` #### 3. 获取用户信息 - **权限要求**:需要登录 - **注解**:`@PreAuthorize("@ss.hasPermi('system:auth:getInfo')")` ### 接口文档 #### 用户登录接口 **功能描述**:用户使用用户名和密码登录系统 **请求参数**: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | username | String | 是 | 用户名 | | password | String | 是 | 密码 | | code | String | 是 | 验证码 | | uuid | String | 是 | 验证码唯一标识 | **响应参数**: | 参数名 | 类型 | 说明 | |--------|------|------| | code | Integer | 状态码(200 成功,其他失败) | | msg | String | 提示信息 | | token | String | JWT Token | **示例**: ```bash curl -X POST http://localhost:8080/api/system/auth/login \ -H "Content-Type: application/json" \ -d '{"username":"admin","password":"123456","code":"1234","uuid":"abc123"}' ``` ## 实现要点 ### 关键实现逻辑 #### 1. 登录流程 1. 前端发送登录请求(用户名、密码、验证码) 2. Controller 接收请求,验证验证码 3. Service 查询用户信息 4. 验证用户状态(是否停用) 5. 验证密码(BCrypt 加密比对) 6. 生成 JWT Token 7. 存储 Token 到 Redis 8. 更新用户最后登录 IP 和时间 9. 返回 Token 给前端 #### 2. 登出流程 1. 前端发送登出请求(携带 Token) 2. Controller 接收请求,验证 Token 3. 从 Redis 中删除 Token 4. 返回登出成功 #### 3. 获取用户信息流程 1. 前端发送请求(携带 Token) 2. Controller 接收请求,验证 Token 3. 从 Token 中解析用户 ID 4. Service 查询用户信息 5. Service 查询用户角色和权限 6. 返回用户信息、角色、权限 ### 异常处理 #### 1. 验证码错误 - 异常类型:`CaptchaException` - 异常信息:"验证码错误" - 处理方式:返回错误码 500,提示用户重新输入验证码 #### 2. 用户不存在 - 异常类型:`UserNotExistsException` - 异常信息:"用户不存在" - 处理方式:返回错误码 500,提示用户检查用户名 #### 3. 密码错误 - 异常类型:`UserPasswordNotMatchException` - 异常信息:"用户密码错误" - 处理方式:返回错误码 500,提示用户检查密码 #### 4. 用户已停用 - 异常类型:`UserDeletedException` - 异常信息:"用户已停用" - 处理方式:返回错误码 500,提示用户联系管理员 ### 性能优化 #### 1. 缓存优化 - 使用 Redis 缓存用户信息,减少数据库查询 - 缓存过期时间:30 分钟 #### 2. 数据库优化 - 在 `sys_user` 表的 `user_name` 字段上创建索引 - 使用 MyBatis Plus 的分页插件,避免全表扫描 #### 3. Token 优化 - Token 有效期设置为 2 小时,避免频繁登录 - 使用 Redis 存储 Token,实现单点登录 ### 安全设计 #### 1. 密码加密 - 使用 BCrypt 加密算法,加密强度为 10 - 密码在数据库中存储为加密后的字符串 #### 2. Token 安全 - 使用 JWT 生成 Token,包含用户 ID、用户名、角色、权限 - Token 有效期为 2 小时,过期后需要重新登录 - Token 存储在 Redis 中,实现单点登录 #### 3. 防注入 - 使用 MyBatis Plus 的预编译 SQL,防止 SQL 注入 - 使用 Spring Security 的 CSRF 防护,防止 CSRF 攻击 - 使用 XSS 过滤器,防止 XSS 攻击 ## 相关文档 - [需求文档](../requirements/2026-01-21-001-用户登录功能.md) - [决策记录](../decisions/2026-01-21-001-ADR-用户登录功能-技术选型.md) ``` --- ## 附录:快速参考 ### 文件路径速查 - 需求文档:`docs/requirements/YYYY-MM-DD-00X-需求名.md` - 设计文档:`docs/design/YYYY-MM-DD-00X-设计名.md` - 主索引:`docs/index.md` - 会话记录:`docs/sessions/YYYY-MM-DD-00X-session.md` - 项目规则:`.trae/rules/project_rules.md` - SSOT 架构师提示词:`docs/Prompt/0004-单一真源文档驱动架构师.md` ### 工具命令速查 ```powershell # 读取需求文档 Read(file_path="d:\\idea_demo\\datai\\docs\\requirements\\2026-01-21-001-用户登录功能.md") # 创建设计文档 Write(file_path="d:\\idea_demo\\datai\\docs\\design\\2026-01-21-001-用户登录功能-设计.md", content="...") # 读取索引 Read(file_path="d:\\idea_demo\\datai\\docs\\index.md") # 更新索引 Write(file_path="d:\\idea_demo\\datai\\docs\\index.md", content="...") # 搜索现有代码 SearchCodebase(information_request="查找 datai-modules-system 模块下的 Controller 类") # 查找所有设计文档 Glob(pattern="docs/design/*.md") ``` ### 阶段 2 输出清单 - [ ] 设计文档:`docs/design/YYYY-MM-DD-00X-设计名.md` - [ ] 更新的索引:`docs/index.md` - [ ] 更新的需求文档:`docs/requirements/YYYY-MM-DD-00X-需求名.md` - [ ] 更新的会话记录:`docs/sessions/YYYY-MM-DD-00X-session.md` ### 下一阶段提示 如果用户确认进入下一阶段,请参考: - [project_rules.md](file:///d:\idea_demo\datai\.trae\rules\project_rules.md) 的"阶段 3:方案决策" - 准备创建决策记录(ADR) - 准备分析至少两种技术方案 - 准备记录最终决策和理由