f and add
This commit is contained in:
@@ -109,6 +109,12 @@ func (s *CertificationApplicationServiceImpl) SubmitEnterpriseInfo(
|
|||||||
s.logger.Info("开始提交企业信息",
|
s.logger.Info("开始提交企业信息",
|
||||||
zap.String("user_id", cmd.UserID))
|
zap.String("user_id", cmd.UserID))
|
||||||
|
|
||||||
|
// 0. 若该用户已有待审核的提交记录,则不允许重复提交
|
||||||
|
latestRecord, err := s.enterpriseInfoSubmitRecordRepo.FindLatestByUserID(ctx, cmd.UserID)
|
||||||
|
if err == nil && latestRecord != nil && latestRecord.ManualReviewStatus == "pending" {
|
||||||
|
return nil, fmt.Errorf("您已有待审核的提交,请等待管理员审核后再操作")
|
||||||
|
}
|
||||||
|
|
||||||
// 1.5 插入企业信息提交记录(包含扩展字段)
|
// 1.5 插入企业信息提交记录(包含扩展字段)
|
||||||
record := entities.NewEnterpriseInfoSubmitRecord(
|
record := entities.NewEnterpriseInfoSubmitRecord(
|
||||||
cmd.UserID,
|
cmd.UserID,
|
||||||
@@ -164,7 +170,8 @@ func (s *CertificationApplicationServiceImpl) SubmitEnterpriseInfo(
|
|||||||
}
|
}
|
||||||
s.logger.Info("开始处理企业信息提交",
|
s.logger.Info("开始处理企业信息提交",
|
||||||
zap.String("user_id", cmd.UserID))
|
zap.String("user_id", cmd.UserID))
|
||||||
// 1. 检查企业信息是否重复(统一社会信用代码,已经认证了的,不能重复提交)
|
// 1. 检查企业信息是否重复(统一社会信用代码:已认证或已提交待审核的都不能重复)
|
||||||
|
// 1.1 已写入用户域 enterprise_infos 的(已完成认证)
|
||||||
exists, err := s.userAggregateService.CheckUnifiedSocialCodeExists(ctx, cmd.UnifiedSocialCode, cmd.UserID)
|
exists, err := s.userAggregateService.CheckUnifiedSocialCodeExists(ctx, cmd.UnifiedSocialCode, cmd.UserID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
record.MarkAsFailed(err.Error())
|
record.MarkAsFailed(err.Error())
|
||||||
@@ -174,7 +181,6 @@ func (s *CertificationApplicationServiceImpl) SubmitEnterpriseInfo(
|
|||||||
}
|
}
|
||||||
return nil, fmt.Errorf("检查企业信息失败: %s", err.Error())
|
return nil, fmt.Errorf("检查企业信息失败: %s", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
if exists {
|
if exists {
|
||||||
record.MarkAsFailed("该企业信息已被其他用户使用,请确认企业信息是否正确")
|
record.MarkAsFailed("该企业信息已被其他用户使用,请确认企业信息是否正确")
|
||||||
saveErr := s.enterpriseInfoSubmitRecordService.Save(ctx, record)
|
saveErr := s.enterpriseInfoSubmitRecordService.Save(ctx, record)
|
||||||
@@ -182,7 +188,24 @@ func (s *CertificationApplicationServiceImpl) SubmitEnterpriseInfo(
|
|||||||
return nil, fmt.Errorf("保存企业信息提交记录失败: %s", saveErr.Error())
|
return nil, fmt.Errorf("保存企业信息提交记录失败: %s", saveErr.Error())
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("该企业信息已被其他用户使用,请确认企业信息是否正确")
|
return nil, fmt.Errorf("该企业信息已被其他用户使用,请确认企业信息是否正确")
|
||||||
|
}
|
||||||
|
// 1.2 已提交/已通过验证的提交记录(尚未完成认证但已占用的信用代码)
|
||||||
|
existsInSubmit, err := s.enterpriseInfoSubmitRecordRepo.ExistsByUnifiedSocialCodeExcludeUser(ctx, cmd.UnifiedSocialCode, cmd.UserID)
|
||||||
|
if err != nil {
|
||||||
|
record.MarkAsFailed(err.Error())
|
||||||
|
saveErr := s.enterpriseInfoSubmitRecordService.Save(ctx, record)
|
||||||
|
if saveErr != nil {
|
||||||
|
return nil, fmt.Errorf("保存企业信息提交记录失败: %s", saveErr.Error())
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("检查企业信息失败: %s", err.Error())
|
||||||
|
}
|
||||||
|
if existsInSubmit {
|
||||||
|
record.MarkAsFailed("该企业信息已被其他用户使用,请确认企业信息是否正确")
|
||||||
|
saveErr := s.enterpriseInfoSubmitRecordService.Save(ctx, record)
|
||||||
|
if saveErr != nil {
|
||||||
|
return nil, fmt.Errorf("保存企业信息提交记录失败: %s", saveErr.Error())
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("该企业信息已被其他用户使用,请确认企业信息是否正确")
|
||||||
}
|
}
|
||||||
|
|
||||||
enterpriseInfo := &certification_value_objects.EnterpriseInfo{
|
enterpriseInfo := &certification_value_objects.EnterpriseInfo{
|
||||||
@@ -214,10 +237,6 @@ func (s *CertificationApplicationServiceImpl) SubmitEnterpriseInfo(
|
|||||||
return nil, fmt.Errorf("企业信息验证失败, %s", err.Error())
|
return nil, fmt.Errorf("企业信息验证失败, %s", err.Error())
|
||||||
}
|
}
|
||||||
record.MarkAsVerified()
|
record.MarkAsVerified()
|
||||||
saveErr := s.enterpriseInfoSubmitRecordService.Save(ctx, record)
|
|
||||||
if saveErr != nil {
|
|
||||||
return nil, fmt.Errorf("保存企业信息提交记录失败: %s", saveErr.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
var response *responses.CertificationResponse
|
var response *responses.CertificationResponse
|
||||||
err = s.txManager.ExecuteInTx(ctx, func(txCtx context.Context) error {
|
err = s.txManager.ExecuteInTx(ctx, func(txCtx context.Context) error {
|
||||||
@@ -255,23 +274,25 @@ func (s *CertificationApplicationServiceImpl) SubmitEnterpriseInfo(
|
|||||||
return fmt.Errorf("提交企业信息失败: %s", err.Error())
|
return fmt.Errorf("提交企业信息失败: %s", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
respMeta := map[string]interface{}{
|
|
||||||
"enterprise_info": enterpriseInfo,
|
|
||||||
"next_action": "请等待管理员审核企业信息",
|
|
||||||
}
|
|
||||||
|
|
||||||
err = s.aggregateService.SaveCertification(txCtx, cert)
|
err = s.aggregateService.SaveCertification(txCtx, cert)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("保存认证信息失败: %s", err.Error())
|
return fmt.Errorf("保存认证信息失败: %s", err.Error())
|
||||||
}
|
}
|
||||||
// 5. 转换为响应DTO
|
|
||||||
response = s.convertToResponse(cert)
|
|
||||||
|
|
||||||
// 6. 添加工作流结果信息
|
// 5. 提交记录与认证状态在同一事务内保存,避免出现「有记录但认证未变待审核」的不一致
|
||||||
|
if saveErr := s.enterpriseInfoSubmitRecordService.Save(txCtx, record); saveErr != nil {
|
||||||
|
return fmt.Errorf("保存企业信息提交记录失败: %s", saveErr.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
respMeta := map[string]interface{}{
|
||||||
|
"enterprise_info": enterpriseInfo,
|
||||||
|
"next_action": "请等待管理员审核企业信息",
|
||||||
|
}
|
||||||
|
// 6. 转换为响应 DTO
|
||||||
|
response = s.convertToResponse(cert)
|
||||||
if respMeta != nil {
|
if respMeta != nil {
|
||||||
response.Metadata = respMeta
|
response.Metadata = respMeta
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -804,9 +825,19 @@ func (s *CertificationApplicationServiceImpl) AdminApproveSubmitRecord(ctx conte
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("加载认证信息失败: %w", err)
|
return fmt.Errorf("加载认证信息失败: %w", err)
|
||||||
}
|
}
|
||||||
|
// 兼容线上脏数据:提交记录已落库但当时事务失败导致认证仍为「待认证」,先同步为待审核再执行通过
|
||||||
|
if cert.Status != enums.StatusInfoPendingReview {
|
||||||
|
if err := s.syncCertToPendingReviewIfRecordPending(ctx, cert, record); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cert, err = s.aggregateService.LoadCertificationByUserID(ctx, record.UserID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("加载认证信息失败: %w", err)
|
||||||
|
}
|
||||||
if cert.Status != enums.StatusInfoPendingReview {
|
if cert.Status != enums.StatusInfoPendingReview {
|
||||||
return fmt.Errorf("认证状态不是待审核,当前: %s", enums.GetStatusName(cert.Status))
|
return fmt.Errorf("认证状态不是待审核,当前: %s", enums.GetStatusName(cert.Status))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
enterpriseInfo := &certification_value_objects.EnterpriseInfo{
|
enterpriseInfo := &certification_value_objects.EnterpriseInfo{
|
||||||
CompanyName: record.CompanyName,
|
CompanyName: record.CompanyName,
|
||||||
UnifiedSocialCode: record.UnifiedSocialCode,
|
UnifiedSocialCode: record.UnifiedSocialCode,
|
||||||
@@ -857,9 +888,19 @@ func (s *CertificationApplicationServiceImpl) AdminRejectSubmitRecord(ctx contex
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("加载认证信息失败: %w", err)
|
return fmt.Errorf("加载认证信息失败: %w", err)
|
||||||
}
|
}
|
||||||
|
// 兼容线上脏数据:提交记录已落库但当时事务失败导致认证仍为「待认证」,先同步为待审核再执行拒绝
|
||||||
|
if cert.Status != enums.StatusInfoPendingReview {
|
||||||
|
if err := s.syncCertToPendingReviewIfRecordPending(ctx, cert, record); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cert, err = s.aggregateService.LoadCertificationByUserID(ctx, record.UserID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("加载认证信息失败: %w", err)
|
||||||
|
}
|
||||||
if cert.Status != enums.StatusInfoPendingReview {
|
if cert.Status != enums.StatusInfoPendingReview {
|
||||||
return fmt.Errorf("认证状态不是待审核,当前: %s", enums.GetStatusName(cert.Status))
|
return fmt.Errorf("认证状态不是待审核,当前: %s", enums.GetStatusName(cert.Status))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
record.MarkManualRejected(adminID, remark)
|
record.MarkManualRejected(adminID, remark)
|
||||||
if err := s.enterpriseInfoSubmitRecordService.Save(ctx, record); err != nil {
|
if err := s.enterpriseInfoSubmitRecordService.Save(ctx, record); err != nil {
|
||||||
return fmt.Errorf("保存提交记录失败: %w", err)
|
return fmt.Errorf("保存提交记录失败: %w", err)
|
||||||
@@ -876,6 +917,33 @@ func (s *CertificationApplicationServiceImpl) AdminRejectSubmitRecord(ctx contex
|
|||||||
|
|
||||||
// ================ 辅助方法 ================
|
// ================ 辅助方法 ================
|
||||||
|
|
||||||
|
// syncCertToPendingReviewIfRecordPending 兼容历史脏数据:当认证为「待认证」或「已拒绝」且存在待审核提交记录时,
|
||||||
|
// 用该记录的企业信息把认证同步为「待审核」,便于管理员直接审核通过/拒绝。
|
||||||
|
func (s *CertificationApplicationServiceImpl) syncCertToPendingReviewIfRecordPending(ctx context.Context, cert *entities.Certification, record *entities.EnterpriseInfoSubmitRecord) error {
|
||||||
|
if record.ManualReviewStatus != "pending" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if cert.Status != enums.StatusPending && cert.Status != enums.StatusInfoRejected {
|
||||||
|
return fmt.Errorf("认证状态不是待审核,当前: %s", enums.GetStatusName(cert.Status))
|
||||||
|
}
|
||||||
|
enterpriseInfo := &certification_value_objects.EnterpriseInfo{
|
||||||
|
CompanyName: record.CompanyName,
|
||||||
|
UnifiedSocialCode: record.UnifiedSocialCode,
|
||||||
|
LegalPersonName: record.LegalPersonName,
|
||||||
|
LegalPersonID: record.LegalPersonID,
|
||||||
|
LegalPersonPhone: record.LegalPersonPhone,
|
||||||
|
EnterpriseAddress: record.EnterpriseAddress,
|
||||||
|
}
|
||||||
|
if err := cert.SubmitEnterpriseInfoForReview(enterpriseInfo); err != nil {
|
||||||
|
return fmt.Errorf("同步认证为待审核失败: %w", err)
|
||||||
|
}
|
||||||
|
if err := s.aggregateService.SaveCertification(ctx, cert); err != nil {
|
||||||
|
return fmt.Errorf("保存认证信息失败: %w", err)
|
||||||
|
}
|
||||||
|
s.logger.Info("已同步认证为待审核(兼容历史脏数据)", zap.String("user_id", cert.UserID), zap.String("record_id", record.ID))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// convertToResponse 转换实体为响应DTO
|
// convertToResponse 转换实体为响应DTO
|
||||||
func (s *CertificationApplicationServiceImpl) convertToResponse(cert *entities.Certification) *responses.CertificationResponse {
|
func (s *CertificationApplicationServiceImpl) convertToResponse(cert *entities.Certification) *responses.CertificationResponse {
|
||||||
response := &responses.CertificationResponse{
|
response := &responses.CertificationResponse{
|
||||||
|
|||||||
@@ -616,6 +616,15 @@ type QYGLJ0Q1Req struct {
|
|||||||
EntName string `json:"ent_name" validate:"omitempty,min=1,validEnterpriseName"`
|
EntName string `json:"ent_name" validate:"omitempty,min=1,validEnterpriseName"`
|
||||||
EntCode string `json:"ent_code" validate:"omitempty,validUSCI"`
|
EntCode string `json:"ent_code" validate:"omitempty,validUSCI"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type QYGLDJG3Req struct {
|
||||||
|
IDCard string `json:"id_card" validate:"required,validIDCard"`
|
||||||
|
}
|
||||||
|
type QYGLDJ12Req struct {
|
||||||
|
EntName string `json:"ent_name" validate:"omitempty,min=1,validEnterpriseName"`
|
||||||
|
EntCode string `json:"ent_code" validate:"omitempty,validUSCI"`
|
||||||
|
EntRegNo string `json:"ent_reg_no" validate:"omitempty,min=1,validEntRegNo"`
|
||||||
|
}
|
||||||
type YYSY6D9AReq struct {
|
type YYSY6D9AReq struct {
|
||||||
MobileNo string `json:"mobile_no" validate:"required,min=11,max=11,validMobileNo"`
|
MobileNo string `json:"mobile_no" validate:"required,min=11,max=11,validMobileNo"`
|
||||||
IDCard string `json:"id_card" validate:"required,validIDCard"`
|
IDCard string `json:"id_card" validate:"required,validIDCard"`
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package flxg
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"tyapi-server/internal/domains/api/dto"
|
||||||
|
"tyapi-server/internal/domains/api/services/processors"
|
||||||
|
"tyapi-server/internal/infrastructure/external/shujubao"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ProcessQYGLDJG3Request QYGLDJG3 董监高司法综合信息核验 API 处理方法(使用数据宝服务示例)
|
||||||
|
func ProcessQYGLDJG3Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||||
|
var paramsDto dto.QYGLDJG3Req
|
||||||
|
if err := json.Unmarshal(params, ¶msDto); err != nil {
|
||||||
|
return nil, errors.Join(processors.ErrSystem, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
|
||||||
|
return nil, errors.Join(processors.ErrInvalidParam, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建数据宝入参(sign 外的业务参数可按需 AES 加密后作为 bodyData)
|
||||||
|
reqParams := map[string]interface{}{
|
||||||
|
"key": "1cce582f0a6f3ca40de80f1bea9b9698",
|
||||||
|
"idcard": paramsDto.IDCard,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 最终请求 URL = https://api.chinadatapay.com/communication + 拼接接口地址值,如 personal/197
|
||||||
|
apiPath := "/communication/personal/10166"
|
||||||
|
data, err := deps.ShujubaoService.CallAPI(ctx, apiPath, reqParams)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, shujubao.ErrDatasource) {
|
||||||
|
return nil, errors.Join(processors.ErrDatasource, err)
|
||||||
|
}
|
||||||
|
if errors.Is(err, shujubao.ErrQueryEmpty) {
|
||||||
|
return nil, errors.Join(processors.ErrNotFound, err)
|
||||||
|
}
|
||||||
|
return nil, errors.Join(processors.ErrSystem, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析响应中的 JSON 字符串(使用 qyglb4c0 中的 RecursiveParse)
|
||||||
|
parsedResp, err := RecursiveParse(data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Join(processors.ErrSystem, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
respBytes, err := json.Marshal(parsedResp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Join(processors.ErrSystem, err)
|
||||||
|
}
|
||||||
|
return respBytes, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package qygl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"tyapi-server/internal/domains/api/dto"
|
||||||
|
"tyapi-server/internal/domains/api/services/processors"
|
||||||
|
"tyapi-server/internal/infrastructure/external/shujubao"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ProcessQYGL8848Request QYGL8848 企业税收违法核查 API 处理方法(使用数据宝服务示例)
|
||||||
|
func ProcessQYGL8848Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||||
|
var paramsDto dto.QYGLDJ12Req
|
||||||
|
if err := json.Unmarshal(params, ¶msDto); err != nil {
|
||||||
|
return nil, errors.Join(processors.ErrSystem, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
|
||||||
|
return nil, errors.Join(processors.ErrInvalidParam, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 三选一:企业名称(entName) 与 统一社会信用代码(creditCode) 与 企业注册号(entRegNo) 必须且仅能传其一
|
||||||
|
hasEntName := paramsDto.EntName != ""
|
||||||
|
hasEntCode := paramsDto.EntCode != ""
|
||||||
|
hasEntRegNo := paramsDto.EntRegNo != ""
|
||||||
|
if hasEntName == hasEntCode == hasEntRegNo { // 三个都填或三个都未填
|
||||||
|
return nil, errors.Join(processors.ErrInvalidParam, errors.New("ent_name 与 ent_code 与 ent_reg_no 三选一,必须且仅能传其中一个"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建数据宝入参(sign 外的业务参数可按需 AES 加密后作为 bodyData)
|
||||||
|
reqParams := map[string]interface{}{
|
||||||
|
"key": "c67673dd2e92deb2d2ec91b87bb0a81c",
|
||||||
|
}
|
||||||
|
if hasEntName {
|
||||||
|
reqParams["entName"] = paramsDto.EntName
|
||||||
|
} else if hasEntCode {
|
||||||
|
reqParams["creditCode"] = paramsDto.EntCode
|
||||||
|
} else if hasEntRegNo {
|
||||||
|
reqParams["regCode"] = paramsDto.EntRegNo
|
||||||
|
}
|
||||||
|
|
||||||
|
// 最终请求 URL = https://api.chinadatapay.com/communication + 拼接接口地址值,如 personal/197
|
||||||
|
apiPath := "/communication/personal/10233"
|
||||||
|
data, err := deps.ShujubaoService.CallAPI(ctx, apiPath, reqParams)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, shujubao.ErrDatasource) {
|
||||||
|
return nil, errors.Join(processors.ErrDatasource, err)
|
||||||
|
}
|
||||||
|
if errors.Is(err, shujubao.ErrQueryEmpty) {
|
||||||
|
return nil, errors.Join(processors.ErrNotFound, err)
|
||||||
|
}
|
||||||
|
return nil, errors.Join(processors.ErrSystem, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析响应中的 JSON 字符串(使用 qyglb4c0 中的 RecursiveParse)
|
||||||
|
parsedResp, err := RecursiveParse(data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Join(processors.ErrSystem, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
respBytes, err := json.Marshal(parsedResp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Join(processors.ErrSystem, err)
|
||||||
|
}
|
||||||
|
return respBytes, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package qygl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"tyapi-server/internal/domains/api/dto"
|
||||||
|
"tyapi-server/internal/domains/api/services/processors"
|
||||||
|
"tyapi-server/internal/infrastructure/external/shujubao"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ProcessQYGLDJ12Request QYGLDJ12 企业年报信息核验 API 处理方法(使用数据宝服务示例)
|
||||||
|
func ProcessQYGLDJ12Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||||
|
var paramsDto dto.QYGLDJ12Req
|
||||||
|
if err := json.Unmarshal(params, ¶msDto); err != nil {
|
||||||
|
return nil, errors.Join(processors.ErrSystem, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
|
||||||
|
return nil, errors.Join(processors.ErrInvalidParam, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 三选一:企业名称(entName) 与 统一社会信用代码(creditCode) 与 企业注册号(entRegNo) 必须且仅能传其一
|
||||||
|
hasEntName := paramsDto.EntName != ""
|
||||||
|
hasEntCode := paramsDto.EntCode != ""
|
||||||
|
hasEntRegNo := paramsDto.EntRegNo != ""
|
||||||
|
if hasEntName == hasEntCode == hasEntRegNo { // 三个都填或三个都未填
|
||||||
|
return nil, errors.Join(processors.ErrInvalidParam, errors.New("ent_name 与 ent_code 与 ent_reg_no 三选一,必须且仅能传其中一个"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建数据宝入参(sign 外的业务参数可按需 AES 加密后作为 bodyData)
|
||||||
|
reqParams := map[string]interface{}{
|
||||||
|
"key": "112813815e2cc281ad8f552deb7a3c7f",
|
||||||
|
}
|
||||||
|
if hasEntName {
|
||||||
|
reqParams["entName"] = paramsDto.EntName
|
||||||
|
} else if hasEntCode {
|
||||||
|
reqParams["creditCode"] = paramsDto.EntCode
|
||||||
|
} else if hasEntRegNo {
|
||||||
|
reqParams["regCode"] = paramsDto.EntRegNo
|
||||||
|
}
|
||||||
|
|
||||||
|
// 最终请求 URL = https://api.chinadatapay.com/communication + 拼接接口地址值,如 personal/197
|
||||||
|
apiPath := "/communication/personal/10192"
|
||||||
|
data, err := deps.ShujubaoService.CallAPI(ctx, apiPath, reqParams)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, shujubao.ErrDatasource) {
|
||||||
|
return nil, errors.Join(processors.ErrDatasource, err)
|
||||||
|
}
|
||||||
|
if errors.Is(err, shujubao.ErrQueryEmpty) {
|
||||||
|
return nil, errors.Join(processors.ErrNotFound, err)
|
||||||
|
}
|
||||||
|
return nil, errors.Join(processors.ErrSystem, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析响应中的 JSON 字符串(使用 qyglb4c0 中的 RecursiveParse)
|
||||||
|
parsedResp, err := RecursiveParse(data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Join(processors.ErrSystem, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
respBytes, err := json.Marshal(parsedResp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Join(processors.ErrSystem, err)
|
||||||
|
}
|
||||||
|
return respBytes, nil
|
||||||
|
}
|
||||||
@@ -25,5 +25,7 @@ type EnterpriseInfoSubmitRecordRepository interface {
|
|||||||
FindByID(ctx context.Context, id string) (*entities.EnterpriseInfoSubmitRecord, error)
|
FindByID(ctx context.Context, id string) (*entities.EnterpriseInfoSubmitRecord, error)
|
||||||
FindLatestByUserID(ctx context.Context, userID string) (*entities.EnterpriseInfoSubmitRecord, error)
|
FindLatestByUserID(ctx context.Context, userID string) (*entities.EnterpriseInfoSubmitRecord, error)
|
||||||
FindLatestVerifiedByUserID(ctx context.Context, userID string) (*entities.EnterpriseInfoSubmitRecord, error)
|
FindLatestVerifiedByUserID(ctx context.Context, userID string) (*entities.EnterpriseInfoSubmitRecord, error)
|
||||||
|
// ExistsByUnifiedSocialCodeExcludeUser 检查该统一社会信用代码是否已被其他用户提交(已提交/已通过验证,排除指定用户)
|
||||||
|
ExistsByUnifiedSocialCodeExcludeUser(ctx context.Context, unifiedSocialCode string, excludeUserID string) (bool, error)
|
||||||
List(ctx context.Context, filter ListSubmitRecordsFilter) (*ListSubmitRecordsResult, error)
|
List(ctx context.Context, filter ListSubmitRecordsFilter) (*ListSubmitRecordsResult, error)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,6 +73,23 @@ func (r *GormEnterpriseInfoSubmitRecordRepository) FindLatestVerifiedByUserID(ct
|
|||||||
return &record, nil
|
return &record, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExistsByUnifiedSocialCodeExcludeUser 检查该统一社会信用代码是否已被其他用户占用(已提交或已通过验证的记录)
|
||||||
|
func (r *GormEnterpriseInfoSubmitRecordRepository) ExistsByUnifiedSocialCodeExcludeUser(ctx context.Context, unifiedSocialCode string, excludeUserID string) (bool, error) {
|
||||||
|
if unifiedSocialCode == "" {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
var count int64
|
||||||
|
query := r.GetDB(ctx).Model(&entities.EnterpriseInfoSubmitRecord{}).
|
||||||
|
Where("unified_social_code = ? AND status IN (?, ?)", unifiedSocialCode, "submitted", "verified")
|
||||||
|
if excludeUserID != "" {
|
||||||
|
query = query.Where("user_id != ?", excludeUserID)
|
||||||
|
}
|
||||||
|
if err := query.Count(&count).Error; err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return count > 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *GormEnterpriseInfoSubmitRecordRepository) List(ctx context.Context, filter repositories.ListSubmitRecordsFilter) (*repositories.ListSubmitRecordsResult, error) {
|
func (r *GormEnterpriseInfoSubmitRecordRepository) List(ctx context.Context, filter repositories.ListSubmitRecordsFilter) (*repositories.ListSubmitRecordsResult, error) {
|
||||||
db := r.GetDB(ctx).Model(&entities.EnterpriseInfoSubmitRecord{})
|
db := r.GetDB(ctx).Model(&entities.EnterpriseInfoSubmitRecord{})
|
||||||
if filter.ManualReviewStatus != "" {
|
if filter.ManualReviewStatus != "" {
|
||||||
|
|||||||
Reference in New Issue
Block a user