This commit is contained in:
Mrx
2026-03-26 16:08:48 +08:00
parent e095553ba8
commit a6a2d8d9c5
2 changed files with 105 additions and 2 deletions

View File

@@ -108,13 +108,21 @@ func (s *CertificationApplicationServiceImpl) SubmitEnterpriseInfo(
cmd *commands.SubmitEnterpriseInfoCommand,
) (*responses.CertificationResponse, error) {
s.logger.Info("开始提交企业信息",
zap.String("user_id", cmd.UserID))
zap.String("user_id", cmd.UserID),
zap.String("company_name", cmd.CompanyName),
zap.String("unified_social_code", cmd.UnifiedSocialCode))
// 0. 若该用户已有待审核(认证状态仍在待审核),则不允许重复提交
latestRecord, err := s.enterpriseInfoSubmitRecordRepo.FindLatestByUserID(ctx, cmd.UserID)
if err == nil && latestRecord != nil {
s.logger.Info("步骤0-检测到历史提交记录",
zap.String("user_id", cmd.UserID),
zap.String("latest_record_id", latestRecord.ID))
cert, loadErr := s.aggregateService.LoadCertificationByUserID(ctx, cmd.UserID)
if loadErr == nil && cert != nil && cert.Status == enums.StatusInfoPendingReview {
s.logger.Warn("步骤0-存在待审核记录,拒绝重复提交",
zap.String("user_id", cmd.UserID),
zap.String("cert_status", string(cert.Status)))
return nil, fmt.Errorf("您已有待审核的提交,请等待管理员审核后再操作")
}
}
@@ -163,7 +171,11 @@ func (s *CertificationApplicationServiceImpl) SubmitEnterpriseInfo(
// 验证验证码
// 特殊验证码"768005"直接跳过验证环节
if cmd.VerificationCode != "768005" {
s.logger.Info("步骤1-开始验证短信验证码", zap.String("user_id", cmd.UserID))
if err := s.smsCodeService.VerifyCode(ctx, cmd.LegalPersonPhone, cmd.VerificationCode, user_entities.SMSSceneCertification); err != nil {
s.logger.Warn("步骤1-短信验证码校验失败",
zap.String("user_id", cmd.UserID),
zap.Error(err))
record.MarkAsFailed(err.Error())
saveErr := s.enterpriseInfoSubmitRecordService.Save(ctx, record)
if saveErr != nil {
@@ -171,6 +183,9 @@ func (s *CertificationApplicationServiceImpl) SubmitEnterpriseInfo(
}
return nil, fmt.Errorf("验证码错误或已过期")
}
s.logger.Info("步骤1-短信验证码校验通过", zap.String("user_id", cmd.UserID))
} else {
s.logger.Info("步骤1-命中特殊验证码,跳过校验", zap.String("user_id", cmd.UserID))
}
s.logger.Info("开始处理企业信息提交",
zap.String("user_id", cmd.UserID))
@@ -178,6 +193,10 @@ func (s *CertificationApplicationServiceImpl) SubmitEnterpriseInfo(
// 1.1 已写入用户域 enterprise_infos 的(已完成认证)
exists, err := s.userAggregateService.CheckUnifiedSocialCodeExists(ctx, cmd.UnifiedSocialCode, cmd.UserID)
if err != nil {
s.logger.Error("步骤2.1-检查用户域统一社会信用代码失败",
zap.String("user_id", cmd.UserID),
zap.String("unified_social_code", cmd.UnifiedSocialCode),
zap.Error(err))
record.MarkAsFailed(err.Error())
saveErr := s.enterpriseInfoSubmitRecordService.Save(ctx, record)
if saveErr != nil {
@@ -186,6 +205,9 @@ func (s *CertificationApplicationServiceImpl) SubmitEnterpriseInfo(
return nil, fmt.Errorf("检查企业信息失败: %s", err.Error())
}
if exists {
s.logger.Warn("步骤2.1-统一社会信用代码已被占用(用户域)",
zap.String("user_id", cmd.UserID),
zap.String("unified_social_code", cmd.UnifiedSocialCode))
record.MarkAsFailed("该企业信息已被其他用户使用,请确认企业信息是否正确")
saveErr := s.enterpriseInfoSubmitRecordService.Save(ctx, record)
if saveErr != nil {
@@ -196,6 +218,10 @@ func (s *CertificationApplicationServiceImpl) SubmitEnterpriseInfo(
// 1.2 已提交/已通过验证的提交记录(尚未完成认证但已占用的信用代码)
existsInSubmit, err := s.enterpriseInfoSubmitRecordRepo.ExistsByUnifiedSocialCodeExcludeUser(ctx, cmd.UnifiedSocialCode, cmd.UserID)
if err != nil {
s.logger.Error("步骤2.2-检查提交记录统一社会信用代码失败",
zap.String("user_id", cmd.UserID),
zap.String("unified_social_code", cmd.UnifiedSocialCode),
zap.Error(err))
record.MarkAsFailed(err.Error())
saveErr := s.enterpriseInfoSubmitRecordService.Save(ctx, record)
if saveErr != nil {
@@ -204,6 +230,9 @@ func (s *CertificationApplicationServiceImpl) SubmitEnterpriseInfo(
return nil, fmt.Errorf("检查企业信息失败: %s", err.Error())
}
if existsInSubmit {
s.logger.Warn("步骤2.2-统一社会信用代码已被占用(提交记录)",
zap.String("user_id", cmd.UserID),
zap.String("unified_social_code", cmd.UnifiedSocialCode))
record.MarkAsFailed("该企业信息已被其他用户使用,请确认企业信息是否正确")
saveErr := s.enterpriseInfoSubmitRecordService.Save(ctx, record)
if saveErr != nil {
@@ -230,6 +259,9 @@ func (s *CertificationApplicationServiceImpl) SubmitEnterpriseInfo(
}
return nil, fmt.Errorf("企业信息验证失败: %s", err.Error())
}
s.logger.Info("步骤3-企业信息基础校验通过",
zap.String("user_id", cmd.UserID),
zap.String("company_name", enterpriseInfo.CompanyName))
err = s.enterpriseInfoSubmitRecordService.ValidateWithWestdex(ctx, enterpriseInfo)
if err != nil {
s.logger.Error("企业信息验证失败", zap.Error(err))
@@ -240,10 +272,14 @@ func (s *CertificationApplicationServiceImpl) SubmitEnterpriseInfo(
}
return nil, fmt.Errorf("企业信息验证失败, %s", err.Error())
}
s.logger.Info("步骤4-企业信息三方校验通过",
zap.String("user_id", cmd.UserID),
zap.String("company_name", enterpriseInfo.CompanyName))
record.MarkAsVerified()
var response *responses.CertificationResponse
err = s.txManager.ExecuteInTx(ctx, func(txCtx context.Context) error {
s.logger.Info("步骤5-开始事务处理认证提交流程", zap.String("user_id", cmd.UserID))
// 2. 检查用户认证是否存在
existsCert, err := s.aggregateService.ExistsByUserID(txCtx, cmd.UserID)
if err != nil {
@@ -251,10 +287,12 @@ func (s *CertificationApplicationServiceImpl) SubmitEnterpriseInfo(
}
if !existsCert {
// 创建
s.logger.Info("步骤5.1-认证记录不存在,开始创建", zap.String("user_id", cmd.UserID))
_, err := s.aggregateService.CreateCertification(txCtx, cmd.UserID)
if err != nil {
return fmt.Errorf("创建认证信息失败: %s", err.Error())
}
s.logger.Info("步骤5.1-认证记录创建成功", zap.String("user_id", cmd.UserID))
}
// 3. 加载认证聚合根
@@ -277,9 +315,15 @@ func (s *CertificationApplicationServiceImpl) SubmitEnterpriseInfo(
}
authURL, alreadyVerified, err := s.generateEnterpriseAuthOrDetectVerified(txCtx, authReq)
if err != nil {
s.logger.Error("步骤5.2-生成企业认证链接失败",
zap.String("user_id", cmd.UserID),
zap.Error(err))
return fmt.Errorf("生成企业认证链接失败: %w", err)
}
if alreadyVerified {
s.logger.Info("步骤5.2-检测到企业已实名,进入自动完成认证流程",
zap.String("user_id", cmd.UserID),
zap.String("company_name", enterpriseInfo.CompanyName))
// 三方侧已实名:先进入 info_submitted再在同事务内自动推进到 enterprise_verified。
if err = cert.SubmitEnterpriseInfo(enterpriseInfo, "", ""); err != nil {
return fmt.Errorf("提交企业信息失败: %s", err.Error())
@@ -287,7 +331,11 @@ func (s *CertificationApplicationServiceImpl) SubmitEnterpriseInfo(
if err = s.completeEnterpriseVerification(txCtx, cert, cert.UserID, enterpriseInfo.CompanyName, enterpriseInfo.LegalPersonName); err != nil {
return fmt.Errorf("自动完成企业认证失败: %w", err)
}
s.logger.Info("步骤5.2-自动完成企业认证成功", zap.String("user_id", cmd.UserID))
} else {
s.logger.Info("步骤5.2-企业未实名,写入认证链接并等待用户操作",
zap.String("user_id", cmd.UserID),
zap.String("auth_flow_id", authURL.AuthFlowID))
err = cert.SubmitEnterpriseInfo(enterpriseInfo, authURL.AuthShortURL, authURL.AuthFlowID)
if err != nil {
return fmt.Errorf("提交企业信息失败: %s", err.Error())
@@ -296,12 +344,16 @@ func (s *CertificationApplicationServiceImpl) SubmitEnterpriseInfo(
if err != nil {
return fmt.Errorf("保存认证信息失败: %s", err.Error())
}
s.logger.Info("步骤5.2-认证信息保存成功(待用户完成企业认证)", zap.String("user_id", cmd.UserID))
}
// 5. 提交记录与认证状态在同一事务内保存
if saveErr := s.enterpriseInfoSubmitRecordService.Save(txCtx, record); saveErr != nil {
return fmt.Errorf("保存企业信息提交记录失败: %s", saveErr.Error())
}
s.logger.Info("步骤5.3-企业信息提交记录保存成功",
zap.String("user_id", cmd.UserID),
zap.String("record_id", record.ID))
respMeta := map[string]interface{}{
"enterprise_info": enterpriseInfo,
@@ -365,13 +417,23 @@ func (s *CertificationApplicationServiceImpl) ConfirmAuth(
}
// 步骤二:审核状态检查(审核通过后才能进入企业认证确认)
s.logger.Info("确认状态-步骤1-开始审核状态检查", zap.String("user_id", cmd.UserID))
if err := s.checkAuditStatus(ctx, cert); err != nil {
return nil, err
}
s.logger.Info("确认状态-步骤1-审核状态检查通过",
zap.String("user_id", cmd.UserID),
zap.String("cert_status", string(cert.Status)))
record, err := s.enterpriseInfoSubmitRecordRepo.FindLatestByUserID(ctx, cert.UserID)
if err != nil {
return nil, fmt.Errorf("查找企业信息失败: %w", err)
}
s.logger.Info("确认状态-步骤2-获取最近提交记录成功",
zap.String("user_id", cmd.UserID),
zap.String("record_id", record.ID))
s.logger.Info("确认状态-步骤3-开始查询三方实名状态",
zap.String("user_id", cmd.UserID),
zap.String("company_name", record.CompanyName))
identity, err := s.esignClient.QueryOrgIdentityInfo(&esign.QueryOrgIdentityRequest{
OrgName: record.CompanyName,
})
@@ -381,6 +443,8 @@ func (s *CertificationApplicationServiceImpl) ConfirmAuth(
}
reason := ""
if identity != nil && identity.Data.RealnameStatus == 1 {
s.logger.Info("确认状态-步骤3-三方实名状态已完成,准备事务内推进认证",
zap.String("user_id", cmd.UserID))
err = s.txManager.ExecuteInTx(ctx, func(txCtx context.Context) error {
err = s.completeEnterpriseVerification(txCtx, cert, cert.UserID, record.CompanyName, record.LegalPersonName)
if err != nil {
@@ -392,8 +456,13 @@ func (s *CertificationApplicationServiceImpl) ConfirmAuth(
if err != nil {
return nil, fmt.Errorf("完成企业认证失败: %w", err)
}
s.logger.Info("确认状态-步骤4-认证状态推进完成",
zap.String("user_id", cmd.UserID),
zap.String("cert_status", string(cert.Status)))
} else {
reason = "企业未完成"
s.logger.Info("确认状态-步骤3-三方实名状态未完成",
zap.String("user_id", cmd.UserID))
}
return &responses.ConfirmAuthResponse{
Status: cert.Status,
@@ -1085,11 +1154,20 @@ func (s *CertificationApplicationServiceImpl) generateEnterpriseAuthOrDetectVeri
ctx context.Context,
req *esign.EnterpriseAuthRequest,
) (*esign.EnterpriseAuthResult, bool, error) {
s.logger.Info("企业认证链接生成-步骤1-开始调用三方创建认证链接",
zap.String("company_name", req.CompanyName),
zap.String("unified_social_code", req.UnifiedSocialCode))
authURL, err := s.esignClient.GenerateEnterpriseAuth(req)
if err == nil {
s.logger.Info("企业认证链接生成-步骤1-创建成功",
zap.String("company_name", req.CompanyName),
zap.String("auth_flow_id", authURL.AuthFlowID))
return authURL, false, nil
}
if !isEnterpriseAlreadyRealnamedErr(err) {
s.logger.Error("企业认证链接生成-步骤1-创建失败且非已实名场景",
zap.String("company_name", req.CompanyName),
zap.Error(err))
return nil, false, err
}
@@ -1103,6 +1181,9 @@ func (s *CertificationApplicationServiceImpl) generateEnterpriseAuthOrDetectVeri
OrgIDCardType: esign.OrgIDCardTypeUSCC,
})
if identityErr != nil {
s.logger.Warn("企业认证链接生成-步骤2-按信用代码查询实名状态失败,回退按企业名查询",
zap.String("company_name", req.CompanyName),
zap.Error(identityErr))
identity, identityErr = s.esignClient.QueryOrgIdentityInfo(&esign.QueryOrgIdentityRequest{
OrgName: req.CompanyName,
})
@@ -1110,9 +1191,14 @@ func (s *CertificationApplicationServiceImpl) generateEnterpriseAuthOrDetectVeri
if identityErr != nil {
return nil, false, fmt.Errorf("企业用户已实名,但查询实名状态失败: %w", identityErr)
}
s.logger.Info("企业认证链接生成-步骤2-实名状态查询成功",
zap.String("company_name", req.CompanyName),
zap.Int32("realname_status", identity.Data.RealnameStatus))
if identity == nil || identity.Data.RealnameStatus != 1 {
return nil, false, err
}
s.logger.Info("企业认证链接生成-步骤3-确认企业已实名,返回自动确认标记",
zap.String("company_name", req.CompanyName))
return nil, true, nil
}
@@ -1179,6 +1265,9 @@ func (s *CertificationApplicationServiceImpl) completeEnterpriseVerification(
companyName string,
legalPersonName string,
) error {
s.logger.Info("完成企业认证-步骤1-开始状态流转",
zap.String("user_id", userID),
zap.String("company_name", companyName))
// 完成企业认证
err := cert.CompleteEnterpriseVerification()
if err != nil {
@@ -1192,6 +1281,9 @@ func (s *CertificationApplicationServiceImpl) completeEnterpriseVerification(
s.logger.Error("查找企业信息失败", zap.Error(err))
return fmt.Errorf("查找企业信息失败: %w", err)
}
s.logger.Info("完成企业认证-步骤2-获取提交记录成功",
zap.String("user_id", userID),
zap.String("record_id", record.ID))
err = s.userAggregateService.CreateEnterpriseInfo(
ctx,
@@ -1215,6 +1307,7 @@ func (s *CertificationApplicationServiceImpl) completeEnterpriseVerification(
if err != nil {
return err
}
s.logger.Info("完成企业认证-步骤3-合同文件生成并写入认证成功", zap.String("user_id", userID))
// 保存认证信息
err = s.aggregateService.SaveCertification(ctx, cert)
@@ -1222,6 +1315,7 @@ func (s *CertificationApplicationServiceImpl) completeEnterpriseVerification(
s.logger.Error("保存认证信息失败", zap.Error(err))
return fmt.Errorf("保存认证信息失败: %w", err)
}
s.logger.Info("完成企业认证-步骤4-认证信息保存成功", zap.String("user_id", userID))
return nil
}
@@ -1237,6 +1331,9 @@ func (s *CertificationApplicationServiceImpl) generateAndAddContractFile(
legalPersonPhone string,
legalPersonID string,
) error {
s.logger.Info("合同生成-步骤1-开始填充合同模板",
zap.String("user_id", cert.UserID),
zap.String("company_name", companyName))
fileComponent := map[string]string{
"YFCompanyName": companyName,
"YFCompanyName2": companyName,
@@ -1255,11 +1352,17 @@ func (s *CertificationApplicationServiceImpl) generateAndAddContractFile(
s.logger.Error("生成合同失败", zap.Error(err))
return fmt.Errorf("生成合同失败: %s", err.Error())
}
s.logger.Info("合同生成-步骤1-模板填充成功",
zap.String("user_id", cert.UserID),
zap.String("file_id", fillTemplateResp.FileID))
err = cert.AddContractFileID(fillTemplateResp.FileID, fillTemplateResp.FileDownloadUrl)
if err != nil {
s.logger.Error("加入合同文件ID链接失败", zap.Error(err))
return fmt.Errorf("加入合同文件ID链接失败: %s", err.Error())
}
s.logger.Info("合同生成-步骤2-合同文件写入认证实体成功",
zap.String("user_id", cert.UserID),
zap.String("file_id", fillTemplateResp.FileID))
return nil
}