From a01226c7c0062a2178ccd4ddada317d2827e5025 Mon Sep 17 00:00:00 2001 From: Mrx <18278715334@163.com> Date: Fri, 17 Apr 2026 18:37:19 +0800 Subject: [PATCH] f --- config.yaml | 1 + .../api/api_application_service.go | 15 ++++- internal/domains/api/dto/api_request_dto.go | 9 ++- .../api/services/api_request_service.go | 1 + .../api/services/form_config_service.go | 1 + .../processors/ivyz/ivyzfic1_processor.go | 55 +++++++++++++++++++ 6 files changed, 78 insertions(+), 4 deletions(-) create mode 100644 internal/domains/api/services/processors/ivyz/ivyzfic1_processor.go diff --git a/config.yaml b/config.yaml index 9474966..5bbc9ba 100644 --- a/config.yaml +++ b/config.yaml @@ -399,6 +399,7 @@ WechatH5: # =========================================== # 🔍 天眼查配置 # =========================================== + tianyancha: base_url: http://open.api.tianyancha.com/services api_key: e6a43dc9-786e-4a16-bb12-392b8201d8e2 diff --git a/internal/application/api/api_application_service.go b/internal/application/api/api_application_service.go index a2533e0..61e01a1 100644 --- a/internal/application/api/api_application_service.go +++ b/internal/application/api/api_application_service.go @@ -226,13 +226,19 @@ func (s *ApiApplicationServiceImpl) validateApiCall(ctx context.Context, cmd *co // 4. 验证IP白名单(非开发环境) if !s.config.App.IsDevelopment() && !cmd.Options.IsDebug { + whiteListIPs := make([]string, 0, len(apiUser.WhiteList)) + for _, item := range apiUser.WhiteList { + whiteListIPs = append(whiteListIPs, item.IPAddress) + } + // 添加调试日志 s.logger.Info("开始验证白名单", zap.String("userId", apiUser.UserId), zap.String("clientIP", cmd.ClientIP), zap.Bool("isDevelopment", s.config.App.IsDevelopment()), zap.Bool("isDebug", cmd.Options.IsDebug), - zap.Int("whiteListCount", len(apiUser.WhiteList))) + zap.Int("whiteListCount", len(apiUser.WhiteList)), + zap.Strings("whiteListIPs", whiteListIPs)) // 输出白名单详细信息(用于调试) for idx, item := range apiUser.WhiteList { @@ -246,10 +252,13 @@ func (s *ApiApplicationServiceImpl) validateApiCall(ctx context.Context, cmd *co s.logger.Error("IP不在白名单内", zap.String("userId", apiUser.UserId), zap.String("ip", cmd.ClientIP), - zap.Int("whiteListSize", len(apiUser.WhiteList))) + zap.Int("whiteListSize", len(apiUser.WhiteList)), + zap.Strings("whiteListIPs", whiteListIPs)) return nil, ErrInvalidIP } - s.logger.Info("白名单验证通过", zap.String("ip", cmd.ClientIP)) + s.logger.Info("白名单验证通过", + zap.String("ip", cmd.ClientIP), + zap.Strings("whiteListIPs", whiteListIPs)) } // 5. 验证钱包状态 diff --git a/internal/domains/api/dto/api_request_dto.go b/internal/domains/api/dto/api_request_dto.go index f627f49..7261c72 100644 --- a/internal/domains/api/dto/api_request_dto.go +++ b/internal/domains/api/dto/api_request_dto.go @@ -73,7 +73,7 @@ type IVYZ81NCReq struct { IDCard string `json:"id_card" validate:"required,validIDCard"` } type IVYZ2MN6Req struct { - IDCard string `json:"id_card" validate:"required,validIDCard"` + IDCard string `json:"id_card" validate:"required,validIDCard"` Name string `json:"name" validate:"required,min=1,validName"` Authorized string `json:"authorized" validate:"required,oneof=0 1"` } @@ -1048,6 +1048,13 @@ type IVYZA1B3Req struct { PhotoData string `json:"photo_data" validate:"required,validBase64Image"` } +type IVYZFIC1Req struct { + IDCard string `json:"id_card" validate:"required,validIDCard"` + Name string `json:"name" validate:"required,min=1,validName"` + PhotoData string `json:"photo_data" validate:"omitempty,validBase64Image"` + ImageUrl string `json:"image_url" validate:"omitempty,url"` +} + type IVYZC4R9Req struct { IDCard string `json:"id_card" validate:"required,validIDCard"` Name string `json:"name" validate:"required,min=1,validName"` diff --git a/internal/domains/api/services/api_request_service.go b/internal/domains/api/services/api_request_service.go index af10d86..2b72792 100644 --- a/internal/domains/api/services/api_request_service.go +++ b/internal/domains/api/services/api_request_service.go @@ -318,6 +318,7 @@ func registerAllProcessors(combService *comb.CombService) { "IVYZ1J7H": ivyz.ProcessIVYZ1J7HRequest, //行驶证核查v2 "IVYZ9K7F": ivyz.ProcessIVYZ9K7FRequest, //身份证实名认证即时版 "IVYZA1B3": ivyz.ProcessIVYZA1B3Request, //公安三要素人脸识别 + "IVYZFIC1": ivyz.ProcessIVYZFIC1Request, //人脸身份证比对(数脉) "IVYZN2P8": ivyz.ProcessIVYZN2P8Request, //身份证实名认证政务版 "IVYZX5QZ": ivyz.ProcessIVYZX5QZRequest, //活体检测 "IVYZX5Q2": ivyz.ProcessIVYZX5Q2Request, //活体识别步骤二 diff --git a/internal/domains/api/services/form_config_service.go b/internal/domains/api/services/form_config_service.go index 8d1b6b6..b9d981c 100644 --- a/internal/domains/api/services/form_config_service.go +++ b/internal/domains/api/services/form_config_service.go @@ -241,6 +241,7 @@ func (s *FormConfigServiceImpl) getDTOStruct(ctx context.Context, apiCode string "YYSYK8R3": &dto.YYSYK8R3Req{}, //手机空号检测查询 "YYSYF2T7": &dto.YYSYF2T7Req{}, //手机二次放号检测查询 "IVYZA1B3": &dto.IVYZA1B3Req{}, //公安三要素人脸识别 + "IVYZFIC1": &dto.IVYZFIC1Req{}, //人脸身份证比对(数脉) "IVYZX5QZ": &dto.IVYZX5QZReq{}, //活体识别 "IVYZN2P8": &dto.IVYZ9K7FReq{}, //身份证实名认证政务版 "YYSYH6F3": &dto.YYSYH6F3Req{}, //运营商三要素简版即时版查询 diff --git a/internal/domains/api/services/processors/ivyz/ivyzfic1_processor.go b/internal/domains/api/services/processors/ivyz/ivyzfic1_processor.go new file mode 100644 index 0000000..13505ec --- /dev/null +++ b/internal/domains/api/services/processors/ivyz/ivyzfic1_processor.go @@ -0,0 +1,55 @@ +package ivyz + +import ( + "context" + "encoding/json" + "errors" + "strings" + + "tyapi-server/internal/domains/api/dto" + "tyapi-server/internal/domains/api/services/processors" + "tyapi-server/internal/infrastructure/external/shumai" +) + +// ProcessIVYZFIC1Request IVYZFIC1 人脸身份证比对 API 处理方法(数脉) +func ProcessIVYZFIC1Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) { + var paramsDto dto.IVYZFIC1Req + 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) + } + + if strings.TrimSpace(paramsDto.PhotoData) == "" && strings.TrimSpace(paramsDto.ImageUrl) == "" { + return nil, errors.Join(processors.ErrInvalidParam, errors.New("image和url至少传一个")) + } + + reqFormData := map[string]interface{}{ + "idcard": paramsDto.IDCard, + "name": paramsDto.Name, + "image": paramsDto.PhotoData, + "url": paramsDto.ImageUrl, + } + + apiPath := "/v4/face_id_card/compare" + + // 先尝试政务接口,再回退实时接口 + respBytes, err := deps.ShumaiService.CallAPIForm(ctx, apiPath, reqFormData, true) + if err != nil { + respBytes, err = deps.ShumaiService.CallAPIForm(ctx, apiPath, reqFormData, false) + if err != nil { + if errors.Is(err, shumai.ErrNotFound) { + return nil, errors.Join(processors.ErrNotFound, err) + } else if errors.Is(err, shumai.ErrDatasource) { + return nil, errors.Join(processors.ErrDatasource, err) + } else if errors.Is(err, shumai.ErrSystem) { + return nil, errors.Join(processors.ErrSystem, err) + } + return nil, errors.Join(processors.ErrSystem, err) + } + } + + return respBytes, nil +}