This commit is contained in:
Mrx
2026-03-26 15:31:37 +08:00
parent a73097aed3
commit e095553ba8

View File

@@ -6,6 +6,7 @@ import (
"fmt"
"io"
"net/http"
"strings"
"time"
"tyapi-server/internal/application/certification/dto/commands"
@@ -265,8 +266,7 @@ func (s *CertificationApplicationServiceImpl) SubmitEnterpriseInfo(
// 4. 提交企业信息:暂时跳过人工审核,直接进入「已提交」状态(第三步企业认证)
// 恢复人工审核时改为 cert.SubmitEnterpriseInfoForReview(enterpriseInfo),并将 next_action 改为「请等待管理员审核企业信息」
// 生成企业认证链接
authURL, err := s.esignClient.GenerateEnterpriseAuth(&esign.EnterpriseAuthRequest{
authReq := &esign.EnterpriseAuthRequest{
CompanyName: enterpriseInfo.CompanyName,
UnifiedSocialCode: enterpriseInfo.UnifiedSocialCode,
LegalPersonName: enterpriseInfo.LegalPersonName,
@@ -274,20 +274,29 @@ func (s *CertificationApplicationServiceImpl) SubmitEnterpriseInfo(
TransactorName: enterpriseInfo.LegalPersonName,
TransactorMobile: enterpriseInfo.LegalPersonPhone,
TransactorID: enterpriseInfo.LegalPersonID,
})
}
authURL, alreadyVerified, err := s.generateEnterpriseAuthOrDetectVerified(txCtx, authReq)
if err != nil {
return fmt.Errorf("生成企业认证链接失败: %w", err)
}
if alreadyVerified {
// 三方侧已实名:先进入 info_submitted再在同事务内自动推进到 enterprise_verified。
if err = cert.SubmitEnterpriseInfo(enterpriseInfo, "", ""); err != nil {
return fmt.Errorf("提交企业信息失败: %s", err.Error())
}
if err = s.completeEnterpriseVerification(txCtx, cert, cert.UserID, enterpriseInfo.CompanyName, enterpriseInfo.LegalPersonName); err != nil {
return fmt.Errorf("自动完成企业认证失败: %w", err)
}
} else {
err = cert.SubmitEnterpriseInfo(enterpriseInfo, authURL.AuthShortURL, authURL.AuthFlowID)
if err != nil {
return fmt.Errorf("提交企业信息失败: %s", err.Error())
}
err = s.aggregateService.SaveCertification(txCtx, cert)
if err != nil {
return fmt.Errorf("保存认证信息失败: %s", err.Error())
}
}
// 5. 提交记录与认证状态在同一事务内保存
if saveErr := s.enterpriseInfoSubmitRecordService.Save(txCtx, record); saveErr != nil {
@@ -296,13 +305,22 @@ func (s *CertificationApplicationServiceImpl) SubmitEnterpriseInfo(
respMeta := map[string]interface{}{
"enterprise_info": enterpriseInfo,
"next_action": "请完成企业认证",
"polling": map[string]interface{}{
"enabled": !alreadyVerified,
"endpoint": "/api/v1/certifications/confirm-auth",
"interval_seconds": 3,
},
}
if alreadyVerified {
respMeta["next_action"] = "企业已实名,已自动完成认证,可进入合同签署"
respMeta["target_view"] = "contract_sign"
} else {
respMeta["next_action"] = "请完成企业认证"
respMeta["target_view"] = "enterprise_auth"
}
// 6. 转换为响应 DTO
response = s.convertToResponse(cert)
if respMeta != nil {
response.Metadata = respMeta
}
return nil
})
if err != nil {
@@ -875,7 +893,7 @@ func (s *CertificationApplicationServiceImpl) AdminApproveSubmitRecord(ctx conte
LegalPersonPhone: record.LegalPersonPhone,
EnterpriseAddress: record.EnterpriseAddress,
}
authURL, err := s.esignClient.GenerateEnterpriseAuth(&esign.EnterpriseAuthRequest{
authReq := &esign.EnterpriseAuthRequest{
CompanyName: enterpriseInfo.CompanyName,
UnifiedSocialCode: enterpriseInfo.UnifiedSocialCode,
LegalPersonName: enterpriseInfo.LegalPersonName,
@@ -883,10 +901,17 @@ func (s *CertificationApplicationServiceImpl) AdminApproveSubmitRecord(ctx conte
TransactorName: enterpriseInfo.LegalPersonName,
TransactorMobile: enterpriseInfo.LegalPersonPhone,
TransactorID: enterpriseInfo.LegalPersonID,
})
}
authURL, alreadyVerified, err := s.generateEnterpriseAuthOrDetectVerified(ctx, authReq)
if err != nil {
return fmt.Errorf("生成企业认证链接失败: %w", err)
}
if alreadyVerified {
if err := cert.ApproveEnterpriseInfoReview("", "", adminID); err != nil {
return fmt.Errorf("更新认证状态失败: %w", err)
}
return s.completeEnterpriseVerification(ctx, cert, cert.UserID, record.CompanyName, record.LegalPersonName)
}
if err := cert.ApproveEnterpriseInfoReview(authURL.AuthShortURL, authURL.AuthFlowID, adminID); err != nil {
return fmt.Errorf("更新认证状态失败: %w", err)
}
@@ -964,14 +989,21 @@ func (s *CertificationApplicationServiceImpl) AdminTransitionCertificationStatus
LegalPersonName: record.LegalPersonName, LegalPersonID: record.LegalPersonID,
LegalPersonPhone: record.LegalPersonPhone, EnterpriseAddress: record.EnterpriseAddress,
}
authURL, err := s.esignClient.GenerateEnterpriseAuth(&esign.EnterpriseAuthRequest{
authReq := &esign.EnterpriseAuthRequest{
CompanyName: enterpriseInfo.CompanyName, UnifiedSocialCode: enterpriseInfo.UnifiedSocialCode,
LegalPersonName: enterpriseInfo.LegalPersonName, LegalPersonID: enterpriseInfo.LegalPersonID,
TransactorName: enterpriseInfo.LegalPersonName, TransactorMobile: enterpriseInfo.LegalPersonPhone, TransactorID: enterpriseInfo.LegalPersonID,
})
}
authURL, alreadyVerified, err := s.generateEnterpriseAuthOrDetectVerified(ctx, authReq)
if err != nil {
return fmt.Errorf("生成企业认证链接失败: %w", err)
}
if alreadyVerified {
if err := cert.ApproveEnterpriseInfoReview("", "", cmd.AdminID); err != nil {
return fmt.Errorf("更新认证状态失败: %w", err)
}
return s.completeEnterpriseVerification(ctx, cert, cert.UserID, record.CompanyName, record.LegalPersonName)
}
if err := cert.ApproveEnterpriseInfoReview(authURL.AuthShortURL, authURL.AuthFlowID, cmd.AdminID); err != nil {
return fmt.Errorf("更新认证状态失败: %w", err)
}
@@ -1049,6 +1081,49 @@ func (s *CertificationApplicationServiceImpl) convertToResponse(cert *entities.C
return response
}
func (s *CertificationApplicationServiceImpl) generateEnterpriseAuthOrDetectVerified(
ctx context.Context,
req *esign.EnterpriseAuthRequest,
) (*esign.EnterpriseAuthResult, bool, error) {
authURL, err := s.esignClient.GenerateEnterpriseAuth(req)
if err == nil {
return authURL, false, nil
}
if !isEnterpriseAlreadyRealnamedErr(err) {
return nil, false, err
}
s.logger.Warn("企业已实名,跳过生成认证链接并转为自动确认",
zap.String("company_name", req.CompanyName),
zap.String("unified_social_code", req.UnifiedSocialCode),
zap.Error(err))
identity, identityErr := s.esignClient.QueryOrgIdentityInfo(&esign.QueryOrgIdentityRequest{
OrgIDCardNum: req.UnifiedSocialCode,
OrgIDCardType: esign.OrgIDCardTypeUSCC,
})
if identityErr != nil {
identity, identityErr = s.esignClient.QueryOrgIdentityInfo(&esign.QueryOrgIdentityRequest{
OrgName: req.CompanyName,
})
}
if identityErr != nil {
return nil, false, fmt.Errorf("企业用户已实名,但查询实名状态失败: %w", identityErr)
}
if identity == nil || identity.Data.RealnameStatus != 1 {
return nil, false, err
}
return nil, true, nil
}
func isEnterpriseAlreadyRealnamedErr(err error) bool {
if err == nil {
return false
}
msg := err.Error()
return strings.Contains(msg, "企业用户已实名") || strings.Contains(msg, "已实名")
}
// validateApplyContractCommand 验证申请合同命令
func (s *CertificationApplicationServiceImpl) validateApplyContractCommand(cmd *commands.ApplyContractCommand) error {
if cmd.UserID == "" {