This commit is contained in:
Mrx
2026-05-09 18:50:45 +08:00
parent b22fdd297b
commit 3c71431e55
4 changed files with 120 additions and 0 deletions

View File

@@ -246,6 +246,12 @@ type IVYZZQT3Req struct {
IDCard string `json:"id_card" validate:"required,validIDCard"`
PhotoData string `json:"photo_data" validate:"required,validBase64Image"`
}
type IVYZZQ3BReq struct {
Name string `json:"name" validate:"required,min=1,validName"`
IDCard string `json:"id_card" validate:"required,validIDCard"`
ImageUrl string `json:"image_url" validate:"required,url"`
Authorized string `json:"authorized" validate:"required,oneof=0 1"`
}
type IVYZSFELReq struct {
Name string `json:"name" validate:"required,min=1,validName"`

View File

@@ -318,6 +318,7 @@ func registerAllProcessors(combService *comb.CombService) {
"IVYZ6M8P": ivyz.ProcessIVYZ6M8PRequest, //职业资格证书
"IVYZ9H2M": ivyz.ProcessIVYZ9H2MRequest, //极光个人婚姻查询V2版
"IVYZZQT3": ivyz.ProcessIVYZZQT3Request, //人脸比对V3
"IVYZZQ3B": ivyz.ProcessIVYZZQ3BRequest, //人脸比对BBsimilarity + verification_result
"IVYZBPQ2": ivyz.ProcessIVYZBPQ2Request, //人脸比对V2
"IVYZSFEL": ivyz.ProcessIVYZSFELRequest, //全国自然人人像三要素核验_V1
"IVYZ0S0D": ivyz.ProcessIVYZ0S0DRequest, //劳动仲裁信息查询(个人版)

View File

@@ -206,6 +206,7 @@ func (s *FormConfigServiceImpl) getDTOStruct(ctx context.Context, apiCode string
"QYGL5CMP": &dto.QYGL5CMPReq{}, //企业五要素验证
"QCXG4896": &dto.QCXG4896Req{}, //网约车风险查询
"IVYZZQT3": &dto.IVYZZQT3Req{}, //人脸比对V3
"IVYZZQ3B": &dto.IVYZZQ3BReq{}, //人脸比对BBsimilarity + verification_result
"IVYZBPQ2": &dto.IVYZBPQ2Req{}, //人脸比对V2
"IVYZSFEL": &dto.IVYZSFELReq{}, //全国自然人人像三要素核验_V1
"QYGL66SL": &dto.QYGL66SLReq{}, //全国企业司法模型服务查询_V1

View File

@@ -0,0 +1,112 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"strconv"
"time"
"tyapi-server/internal/domains/api/dto"
"tyapi-server/internal/domains/api/services/processors"
"tyapi-server/internal/infrastructure/external/zhicha"
)
// ProcessIVYZZQ3BRequest IVYZZQ3B 人脸比对 B
func ProcessIVYZZQ3BRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZZQ3BReq
if err := json.Unmarshal(params, &paramsDto); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err)
}
encryptedName, err := deps.ZhichaService.Encrypt(paramsDto.Name)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
encryptedIDCard, err := deps.ZhichaService.Encrypt(paramsDto.IDCard)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
encryptedImageUrl, err := deps.ZhichaService.Encrypt(paramsDto.ImageUrl)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
reqData := map[string]interface{}{
"idCard": encryptedIDCard,
"name": encryptedName,
"imageId": encryptedImageUrl,
"authorized": paramsDto.Authorized,
}
respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI062", reqData)
if err != nil {
if errors.Is(err, zhicha.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
} else {
return nil, errors.Join(processors.ErrSystem, err)
}
}
respBytes, err := json.Marshal(respData)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
outBytes, err := mapZCI062RespToIVYZZQ3B(respBytes)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return outBytes, nil
}
type IVYZZQ3BOut struct {
HandleTime string `json:"handleTime"`
ResultData IVYZZQ3BOutResultData `json:"resultData"`
}
type IVYZZQ3BOutResultData struct {
// VerificationResult 审核校验结果valid 身份审核通过invalid 身份审核不通过(与 similarity 区间联动,见 mapVerificationResultFromSimilarity
VerificationResult string `json:"verification_result"`
// Similarity 照片相似度分数字符串01000。区间说明0600不同人600700不能确定是否同人7001000同人。数值为上游 score(0~1)×1000。
Similarity string `json:"similarity"`
}
// zci062UpstreamResp 智查 ZCI062 成功返回体中的分数字段(分值越大相似度越高)
type zci062UpstreamResp struct {
Score interface{} `json:"score"`
}
func mapZCI062RespToIVYZZQ3B(respBytes []byte) ([]byte, error) {
var r zci062UpstreamResp
if err := json.Unmarshal(respBytes, &r); err != nil {
return nil, err
}
score := parseScoreToFloat64(r.Score)
similarityVal := score * 1000
similarity := strconv.FormatFloat(similarityVal, 'f', 2, 64)
verificationResult := mapVerificationResultFromSimilarity(similarityVal)
out := IVYZZQ3BOut{
HandleTime: time.Now().Format("2006-01-02 15:04:05"),
ResultData: IVYZZQ3BOutResultData{
VerificationResult: verificationResult,
Similarity: similarity,
},
}
return json.Marshal(out)
}
// mapVerificationResultFromSimilarity 与 similarity01000区间说明对齐
// 7001000】系统判断为同一人 → 身份审核通过 valid其余 → invalid。
func mapVerificationResultFromSimilarity(similarity float64) string {
if similarity >= 700 {
return "valid"
}
return "invalid"
}