datai/docs/skill/phase2-design.md
Kris b7163d555b feat: 实现动态数据源延迟加载功能 (2026-01-21-001)
## 功能概述
- 实现动态数据源的延迟加载机制,支持应用启动时只加载主库,从库按需动态加载和切换
- 从库配置存储在主库中,支持运行时灵活切换从库库名
- 使用现有的 @DataSource 注解进行数据源切换,业务代码无需修改

## 新增功能
- 动态数据源管理接口 IDynamicDataSourceManager
- 动态数据源服务接口 IDynamicDataSourceService
- 动态数据源服务实现 DynamicDataSourceServiceImpl
- 数据源管理控制器 DatasourceController
- 数据源配置表 sys_datasource_config

## 新增文档
- 需求文档: docs/requirements/2026-01-21-001-动态数据源延迟加载.md
- 设计文档: docs/design/2026-01-21-001-动态数据源延迟加载设计.md
- 决策记录: docs/decisions/2026-01-21-001-ADR-动态数据源延迟加载.md
- SQL 脚本: docs/sql/2026-01-21-001-sys_datasource_config.sql
- 提示词: docs/prompts/2026-01-21-001-动态数据源延迟加载代码生成提示词.md
- 会话记录: docs/sessions/2026-01-21-001-session.md
- 变更日志: docs/changelog/2026-01-21-001-changelog.md
- 复盘文档: docs/retros/2026-01-21-001-retro.md
- API 文档: docs/api-docs/2026-01-21-001-api.md
- 根目录变更日志: CHANGELOG.md

## 修改功能
- 扩展 DataSourceManager 类,添加动态数据源管理方法
- 扩展 SysDatasourceConfigMapper 接口,添加 selectSysDatasourceConfigByDsName 方法
- 更新项目索引和 Authentication.canvas

## 修复问题
- 修复循环依赖问题:创建 IDynamicDataSourceManager 接口解决 datai-system 和 datai-framework 互相依赖
- 修复导入错误:删除 DynamicDataSourceServiceImpl 中未使用的导入
- 修复异常处理:将 setFilters() 调用移到 try-catch 块内

## API 接口
- POST /system/datasource/loadSlave - 加载从库数据源
- POST /system/datasource/switchSlave/{dbName} - 切换从库库名
- GET /system/datasource/getSlaveConfig - 获取从库配置
- POST /system/datasource/switch/{dsName} - 切换数据源
- DELETE /system/datasource/{dsName} - 移除数据源
2026-01-21 18:24:24 +08:00

924 lines
28 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 阶段 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
- 准备分析至少两种技术方案
- 准备记录最终决策和理由