f
This commit is contained in:
@@ -0,0 +1,349 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"hyapi-server/internal/domains/certification/entities"
|
||||
"hyapi-server/internal/domains/certification/enums"
|
||||
"hyapi-server/internal/domains/certification/repositories"
|
||||
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// CertificationAggregateService 认证聚合服务接口
|
||||
// 负责认证聚合根的生命周期管理和状态转换协调
|
||||
type CertificationAggregateService interface {
|
||||
// 聚合根管理
|
||||
CreateCertification(ctx context.Context, userID string) (*entities.Certification, error)
|
||||
LoadCertification(ctx context.Context, certificationID string) (*entities.Certification, error)
|
||||
SaveCertification(ctx context.Context, cert *entities.Certification) error
|
||||
LoadCertificationByUserID(ctx context.Context, userID string) (*entities.Certification, error)
|
||||
LoadCertificationByAuthFlowId(ctx context.Context, authFlowId string) (*entities.Certification, error)
|
||||
LoadCertificationByEsignFlowId(ctx context.Context, esignFlowId string) (*entities.Certification, error)
|
||||
// 业务规则验证
|
||||
ValidateBusinessRules(ctx context.Context, cert *entities.Certification) error
|
||||
CheckInvariance(ctx context.Context, cert *entities.Certification) error
|
||||
|
||||
// 查询方法
|
||||
ExistsByUserID(ctx context.Context, userID string) (bool, error)
|
||||
}
|
||||
|
||||
// CertificationAggregateServiceImpl 认证聚合服务实现
|
||||
type CertificationAggregateServiceImpl struct {
|
||||
commandRepo repositories.CertificationCommandRepository
|
||||
queryRepo repositories.CertificationQueryRepository
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
// NewCertificationAggregateService 创建认证聚合服务
|
||||
func NewCertificationAggregateService(
|
||||
commandRepo repositories.CertificationCommandRepository,
|
||||
queryRepo repositories.CertificationQueryRepository,
|
||||
logger *zap.Logger,
|
||||
) CertificationAggregateService {
|
||||
return &CertificationAggregateServiceImpl{
|
||||
commandRepo: commandRepo,
|
||||
queryRepo: queryRepo,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
// ================ 聚合根管理 ================
|
||||
|
||||
// CreateCertification 创建认证申请
|
||||
func (s *CertificationAggregateServiceImpl) CreateCertification(ctx context.Context, userID string) (*entities.Certification, error) {
|
||||
s.logger.Info("创建认证申请", zap.String("user_id", userID))
|
||||
|
||||
// 1. 检查用户是否已有认证申请
|
||||
exists, err := s.ExistsByUserID(ctx, userID)
|
||||
if err != nil {
|
||||
s.logger.Error("检查用户认证是否存在失败", zap.Error(err), zap.String("user_id", userID))
|
||||
return nil, fmt.Errorf("检查用户认证是否存在失败: %w", err)
|
||||
}
|
||||
if exists {
|
||||
s.logger.Info("用户已有认证申请,不允许创建新申请",
|
||||
zap.String("user_id", userID))
|
||||
return nil, fmt.Errorf("用户已有认证申请")
|
||||
}
|
||||
|
||||
// 2. 创建新的认证聚合根
|
||||
cert, err := entities.NewCertification(userID)
|
||||
if err != nil {
|
||||
s.logger.Error("创建认证实体失败", zap.Error(err), zap.String("user_id", userID))
|
||||
return nil, fmt.Errorf("创建认证实体失败: %w", err)
|
||||
}
|
||||
|
||||
// 3. 验证业务规则
|
||||
if err := s.ValidateBusinessRules(ctx, cert); err != nil {
|
||||
s.logger.Error("认证业务规则验证失败", zap.Error(err))
|
||||
return nil, fmt.Errorf("业务规则验证失败: %w", err)
|
||||
}
|
||||
|
||||
// 4. 保存聚合根
|
||||
if err := s.SaveCertification(ctx, cert); err != nil {
|
||||
s.logger.Error("保存认证申请失败", zap.Error(err))
|
||||
return nil, fmt.Errorf("保存认证申请失败: %w", err)
|
||||
}
|
||||
|
||||
s.logger.Info("认证申请创建成功",
|
||||
zap.String("user_id", userID),
|
||||
zap.String("certification_id", cert.ID))
|
||||
|
||||
return cert, nil
|
||||
}
|
||||
|
||||
// LoadCertification 加载认证聚合根
|
||||
func (s *CertificationAggregateServiceImpl) LoadCertification(ctx context.Context, certificationID string) (*entities.Certification, error) {
|
||||
s.logger.Debug("加载认证聚合根", zap.String("certification_id", certificationID))
|
||||
|
||||
// 从查询仓储加载
|
||||
cert, err := s.queryRepo.GetByID(ctx, certificationID)
|
||||
if err != nil {
|
||||
s.logger.Error("加载认证聚合根失败", zap.Error(err), zap.String("certification_id", certificationID))
|
||||
return nil, fmt.Errorf("认证申请不存在: %w", err)
|
||||
}
|
||||
|
||||
// 验证聚合根完整性
|
||||
if err := s.CheckInvariance(ctx, cert); err != nil {
|
||||
s.logger.Error("认证聚合根完整性验证失败", zap.Error(err))
|
||||
return nil, fmt.Errorf("认证数据完整性验证失败: %w", err)
|
||||
}
|
||||
|
||||
return cert, nil
|
||||
}
|
||||
|
||||
// LoadCertificationByUserID 加载用户认证聚合根
|
||||
func (s *CertificationAggregateServiceImpl) LoadCertificationByUserID(ctx context.Context, userID string) (*entities.Certification, error) {
|
||||
s.logger.Debug("加载用户认证聚合根", zap.String("user_id", userID))
|
||||
|
||||
// 从查询仓储加载
|
||||
cert, err := s.queryRepo.GetByUserID(ctx, userID)
|
||||
if err != nil {
|
||||
s.logger.Error("加载用户认证聚合根失败", zap.Error(err), zap.String("user_id", userID))
|
||||
return nil, fmt.Errorf("认证申请不存在: %w", err)
|
||||
}
|
||||
|
||||
return cert, nil
|
||||
}
|
||||
|
||||
// LoadCertificationByAuthFlowId 加载认证聚合根
|
||||
func (s *CertificationAggregateServiceImpl) LoadCertificationByAuthFlowId(ctx context.Context, authFlowId string) (*entities.Certification, error) {
|
||||
s.logger.Debug("加载认证聚合根", zap.String("auth_flow_id", authFlowId))
|
||||
|
||||
// 从查询仓储加载
|
||||
cert, err := s.queryRepo.FindByAuthFlowID(ctx, authFlowId)
|
||||
if err != nil {
|
||||
s.logger.Error("加载认证聚合根失败", zap.Error(err), zap.String("auth_flow_id", authFlowId))
|
||||
return nil, fmt.Errorf("认证申请不存在: %w", err)
|
||||
}
|
||||
|
||||
return cert, nil
|
||||
}
|
||||
|
||||
// LoadCertificationByEsignFlowId 加载认证聚合根
|
||||
func (s *CertificationAggregateServiceImpl) LoadCertificationByEsignFlowId(ctx context.Context, esignFlowId string) (*entities.Certification, error) {
|
||||
s.logger.Debug("加载认证聚合根", zap.String("esign_flow_id", esignFlowId))
|
||||
|
||||
// 从查询仓储加载
|
||||
cert, err := s.queryRepo.FindByEsignFlowID(ctx, esignFlowId)
|
||||
if err != nil {
|
||||
s.logger.Error("加载认证聚合根失败", zap.Error(err), zap.String("esign_flow_id", esignFlowId))
|
||||
return nil, fmt.Errorf("认证申请不存在: %w", err)
|
||||
}
|
||||
|
||||
return cert, nil
|
||||
}
|
||||
|
||||
// SaveCertification 保存认证聚合根
|
||||
func (s *CertificationAggregateServiceImpl) SaveCertification(ctx context.Context, cert *entities.Certification) error {
|
||||
s.logger.Debug("保存认证聚合根", zap.String("certification_id", cert.ID))
|
||||
|
||||
// 1. 验证业务规则
|
||||
if err := s.ValidateBusinessRules(ctx, cert); err != nil {
|
||||
return fmt.Errorf("业务规则验证失败: %w", err)
|
||||
}
|
||||
|
||||
// 2. 检查聚合根是否存在
|
||||
exists, err := s.queryRepo.Exists(ctx, cert.ID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("检查认证存在性失败: %w", err)
|
||||
}
|
||||
|
||||
// 3. 保存到命令仓储
|
||||
if exists {
|
||||
err = s.commandRepo.Update(ctx, *cert)
|
||||
if err != nil {
|
||||
s.logger.Error("更新认证聚合根失败", zap.Error(err))
|
||||
return fmt.Errorf("更新认证失败: %w", err)
|
||||
}
|
||||
} else {
|
||||
err = s.commandRepo.Create(ctx, *cert)
|
||||
if err != nil {
|
||||
s.logger.Error("创建认证聚合根失败", zap.Error(err))
|
||||
return fmt.Errorf("创建认证失败: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
s.logger.Debug("认证聚合根保存成功", zap.String("certification_id", cert.ID))
|
||||
return nil
|
||||
}
|
||||
|
||||
// ================ 业务规则验证 ================
|
||||
|
||||
// ValidateBusinessRules 验证业务规则
|
||||
func (s *CertificationAggregateServiceImpl) ValidateBusinessRules(ctx context.Context, cert *entities.Certification) error {
|
||||
s.logger.Debug("验证认证业务规则", zap.String("certification_id", cert.ID))
|
||||
|
||||
// 1. 实体内部业务规则验证
|
||||
if err := cert.ValidateBusinessRules(); err != nil {
|
||||
return fmt.Errorf("实体业务规则验证失败: %w", err)
|
||||
}
|
||||
|
||||
// 2. 跨聚合根业务规则验证
|
||||
if err := s.validateCrossAggregateRules(ctx, cert); err != nil {
|
||||
return fmt.Errorf("跨聚合根业务规则验证失败: %w", err)
|
||||
}
|
||||
|
||||
// 3. 领域级业务规则验证
|
||||
if err := s.validateDomainRules(ctx, cert); err != nil {
|
||||
return fmt.Errorf("领域业务规则验证失败: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CheckInvariance 检查聚合根不变量
|
||||
func (s *CertificationAggregateServiceImpl) CheckInvariance(ctx context.Context, cert *entities.Certification) error {
|
||||
s.logger.Debug("检查认证聚合根不变量", zap.String("certification_id", cert.ID))
|
||||
|
||||
// 1. 基础不变量检查
|
||||
if cert.ID == "" {
|
||||
return fmt.Errorf("认证ID不能为空")
|
||||
}
|
||||
|
||||
if cert.UserID == "" {
|
||||
return fmt.Errorf("用户ID不能为空")
|
||||
}
|
||||
|
||||
if !enums.IsValidStatus(cert.Status) {
|
||||
return fmt.Errorf("无效的认证状态: %s", cert.Status)
|
||||
}
|
||||
|
||||
// 2. 状态相关不变量检查
|
||||
if err := s.validateStatusInvariance(cert); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 3. 时间戳不变量检查
|
||||
if err := s.validateTimestampInvariance(cert); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ================ 查询方法 ================
|
||||
|
||||
// Exists 判断认证是否存在
|
||||
func (s *CertificationAggregateServiceImpl) ExistsByUserID(ctx context.Context, userID string) (bool, error) {
|
||||
return s.queryRepo.ExistsByUserID(ctx, userID)
|
||||
}
|
||||
|
||||
// ================ 私有方法 ================
|
||||
|
||||
// validateCrossAggregateRules 验证跨聚合根业务规则
|
||||
func (s *CertificationAggregateServiceImpl) validateCrossAggregateRules(ctx context.Context, cert *entities.Certification) error {
|
||||
// TODO: 实现跨聚合根业务规则验证
|
||||
// 例如:检查用户是否有权限申请认证、检查企业信息是否已被其他用户使用等
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateDomainRules 验证领域级业务规则
|
||||
func (s *CertificationAggregateServiceImpl) validateDomainRules(ctx context.Context, cert *entities.Certification) error {
|
||||
// TODO: 实现领域级业务规则验证
|
||||
// 例如:检查认证流程是否符合法规要求、检查时间窗口限制等
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateStatusInvariance 验证状态相关不变量
|
||||
func (s *CertificationAggregateServiceImpl) validateStatusInvariance(cert *entities.Certification) error {
|
||||
switch cert.Status {
|
||||
case enums.StatusEnterpriseVerified:
|
||||
if cert.AuthFlowID == "" {
|
||||
return fmt.Errorf("企业认证状态下必须有认证流程ID")
|
||||
}
|
||||
if cert.EnterpriseVerifiedAt == nil {
|
||||
return fmt.Errorf("企业认证状态下必须有认证完成时间")
|
||||
}
|
||||
|
||||
case enums.StatusContractApplied:
|
||||
if cert.AuthFlowID == "" {
|
||||
return fmt.Errorf("合同申请状态下必须有企业认证流程ID")
|
||||
}
|
||||
if cert.ContractAppliedAt == nil {
|
||||
return fmt.Errorf("合同申请状态下必须有合同申请时间")
|
||||
}
|
||||
|
||||
case enums.StatusContractSigned:
|
||||
if cert.ContractFileID == "" || cert.EsignFlowID == "" {
|
||||
return fmt.Errorf("合同签署状态下必须有完整的合同信息")
|
||||
}
|
||||
if cert.ContractSignedAt == nil {
|
||||
return fmt.Errorf("合同签署状态下必须有签署完成时间")
|
||||
}
|
||||
|
||||
case enums.StatusCompleted:
|
||||
if cert.ContractFileID == "" || cert.EsignFlowID == "" || cert.ContractURL == "" {
|
||||
return fmt.Errorf("认证完成状态下必须有完整的合同信息")
|
||||
}
|
||||
if cert.ContractSignedAt == nil {
|
||||
return fmt.Errorf("认证完成状态下必须有合同签署时间")
|
||||
}
|
||||
if cert.CompletedAt == nil {
|
||||
return fmt.Errorf("认证完成状态下必须有完成时间")
|
||||
}
|
||||
}
|
||||
|
||||
// 失败状态检查
|
||||
if enums.IsFailureStatus(cert.Status) {
|
||||
if cert.FailureReason == "" {
|
||||
return fmt.Errorf("失败状态下必须有失败原因")
|
||||
}
|
||||
if !enums.IsValidFailureReason(cert.FailureReason) {
|
||||
return fmt.Errorf("无效的失败原因: %s", cert.FailureReason)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateTimestampInvariance 验证时间戳不变量
|
||||
func (s *CertificationAggregateServiceImpl) validateTimestampInvariance(cert *entities.Certification) error {
|
||||
// 检查时间戳的逻辑顺序
|
||||
if cert.InfoSubmittedAt != nil && cert.EnterpriseVerifiedAt != nil {
|
||||
if cert.InfoSubmittedAt.After(*cert.EnterpriseVerifiedAt) {
|
||||
return fmt.Errorf("企业信息提交时间不能晚于企业认证时间")
|
||||
}
|
||||
}
|
||||
|
||||
if cert.EnterpriseVerifiedAt != nil && cert.ContractAppliedAt != nil {
|
||||
if cert.EnterpriseVerifiedAt.After(*cert.ContractAppliedAt) {
|
||||
return fmt.Errorf("企业认证时间不能晚于合同申请时间")
|
||||
}
|
||||
}
|
||||
|
||||
if cert.ContractAppliedAt != nil && cert.ContractSignedAt != nil {
|
||||
if cert.ContractAppliedAt.After(*cert.ContractSignedAt) {
|
||||
return fmt.Errorf("合同申请时间不能晚于合同签署时间")
|
||||
}
|
||||
}
|
||||
|
||||
if cert.ContractSignedAt != nil && cert.CompletedAt != nil {
|
||||
if cert.ContractSignedAt.After(*cert.CompletedAt) {
|
||||
return fmt.Errorf("合同签署时间不能晚于认证完成时间")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,633 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"hyapi-server/internal/domains/certification/entities"
|
||||
"hyapi-server/internal/domains/certification/entities/value_objects"
|
||||
"hyapi-server/internal/domains/certification/enums"
|
||||
|
||||
"hyapi-server/internal/shared/esign"
|
||||
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// WorkflowResult 工作流执行结果
|
||||
type WorkflowResult struct {
|
||||
Success bool `json:"success"`
|
||||
CertificationID string `json:"certification_id"`
|
||||
CurrentStatus enums.CertificationStatus `json:"current_status"`
|
||||
Message string `json:"message"`
|
||||
Data map[string]interface{} `json:"data,omitempty"`
|
||||
ExecutedAt time.Time `json:"executed_at"`
|
||||
}
|
||||
|
||||
// SubmitEnterpriseInfoCommand 提交企业信息命令
|
||||
type SubmitEnterpriseInfoCommand struct {
|
||||
UserID string `json:"user_id"`
|
||||
EnterpriseInfo *value_objects.EnterpriseInfo `json:"enterprise_info"`
|
||||
}
|
||||
|
||||
// 完成企业认证命令
|
||||
type CompleteEnterpriseVerificationCommand struct {
|
||||
AuthFlowId string `json:"auth_flow_id"`
|
||||
}
|
||||
|
||||
// ApplyContractCommand 申请合同命令
|
||||
type ApplyContractCommand struct {
|
||||
CertificationID string `json:"certification_id"`
|
||||
UserID string `json:"user_id"`
|
||||
}
|
||||
|
||||
// EsignCallbackCommand e签宝回调命令
|
||||
type EsignCallbackCommand struct {
|
||||
CertificationID string `json:"certification_id"`
|
||||
CallbackType string `json:"callback_type"` // "auth_result" | "sign_result" | "flow_status"
|
||||
}
|
||||
|
||||
// CertificationWorkflowOrchestrator 认证工作流编排器接口
|
||||
// 负责编排认证业务流程,协调各个领域服务的协作
|
||||
type CertificationWorkflowOrchestrator interface {
|
||||
// 用户操作用例
|
||||
// 提交企业信息
|
||||
SubmitEnterpriseInfo(ctx context.Context, cmd *SubmitEnterpriseInfoCommand) (*WorkflowResult, error)
|
||||
// 完成企业认证
|
||||
CompleteEnterpriseVerification(ctx context.Context, cmd *CompleteEnterpriseVerificationCommand) (*WorkflowResult, error)
|
||||
// 申请合同签署
|
||||
ApplyContract(ctx context.Context, cmd *ApplyContractCommand) (*WorkflowResult, error)
|
||||
|
||||
// e签宝回调处理
|
||||
HandleEnterpriseVerificationCallback(ctx context.Context, cmd *EsignCallbackCommand) (*WorkflowResult, error)
|
||||
HandleContractSignCallback(ctx context.Context, cmd *EsignCallbackCommand) (*WorkflowResult, error)
|
||||
|
||||
// 异常处理
|
||||
HandleFailure(ctx context.Context, certificationID string, failureType string, reason string) (*WorkflowResult, error)
|
||||
|
||||
// 查询操作
|
||||
GetCertification(ctx context.Context, userID string) (*WorkflowResult, error)
|
||||
GetWorkflowStatus(ctx context.Context, certificationID string) (*WorkflowResult, error)
|
||||
}
|
||||
|
||||
// CertificationWorkflowOrchestratorImpl 认证工作流编排器实现
|
||||
type CertificationWorkflowOrchestratorImpl struct {
|
||||
aggregateService CertificationAggregateService
|
||||
logger *zap.Logger
|
||||
esignClient *esign.Client
|
||||
}
|
||||
|
||||
// NewCertificationWorkflowOrchestrator 创建认证工作流编排器
|
||||
func NewCertificationWorkflowOrchestrator(
|
||||
aggregateService CertificationAggregateService,
|
||||
logger *zap.Logger,
|
||||
esignClient *esign.Client,
|
||||
) CertificationWorkflowOrchestrator {
|
||||
return &CertificationWorkflowOrchestratorImpl{
|
||||
aggregateService: aggregateService,
|
||||
logger: logger,
|
||||
esignClient: esignClient,
|
||||
}
|
||||
}
|
||||
|
||||
// ================ 用户操作用例 ================
|
||||
|
||||
// GetCertification 获取认证详情
|
||||
func (o *CertificationWorkflowOrchestratorImpl) GetCertification(
|
||||
ctx context.Context,
|
||||
userID string,
|
||||
) (*WorkflowResult, error) {
|
||||
exists, err := o.aggregateService.ExistsByUserID(ctx, userID)
|
||||
if err != nil {
|
||||
o.logger.Error("获取认证信息失败", zap.Error(err))
|
||||
return nil, fmt.Errorf("获取认证信息失败: %w", err)
|
||||
}
|
||||
var cert *entities.Certification
|
||||
if !exists {
|
||||
cert, err = o.aggregateService.CreateCertification(ctx, userID)
|
||||
if err != nil {
|
||||
o.logger.Error("创建认证信息失败", zap.Error(err))
|
||||
return nil, fmt.Errorf("创建认证信息失败: %w", err)
|
||||
}
|
||||
} else {
|
||||
cert, err = o.aggregateService.LoadCertificationByUserID(ctx, userID)
|
||||
if err != nil {
|
||||
o.logger.Error("获取认证信息失败", zap.Error(err))
|
||||
return nil, fmt.Errorf("认证信息不存在: %w", err)
|
||||
}
|
||||
}
|
||||
meta := cert.GetDataByStatus()
|
||||
return o.createSuccessResult(userID, cert.Status, "获取认证信息成功", meta), nil
|
||||
}
|
||||
|
||||
// SubmitEnterpriseInfo 用户提交企业信息
|
||||
func (o *CertificationWorkflowOrchestratorImpl) SubmitEnterpriseInfo(
|
||||
ctx context.Context,
|
||||
cmd *SubmitEnterpriseInfoCommand,
|
||||
) (*WorkflowResult, error) {
|
||||
o.logger.Info("开始处理企业信息提交",
|
||||
zap.String("user_id", cmd.UserID))
|
||||
|
||||
// 1. 检查用户认证是否存在
|
||||
exists, err := o.aggregateService.ExistsByUserID(ctx, cmd.UserID)
|
||||
if err != nil {
|
||||
return o.createFailureResult(cmd.UserID, "", fmt.Sprintf("检查用户认证是否存在失败: %s", err.Error())), err
|
||||
}
|
||||
if !exists {
|
||||
// 创建
|
||||
_, err := o.aggregateService.CreateCertification(ctx, cmd.UserID)
|
||||
if err != nil {
|
||||
return o.createFailureResult(cmd.UserID, "", fmt.Sprintf("创建认证信息失败: %s", err.Error())), err
|
||||
}
|
||||
}
|
||||
// 1.1 验证企业信息
|
||||
err = cmd.EnterpriseInfo.Validate()
|
||||
if err != nil {
|
||||
return o.createFailureResult(cmd.UserID, "", fmt.Sprintf("企业信息验证失败: %s", err.Error())), err
|
||||
}
|
||||
// 2. 加载认证聚合根
|
||||
cert, err := o.aggregateService.LoadCertificationByUserID(ctx, cmd.UserID)
|
||||
if err != nil {
|
||||
return o.createFailureResult(cmd.UserID, "", fmt.Sprintf("加载认证信息失败: %s", err.Error())), err
|
||||
}
|
||||
|
||||
// 3. 验证业务前置条件(暂时没啥用,后面的都会校验)
|
||||
if err := o.validateEnterpriseInfoSubmissionPreconditions(cert, cmd.UserID); err != nil {
|
||||
return o.createFailureResult(cmd.UserID, cert.Status, err.Error()), err
|
||||
}
|
||||
|
||||
// 5. 调用e签宝看是否进行过认证
|
||||
respMeta := map[string]interface{}{}
|
||||
|
||||
identity, err := o.esignClient.QueryOrgIdentityInfo(&esign.QueryOrgIdentityRequest{
|
||||
OrgName: cmd.EnterpriseInfo.CompanyName,
|
||||
})
|
||||
if identity != nil && identity.Data.RealnameStatus == 1 {
|
||||
o.logger.Info("企业认证成功", zap.Any("identity", identity))
|
||||
err = cert.CompleteEnterpriseVerification()
|
||||
if err != nil {
|
||||
return o.createFailureResult(cmd.UserID, cert.Status, err.Error()), err
|
||||
}
|
||||
respMeta = map[string]interface{}{
|
||||
"enterprise_info": cmd.EnterpriseInfo,
|
||||
"next_action": "企业已认证,可进行后续操作",
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
o.logger.Error("e签宝查询企业认证信息失败或未进行企业认证", zap.Error(err))
|
||||
}
|
||||
authURL, err := o.esignClient.GenerateEnterpriseAuth(&esign.EnterpriseAuthRequest{
|
||||
CompanyName: cmd.EnterpriseInfo.CompanyName,
|
||||
UnifiedSocialCode: cmd.EnterpriseInfo.UnifiedSocialCode,
|
||||
LegalPersonName: cmd.EnterpriseInfo.LegalPersonName,
|
||||
LegalPersonID: cmd.EnterpriseInfo.LegalPersonID,
|
||||
TransactorName: cmd.EnterpriseInfo.LegalPersonName,
|
||||
TransactorMobile: cmd.EnterpriseInfo.LegalPersonPhone,
|
||||
TransactorID: cmd.EnterpriseInfo.LegalPersonID,
|
||||
})
|
||||
if err != nil {
|
||||
o.logger.Error("生成企业认证链接失败", zap.Error(err))
|
||||
return o.createFailureResult(cmd.UserID, cert.Status, err.Error()), err
|
||||
}
|
||||
err = cert.SubmitEnterpriseInfo(cmd.EnterpriseInfo, authURL.AuthShortURL, authURL.AuthFlowID)
|
||||
if err != nil {
|
||||
return o.createFailureResult(cmd.UserID, cert.Status, err.Error()), err
|
||||
}
|
||||
respMeta = map[string]interface{}{
|
||||
"enterprise_info": cmd.EnterpriseInfo,
|
||||
"authUrl": authURL.AuthURL,
|
||||
"next_action": "请完成企业认证",
|
||||
}
|
||||
}
|
||||
|
||||
err = o.aggregateService.SaveCertification(ctx, cert)
|
||||
if err != nil {
|
||||
return o.createFailureResult(cmd.UserID, cert.Status, err.Error()), err
|
||||
}
|
||||
|
||||
// 6. 构建成功结果
|
||||
return o.createSuccessResult(cmd.UserID, enums.StatusInfoSubmitted, "企业信息提交成功", respMeta), nil
|
||||
}
|
||||
|
||||
// CompleteEnterpriseVerification 完成企业认证
|
||||
func (o *CertificationWorkflowOrchestratorImpl) CompleteEnterpriseVerification(
|
||||
ctx context.Context,
|
||||
cmd *CompleteEnterpriseVerificationCommand,
|
||||
) (*WorkflowResult, error) {
|
||||
cert, err := o.aggregateService.LoadCertificationByAuthFlowId(ctx, cmd.AuthFlowId)
|
||||
if err != nil {
|
||||
return o.createFailureResult(cmd.AuthFlowId, "", fmt.Sprintf("加载认证信息失败: %s", err.Error())), err
|
||||
}
|
||||
err = cert.CompleteEnterpriseVerification()
|
||||
if err != nil {
|
||||
return o.createFailureResult(cmd.AuthFlowId, "", fmt.Sprintf("完成企业认证失败: %s", err.Error())), err
|
||||
}
|
||||
err = o.aggregateService.SaveCertification(ctx, cert)
|
||||
if err != nil {
|
||||
return o.createFailureResult(cmd.AuthFlowId, "", fmt.Sprintf("保存认证信息失败: %s", err.Error())), err
|
||||
}
|
||||
o.logger.Info("完成企业认证", zap.String("certification_id", cert.ID))
|
||||
return o.createSuccessResult(cmd.AuthFlowId, enums.StatusEnterpriseVerified, "企业认证成功", map[string]interface{}{}), nil
|
||||
}
|
||||
|
||||
// ApplyContract 用户申请合同签署
|
||||
func (o *CertificationWorkflowOrchestratorImpl) ApplyContract(
|
||||
ctx context.Context,
|
||||
cmd *ApplyContractCommand,
|
||||
) (*WorkflowResult, error) {
|
||||
return nil, nil
|
||||
// o.logger.Info("开始处理合同申请",
|
||||
// zap.String("certification_id", cmd.CertificationID),
|
||||
// zap.String("user_id", cmd.UserID))
|
||||
|
||||
// // 1. 验证命令完整性
|
||||
// if err := o.validateApplyContractCommand(cmd); err != nil {
|
||||
// return o.createFailureResult(cmd.CertificationID, "", fmt.Sprintf("命令验证失败: %s", err.Error())), err
|
||||
// }
|
||||
|
||||
// // 2. 加载认证聚合根
|
||||
// cert, err := o.aggregateService.LoadCertification(ctx, cmd.CertificationID)
|
||||
// if err != nil {
|
||||
// return o.createFailureResult(cmd.CertificationID, "", fmt.Sprintf("加载认证信息失败: %s", err.Error())), err
|
||||
// }
|
||||
|
||||
// // 3. 验证业务前置条件
|
||||
// if err := o.validateContractApplicationPreconditions(cert, cmd.UserID); err != nil {
|
||||
// return o.createFailureResult(cmd.CertificationID, cert.Status, err.Error()), err
|
||||
// }
|
||||
|
||||
// // 4. 执行状态转换
|
||||
// result, err := o.aggregateService.TransitionState(
|
||||
// ctx,
|
||||
// cmd.CertificationID,
|
||||
// enums.StatusContractApplied,
|
||||
// enums.ActorTypeUser,
|
||||
// cmd.UserID,
|
||||
// "用户申请合同签署",
|
||||
// map[string]interface{}{},
|
||||
// )
|
||||
// if err != nil {
|
||||
// o.logger.Error("合同申请状态转换失败", zap.Error(err))
|
||||
// return o.createFailureResult(cmd.CertificationID, cert.Status, fmt.Sprintf("状态转换失败: %s", err.Error())), err
|
||||
// }
|
||||
|
||||
// // 5. 生成合同和签署链接
|
||||
// contractInfo, err := o.generateContractAndSignURL(ctx, cmd.CertificationID, cert)
|
||||
// if err != nil {
|
||||
// o.logger.Error("生成合同失败", zap.Error(err))
|
||||
// // 需要回滚状态
|
||||
// return o.createFailureResult(cmd.CertificationID, cert.Status, fmt.Sprintf("生成合同失败: %s", err.Error())), err
|
||||
// }
|
||||
|
||||
// // 6. 构建成功结果
|
||||
// return o.createSuccessResult(cmd.CertificationID, enums.StatusContractApplied, "合同申请成功", map[string]interface{}{
|
||||
// "contract_sign_url": contractInfo.ContractSignURL,
|
||||
// "contract_url": contractInfo.ContractURL,
|
||||
// "next_action": "请在规定时间内完成合同签署",
|
||||
// }, result), nil
|
||||
}
|
||||
|
||||
// ================ e签宝回调处理 ================
|
||||
|
||||
// HandleEnterpriseVerificationCallback 处理企业认证回调
|
||||
func (o *CertificationWorkflowOrchestratorImpl) HandleEnterpriseVerificationCallback(
|
||||
ctx context.Context,
|
||||
cmd *EsignCallbackCommand,
|
||||
) (*WorkflowResult, error) {
|
||||
o.logger.Info("开始处理企业认证回调",
|
||||
zap.String("certification_id", cmd.CertificationID),
|
||||
zap.String("callback_type", cmd.CallbackType))
|
||||
return nil, nil
|
||||
// // 1. 验证回调数据
|
||||
// if err := o.callbackHandler.ValidateCallbackData(cmd.CallbackData); err != nil {
|
||||
// return o.createFailureResult(cmd.CertificationID, "", fmt.Sprintf("回调数据验证失败: %s", err.Error())), err
|
||||
// }
|
||||
|
||||
// // 2. 加载认证聚合根
|
||||
// cert, err := o.aggregateService.LoadCertification(ctx, cmd.CertificationID)
|
||||
// if err != nil {
|
||||
// return o.createFailureResult(cmd.CertificationID, "", fmt.Sprintf("加载认证信息失败: %s", err.Error())), err
|
||||
// }
|
||||
|
||||
// // 3. 验证回调处理前置条件
|
||||
// if cert.Status != enums.StatusInfoSubmitted {
|
||||
// return o.createFailureResult(cmd.CertificationID, cert.Status,
|
||||
// fmt.Sprintf("当前状态 %s 不允许处理企业认证回调", enums.GetStatusName(cert.Status))),
|
||||
// fmt.Errorf("无效的状态转换")
|
||||
// }
|
||||
|
||||
// // 4. 处理回调
|
||||
// err = o.callbackHandler.HandleCallback(ctx, cmd.CertificationID, cmd.CallbackData)
|
||||
// if err != nil {
|
||||
// o.logger.Error("处理企业认证回调失败", zap.Error(err))
|
||||
// return o.createFailureResult(cmd.CertificationID, cert.Status, fmt.Sprintf("回调处理失败: %s", err.Error())), err
|
||||
// }
|
||||
|
||||
// // 5. 重新加载认证信息获取最新状态
|
||||
// updatedCert, err := o.aggregateService.LoadCertification(ctx, cmd.CertificationID)
|
||||
// if err != nil {
|
||||
// return o.createFailureResult(cmd.CertificationID, cert.Status, "加载更新后的认证信息失败"), err
|
||||
// }
|
||||
|
||||
// // 6. 构建结果
|
||||
// message := "企业认证回调处理成功"
|
||||
// data := map[string]interface{}{
|
||||
// "auth_flow_id": cmd.CallbackData.FlowID,
|
||||
// "status": cmd.CallbackData.Status,
|
||||
// }
|
||||
|
||||
// if updatedCert.Status == enums.StatusEnterpriseVerified {
|
||||
// message = "企业认证成功"
|
||||
// data["next_action"] = "可以申请合同签署"
|
||||
// } else if updatedCert.Status == enums.StatusInfoRejected {
|
||||
// message = "企业认证失败"
|
||||
// data["next_action"] = "请修正企业信息后重新提交"
|
||||
// data["failure_reason"] = enums.GetFailureReasonName(updatedCert.FailureReason)
|
||||
// data["failure_message"] = updatedCert.FailureMessage
|
||||
// }
|
||||
|
||||
// return o.createSuccessResult(cmd.CertificationID, updatedCert.Status, message, data, nil), nil
|
||||
}
|
||||
|
||||
// HandleContractSignCallback 处理合同签署回调
|
||||
func (o *CertificationWorkflowOrchestratorImpl) HandleContractSignCallback(
|
||||
ctx context.Context,
|
||||
cmd *EsignCallbackCommand,
|
||||
) (*WorkflowResult, error) {
|
||||
o.logger.Info("开始处理合同签署回调",
|
||||
zap.String("certification_id", cmd.CertificationID),
|
||||
zap.String("callback_type", cmd.CallbackType))
|
||||
|
||||
// // 1. 验证回调数据
|
||||
// if err := o.callbackHandler.ValidateCallbackData(cmd.CallbackData); err != nil {
|
||||
// return o.createFailureResult(cmd.CertificationID, "", fmt.Sprintf("回调数据验证失败: %s", err.Error())), err
|
||||
// }
|
||||
|
||||
// // 2. 加载认证聚合根
|
||||
// cert, err := o.aggregateService.LoadCertification(ctx, cmd.CertificationID)
|
||||
// if err != nil {
|
||||
// return o.createFailureResult(cmd.CertificationID, "", fmt.Sprintf("加载认证信息失败: %s", err.Error())), err
|
||||
// }
|
||||
|
||||
// // 3. 验证回调处理前置条件
|
||||
// if cert.Status != enums.StatusContractApplied {
|
||||
// return o.createFailureResult(cmd.CertificationID, cert.Status,
|
||||
// fmt.Sprintf("当前状态 %s 不允许处理合同签署回调", enums.GetStatusName(cert.Status))),
|
||||
// fmt.Errorf("无效的状态转换")
|
||||
// }
|
||||
|
||||
// // 4. 处理回调
|
||||
// err = o.callbackHandler.HandleCallback(ctx, cmd.CertificationID, cmd.CallbackData)
|
||||
// if err != nil {
|
||||
// o.logger.Error("处理合同签署回调失败", zap.Error(err))
|
||||
// return o.createFailureResult(cmd.CertificationID, cert.Status, fmt.Sprintf("回调处理失败: %s", err.Error())), err
|
||||
// }
|
||||
|
||||
// // 5. 重新加载认证信息获取最新状态
|
||||
// updatedCert, err := o.aggregateService.LoadCertification(ctx, cmd.CertificationID)
|
||||
// if err != nil {
|
||||
// return o.createFailureResult(cmd.CertificationID, cert.Status, "加载更新后的认证信息失败"), err
|
||||
// }
|
||||
|
||||
// // 6. 构建结果
|
||||
// message := "合同签署回调处理成功"
|
||||
// data := map[string]interface{}{
|
||||
// "esign_flow_id": cmd.CallbackData.FlowID,
|
||||
// "status": cmd.CallbackData.Status,
|
||||
// }
|
||||
|
||||
// if updatedCert.Status == enums.StatusContractSigned {
|
||||
// message = "认证完成"
|
||||
// data["next_action"] = "认证流程已完成"
|
||||
// data["contract_url"] = updatedCert.ContractURL
|
||||
// } else if enums.IsFailureStatus(updatedCert.Status) {
|
||||
// message = "合同签署失败"
|
||||
// data["next_action"] = "可以重新申请合同签署"
|
||||
// data["failure_reason"] = enums.GetFailureReasonName(updatedCert.FailureReason)
|
||||
// data["failure_message"] = updatedCert.FailureMessage
|
||||
// }
|
||||
|
||||
// return o.createSuccessResult(cmd.CertificationID, updatedCert.Status, message, data, nil), nil
|
||||
return nil, nil
|
||||
|
||||
}
|
||||
|
||||
// ================ 异常处理 ================
|
||||
|
||||
// HandleFailure 处理业务失败
|
||||
func (o *CertificationWorkflowOrchestratorImpl) HandleFailure(
|
||||
ctx context.Context,
|
||||
certificationID string,
|
||||
failureType string,
|
||||
reason string,
|
||||
) (*WorkflowResult, error) {
|
||||
return nil, nil
|
||||
// o.logger.Info("开始处理业务失败",
|
||||
// zap.String("certification_id", certificationID),
|
||||
// zap.String("failure_type", failureType),
|
||||
// zap.String("reason", reason))
|
||||
|
||||
// // 1. 加载认证聚合根
|
||||
// cert, err := o.aggregateService.LoadCertification(ctx, certificationID)
|
||||
// if err != nil {
|
||||
// return o.createFailureResult(certificationID, "", fmt.Sprintf("加载认证信息失败: %s", err.Error())), err
|
||||
// }
|
||||
|
||||
// // 2. 根据失败类型执行相应处理
|
||||
// var targetStatus enums.CertificationStatus
|
||||
// var failureReason enums.FailureReason
|
||||
|
||||
// switch failureType {
|
||||
// case "enterprise_verification_failed":
|
||||
// targetStatus = enums.StatusInfoRejected
|
||||
// failureReason = enums.FailureReasonEsignVerificationFailed
|
||||
// case "contract_sign_failed":
|
||||
// targetStatus = enums.StatusContractRejected
|
||||
// failureReason = enums.FailureReasonSignProcessFailed
|
||||
// case "contract_expired":
|
||||
// targetStatus = enums.StatusContractExpired
|
||||
// failureReason = enums.FailureReasonContractExpired
|
||||
// default:
|
||||
// return o.createFailureResult(certificationID, cert.Status, fmt.Sprintf("未知的失败类型: %s", failureType)),
|
||||
// fmt.Errorf("未知的失败类型")
|
||||
// }
|
||||
|
||||
// // 3. 执行状态转换
|
||||
// metadata := map[string]interface{}{
|
||||
// "failure_reason": failureReason,
|
||||
// "failure_message": reason,
|
||||
// }
|
||||
|
||||
// result, err := o.aggregateService.TransitionState(
|
||||
// ctx,
|
||||
// certificationID,
|
||||
// targetStatus,
|
||||
// enums.ActorTypeSystem,
|
||||
// "failure_handler",
|
||||
// fmt.Sprintf("系统处理失败: %s", reason),
|
||||
// metadata,
|
||||
// )
|
||||
// if err != nil {
|
||||
// return o.createFailureResult(certificationID, cert.Status, fmt.Sprintf("失败处理状态转换失败: %s", err.Error())), err
|
||||
// }
|
||||
|
||||
// return o.createSuccessResult(certificationID, targetStatus, "失败处理完成", map[string]interface{}{
|
||||
// "failure_type": failureType,
|
||||
// "failure_reason": enums.GetFailureReasonName(failureReason),
|
||||
// "can_retry": enums.IsRetryable(failureReason),
|
||||
// }, result), nil
|
||||
}
|
||||
|
||||
// ================ 查询操作 ================
|
||||
|
||||
// GetWorkflowStatus 获取工作流状态
|
||||
func (o *CertificationWorkflowOrchestratorImpl) GetWorkflowStatus(
|
||||
ctx context.Context,
|
||||
certificationID string,
|
||||
) (*WorkflowResult, error) {
|
||||
// 加载认证聚合根
|
||||
cert, err := o.aggregateService.LoadCertification(ctx, certificationID)
|
||||
if err != nil {
|
||||
return o.createFailureResult(certificationID, "", fmt.Sprintf("加载认证信息失败: %s", err.Error())), err
|
||||
}
|
||||
|
||||
// 构建状态信息
|
||||
data := map[string]interface{}{
|
||||
"status": cert.Status,
|
||||
"status_name": enums.GetStatusName(cert.Status),
|
||||
"progress": cert.GetProgress(),
|
||||
"is_final": cert.IsFinalStatus(),
|
||||
"is_completed": cert.IsCompleted(),
|
||||
"user_action_required": cert.IsUserActionRequired(),
|
||||
"next_action": o.getNextActionForStatus(cert.Status),
|
||||
"available_actions": cert.GetAvailableActions(),
|
||||
}
|
||||
|
||||
// 添加失败信息(如果存在)
|
||||
if enums.IsFailureStatus(cert.Status) {
|
||||
data["failure_reason"] = enums.GetFailureReasonName(cert.FailureReason)
|
||||
data["failure_message"] = cert.FailureMessage
|
||||
data["can_retry"] = enums.IsRetryable(cert.FailureReason)
|
||||
data["retry_count"] = cert.RetryCount
|
||||
}
|
||||
|
||||
// 添加时间戳信息
|
||||
if cert.InfoSubmittedAt != nil {
|
||||
data["info_submitted_at"] = cert.InfoSubmittedAt
|
||||
}
|
||||
if cert.EnterpriseVerifiedAt != nil {
|
||||
data["enterprise_verified_at"] = cert.EnterpriseVerifiedAt
|
||||
}
|
||||
if cert.ContractAppliedAt != nil {
|
||||
data["contract_applied_at"] = cert.ContractAppliedAt
|
||||
}
|
||||
if cert.ContractSignedAt != nil {
|
||||
data["contract_signed_at"] = cert.ContractSignedAt
|
||||
}
|
||||
|
||||
return o.createSuccessResult(certificationID, cert.Status, "工作流状态查询成功", data), nil
|
||||
}
|
||||
|
||||
// ================ 辅助方法 ================
|
||||
|
||||
// validateApplyContractCommand 验证申请合同命令
|
||||
func (o *CertificationWorkflowOrchestratorImpl) validateApplyContractCommand(cmd *ApplyContractCommand) error {
|
||||
if cmd.CertificationID == "" {
|
||||
return fmt.Errorf("认证ID不能为空")
|
||||
}
|
||||
if cmd.UserID == "" {
|
||||
return fmt.Errorf("用户ID不能为空")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateEnterpriseInfoSubmissionPreconditions 验证企业信息提交前置条件
|
||||
func (o *CertificationWorkflowOrchestratorImpl) validateEnterpriseInfoSubmissionPreconditions(cert *entities.Certification, userID string) error {
|
||||
if cert.UserID != userID {
|
||||
return fmt.Errorf("用户无权限操作此认证申请")
|
||||
}
|
||||
if cert.Status != enums.StatusPending && cert.Status != enums.StatusInfoRejected {
|
||||
return fmt.Errorf("当前状态 %s 不允许提交企业信息", enums.GetStatusName(cert.Status))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateContractApplicationPreconditions 验证合同申请前置条件
|
||||
func (o *CertificationWorkflowOrchestratorImpl) validateContractApplicationPreconditions(cert *entities.Certification, userID string) error {
|
||||
if cert.UserID != userID {
|
||||
return fmt.Errorf("用户无权限操作此认证申请")
|
||||
}
|
||||
if cert.Status != enums.StatusEnterpriseVerified {
|
||||
return fmt.Errorf("必须先完成企业认证才能申请合同")
|
||||
}
|
||||
if cert.AuthFlowID == "" {
|
||||
return fmt.Errorf("缺少企业认证流程ID")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// triggerEnterpriseVerification 触发企业认证
|
||||
func (o *CertificationWorkflowOrchestratorImpl) triggerEnterpriseVerification(ctx context.Context, certificationID string, enterpriseInfo *value_objects.EnterpriseInfo) error {
|
||||
// TODO: 调用e签宝API进行企业认证
|
||||
o.logger.Info("触发企业认证",
|
||||
zap.String("certification_id", certificationID),
|
||||
zap.String("company_name", enterpriseInfo.CompanyName))
|
||||
return nil
|
||||
}
|
||||
|
||||
// generateContractAndSignURL 生成合同和签署链接
|
||||
func (o *CertificationWorkflowOrchestratorImpl) generateContractAndSignURL(ctx context.Context, certificationID string, cert *entities.Certification) (*value_objects.ContractInfo, error) {
|
||||
// TODO: 调用e签宝API生成合同和签署链接
|
||||
o.logger.Info("生成合同和签署链接", zap.String("certification_id", certificationID))
|
||||
|
||||
// 临时返回模拟数据
|
||||
contractInfo, err := value_objects.NewContractInfo(
|
||||
"contract_file_"+certificationID,
|
||||
"esign_flow_"+certificationID,
|
||||
"https://example.com/contract/"+certificationID,
|
||||
"https://example.com/sign/"+certificationID,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return contractInfo, nil
|
||||
}
|
||||
|
||||
// getNextActionForStatus 获取状态对应的下一步操作提示
|
||||
func (o *CertificationWorkflowOrchestratorImpl) getNextActionForStatus(status enums.CertificationStatus) string {
|
||||
return enums.GetUserActionHint(status)
|
||||
}
|
||||
|
||||
// createSuccessResult 创建成功结果
|
||||
func (o *CertificationWorkflowOrchestratorImpl) createSuccessResult(
|
||||
certificationID string,
|
||||
status enums.CertificationStatus,
|
||||
message string,
|
||||
data map[string]interface{},
|
||||
) *WorkflowResult {
|
||||
return &WorkflowResult{
|
||||
Success: true,
|
||||
CertificationID: certificationID,
|
||||
CurrentStatus: status,
|
||||
Message: message,
|
||||
Data: data,
|
||||
ExecutedAt: time.Now(),
|
||||
}
|
||||
}
|
||||
|
||||
// createFailureResult 创建失败结果
|
||||
func (o *CertificationWorkflowOrchestratorImpl) createFailureResult(
|
||||
certificationID string,
|
||||
status enums.CertificationStatus,
|
||||
message string,
|
||||
) *WorkflowResult {
|
||||
return &WorkflowResult{
|
||||
Success: false,
|
||||
CertificationID: certificationID,
|
||||
CurrentStatus: status,
|
||||
Message: message,
|
||||
Data: map[string]interface{}{},
|
||||
ExecutedAt: time.Now(),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hyapi-server/internal/config"
|
||||
"hyapi-server/internal/domains/api/dto"
|
||||
"hyapi-server/internal/domains/api/services/processors"
|
||||
"hyapi-server/internal/domains/api/services/processors/qygl"
|
||||
"hyapi-server/internal/domains/certification/entities"
|
||||
"hyapi-server/internal/domains/certification/entities/value_objects"
|
||||
"hyapi-server/internal/domains/certification/repositories"
|
||||
"hyapi-server/internal/infrastructure/external/alicloud"
|
||||
"hyapi-server/internal/infrastructure/external/tianyancha"
|
||||
"hyapi-server/internal/infrastructure/external/westdex"
|
||||
"hyapi-server/internal/infrastructure/external/yushan"
|
||||
"hyapi-server/internal/shared/interfaces"
|
||||
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// EnterpriseInfoSubmitRecordService 企业信息提交记录领域服务
|
||||
// 负责与westdex等外部服务交互
|
||||
// 领域服务应无状态
|
||||
|
||||
type EnterpriseInfoSubmitRecordService struct {
|
||||
westdexService *westdex.WestDexService
|
||||
tianYanChaService *tianyancha.TianYanChaService
|
||||
alicloudService *alicloud.AlicloudService
|
||||
yushanService *yushan.YushanService
|
||||
validator interfaces.RequestValidator
|
||||
repositories repositories.EnterpriseInfoSubmitRecordRepository
|
||||
appConfig config.AppConfig
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
// NewEnterpriseInfoSubmitRecordService 构造函数
|
||||
func NewEnterpriseInfoSubmitRecordService(
|
||||
westdexService *westdex.WestDexService,
|
||||
tianYanChaService *tianyancha.TianYanChaService,
|
||||
alicloudService *alicloud.AlicloudService,
|
||||
yushanService *yushan.YushanService,
|
||||
validator interfaces.RequestValidator,
|
||||
repositories repositories.EnterpriseInfoSubmitRecordRepository,
|
||||
appConfig config.AppConfig,
|
||||
logger *zap.Logger,
|
||||
) *EnterpriseInfoSubmitRecordService {
|
||||
return &EnterpriseInfoSubmitRecordService{
|
||||
westdexService: westdexService,
|
||||
tianYanChaService: tianYanChaService,
|
||||
alicloudService: alicloudService,
|
||||
yushanService: yushanService,
|
||||
validator: validator,
|
||||
repositories: repositories,
|
||||
appConfig: appConfig,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
// Save 保存企业信息提交记录
|
||||
func (s *EnterpriseInfoSubmitRecordService) Save(ctx context.Context, enterpriseInfoSubmitRecord *entities.EnterpriseInfoSubmitRecord) error {
|
||||
exists, err := s.repositories.Exists(ctx, enterpriseInfoSubmitRecord.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if exists {
|
||||
return s.repositories.Update(ctx, enterpriseInfoSubmitRecord)
|
||||
}
|
||||
return s.repositories.Create(ctx, enterpriseInfoSubmitRecord)
|
||||
}
|
||||
|
||||
// ValidateWithWestdex 调用QYGL5CMP处理器验证企业信息
|
||||
func (s *EnterpriseInfoSubmitRecordService) ValidateWithWestdex(ctx context.Context, info *value_objects.EnterpriseInfo) error {
|
||||
if info == nil {
|
||||
return errors.New("企业信息不能为空")
|
||||
}
|
||||
// 先做本地校验
|
||||
if err := info.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 开发环境下跳过外部验证
|
||||
// if s.appConfig.IsDevelopment() {
|
||||
// s.logger.Info("开发环境:跳过企业信息外部验证",
|
||||
// zap.String("company_name", info.CompanyName),
|
||||
// zap.String("legal_person", info.LegalPersonName))
|
||||
// return nil
|
||||
// }
|
||||
|
||||
// 构建QYGL5CMP请求参数
|
||||
reqDto := dto.QYGL5CMPReq{
|
||||
EntName: info.CompanyName,
|
||||
LegalPerson: info.LegalPersonName,
|
||||
EntCode: info.UnifiedSocialCode,
|
||||
IDCard: info.LegalPersonID,
|
||||
MobileNo: info.LegalPersonPhone,
|
||||
}
|
||||
|
||||
// 序列化请求参数
|
||||
paramsBytes, err := json.Marshal(reqDto)
|
||||
if err != nil {
|
||||
return fmt.Errorf("序列化请求参数失败: %w", err)
|
||||
}
|
||||
|
||||
// 创建处理器依赖
|
||||
deps := &processors.ProcessorDependencies{
|
||||
WestDexService: s.westdexService,
|
||||
TianYanChaService: s.tianYanChaService,
|
||||
AlicloudService: s.alicloudService,
|
||||
YushanService: s.yushanService,
|
||||
Validator: s.validator,
|
||||
}
|
||||
|
||||
// 调用QYGL23T7处理器进行验证
|
||||
responseBytes, err := qygl.ProcessQYGL23T7Request(ctx, paramsBytes, deps)
|
||||
if err != nil {
|
||||
// 检查是否是数据源错误企业信息不一致
|
||||
if errors.Is(err, processors.ErrDatasource) {
|
||||
return fmt.Errorf("数据源异常: %w", err)
|
||||
}
|
||||
return fmt.Errorf("企业信息验证失败: %w", err)
|
||||
}
|
||||
|
||||
// 解析响应结果
|
||||
var response map[string]interface{}
|
||||
if err := json.Unmarshal(responseBytes, &response); err != nil {
|
||||
return fmt.Errorf("解析响应结果失败: %w", err)
|
||||
}
|
||||
|
||||
// 检查验证状态
|
||||
status, ok := response["status"].(float64)
|
||||
if !ok {
|
||||
return fmt.Errorf("响应格式错误")
|
||||
}
|
||||
|
||||
// 根据状态码判断验证结果
|
||||
switch int(status) {
|
||||
case 0:
|
||||
// 验证通过
|
||||
s.logger.Info("企业信息验证通过",
|
||||
zap.String("company_name", info.CompanyName),
|
||||
zap.String("legal_person", info.LegalPersonName))
|
||||
return nil
|
||||
case 1:
|
||||
// 企业信息不一致
|
||||
return fmt.Errorf("企业信息不一致")
|
||||
case 2:
|
||||
// 身份证信息不一致
|
||||
return fmt.Errorf("身份证信息不一致")
|
||||
default:
|
||||
return fmt.Errorf("未知的验证状态: %d", int(status))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user