374 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
		
		
			
		
	
	
			374 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
|  | # 领域服务层设计文档
 | |||
|  | 
 | |||
|  | ## 概述
 | |||
|  | 
 | |||
|  | 本文档描述了认证域和用户域的领域服务层设计,包括核心业务逻辑、服务接口和职责分工。 | |||
|  | 
 | |||
|  | ## 认证域领域服务 (CertificationService)
 | |||
|  | 
 | |||
|  | ### 服务职责
 | |||
|  | 
 | |||
|  | 认证域领域服务负责管理企业认证流程的核心业务逻辑,包括: | |||
|  | 
 | |||
|  | -   认证申请的生命周期管理 | |||
|  | -   状态机驱动的流程控制 | |||
|  | -   人脸识别验证流程 | |||
|  | -   合同申请和审核流程 | |||
|  | -   认证完成和失败处理 | |||
|  | -   进度跟踪和状态查询 | |||
|  | 
 | |||
|  | ### 核心方法
 | |||
|  | 
 | |||
|  | #### 1. 认证申请管理
 | |||
|  | 
 | |||
|  | -   `CreateCertification(ctx, userID)` - 创建认证申请 | |||
|  | -   `GetCertificationByUserID(ctx, userID)` - 根据用户 ID 获取认证申请 | |||
|  | -   `GetCertificationByID(ctx, certificationID)` - 根据 ID 获取认证申请 | |||
|  | -   `GetCertificationWithDetails(ctx, certificationID)` - 获取认证申请详细信息(包含关联记录) | |||
|  | 
 | |||
|  | #### 2. 企业信息提交
 | |||
|  | 
 | |||
|  | -   `SubmitEnterpriseInfo(ctx, certificationID)` - 提交企业信息,触发状态转换 | |||
|  | 
 | |||
|  | #### 3. 人脸识别验证
 | |||
|  | 
 | |||
|  | -   `InitiateFaceVerify(ctx, certificationID, realName, idCardNumber)` - 发起人脸识别验证 | |||
|  | -   `CompleteFaceVerify(ctx, faceVerifyID, isSuccess)` - 完成人脸识别验证 | |||
|  | -   `RetryFaceVerify(ctx, certificationID)` - 重试人脸识别 | |||
|  | 
 | |||
|  | #### 4. 合同流程管理
 | |||
|  | 
 | |||
|  | -   `ApplyContract(ctx, certificationID)` - 申请合同 | |||
|  | -   `ApproveContract(ctx, certificationID, adminID, signingURL, approvalNotes)` - 管理员审核通过 | |||
|  | -   `RejectContract(ctx, certificationID, adminID, rejectReason)` - 管理员拒绝 | |||
|  | -   `CompleteContractSign(ctx, certificationID, contractURL)` - 完成合同签署 | |||
|  | 
 | |||
|  | #### 5. 认证完成
 | |||
|  | 
 | |||
|  | -   `CompleteCertification(ctx, certificationID)` - 完成认证流程 | |||
|  | -   `RestartCertification(ctx, certificationID)` - 重新开始认证流程 | |||
|  | 
 | |||
|  | #### 6. 记录查询
 | |||
|  | 
 | |||
|  | -   `GetFaceVerifyRecords(ctx, certificationID)` - 获取人脸识别记录 | |||
|  | -   `GetContractRecords(ctx, certificationID)` - 获取合同记录 | |||
|  | 
 | |||
|  | #### 7. 进度和状态管理
 | |||
|  | 
 | |||
|  | -   `GetCertificationProgress(ctx, certificationID)` - 获取认证进度信息 | |||
|  | -   `UpdateOCRResult(ctx, certificationID, ocrRequestID, confidence)` - 更新 OCR 识别结果 | |||
|  | 
 | |||
|  | ### 状态机集成
 | |||
|  | 
 | |||
|  | 认证服务与状态机紧密集成,所有状态转换都通过状态机进行: | |||
|  | 
 | |||
|  | -   确保状态转换的合法性 | |||
|  | -   自动更新相关时间戳 | |||
|  | -   记录状态转换日志 | |||
|  | -   支持权限控制(用户/管理员) | |||
|  | 
 | |||
|  | ## 认证状态机 (CertificationStateMachine)
 | |||
|  | 
 | |||
|  | ### 状态机职责
 | |||
|  | 
 | |||
|  | 认证状态机负责管理认证流程的状态转换,包括: | |||
|  | 
 | |||
|  | -   状态转换规则定义 | |||
|  | -   转换验证和权限控制 | |||
|  | -   时间戳自动更新 | |||
|  | -   元数据管理 | |||
|  | -   流程完整性验证 | |||
|  | 
 | |||
|  | ### 核心方法
 | |||
|  | 
 | |||
|  | #### 1. 状态转换管理
 | |||
|  | 
 | |||
|  | -   `CanTransition(from, to, isUser, isAdmin)` - 检查是否可以转换到指定状态 | |||
|  | -   `TransitionTo(ctx, certificationID, targetStatus, isUser, isAdmin, metadata)` - 执行状态转换 | |||
|  | -   `GetValidNextStatuses(currentStatus, isUser, isAdmin)` - 获取当前状态可以转换到的下一个状态列表 | |||
|  | 
 | |||
|  | #### 2. 转换规则管理
 | |||
|  | 
 | |||
|  | -   `GetTransitionAction(from, to)` - 获取状态转换对应的操作名称 | |||
|  | -   `initializeTransitions()` - 初始化状态转换规则 | |||
|  | 
 | |||
|  | #### 3. 流程验证和历史
 | |||
|  | 
 | |||
|  | -   `GetTransitionHistory(ctx, certificationID)` - 获取状态转换历史 | |||
|  | -   `ValidateCertificationFlow(ctx, certificationID)` - 验证认证流程的完整性 | |||
|  | 
 | |||
|  | ### 状态转换规则
 | |||
|  | 
 | |||
|  | #### 正常流程转换
 | |||
|  | 
 | |||
|  | -   `PENDING` → `INFO_SUBMITTED` (用户提交企业信息) | |||
|  | -   `INFO_SUBMITTED` → `FACE_VERIFIED` (人脸识别成功) | |||
|  | -   `FACE_VERIFIED` → `CONTRACT_APPLIED` (申请合同) | |||
|  | -   `CONTRACT_APPLIED` → `CONTRACT_PENDING` (系统处理) | |||
|  | -   `CONTRACT_PENDING` → `CONTRACT_APPROVED` (管理员审核通过) | |||
|  | -   `CONTRACT_APPROVED` → `CONTRACT_SIGNED` (用户签署) | |||
|  | -   `CONTRACT_SIGNED` → `COMPLETED` (系统完成) | |||
|  | 
 | |||
|  | #### 失败和重试转换
 | |||
|  | 
 | |||
|  | -   `INFO_SUBMITTED` → `FACE_FAILED` (人脸识别失败) | |||
|  | -   `FACE_FAILED` → `FACE_VERIFIED` (重试人脸识别) | |||
|  | -   `CONTRACT_PENDING` → `REJECTED` (管理员拒绝) | |||
|  | -   `REJECTED` → `INFO_SUBMITTED` (重新开始流程) | |||
|  | -   `CONTRACT_APPROVED` → `SIGN_FAILED` (签署失败) | |||
|  | -   `SIGN_FAILED` → `CONTRACT_SIGNED` (重试签署) | |||
|  | 
 | |||
|  | ## 用户域领域服务
 | |||
|  | 
 | |||
|  | ### 用户基础服务 (UserService)
 | |||
|  | 
 | |||
|  | #### 服务职责
 | |||
|  | 
 | |||
|  | 用户基础服务负责用户核心信息的管理,包括: | |||
|  | 
 | |||
|  | -   用户基础信息的 CRUD 操作 | |||
|  | -   用户密码管理 | |||
|  | -   用户状态验证 | |||
|  | -   用户统计信息 | |||
|  | 
 | |||
|  | #### 核心方法
 | |||
|  | 
 | |||
|  | -   `IsPhoneRegistered(ctx, phone)` - 检查手机号是否已注册 | |||
|  | -   `GetUserByID(ctx, userID)` - 根据 ID 获取用户信息 | |||
|  | -   `GetUserByPhone(ctx, phone)` - 根据手机号获取用户信息 | |||
|  | -   `GetUserWithEnterpriseInfo(ctx, userID)` - 获取用户信息(包含企业信息) | |||
|  | -   `UpdateUser(ctx, user)` - 更新用户信息 | |||
|  | -   `ChangePassword(ctx, userID, oldPassword, newPassword)` - 修改用户密码 | |||
|  | -   `ValidateUser(ctx, userID)` - 验证用户信息 | |||
|  | -   `GetUserStats(ctx)` - 获取用户统计信息 | |||
|  | 
 | |||
|  | ### 企业信息服务 (EnterpriseService)
 | |||
|  | 
 | |||
|  | #### 服务职责
 | |||
|  | 
 | |||
|  | 企业信息服务专门负责企业信息的管理,包括: | |||
|  | 
 | |||
|  | -   企业信息的创建、更新和查询 | |||
|  | -   企业认证状态管理 | |||
|  | -   数据验证和业务规则检查 | |||
|  | -   认证状态跟踪 | |||
|  | 
 | |||
|  | #### 核心方法
 | |||
|  | 
 | |||
|  | ##### 1. 企业信息管理
 | |||
|  | 
 | |||
|  | -   `CreateEnterpriseInfo(ctx, userID, companyName, unifiedSocialCode, legalPersonName, legalPersonID)` - 创建企业信息 | |||
|  | -   `GetEnterpriseInfo(ctx, userID)` - 获取企业信息 | |||
|  | -   `UpdateEnterpriseInfo(ctx, userID, companyName, unifiedSocialCode, legalPersonName, legalPersonID)` - 更新企业信息 | |||
|  | -   `GetEnterpriseInfoByUnifiedSocialCode(ctx, unifiedSocialCode)` - 根据统一社会信用代码获取企业信息 | |||
|  | 
 | |||
|  | ##### 2. 认证状态管理
 | |||
|  | 
 | |||
|  | -   `UpdateOCRVerification(ctx, userID, isVerified, rawData, confidence)` - 更新 OCR 验证状态 | |||
|  | -   `UpdateFaceVerification(ctx, userID, isVerified)` - 更新人脸识别验证状态 | |||
|  | -   `CompleteEnterpriseCertification(ctx, userID)` - 完成企业认证 | |||
|  | 
 | |||
|  | ##### 3. 数据验证和查询
 | |||
|  | 
 | |||
|  | -   `CheckUnifiedSocialCodeExists(ctx, unifiedSocialCode, excludeUserID)` - 检查统一社会信用代码唯一性 | |||
|  | -   `ValidateEnterpriseInfo(ctx, userID)` - 验证企业信息完整性 | |||
|  | -   `IsEnterpriseCertified(ctx, userID)` - 检查用户是否已完成企业认证 | |||
|  | -   `GetEnterpriseCertificationStatus(ctx, userID)` - 获取企业认证状态 | |||
|  | 
 | |||
|  | ##### 4. 用户信息集成
 | |||
|  | 
 | |||
|  | -   `GetUserWithEnterpriseInfo(ctx, userID)` - 获取用户信息(包含企业信息) | |||
|  | 
 | |||
|  | ### 短信验证码服务 (SMSCodeService)
 | |||
|  | 
 | |||
|  | #### 服务职责
 | |||
|  | 
 | |||
|  | 短信验证码服务负责短信验证码的完整生命周期管理,包括: | |||
|  | 
 | |||
|  | -   验证码生成和发送 | |||
|  | -   验证码验证 | |||
|  | -   频率限制控制 | |||
|  | -   安全策略执行 | |||
|  | 
 | |||
|  | #### 核心方法
 | |||
|  | 
 | |||
|  | -   `SendCode(ctx, phone, scene, clientIP, userAgent)` - 发送验证码 | |||
|  | -   `VerifyCode(ctx, phone, code, scene)` - 验证验证码 | |||
|  | -   `CanResendCode(ctx, phone, scene)` - 检查是否可以重新发送 | |||
|  | -   `GetCodeStatus(ctx, phone, scene)` - 获取验证码状态 | |||
|  | -   `CheckRateLimit(ctx, phone, scene)` - 检查发送频率限制 | |||
|  | 
 | |||
|  | ## 服务协作模式
 | |||
|  | 
 | |||
|  | ### 服务依赖关系
 | |||
|  | 
 | |||
|  | ``` | |||
|  | CertificationService | |||
|  | ├── 依赖 CertificationRepository | |||
|  | ├── 依赖 FaceVerifyRecordRepository | |||
|  | ├── 依赖 ContractRecordRepository | |||
|  | ├── 依赖 LicenseUploadRecordRepository | |||
|  | ├── 依赖 CertificationStateMachine | |||
|  | └── 提供认证流程管理功能 | |||
|  | 
 | |||
|  | CertificationStateMachine | |||
|  | ├── 依赖 CertificationRepository | |||
|  | ├── 管理状态转换规则 | |||
|  | └── 提供流程验证功能 | |||
|  | 
 | |||
|  | UserService | |||
|  | ├── 依赖 EnterpriseService (用于获取包含企业信息的用户数据) | |||
|  | └── 依赖 UserRepository | |||
|  | 
 | |||
|  | EnterpriseService | |||
|  | ├── 依赖 UserRepository (用于验证用户存在性) | |||
|  | ├── 依赖 EnterpriseInfoRepository | |||
|  | └── 提供企业信息相关功能 | |||
|  | 
 | |||
|  | SMSCodeService | |||
|  | ├── 依赖 SMSCodeRepository | |||
|  | ├── 依赖 AliSMSService | |||
|  | ├── 依赖 CacheService | |||
|  | └── 独立运行,不依赖其他领域服务 | |||
|  | ``` | |||
|  | 
 | |||
|  | ### 跨域调用
 | |||
|  | 
 | |||
|  | 1. **认证域调用用户域** | |||
|  | 
 | |||
|  |     - 认证服务在需要企业信息时调用企业服务 | |||
|  |     - 通过依赖注入获取企业服务实例 | |||
|  |     - 保持领域边界清晰 | |||
|  | 
 | |||
|  | 2. **应用服务层协调** | |||
|  |     - 应用服务层负责协调不同领域服务 | |||
|  |     - 处理跨域事务和一致性 | |||
|  |     - 发布领域事件 | |||
|  | 
 | |||
|  | ### 事件驱动
 | |||
|  | 
 | |||
|  | 1. **领域事件发布** | |||
|  | 
 | |||
|  |     - 认证状态变更时发布事件 | |||
|  |     - 企业信息创建/更新时发布事件 | |||
|  |     - 用户注册/更新时发布事件 | |||
|  |     - 支持异步处理和集成 | |||
|  | 
 | |||
|  | 2. **事件处理** | |||
|  |     - 事件处理器响应领域事件 | |||
|  |     - 执行副作用操作(如通知、日志) | |||
|  |     - 维护数据一致性 | |||
|  | 
 | |||
|  | ## 业务规则
 | |||
|  | 
 | |||
|  | ### 企业信息只读规则
 | |||
|  | 
 | |||
|  | -   认证完成后企业信息不可修改 | |||
|  | -   通过 `IsReadOnly()` 方法检查 | |||
|  | -   在更新操作中强制执行 | |||
|  | 
 | |||
|  | ### 统一社会信用代码唯一性
 | |||
|  | 
 | |||
|  | -   每个统一社会信用代码只能对应一个用户 | |||
|  | -   更新时排除当前用户 ID | |||
|  | -   支持并发检查 | |||
|  | 
 | |||
|  | ### 认证完成条件
 | |||
|  | 
 | |||
|  | -   OCR 验证必须通过 | |||
|  | -   人脸识别验证必须通过 | |||
|  | -   两个条件都满足才能完成认证 | |||
|  | 
 | |||
|  | ### 状态转换规则
 | |||
|  | 
 | |||
|  | -   严格按照状态机定义的转换规则执行 | |||
|  | -   支持用户和管理员权限控制 | |||
|  | -   自动记录转换历史和时间戳 | |||
|  | 
 | |||
|  | ### 短信验证码规则
 | |||
|  | 
 | |||
|  | -   支持多种场景(注册、登录、修改密码等) | |||
|  | -   频率限制(最小间隔、每小时限制、每日限制) | |||
|  | -   开发模式跳过验证 | |||
|  | -   自动过期和清理 | |||
|  | 
 | |||
|  | ## 错误处理
 | |||
|  | 
 | |||
|  | ### 业务错误
 | |||
|  | 
 | |||
|  | -   使用有意义的错误消息 | |||
|  | -   包含业务上下文信息 | |||
|  | -   支持错误分类和处理 | |||
|  | 
 | |||
|  | ### 日志记录
 | |||
|  | 
 | |||
|  | -   记录关键业务操作 | |||
|  | -   包含操作上下文(用户 ID、操作类型等) | |||
|  | -   支持问题排查和审计 | |||
|  | 
 | |||
|  | ## 性能考虑
 | |||
|  | 
 | |||
|  | ### 数据库查询优化
 | |||
|  | 
 | |||
|  | -   合理使用索引 | |||
|  | -   避免 N+1 查询问题 | |||
|  | -   支持分页和缓存 | |||
|  | 
 | |||
|  | ### 并发控制
 | |||
|  | 
 | |||
|  | -   使用乐观锁或悲观锁 | |||
|  | -   防止数据竞争条件 | |||
|  | -   保证数据一致性 | |||
|  | 
 | |||
|  | ## 扩展性设计
 | |||
|  | 
 | |||
|  | ### 新功能扩展
 | |||
|  | 
 | |||
|  | -   通过接口扩展新功能 | |||
|  | -   保持向后兼容性 | |||
|  | -   支持插件化架构 | |||
|  | 
 | |||
|  | ### 多租户支持
 | |||
|  | 
 | |||
|  | -   预留租户字段 | |||
|  | -   支持数据隔离 | |||
|  | -   便于未来扩展 | |||
|  | 
 | |||
|  | ## 测试策略
 | |||
|  | 
 | |||
|  | ### 单元测试
 | |||
|  | 
 | |||
|  | -   测试核心业务逻辑 | |||
|  | -   模拟外部依赖 | |||
|  | -   覆盖边界条件 | |||
|  | 
 | |||
|  | ### 集成测试
 | |||
|  | 
 | |||
|  | -   测试服务间协作 | |||
|  | -   验证数据一致性 | |||
|  | -   测试完整业务流程 | |||
|  | 
 | |||
|  | ## 总结
 | |||
|  | 
 | |||
|  | 领域服务层设计遵循 DDD 原则,实现了: | |||
|  | 
 | |||
|  | 1. **职责分离**: | |||
|  | 
 | |||
|  |     - 认证域负责流程管理和状态控制 | |||
|  |     - 用户域分为基础服务和企业服务,各司其职 | |||
|  |     - 短信服务独立运行 | |||
|  | 
 | |||
|  | 2. **业务封装**: 核心业务逻辑封装在相应的领域服务中 | |||
|  | 
 | |||
|  | 3. **状态管理**: 通过状态机管理复杂流程,支持历史追踪和流程验证 | |||
|  | 
 | |||
|  | 4. **数据一致性**: 通过业务规则保证数据完整性 | |||
|  | 
 | |||
|  | 5. **可扩展性**: 支持未来功能扩展和架构演进 | |||
|  | 
 | |||
|  | 6. **服务协作**: 通过依赖注入实现服务间的松耦合协作 | |||
|  | 
 | |||
|  | 7. **流程完整性**: 通过状态机验证和流程完整性检查确保业务逻辑正确性 | |||
|  | 
 | |||
|  | 这种设计为应用服务层提供了清晰的接口,便于实现复杂的业务流程协调,同时保持了良好的可维护性和可测试性。 |