temp
This commit is contained in:
1606
docs/企业认证系统实施计划.md
Normal file
1606
docs/企业认证系统实施计划.md
Normal file
File diff suppressed because it is too large
Load Diff
568
docs/应用服务层改造TODO.md
Normal file
568
docs/应用服务层改造TODO.md
Normal file
@@ -0,0 +1,568 @@
|
||||
# 应用服务层改造 TODO 清单
|
||||
|
||||
## 📋 总体进度
|
||||
|
||||
- [ ] 阶段一:基础架构搭建 (0/4)
|
||||
- [ ] 阶段二:用户域改造 (0/4)
|
||||
- [ ] 阶段三:认证域改造 (0/4)
|
||||
- [ ] 阶段四:财务域改造 (0/4)
|
||||
- [ ] 阶段五:管理员域改造 (0/3)
|
||||
- [ ] 阶段六:整体优化 (0/4)
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ 阶段一:基础架构搭建
|
||||
|
||||
### 1.1 创建新的目录结构
|
||||
|
||||
- [ ] 创建 `internal/application/` 目录
|
||||
- [ ] 创建 `internal/infrastructure/` 目录
|
||||
- [ ] 创建应用服务层子目录结构
|
||||
- [ ] `internal/application/user/`
|
||||
- [ ] `internal/application/certification/`
|
||||
- [ ] `internal/application/finance/`
|
||||
- [ ] `internal/application/admin/`
|
||||
- [ ] 创建基础设施层子目录结构
|
||||
- [ ] `internal/infrastructure/http/`
|
||||
- [ ] `internal/infrastructure/database/`
|
||||
- [ ] `internal/infrastructure/cache/`
|
||||
- [ ] `internal/infrastructure/external/`
|
||||
- [ ] `internal/infrastructure/config/`
|
||||
|
||||
### 1.2 移动现有组件到基础设施层
|
||||
|
||||
- [ ] 移动 HTTP 处理器
|
||||
- [ ] 移动 `domains/user/handlers/` → `infrastructure/http/handlers/`
|
||||
- [ ] 移动 `domains/certification/handlers/` → `infrastructure/http/handlers/`
|
||||
- [ ] 移动 `domains/finance/handlers/` → `infrastructure/http/handlers/`
|
||||
- [ ] 移动 `domains/admin/handlers/` → `infrastructure/http/handlers/`
|
||||
- [ ] 移动路由
|
||||
- [ ] 移动 `domains/user/routes/` → `infrastructure/http/routes/`
|
||||
- [ ] 移动 `domains/certification/routes/` → `infrastructure/http/routes/`
|
||||
- [ ] 移动 `domains/finance/routes/` → `infrastructure/http/routes/`
|
||||
- [ ] 移动 `domains/admin/routes/` → `infrastructure/http/routes/`
|
||||
- [ ] 移动中间件
|
||||
- [ ] 移动 `shared/middleware/` → `infrastructure/http/middleware/`
|
||||
- [ ] 移动仓储实现
|
||||
- [ ] 移动 `domains/user/repositories/` → `infrastructure/database/repositories/user/`
|
||||
- [ ] 移动 `domains/certification/repositories/` → `infrastructure/database/repositories/certification/`
|
||||
- [ ] 移动 `domains/finance/repositories/` → `infrastructure/database/repositories/finance/`
|
||||
- [ ] 移动 `domains/admin/repositories/` → `infrastructure/database/repositories/admin/`
|
||||
- [ ] 移动外部服务
|
||||
- [ ] 移动 `shared/sms/` → `infrastructure/external/sms/`
|
||||
- [ ] 移动 `shared/ocr/` → `infrastructure/external/ocr/`
|
||||
- [ ] 移动 `shared/storage/` → `infrastructure/external/storage/`
|
||||
- [ ] 移动 `shared/notification/` → `infrastructure/external/notification/`
|
||||
|
||||
### 1.3 更新导入路径
|
||||
|
||||
- [ ] 更新所有移动文件的导入路径
|
||||
- [ ] 更新 `container/container.go` 中的导入路径
|
||||
- [ ] 更新 `app/app.go` 中的导入路径
|
||||
- [ ] 检查并修复所有编译错误
|
||||
|
||||
### 1.4 确保项目能正常启动
|
||||
|
||||
- [ ] 运行 `go mod tidy` 整理依赖
|
||||
- [ ] 编译项目确保无错误
|
||||
- [ ] 启动项目确保能正常运行
|
||||
- [ ] 运行基础功能测试
|
||||
|
||||
---
|
||||
|
||||
## 👤 阶段二:用户域改造
|
||||
|
||||
### 2.1 创建用户应用服务基础结构
|
||||
|
||||
- [ ] 创建 `internal/application/user/user_application_service.go`
|
||||
- [ ] 创建命令对象
|
||||
- [ ] `internal/application/user/dto/commands/register_user_command.go`
|
||||
- [ ] `internal/application/user/dto/commands/login_user_command.go`
|
||||
- [ ] `internal/application/user/dto/commands/change_password_command.go`
|
||||
- [ ] 创建查询对象
|
||||
- [ ] `internal/application/user/dto/queries/get_user_profile_query.go`
|
||||
- [ ] 创建响应对象
|
||||
- [ ] `internal/application/user/dto/responses/register_user_response.go`
|
||||
- [ ] `internal/application/user/dto/responses/login_user_response.go`
|
||||
- [ ] `internal/application/user/dto/responses/user_profile_response.go`
|
||||
- [ ] 创建应用事件
|
||||
- [ ] `internal/application/user/events/user_application_events.go`
|
||||
|
||||
### 2.2 实现用户应用服务逻辑
|
||||
|
||||
- [ ] 实现 `RegisterUser` 方法
|
||||
- [ ] 验证短信验证码
|
||||
- [ ] 检查手机号是否已存在
|
||||
- [ ] 创建用户实体
|
||||
- [ ] 保存用户
|
||||
- [ ] 发布用户注册事件
|
||||
- [ ] 实现 `LoginUser` 方法
|
||||
- [ ] 支持密码登录
|
||||
- [ ] 支持短信登录
|
||||
- [ ] 发布用户登录事件
|
||||
- [ ] 实现 `ChangePassword` 方法
|
||||
- [ ] 验证短信验证码
|
||||
- [ ] 验证旧密码
|
||||
- [ ] 更新密码
|
||||
- [ ] 发布密码修改事件
|
||||
- [ ] 实现 `GetUserProfile` 方法
|
||||
- [ ] 获取用户信息
|
||||
- [ ] 返回脱敏信息
|
||||
|
||||
### 2.3 重构用户 HTTP 处理器
|
||||
|
||||
- [ ] 修改 `infrastructure/http/handlers/user_handler.go`
|
||||
- [ ] 将 HTTP 处理器改为调用应用服务
|
||||
- [ ] 简化 HTTP 处理器的职责
|
||||
- [ ] 保持 API 接口不变
|
||||
- [ ] 更新错误处理
|
||||
|
||||
### 2.4 更新依赖注入配置
|
||||
|
||||
- [ ] 在 `container/container.go` 中注册用户应用服务
|
||||
- [ ] 更新用户 HTTP 处理器的依赖
|
||||
- [ ] 确保向后兼容
|
||||
|
||||
### 2.5 测试用户相关功能
|
||||
|
||||
- [ ] 测试用户注册功能
|
||||
- [ ] 测试用户登录功能(密码/短信)
|
||||
- [ ] 测试密码修改功能
|
||||
- [ ] 测试用户信息查询功能
|
||||
- [ ] 验证 API 接口兼容性
|
||||
|
||||
---
|
||||
|
||||
## 🏢 阶段三:认证域改造
|
||||
|
||||
### 3.1 创建认证应用服务基础结构
|
||||
|
||||
- [ ] 创建 `internal/application/certification/certification_application_service.go`
|
||||
- [ ] 创建命令对象
|
||||
- [ ] `internal/application/certification/dto/commands/create_certification_command.go`
|
||||
- [ ] `internal/application/certification/dto/commands/submit_enterprise_info_command.go`
|
||||
- [ ] `internal/application/certification/dto/commands/upload_license_command.go`
|
||||
- [ ] `internal/application/certification/dto/commands/initiate_face_verify_command.go`
|
||||
- [ ] `internal/application/certification/dto/commands/apply_contract_command.go`
|
||||
- [ ] 创建查询对象
|
||||
- [ ] `internal/application/certification/dto/queries/get_certification_status_query.go`
|
||||
- [ ] `internal/application/certification/dto/queries/get_certification_details_query.go`
|
||||
- [ ] 创建响应对象
|
||||
- [ ] `internal/application/certification/dto/responses/certification_response.go`
|
||||
- [ ] `internal/application/certification/dto/responses/enterprise_info_response.go`
|
||||
- [ ] `internal/application/certification/dto/responses/upload_license_response.go`
|
||||
- [ ] 创建应用事件
|
||||
- [ ] `internal/application/certification/events/certification_application_events.go`
|
||||
|
||||
### 3.2 实现认证应用服务逻辑
|
||||
|
||||
- [ ] 实现 `CreateCertification` 方法
|
||||
- [ ] 检查用户是否已有认证申请
|
||||
- [ ] 创建认证申请
|
||||
- [ ] 发布认证创建事件
|
||||
- [ ] 实现 `SubmitEnterpriseInfo` 方法
|
||||
- [ ] 验证认证状态
|
||||
- [ ] 检查统一社会信用代码
|
||||
- [ ] 创建企业信息
|
||||
- [ ] 更新认证状态
|
||||
- [ ] 发布企业信息提交事件
|
||||
- [ ] 实现 `UploadLicense` 方法
|
||||
- [ ] 上传文件到存储服务
|
||||
- [ ] 创建上传记录
|
||||
- [ ] 进行 OCR 识别
|
||||
- [ ] 发布营业执照上传事件
|
||||
- [ ] 实现 `InitiateFaceVerify` 方法
|
||||
- [ ] 验证认证状态
|
||||
- [ ] 调用人脸识别服务
|
||||
- [ ] 更新认证状态
|
||||
- [ ] 发布人脸识别事件
|
||||
- [ ] 实现 `ApplyContract` 方法
|
||||
- [ ] 验证认证状态
|
||||
- [ ] 申请电子合同
|
||||
- [ ] 更新认证状态
|
||||
- [ ] 发布合同申请事件
|
||||
|
||||
### 3.3 重构认证 HTTP 处理器
|
||||
|
||||
- [ ] 修改 `infrastructure/http/handlers/certification_handler.go`
|
||||
- [ ] 将 HTTP 处理器改为调用应用服务
|
||||
- [ ] 简化 HTTP 处理器的职责
|
||||
- [ ] 保持 API 接口不变
|
||||
- [ ] 更新错误处理
|
||||
|
||||
### 3.4 处理跨域协调逻辑
|
||||
|
||||
- [ ] 在应用服务中协调用户域和认证域
|
||||
- [ ] 确保数据一致性
|
||||
- [ ] 处理跨域事件
|
||||
|
||||
### 3.5 测试认证流程
|
||||
|
||||
- [ ] 测试创建认证申请
|
||||
- [ ] 测试提交企业信息
|
||||
- [ ] 测试上传营业执照
|
||||
- [ ] 测试人脸识别流程
|
||||
- [ ] 测试合同申请流程
|
||||
- [ ] 验证完整认证流程
|
||||
|
||||
---
|
||||
|
||||
## 💰 阶段四:财务域改造
|
||||
|
||||
### 4.1 创建财务应用服务基础结构
|
||||
|
||||
- [ ] 创建 `internal/application/finance/finance_application_service.go`
|
||||
- [ ] 创建命令对象
|
||||
- [ ] `internal/application/finance/dto/commands/create_wallet_command.go`
|
||||
- [ ] `internal/application/finance/dto/commands/recharge_wallet_command.go`
|
||||
- [ ] `internal/application/finance/dto/commands/withdraw_wallet_command.go`
|
||||
- [ ] `internal/application/finance/dto/commands/create_user_secrets_command.go`
|
||||
- [ ] `internal/application/finance/dto/commands/regenerate_access_key_command.go`
|
||||
- [ ] 创建查询对象
|
||||
- [ ] `internal/application/finance/dto/queries/get_wallet_info_query.go`
|
||||
- [ ] `internal/application/finance/dto/queries/get_user_secrets_query.go`
|
||||
- [ ] 创建响应对象
|
||||
- [ ] `internal/application/finance/dto/responses/wallet_response.go`
|
||||
- [ ] `internal/application/finance/dto/responses/transaction_response.go`
|
||||
- [ ] `internal/application/finance/dto/responses/user_secrets_response.go`
|
||||
- [ ] 创建应用事件
|
||||
- [ ] `internal/application/finance/events/finance_application_events.go`
|
||||
|
||||
### 4.2 实现财务应用服务逻辑
|
||||
|
||||
- [ ] 实现 `CreateWallet` 方法
|
||||
- [ ] 检查用户是否已有钱包
|
||||
- [ ] 创建钱包
|
||||
- [ ] 发布钱包创建事件
|
||||
- [ ] 实现 `RechargeWallet` 方法
|
||||
- [ ] 验证金额
|
||||
- [ ] 检查钱包状态
|
||||
- [ ] 增加余额
|
||||
- [ ] 发布充值事件
|
||||
- [ ] 实现 `WithdrawWallet` 方法
|
||||
- [ ] 验证金额
|
||||
- [ ] 检查余额是否足够
|
||||
- [ ] 减少余额
|
||||
- [ ] 发布提现事件
|
||||
- [ ] 实现 `CreateUserSecrets` 方法
|
||||
- [ ] 生成访问密钥
|
||||
- [ ] 创建用户密钥
|
||||
- [ ] 发布密钥创建事件
|
||||
- [ ] 实现 `RegenerateAccessKey` 方法
|
||||
- [ ] 验证用户密钥
|
||||
- [ ] 重新生成访问密钥
|
||||
- [ ] 发布密钥更新事件
|
||||
|
||||
### 4.3 添加事务管理
|
||||
|
||||
- [ ] 在应用服务中添加事务边界
|
||||
- [ ] 确保资金操作的数据一致性
|
||||
- [ ] 处理事务回滚
|
||||
|
||||
### 4.4 重构财务 HTTP 处理器
|
||||
|
||||
- [ ] 修改 `infrastructure/http/handlers/finance_handler.go`
|
||||
- [ ] 将 HTTP 处理器改为调用应用服务
|
||||
- [ ] 简化 HTTP 处理器的职责
|
||||
- [ ] 保持 API 接口不变
|
||||
- [ ] 更新错误处理
|
||||
|
||||
### 4.5 测试财务功能
|
||||
|
||||
- [ ] 测试创建钱包
|
||||
- [ ] 测试钱包充值
|
||||
- [ ] 测试钱包提现
|
||||
- [ ] 测试创建用户密钥
|
||||
- [ ] 测试重新生成访问密钥
|
||||
- [ ] 验证资金安全
|
||||
|
||||
---
|
||||
|
||||
## 👨💼 阶段五:管理员域改造
|
||||
|
||||
### 5.1 创建管理员应用服务基础结构
|
||||
|
||||
- [ ] 创建 `internal/application/admin/admin_application_service.go`
|
||||
- [ ] 创建命令对象
|
||||
- [ ] `internal/application/admin/dto/commands/admin_login_command.go`
|
||||
- [ ] `internal/application/admin/dto/commands/create_admin_command.go`
|
||||
- [ ] `internal/application/admin/dto/commands/update_admin_command.go`
|
||||
- [ ] `internal/application/admin/dto/commands/change_admin_password_command.go`
|
||||
- [ ] 创建查询对象
|
||||
- [ ] `internal/application/admin/dto/queries/get_admin_info_query.go`
|
||||
- [ ] `internal/application/admin/dto/queries/list_admins_query.go`
|
||||
- [ ] 创建响应对象
|
||||
- [ ] `internal/application/admin/dto/responses/admin_login_response.go`
|
||||
- [ ] `internal/application/admin/dto/responses/admin_info_response.go`
|
||||
- [ ] `internal/application/admin/dto/responses/admin_list_response.go`
|
||||
- [ ] 创建应用事件
|
||||
- [ ] `internal/application/admin/events/admin_application_events.go`
|
||||
|
||||
### 5.2 实现管理员应用服务逻辑
|
||||
|
||||
- [ ] 实现 `AdminLogin` 方法
|
||||
- [ ] 验证管理员凭据
|
||||
- [ ] 生成 JWT 令牌
|
||||
- [ ] 记录登录日志
|
||||
- [ ] 发布管理员登录事件
|
||||
- [ ] 实现 `CreateAdmin` 方法
|
||||
- [ ] 检查用户名和邮箱唯一性
|
||||
- [ ] 加密密码
|
||||
- [ ] 创建管理员
|
||||
- [ ] 记录操作日志
|
||||
- [ ] 发布管理员创建事件
|
||||
- [ ] 实现 `UpdateAdmin` 方法
|
||||
- [ ] 验证管理员存在
|
||||
- [ ] 更新管理员信息
|
||||
- [ ] 记录操作日志
|
||||
- [ ] 发布管理员更新事件
|
||||
- [ ] 实现 `ChangeAdminPassword` 方法
|
||||
- [ ] 验证旧密码
|
||||
- [ ] 更新密码
|
||||
- [ ] 记录操作日志
|
||||
- [ ] 发布密码修改事件
|
||||
|
||||
### 5.3 重构管理员 HTTP 处理器
|
||||
|
||||
- [ ] 修改 `infrastructure/http/handlers/admin_handler.go`
|
||||
- [ ] 将 HTTP 处理器改为调用应用服务
|
||||
- [ ] 简化 HTTP 处理器的职责
|
||||
- [ ] 保持 API 接口不变
|
||||
- [ ] 更新错误处理
|
||||
|
||||
### 5.4 测试管理功能
|
||||
|
||||
- [ ] 测试管理员登录
|
||||
- [ ] 测试创建管理员
|
||||
- [ ] 测试更新管理员
|
||||
- [ ] 测试修改管理员密码
|
||||
- [ ] 测试管理员信息查询
|
||||
- [ ] 验证权限控制
|
||||
|
||||
---
|
||||
|
||||
## 🔧 阶段六:整体优化
|
||||
|
||||
### 6.1 添加应用事件处理
|
||||
|
||||
- [ ] 实现应用事件发布机制
|
||||
- [ ] 添加应用事件处理器
|
||||
- [ ] 处理跨域事件协调
|
||||
- [ ] 添加事件持久化
|
||||
|
||||
### 6.2 完善监控和日志
|
||||
|
||||
- [ ] 添加应用服务层的日志记录
|
||||
- [ ] 完善错误处理和监控
|
||||
- [ ] 添加性能指标收集
|
||||
- [ ] 优化日志格式和级别
|
||||
|
||||
### 6.3 性能优化
|
||||
|
||||
- [ ] 优化数据库查询
|
||||
- [ ] 添加缓存策略
|
||||
- [ ] 优化并发处理
|
||||
- [ ] 添加连接池配置
|
||||
|
||||
### 6.4 文档更新
|
||||
|
||||
- [ ] 更新 API 文档
|
||||
- [ ] 更新架构文档
|
||||
- [ ] 更新开发指南
|
||||
- [ ] 添加部署文档
|
||||
|
||||
---
|
||||
|
||||
## 📝 开发指南
|
||||
|
||||
### 应用服务层开发模式
|
||||
|
||||
#### 1. 应用服务结构
|
||||
|
||||
```go
|
||||
type UserApplicationService struct {
|
||||
userService *services.UserService
|
||||
smsCodeService *services.SMSCodeService
|
||||
eventBus interfaces.EventBus
|
||||
logger *zap.Logger
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. 命令对象模式
|
||||
|
||||
```go
|
||||
type RegisterUserCommand struct {
|
||||
Phone string `json:"phone" binding:"required,len=11"`
|
||||
Password string `json:"password" binding:"required,min=6,max=128"`
|
||||
ConfirmPassword string `json:"confirm_password" binding:"required,eqfield=Password"`
|
||||
Code string `json:"code" binding:"required,len=6"`
|
||||
|
||||
// 应用层上下文信息
|
||||
CorrelationID string `json:"-"`
|
||||
ClientIP string `json:"-"`
|
||||
UserAgent string `json:"-"`
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. 查询对象模式
|
||||
|
||||
```go
|
||||
type GetUserProfileQuery struct {
|
||||
UserID string `json:"-"`
|
||||
}
|
||||
```
|
||||
|
||||
#### 4. 响应对象模式
|
||||
|
||||
```go
|
||||
type RegisterUserResponse struct {
|
||||
UserID string `json:"user_id"`
|
||||
Phone string `json:"phone"`
|
||||
RegisteredAt time.Time `json:"registered_at"`
|
||||
}
|
||||
```
|
||||
|
||||
#### 5. 应用事件模式
|
||||
|
||||
```go
|
||||
type UserRegisteredApplicationEvent struct {
|
||||
ID string `json:"id"`
|
||||
UserID string `json:"user_id"`
|
||||
Phone string `json:"phone"`
|
||||
RegisteredAt time.Time `json:"registered_at"`
|
||||
CorrelationID string `json:"correlation_id"`
|
||||
ClientIP string `json:"client_ip"`
|
||||
UserAgent string `json:"user_agent"`
|
||||
}
|
||||
```
|
||||
|
||||
### 业务逻辑编写指南
|
||||
|
||||
#### 1. 应用服务方法结构
|
||||
|
||||
```go
|
||||
func (s *UserApplicationService) RegisterUser(ctx context.Context, cmd *dto.RegisterUserCommand) (*dto.RegisterUserResponse, error) {
|
||||
// 1. 参数验证
|
||||
// 2. 业务规则检查
|
||||
// 3. 调用域服务
|
||||
// 4. 事务处理
|
||||
// 5. 发布事件
|
||||
// 6. 返回结果
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. 错误处理模式
|
||||
|
||||
```go
|
||||
if err != nil {
|
||||
s.logger.Error("操作失败", zap.Error(err))
|
||||
return nil, fmt.Errorf("操作失败: %w", err)
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. 事件发布模式
|
||||
|
||||
```go
|
||||
event := &dto.UserRegisteredApplicationEvent{
|
||||
ID: uuid.New().String(),
|
||||
UserID: user.ID,
|
||||
Phone: user.Phone,
|
||||
RegisteredAt: time.Now(),
|
||||
CorrelationID: cmd.CorrelationID,
|
||||
ClientIP: cmd.ClientIP,
|
||||
UserAgent: cmd.UserAgent,
|
||||
}
|
||||
|
||||
if err := s.eventBus.Publish(ctx, event); err != nil {
|
||||
s.logger.Warn("发布事件失败", zap.Error(err))
|
||||
}
|
||||
```
|
||||
|
||||
#### 4. 事务管理模式
|
||||
|
||||
```go
|
||||
// 在应用服务中使用事务
|
||||
tx := s.db.Begin()
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
tx.Rollback()
|
||||
}
|
||||
}()
|
||||
|
||||
// 执行业务操作
|
||||
if err := s.userService.CreateUser(ctx, user); err != nil {
|
||||
tx.Rollback()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := tx.Commit().Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
```
|
||||
|
||||
### 测试指南
|
||||
|
||||
#### 1. 单元测试
|
||||
|
||||
```go
|
||||
func TestUserApplicationService_RegisterUser(t *testing.T) {
|
||||
// 准备测试数据
|
||||
// 执行测试
|
||||
// 验证结果
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. 集成测试
|
||||
|
||||
```go
|
||||
func TestUserRegistrationFlow(t *testing.T) {
|
||||
// 测试完整流程
|
||||
// 验证数据库状态
|
||||
// 验证事件发布
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 快速开始
|
||||
|
||||
### 第一步:备份当前代码
|
||||
|
||||
```bash
|
||||
git checkout -b feature/application-service-layer
|
||||
git add .
|
||||
git commit -m "备份当前代码状态"
|
||||
```
|
||||
|
||||
### 第二步:开始阶段一
|
||||
|
||||
按照 TODO 清单逐步执行阶段一的任务。
|
||||
|
||||
### 第三步:验证改造
|
||||
|
||||
每个阶段完成后,确保:
|
||||
|
||||
- 项目能正常编译
|
||||
- 项目能正常启动
|
||||
- 基础功能正常工作
|
||||
- 测试通过
|
||||
|
||||
### 第四步:提交代码
|
||||
|
||||
每个阶段完成后提交代码:
|
||||
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "完成阶段X:XXX改造"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📞 支持
|
||||
|
||||
如果在改造过程中遇到问题:
|
||||
|
||||
1. 检查 TODO 清单是否遗漏
|
||||
2. 查看相关文档
|
||||
3. 运行测试验证
|
||||
4. 回滚到上一个稳定版本
|
||||
340
docs/应用服务层改造计划.md
Normal file
340
docs/应用服务层改造计划.md
Normal file
@@ -0,0 +1,340 @@
|
||||
# 应用服务层改造计划
|
||||
|
||||
## 📋 项目概述
|
||||
|
||||
### 当前项目状态
|
||||
|
||||
- **项目名称**: TYAPI Server (Gin 框架)
|
||||
- **当前架构**: DDD 领域驱动设计(不完整)
|
||||
- **现有域**: 用户域、认证域、财务域、管理员域
|
||||
- **主要问题**: HTTP 处理器直接调用域服务,缺乏应用服务层
|
||||
|
||||
### 改造目标
|
||||
|
||||
- 完善 DDD 分层架构
|
||||
- 添加应用服务层
|
||||
- 重构基础设施层
|
||||
- 提高代码可维护性和可测试性
|
||||
|
||||
## 🏗️ 目标架构设计
|
||||
|
||||
### 改造后的目录结构
|
||||
|
||||
```
|
||||
internal/
|
||||
├── application/ # 应用服务层 (Application Services Layer)
|
||||
│ ├── user/
|
||||
│ │ ├── user_application_service.go
|
||||
│ │ ├── dto/
|
||||
│ │ │ ├── commands/
|
||||
│ │ │ │ ├── register_user_command.go
|
||||
│ │ │ │ ├── login_user_command.go
|
||||
│ │ │ │ └── change_password_command.go
|
||||
│ │ │ ├── queries/
|
||||
│ │ │ │ └── get_user_profile_query.go
|
||||
│ │ │ └── responses/
|
||||
│ │ │ ├── register_user_response.go
|
||||
│ │ │ ├── login_user_response.go
|
||||
│ │ │ └── user_profile_response.go
|
||||
│ │ └── events/
|
||||
│ │ └── user_application_events.go
|
||||
│ ├── certification/
|
||||
│ │ ├── certification_application_service.go
|
||||
│ │ ├── dto/
|
||||
│ │ │ ├── commands/
|
||||
│ │ │ │ ├── create_certification_command.go
|
||||
│ │ │ │ ├── submit_enterprise_info_command.go
|
||||
│ │ │ │ ├── upload_license_command.go
|
||||
│ │ │ │ ├── initiate_face_verify_command.go
|
||||
│ │ │ │ └── apply_contract_command.go
|
||||
│ │ │ ├── queries/
|
||||
│ │ │ │ ├── get_certification_status_query.go
|
||||
│ │ │ │ └── get_certification_details_query.go
|
||||
│ │ │ └── responses/
|
||||
│ │ │ ├── certification_response.go
|
||||
│ │ │ ├── enterprise_info_response.go
|
||||
│ │ │ └── upload_license_response.go
|
||||
│ │ └── events/
|
||||
│ │ └── certification_application_events.go
|
||||
│ ├── finance/
|
||||
│ │ ├── finance_application_service.go
|
||||
│ │ ├── dto/
|
||||
│ │ │ ├── commands/
|
||||
│ │ │ │ ├── create_wallet_command.go
|
||||
│ │ │ │ ├── recharge_wallet_command.go
|
||||
│ │ │ │ ├── withdraw_wallet_command.go
|
||||
│ │ │ │ ├── create_user_secrets_command.go
|
||||
│ │ │ │ └── regenerate_access_key_command.go
|
||||
│ │ │ ├── queries/
|
||||
│ │ │ │ ├── get_wallet_info_query.go
|
||||
│ │ │ │ └── get_user_secrets_query.go
|
||||
│ │ │ └── responses/
|
||||
│ │ │ ├── wallet_response.go
|
||||
│ │ │ ├── transaction_response.go
|
||||
│ │ │ └── user_secrets_response.go
|
||||
│ │ └── events/
|
||||
│ │ └── finance_application_events.go
|
||||
│ └── admin/
|
||||
│ ├── admin_application_service.go
|
||||
│ ├── dto/
|
||||
│ │ ├── commands/
|
||||
│ │ │ ├── admin_login_command.go
|
||||
│ │ │ ├── create_admin_command.go
|
||||
│ │ │ ├── update_admin_command.go
|
||||
│ │ │ └── change_admin_password_command.go
|
||||
│ │ ├── queries/
|
||||
│ │ │ ├── get_admin_info_query.go
|
||||
│ │ │ └── list_admins_query.go
|
||||
│ │ └── responses/
|
||||
│ │ ├── admin_login_response.go
|
||||
│ │ ├── admin_info_response.go
|
||||
│ │ └── admin_list_response.go
|
||||
│ └── events/
|
||||
│ └── admin_application_events.go
|
||||
├── domains/ # 领域层 (Domain Layer) - 保持不变
|
||||
│ ├── user/
|
||||
│ │ ├── entities/
|
||||
│ │ ├── services/
|
||||
│ │ ├── repositories/
|
||||
│ │ ├── dto/
|
||||
│ │ └── events/
|
||||
│ ├── certification/
|
||||
│ │ ├── entities/
|
||||
│ │ ├── services/
|
||||
│ │ ├── repositories/
|
||||
│ │ ├── dto/
|
||||
│ │ ├── events/
|
||||
│ │ └── enums/
|
||||
│ ├── finance/
|
||||
│ │ ├── entities/
|
||||
│ │ ├── services/
|
||||
│ │ ├── repositories/
|
||||
│ │ ├── dto/
|
||||
│ │ └── value_objects/
|
||||
│ └── admin/
|
||||
│ ├── entities/
|
||||
│ ├── services/
|
||||
│ ├── repositories/
|
||||
│ └── dto/
|
||||
├── infrastructure/ # 基础设施层 (Infrastructure Layer) - 新增
|
||||
│ ├── http/
|
||||
│ │ ├── handlers/
|
||||
│ │ │ ├── user_handler.go # 从 domains/user/handlers/ 移动
|
||||
│ │ │ ├── certification_handler.go # 从 domains/certification/handlers/ 移动
|
||||
│ │ │ ├── finance_handler.go # 从 domains/finance/handlers/ 移动
|
||||
│ │ │ └── admin_handler.go # 从 domains/admin/handlers/ 移动
|
||||
│ │ ├── middleware/ # 从 shared/middleware/ 移动
|
||||
│ │ │ ├── auth.go
|
||||
│ │ │ ├── cors.go
|
||||
│ │ │ ├── ratelimit.go
|
||||
│ │ │ ├── request_logger.go
|
||||
│ │ │ └── tracing.go
|
||||
│ │ └── routes/
|
||||
│ │ ├── user_routes.go # 从 domains/user/routes/ 移动
|
||||
│ │ ├── certification_routes.go # 从 domains/certification/routes/ 移动
|
||||
│ │ ├── finance_routes.go # 从 domains/finance/routes/ 移动
|
||||
│ │ └── admin_routes.go # 从 domains/admin/routes/ 移动
|
||||
│ ├── database/
|
||||
│ │ ├── repositories/
|
||||
│ │ │ ├── user/
|
||||
│ │ │ │ ├── user_repository.go
|
||||
│ │ │ │ └── sms_code_repository.go
|
||||
│ │ │ ├── certification/
|
||||
│ │ │ │ ├── certification_repository.go
|
||||
│ │ │ │ ├── enterprise_repository.go
|
||||
│ │ │ │ └── license_upload_repository.go
|
||||
│ │ │ ├── finance/
|
||||
│ │ │ │ ├── wallet_repository.go
|
||||
│ │ │ │ └── user_secrets_repository.go
|
||||
│ │ │ └── admin/
|
||||
│ │ │ ├── admin_repository.go
|
||||
│ │ │ └── admin_login_log_repository.go
|
||||
│ │ └── migrations/
|
||||
│ │ ├── user_migrations/
|
||||
│ │ ├── certification_migrations/
|
||||
│ │ ├── finance_migrations/
|
||||
│ │ └── admin_migrations/
|
||||
│ ├── cache/
|
||||
│ │ ├── redis_cache.go
|
||||
│ │ └── memory_cache.go
|
||||
│ ├── external/
|
||||
│ │ ├── sms/
|
||||
│ │ │ └── sms_service.go
|
||||
│ │ ├── ocr/
|
||||
│ │ │ └── baidu_ocr_service.go
|
||||
│ │ ├── storage/
|
||||
│ │ │ └── qiniu_storage_service.go
|
||||
│ │ └── notification/
|
||||
│ │ └── wechat_work_service.go
|
||||
│ └── config/
|
||||
│ ├── database_config.go
|
||||
│ ├── redis_config.go
|
||||
│ └── external_services_config.go
|
||||
├── shared/ # 共享层 (Shared Layer) - 保留核心组件
|
||||
│ ├── interfaces/
|
||||
│ │ ├── service.go
|
||||
│ │ ├── repository.go
|
||||
│ │ ├── event.go
|
||||
│ │ └── http.go
|
||||
│ ├── domain/
|
||||
│ │ └── entity.go
|
||||
│ ├── events/
|
||||
│ │ └── event_bus.go
|
||||
│ ├── logger/
|
||||
│ │ └── logger.go
|
||||
│ ├── metrics/
|
||||
│ │ ├── business_metrics.go
|
||||
│ │ └── prometheus_metrics.go
|
||||
│ ├── resilience/
|
||||
│ │ ├── circuit_breaker.go
|
||||
│ │ └── retry.go
|
||||
│ ├── saga/
|
||||
│ │ └── saga.go
|
||||
│ ├── hooks/
|
||||
│ │ └── hook_system.go
|
||||
│ └── tracing/
|
||||
│ ├── tracer.go
|
||||
│ └── decorators.go
|
||||
├── config/ # 配置层 - 保持不变
|
||||
│ ├── config.go
|
||||
│ └── loader.go
|
||||
├── container/ # 容器层 - 保持不变
|
||||
│ └── container.go
|
||||
└── app/ # 应用层 - 保持不变
|
||||
└── app.go
|
||||
```
|
||||
|
||||
## 📝 各层职责说明
|
||||
|
||||
### 应用服务层 (Application Layer)
|
||||
|
||||
- **职责**: 编排业务用例,管理事务边界,协调跨域操作
|
||||
- **包含**: 应用服务、命令对象、查询对象、响应对象、应用事件
|
||||
- **特点**: 无状态,专注于用例编排
|
||||
|
||||
### 领域层 (Domain Layer)
|
||||
|
||||
- **职责**: 核心业务逻辑,业务规则,领域实体
|
||||
- **包含**: 实体、值对象、域服务、仓储接口、域事件
|
||||
- **特点**: 业务逻辑的核心,与技术实现无关
|
||||
|
||||
### 基础设施层 (Infrastructure Layer)
|
||||
|
||||
- **职责**: 技术实现细节,外部系统集成
|
||||
- **包含**: HTTP 处理器、数据库仓储、缓存、外部服务
|
||||
- **特点**: 实现领域层定义的接口
|
||||
|
||||
### 共享层 (Shared Layer)
|
||||
|
||||
- **职责**: 通用工具、接口定义、跨层共享组件
|
||||
- **包含**: 接口定义、事件总线、日志、监控、追踪
|
||||
- **特点**: 被其他层依赖,但不依赖其他层
|
||||
|
||||
## 🎯 改造优先级
|
||||
|
||||
### 第一优先级:用户域
|
||||
|
||||
- **原因**: 最基础的认证功能,其他域都依赖
|
||||
- **复杂度**: 中等
|
||||
- **影响范围**: 全局
|
||||
|
||||
### 第二优先级:认证域
|
||||
|
||||
- **原因**: 核心业务流程,涉及多个实体协调
|
||||
- **复杂度**: 高
|
||||
- **影响范围**: 用户域、管理员域
|
||||
|
||||
### 第三优先级:财务域
|
||||
|
||||
- **原因**: 涉及资金安全,需要事务管理
|
||||
- **复杂度**: 高
|
||||
- **影响范围**: 用户域
|
||||
|
||||
### 第四优先级:管理员域
|
||||
|
||||
- **原因**: 后台管理功能,相对独立
|
||||
- **复杂度**: 低
|
||||
- **影响范围**: 其他域
|
||||
|
||||
## 📋 实施计划
|
||||
|
||||
### 阶段一:基础架构搭建 (1-2 天)
|
||||
|
||||
1. 创建新的目录结构
|
||||
2. 移动现有组件到基础设施层
|
||||
3. 更新依赖注入配置
|
||||
4. 确保项目能正常启动
|
||||
|
||||
### 阶段二:用户域改造 (2-3 天)
|
||||
|
||||
1. 实现用户应用服务
|
||||
2. 重构用户 HTTP 处理器
|
||||
3. 测试用户相关功能
|
||||
4. 完善错误处理
|
||||
|
||||
### 阶段三:认证域改造 (3-4 天)
|
||||
|
||||
1. 实现认证应用服务
|
||||
2. 重构认证 HTTP 处理器
|
||||
3. 处理跨域协调逻辑
|
||||
4. 测试认证流程
|
||||
|
||||
### 阶段四:财务域改造 (2-3 天)
|
||||
|
||||
1. 实现财务应用服务
|
||||
2. 重构财务 HTTP 处理器
|
||||
3. 添加事务管理
|
||||
4. 测试财务功能
|
||||
|
||||
### 阶段五:管理员域改造 (1-2 天)
|
||||
|
||||
1. 实现管理员应用服务
|
||||
2. 重构管理员 HTTP 处理器
|
||||
3. 测试管理功能
|
||||
|
||||
### 阶段六:整体优化 (2-3 天)
|
||||
|
||||
1. 添加应用事件处理
|
||||
2. 完善监控和日志
|
||||
3. 性能优化
|
||||
4. 文档更新
|
||||
|
||||
## ⚠️ 注意事项
|
||||
|
||||
### 备份策略
|
||||
|
||||
- 每个阶段开始前备份当前代码
|
||||
- 使用 Git 分支进行改造
|
||||
- 保留原始代码作为参考
|
||||
|
||||
### 测试策略
|
||||
|
||||
- 每个域改造完成后进行单元测试
|
||||
- 保持 API 接口兼容性
|
||||
- 进行集成测试验证
|
||||
|
||||
### 回滚策略
|
||||
|
||||
- 如果改造出现问题,可以快速回滚到上一个稳定版本
|
||||
- 保持数据库结构不变
|
||||
- 确保配置文件的兼容性
|
||||
|
||||
## 📊 预期收益
|
||||
|
||||
### 架构改进
|
||||
|
||||
- ✅ 职责分离更清晰
|
||||
- ✅ 代码组织更规范
|
||||
- ✅ 可维护性更强
|
||||
|
||||
### 开发效率
|
||||
|
||||
- ✅ 可测试性更好
|
||||
- ✅ 扩展性更强
|
||||
- ✅ 复用性更高
|
||||
|
||||
### 业务价值
|
||||
|
||||
- ✅ 业务逻辑更清晰
|
||||
- ✅ 跨域协调更简单
|
||||
- ✅ 事务管理更可靠
|
||||
221
docs/用户域实体优化总结.md
Normal file
221
docs/用户域实体优化总结.md
Normal file
@@ -0,0 +1,221 @@
|
||||
# 用户域实体优化总结
|
||||
|
||||
## 🎯 **优化目标**
|
||||
|
||||
将 User 实体从"贫血模型"升级为"充血模型",将业务逻辑从 Service 层迁移到实体层,实现更好的封装和职责分离。
|
||||
|
||||
## ✅ **完成的优化**
|
||||
|
||||
### **1. 实体业务方法增强**
|
||||
|
||||
#### **密码管理方法**
|
||||
|
||||
```go
|
||||
// 修改密码(包含完整的业务验证)
|
||||
func (u *User) ChangePassword(oldPassword, newPassword, confirmPassword string) error
|
||||
|
||||
// 验证密码
|
||||
func (u *User) CheckPassword(password string) bool
|
||||
|
||||
// 设置密码(用于注册或重置)
|
||||
func (u *User) SetPassword(password string) error
|
||||
```
|
||||
|
||||
#### **手机号管理方法**
|
||||
|
||||
```go
|
||||
// 验证手机号格式
|
||||
func (u *User) IsValidPhone() bool
|
||||
|
||||
// 设置手机号(包含格式验证)
|
||||
func (u *User) SetPhone(phone string) error
|
||||
|
||||
// 获取脱敏手机号
|
||||
func (u *User) GetMaskedPhone() string
|
||||
```
|
||||
|
||||
#### **用户状态检查方法**
|
||||
|
||||
```go
|
||||
// 检查用户是否可以登录
|
||||
func (u *User) CanLogin() bool
|
||||
|
||||
// 检查用户是否活跃
|
||||
func (u *User) IsActive() bool
|
||||
|
||||
// 检查用户是否已删除
|
||||
func (u *User) IsDeleted() bool
|
||||
```
|
||||
|
||||
### **2. 业务规则验证**
|
||||
|
||||
#### **密码强度验证**
|
||||
|
||||
- 长度要求:8-128 位
|
||||
- 必须包含数字
|
||||
- 必须包含字母
|
||||
- 必须包含特殊字符
|
||||
|
||||
#### **手机号格式验证**
|
||||
|
||||
- 11 位数字
|
||||
- 以 1 开头
|
||||
- 第二位为 3-9
|
||||
|
||||
#### **业务不变性验证**
|
||||
|
||||
- 新密码不能与旧密码相同
|
||||
- 确认密码必须匹配
|
||||
- 用户状态检查
|
||||
|
||||
### **3. 工厂方法**
|
||||
|
||||
```go
|
||||
// 创建新用户的工厂方法
|
||||
func NewUser(phone, password string) (*User, error)
|
||||
```
|
||||
|
||||
### **4. 静态工具方法**
|
||||
|
||||
```go
|
||||
// 验证手机号格式(静态方法)
|
||||
func IsValidPhoneFormat(phone string) bool
|
||||
|
||||
// 检查是否为验证错误
|
||||
func IsValidationError(err error) bool
|
||||
```
|
||||
|
||||
## 🔄 **Service 层重构**
|
||||
|
||||
### **优化前的问题**
|
||||
|
||||
```go
|
||||
// 业务逻辑集中在Service中
|
||||
func (s *UserService) ChangePassword(ctx context.Context, userID string, req *dto.ChangePasswordRequest) error {
|
||||
// 验证新密码确认
|
||||
if req.NewPassword != req.ConfirmNewPassword { ... }
|
||||
|
||||
// 验证当前密码
|
||||
if !s.checkPassword(req.OldPassword, user.Password) { ... }
|
||||
|
||||
// 哈希新密码
|
||||
hashedPassword, err := s.hashPassword(req.NewPassword)
|
||||
|
||||
// 更新密码
|
||||
user.Password = hashedPassword
|
||||
return s.repo.Update(ctx, user)
|
||||
}
|
||||
```
|
||||
|
||||
### **优化后的改进**
|
||||
|
||||
```go
|
||||
// Service只负责协调,业务逻辑委托给实体
|
||||
func (s *UserService) ChangePassword(ctx context.Context, userID string, req *dto.ChangePasswordRequest) error {
|
||||
// 1. 获取用户信息
|
||||
user, err := s.repo.GetByID(ctx, userID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("用户不存在: %w", err)
|
||||
}
|
||||
|
||||
// 2. 执行业务逻辑(委托给实体)
|
||||
if err := user.ChangePassword(req.OldPassword, req.NewPassword, req.ConfirmNewPassword); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 3. 保存用户
|
||||
return s.repo.Update(ctx, user)
|
||||
}
|
||||
```
|
||||
|
||||
## 📊 **优化效果对比**
|
||||
|
||||
| 方面 | 优化前 | 优化后 |
|
||||
| ---------------- | -------------- | -------------- |
|
||||
| **业务逻辑位置** | Service 层 | 实体层 |
|
||||
| **代码复用性** | 低 | 高 |
|
||||
| **测试难度** | 需要 Mock 仓储 | 可直接测试实体 |
|
||||
| **职责分离** | 不清晰 | 清晰 |
|
||||
| **维护性** | 一般 | 优秀 |
|
||||
|
||||
## 🧪 **测试覆盖**
|
||||
|
||||
### **单元测试**
|
||||
|
||||
- ✅ 密码修改功能测试
|
||||
- ✅ 密码验证功能测试
|
||||
- ✅ 手机号设置功能测试
|
||||
- ✅ 手机号脱敏功能测试
|
||||
- ✅ 手机号格式验证测试
|
||||
- ✅ 用户创建工厂方法测试
|
||||
|
||||
### **测试结果**
|
||||
|
||||
```
|
||||
=== RUN TestUser_ChangePassword
|
||||
--- PASS: TestUser_ChangePassword (0.57s)
|
||||
=== RUN TestUser_CheckPassword
|
||||
--- PASS: TestUser_CheckPassword (0.16s)
|
||||
=== RUN TestUser_SetPhone
|
||||
--- PASS: TestUser_SetPhone (0.00s)
|
||||
=== RUN TestUser_GetMaskedPhone
|
||||
--- PASS: TestUser_GetMaskedPhone (0.00s)
|
||||
=== RUN TestIsValidPhoneFormat
|
||||
--- PASS: TestIsValidPhoneFormat (0.00s)
|
||||
=== RUN TestNewUser
|
||||
--- PASS: TestNewUser (0.08s)
|
||||
PASS
|
||||
```
|
||||
|
||||
## 🚀 **新增功能**
|
||||
|
||||
### **1. 用户信息更新**
|
||||
|
||||
```go
|
||||
func (s *UserService) UpdateUserProfile(ctx context.Context, userID string, req *dto.UpdateProfileRequest) (*entities.User, error)
|
||||
```
|
||||
|
||||
### **2. 用户停用**
|
||||
|
||||
```go
|
||||
func (s *UserService) DeactivateUser(ctx context.Context, userID string) error
|
||||
```
|
||||
|
||||
### **3. 软删除支持**
|
||||
|
||||
```go
|
||||
func (r *UserRepository) SoftDelete(ctx context.Context, id string) error
|
||||
func (r *UserRepository) Restore(ctx context.Context, id string) error
|
||||
```
|
||||
|
||||
## 📈 **架构改进**
|
||||
|
||||
### **1. 更好的封装**
|
||||
|
||||
- 业务规则与数据在一起
|
||||
- 减少外部依赖
|
||||
- 提高内聚性
|
||||
|
||||
### **2. 更清晰的职责**
|
||||
|
||||
- 实体:业务逻辑和验证
|
||||
- Service:协调和事务管理
|
||||
- Repository:数据访问
|
||||
|
||||
### **3. 更容易测试**
|
||||
|
||||
- 实体方法可以独立测试
|
||||
- 不需要复杂的 Mock 设置
|
||||
- 测试覆盖更全面
|
||||
|
||||
## 🎉 **总结**
|
||||
|
||||
这次优化成功实现了:
|
||||
|
||||
1. **✅ 充血模型** - 实体包含丰富的业务方法
|
||||
2. **✅ 职责分离** - Service 专注于协调,实体专注于业务逻辑
|
||||
3. **✅ 更好的封装** - 业务规则与数据紧密耦合
|
||||
4. **✅ 更容易测试** - 实体方法可以独立测试
|
||||
5. **✅ 代码复用** - 业务逻辑可以在不同场景下复用
|
||||
|
||||
这是一个成功的"轻量级 DDD"实践,在保持架构简单的同时,显著提升了代码质量和可维护性!
|
||||
Reference in New Issue
Block a user