package services import ( "context" "fmt" "go.uber.org/zap" "tyapi-server/internal/domains/user/entities" "tyapi-server/internal/domains/user/repositories" ) // EnterpriseService 企业信息领域服务 type EnterpriseService struct { userRepo repositories.UserRepository enterpriseInfoRepo repositories.EnterpriseInfoRepository logger *zap.Logger } // NewEnterpriseService 创建企业信息领域服务 func NewEnterpriseService( userRepo repositories.UserRepository, enterpriseInfoRepo repositories.EnterpriseInfoRepository, logger *zap.Logger, ) *EnterpriseService { return &EnterpriseService{ userRepo: userRepo, enterpriseInfoRepo: enterpriseInfoRepo, logger: logger, } } // CreateEnterpriseInfo 创建企业信息 func (s *EnterpriseService) CreateEnterpriseInfo(ctx context.Context, userID, companyName, unifiedSocialCode, legalPersonName, legalPersonID string) (*entities.EnterpriseInfo, error) { // 检查用户是否存在 _, err := s.userRepo.GetByID(ctx, userID) if err != nil { return nil, fmt.Errorf("用户不存在: %w", err) } // 检查用户是否已有企业信息 existingInfo, err := s.enterpriseInfoRepo.GetByUserID(ctx, userID) if err == nil && existingInfo != nil { return nil, fmt.Errorf("用户已有企业信息") } // 检查统一社会信用代码是否已存在 exists, err := s.enterpriseInfoRepo.CheckUnifiedSocialCodeExists(ctx, unifiedSocialCode, "") if err != nil { return nil, fmt.Errorf("检查企业信息失败: %w", err) } if exists { return nil, fmt.Errorf("统一社会信用代码已存在") } // 创建企业信息 enterpriseInfo := &entities.EnterpriseInfo{ UserID: userID, CompanyName: companyName, UnifiedSocialCode: unifiedSocialCode, LegalPersonName: legalPersonName, LegalPersonID: legalPersonID, } *enterpriseInfo, err = s.enterpriseInfoRepo.Create(ctx, *enterpriseInfo) if err != nil { s.logger.Error("创建企业信息失败", zap.Error(err)) return nil, fmt.Errorf("创建企业信息失败: %w", err) } s.logger.Info("企业信息创建成功", zap.String("user_id", userID), zap.String("enterprise_id", enterpriseInfo.ID), zap.String("company_name", companyName), ) return enterpriseInfo, nil } // GetEnterpriseInfo 获取企业信息 func (s *EnterpriseService) GetEnterpriseInfo(ctx context.Context, userID string) (*entities.EnterpriseInfo, error) { // 检查用户是否存在 _, err := s.userRepo.GetByID(ctx, userID) if err != nil { return nil, fmt.Errorf("用户不存在: %w", err) } enterpriseInfo, err := s.enterpriseInfoRepo.GetByUserID(ctx, userID) if err != nil { return nil, fmt.Errorf("企业信息不存在: %w", err) } return enterpriseInfo, nil } // UpdateEnterpriseInfo 更新企业信息(仅限未认证完成的情况) func (s *EnterpriseService) UpdateEnterpriseInfo(ctx context.Context, userID, companyName, unifiedSocialCode, legalPersonName, legalPersonID string) (*entities.EnterpriseInfo, error) { // 检查用户是否存在 _, err := s.userRepo.GetByID(ctx, userID) if err != nil { return nil, fmt.Errorf("用户不存在: %w", err) } // 获取现有企业信息 enterpriseInfo, err := s.enterpriseInfoRepo.GetByUserID(ctx, userID) if err != nil { return nil, fmt.Errorf("企业信息不存在: %w", err) } // 检查企业信息是否已认证完成(认证完成后不可修改) if enterpriseInfo.IsReadOnly() { return nil, fmt.Errorf("企业信息已认证完成,不可修改") } // 检查统一社会信用代码是否已被其他用户使用 if unifiedSocialCode != enterpriseInfo.UnifiedSocialCode { exists, err := s.enterpriseInfoRepo.CheckUnifiedSocialCodeExists(ctx, unifiedSocialCode, userID) if err != nil { return nil, fmt.Errorf("检查企业信息失败: %w", err) } if exists { return nil, fmt.Errorf("统一社会信用代码已存在") } } // 更新企业信息 enterpriseInfo.CompanyName = companyName enterpriseInfo.UnifiedSocialCode = unifiedSocialCode enterpriseInfo.LegalPersonName = legalPersonName enterpriseInfo.LegalPersonID = legalPersonID if err := s.enterpriseInfoRepo.Update(ctx, *enterpriseInfo); err != nil { s.logger.Error("更新企业信息失败", zap.Error(err)) return nil, fmt.Errorf("更新企业信息失败: %w", err) } s.logger.Info("企业信息更新成功", zap.String("user_id", userID), zap.String("enterprise_id", enterpriseInfo.ID), ) return enterpriseInfo, nil } // UpdateOCRVerification 更新OCR验证状态 func (s *EnterpriseService) UpdateOCRVerification(ctx context.Context, userID string, isVerified bool, rawData string, confidence float64) error { // 获取企业信息 enterpriseInfo, err := s.enterpriseInfoRepo.GetByUserID(ctx, userID) if err != nil { return fmt.Errorf("企业信息不存在: %w", err) } // 更新OCR验证状态 enterpriseInfo.UpdateOCRVerification(isVerified, rawData, confidence) if err := s.enterpriseInfoRepo.Update(ctx, *enterpriseInfo); err != nil { s.logger.Error("更新OCR验证状态失败", zap.Error(err)) return fmt.Errorf("更新OCR验证状态失败: %w", err) } s.logger.Info("OCR验证状态更新成功", zap.String("user_id", userID), zap.Bool("is_verified", isVerified), zap.Float64("confidence", confidence), ) return nil } // UpdateFaceVerification 更新人脸识别验证状态 func (s *EnterpriseService) UpdateFaceVerification(ctx context.Context, userID string, isVerified bool) error { // 获取企业信息 enterpriseInfo, err := s.enterpriseInfoRepo.GetByUserID(ctx, userID) if err != nil { return fmt.Errorf("企业信息不存在: %w", err) } // 更新人脸识别验证状态 enterpriseInfo.UpdateFaceVerification(isVerified) if err := s.enterpriseInfoRepo.Update(ctx, *enterpriseInfo); err != nil { s.logger.Error("更新人脸识别验证状态失败", zap.Error(err)) return fmt.Errorf("更新人脸识别验证状态失败: %w", err) } s.logger.Info("人脸识别验证状态更新成功", zap.String("user_id", userID), zap.Bool("is_verified", isVerified), ) return nil } // CompleteEnterpriseCertification 完成企业认证 func (s *EnterpriseService) CompleteEnterpriseCertification(ctx context.Context, userID string) error { // 获取企业信息 enterpriseInfo, err := s.enterpriseInfoRepo.GetByUserID(ctx, userID) if err != nil { return fmt.Errorf("企业信息不存在: %w", err) } // 检查是否已完成所有验证 if !enterpriseInfo.IsOCRVerified || !enterpriseInfo.IsFaceVerified { return fmt.Errorf("企业信息验证未完成,无法完成认证") } // 完成认证 enterpriseInfo.CompleteCertification() if err := s.enterpriseInfoRepo.Update(ctx, *enterpriseInfo); err != nil { s.logger.Error("完成企业认证失败", zap.Error(err)) return fmt.Errorf("完成企业认证失败: %w", err) } s.logger.Info("企业认证完成", zap.String("user_id", userID), zap.String("enterprise_id", enterpriseInfo.ID), ) return nil } // CheckUnifiedSocialCodeExists 检查统一社会信用代码是否存在 func (s *EnterpriseService) CheckUnifiedSocialCodeExists(ctx context.Context, unifiedSocialCode, excludeUserID string) (bool, error) { return s.enterpriseInfoRepo.CheckUnifiedSocialCodeExists(ctx, unifiedSocialCode, excludeUserID) } // GetUserWithEnterpriseInfo 获取用户信息(包含企业信息) func (s *EnterpriseService) GetUserWithEnterpriseInfo(ctx context.Context, userID string) (*entities.User, error) { // 获取用户信息 user, err := s.userRepo.GetByID(ctx, userID) if err != nil { return nil, fmt.Errorf("用户不存在: %w", err) } // 获取企业信息(如果存在) enterpriseInfo, err := s.enterpriseInfoRepo.GetByUserID(ctx, userID) if err != nil { // 企业信息不存在是正常的,不是错误 s.logger.Debug("用户暂无企业信息", zap.String("user_id", userID)) } else { user.EnterpriseInfo = enterpriseInfo } return &user, nil } // ValidateEnterpriseInfo 验证企业信息完整性 func (s *EnterpriseService) ValidateEnterpriseInfo(ctx context.Context, userID string) error { enterpriseInfo, err := s.enterpriseInfoRepo.GetByUserID(ctx, userID) if err != nil { return fmt.Errorf("企业信息不存在: %w", err) } if err := enterpriseInfo.Validate(); err != nil { return fmt.Errorf("企业信息验证失败: %w", err) } return nil } // GetEnterpriseInfoByUnifiedSocialCode 根据统一社会信用代码获取企业信息 func (s *EnterpriseService) GetEnterpriseInfoByUnifiedSocialCode(ctx context.Context, unifiedSocialCode string) (*entities.EnterpriseInfo, error) { return s.enterpriseInfoRepo.GetByUnifiedSocialCode(ctx, unifiedSocialCode) } // IsEnterpriseCertified 检查用户是否已完成企业认证 func (s *EnterpriseService) IsEnterpriseCertified(ctx context.Context, userID string) (bool, error) { enterpriseInfo, err := s.enterpriseInfoRepo.GetByUserID(ctx, userID) if err != nil { // 没有企业信息,认为未认证 return false, nil } return enterpriseInfo.IsFullyVerified(), nil } // GetEnterpriseCertificationStatus 获取企业认证状态 func (s *EnterpriseService) GetEnterpriseCertificationStatus(ctx context.Context, userID string) (map[string]interface{}, error) { enterpriseInfo, err := s.enterpriseInfoRepo.GetByUserID(ctx, userID) if err != nil { return map[string]interface{}{ "has_enterprise_info": false, "is_certified": false, "message": "用户暂无企业信息", }, nil } status := map[string]interface{}{ "has_enterprise_info": true, "is_certified": enterpriseInfo.IsFullyVerified(), "is_readonly": enterpriseInfo.IsReadOnly(), "ocr_verified": enterpriseInfo.IsOCRVerified, "face_verified": enterpriseInfo.IsFaceVerified, "certified_at": enterpriseInfo.CertifiedAt, "company_name": enterpriseInfo.CompanyName, "unified_social_code": enterpriseInfo.UnifiedSocialCode, "legal_person_name": enterpriseInfo.LegalPersonName, "created_at": enterpriseInfo.CreatedAt, "updated_at": enterpriseInfo.UpdatedAt, } return status, nil }