This commit is contained in:
2026-04-21 22:36:48 +08:00
commit 488c695fdf
748 changed files with 266838 additions and 0 deletions

View File

@@ -0,0 +1,51 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/westdex"
)
// ProcessIVYZ0B03Request IVYZ0B03 API处理方法
func ProcessIVYZ0B03Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZ0B03Req
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.WestDexService.Encrypt(paramsDto.Name)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
encryptedMobileNo, err := deps.WestDexService.Encrypt(paramsDto.MobileNo)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
reqData := map[string]interface{}{
"data": map[string]interface{}{
"name": encryptedName,
"phone": encryptedMobileNo,
},
}
respBytes, err := deps.WestDexService.CallAPI(ctx, "G17BJ02", reqData)
if err != nil {
if errors.Is(err, westdex.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
} else {
return nil, errors.Join(processors.ErrSystem, err)
}
}
return respBytes, nil
}

View File

@@ -0,0 +1,45 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/jiguang"
)
// ProcessIVYZ0S0DRequest IVYZ0S0D API处理方法 - 劳动仲裁信息查询(个人版)
func ProcessIVYZ0S0DRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZ0S0DReq
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)
}
// 构建请求参数
reqData := map[string]interface{}{
"id": paramsDto.IDCard,
"name": paramsDto.Name,
}
// 调用极光API
respBytes, err := deps.JiguangService.CallAPI(ctx, "labor-arbitration-information", "labor-arbitration-information", reqData)
if err != nil {
// 根据错误类型返回相应的错误
if errors.Is(err, jiguang.ErrNotFound) {
return nil, errors.Join(processors.ErrNotFound, err)
} else if errors.Is(err, jiguang.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
} else {
return nil, errors.Join(processors.ErrSystem, err)
}
}
// 极光服务已经返回了 data 字段的 JSON直接返回即可
return respBytes, nil
}

View File

@@ -0,0 +1,63 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/shujubao"
)
// ProcessIVYZ18HYRequest IVYZ18HY 婚姻状况核验V2单人 API 处理方法(使用数据宝服务示例)
func ProcessIVYZ18HYRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZ18HYReq
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)
}
fixedData := map[string]interface{}{"msg": "请联系商务咨询"}
fixedRespBytes, err := json.Marshal(fixedData)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return fixedRespBytes, nil
authDate := ""
if len(paramsDto.AuthDate) >= 8 {
authDate = paramsDto.AuthDate[len(paramsDto.AuthDate)-8:]
}
reqParams := map[string]interface{}{
"key": "",
"idcard": paramsDto.IDCard,
"name": paramsDto.Name,
"maritalType": paramsDto.MaritalType,
"authcode": paramsDto.AuthAuthorizeFileBase64,
"authAuthorizeFileCode": paramsDto.AuthAuthorizeFileCode,
"authDate": authDate,
}
// 最终请求 URL = https://api.chinadatapay.com/communication + 拼接接口地址值,如 personal/197
apiPath := "/communication/personal/10333"
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)
}
respBytes, err := json.Marshal(data)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return respBytes, nil
}

View File

@@ -0,0 +1,52 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/westdex"
)
// ProcessIVYZ1C9DRequest IVYZ1C9D API处理方法
func ProcessIVYZ1C9DRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZ1C9DReq
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.WestDexService.Encrypt(paramsDto.Name)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
encryptedIDCard, err := deps.WestDexService.Encrypt(paramsDto.IDCard)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
reqData := map[string]interface{}{
"data": map[string]interface{}{
"xm": encryptedName,
"sfzh": encryptedIDCard,
"yearNum": paramsDto.Years,
},
}
respBytes, err := deps.WestDexService.CallAPI(ctx, "G38SC02", reqData)
if err != nil {
if errors.Is(err, westdex.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
} else {
return nil, errors.Join(processors.ErrSystem, err)
}
}
return respBytes, nil
}

View File

@@ -0,0 +1,46 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/jiguang"
)
// ProcessIVYZ1J7HRequest IVYZ1J7H API处理方法 - 行驶证核查v2
func ProcessIVYZ1J7HRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZ1J7HReq
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)
}
// 构建请求参数
reqData := map[string]interface{}{
"plate": paramsDto.PlateNo,
"plateType": paramsDto.CarPlateType,
"name": paramsDto.Name,
}
// 调用极光API
respBytes, err := deps.JiguangService.CallAPI(ctx, "vehicle-driving-license-v2", "vehicle/driving-license-v2", reqData)
if err != nil {
// 根据错误类型返回相应的错误
if errors.Is(err, jiguang.ErrNotFound) {
return nil, errors.Join(processors.ErrNotFound, err)
} else if errors.Is(err, jiguang.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
} else {
return nil, errors.Join(processors.ErrSystem, err)
}
}
// 极光服务已经返回了 data 字段的 JSON直接返回即可
return respBytes, nil
}

View File

@@ -0,0 +1,38 @@
package ivyz
import (
"context"
"errors"
"hyapi-server/internal/domains/api/services/processors"
)
// ProcessIVYZ2125Request IVYZ2125 API处理方法
func ProcessIVYZ2125Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
return nil, errors.Join(processors.ErrSystem, errors.New("服务已停用"))
// var paramsDto dto.IVYZ2125Req
// 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)
// }
// reqData := map[string]interface{}{
// "name": paramsDto.Name,
// "idCard": paramsDto.IDCard,
// "mobile": paramsDto.Mobile,
// }
// respBytes, err := deps.WestDexService.CallAPI(ctx, "IVYZ2125", reqData)
// if err != nil {
// if errors.Is(err, westdex.ErrDatasource) {
// return nil, errors.Join(processors.ErrDatasource, err)
// } else {
// return nil, errors.Join(processors.ErrSystem, err)
// }
// }
// return respBytes, nil
}

View File

@@ -0,0 +1,54 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/shujubao"
)
// ProcessIVYZ28HYRequest IVYZ28HY 婚姻状况核验单人) API 处理方法(使用数据宝服务示例)
func ProcessIVYZ28HYRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZ28HYReq
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)
}
fixedData := map[string]interface{}{"msg": "请联系商务咨询"}
fixedRespBytes, err := json.Marshal(fixedData)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return fixedRespBytes, nil
reqParams := map[string]interface{}{
"key": "",
"idcard": paramsDto.IDCard,
"name": paramsDto.Name,
}
// 最终请求 URL = https://api.chinadatapay.com/communication + 拼接接口地址值,如 personal/197
apiPath := "/communication/personal/10149"
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)
}
respBytes, err := json.Marshal(data)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return respBytes, nil
}

View File

@@ -0,0 +1,161 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"strconv"
"strings"
"time"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/shumai"
)
// ivyz2a8bShumaiResp 数脉 /v4/id_card/check 返回格式
type ivyz2a8bShumaiResp struct {
Result float64 `json:"result"`
OrderNo string `json:"order_no"`
Desc string `json:"desc"`
Sex string `json:"sex"`
Birthday string `json:"birthday"` // yyyyMMdd
Address string `json:"address"`
}
// ProcessIVYZ2A8BRequest IVYZ2A8B API处理方法 - 身份二要素认证政务版 数脉内部替换
func ProcessIVYZ2A8BRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZ2A8BReq
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)
}
reqFormData := map[string]interface{}{
"idcard": paramsDto.IDCard,
"name": paramsDto.Name,
}
// 以表单方式调用数脉 API参数在 CallAPIForm 内转为 application/x-www-form-urlencoded
apiPath := "/v4/id_card/check" // 接口路径,根据数脉文档填写(如 v4/xxx
// 先尝试使用政务接口app_id2 和 app_secret2
respBytes, err := deps.ShumaiService.CallAPIForm(ctx, apiPath, reqFormData, true)
if err != nil {
// 使用实时接口app_id 和 app_secret重试
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)
} else {
// 其他未知错误
return nil, errors.Join(processors.ErrSystem, err)
}
}
}
// 将数脉返回的新格式映射为原有 API 输出格式
oldFormat, err := mapIVYZ2A8BShumaiToOld(respBytes)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return json.Marshal(oldFormat)
}
func mapIVYZ2A8BShumaiToOld(respBytes []byte) (map[string]interface{}, error) {
var r ivyz2a8bShumaiResp
if err := json.Unmarshal(respBytes, &r); err != nil {
return nil, err
}
// final_auth_result: "0"=一致,"1"=不一致/无记录;按 result0-一致1-不一致2-无记录(预留)
finalAuth := "1"
switch int(r.Result) {
case 0:
finalAuth = "0"
}
return map[string]interface{}{
"final_auth_result": finalAuth,
"birthday": formatBirthdayOld(r.Birthday),
"address": r.Address,
"constellation": constellationFromBirthday(r.Birthday),
"gender": r.Sex,
"age": ageFromBirthday(r.Birthday),
}, nil
}
func formatBirthdayOld(s string) string {
s = strings.TrimSpace(s)
if len(s) != 8 {
return s
}
for _, c := range s {
if c < '0' || c > '9' {
return s
}
}
return s[0:4] + "年" + s[4:6] + "月" + s[6:8] + "日"
}
func constellationFromBirthday(s string) string {
if len(s) != 8 {
return ""
}
month, _ := strconv.Atoi(s[4:6])
day, _ := strconv.Atoi(s[6:8])
if month < 1 || month > 12 || day < 1 || day > 31 {
return ""
}
switch {
case (month == 12 && day >= 22) || (month == 1 && day <= 19):
return "魔羯座"
case (month == 1 && day >= 20) || (month == 2 && day <= 18):
return "水瓶座"
case (month == 2 && day >= 19) || (month == 3 && day <= 20):
return "双鱼座"
case (month == 3 && day >= 21) || (month == 4 && day <= 19):
return "白羊座"
case (month == 4 && day >= 20) || (month == 5 && day <= 20):
return "金牛座"
case (month == 5 && day >= 21) || (month == 6 && day <= 21):
return "双子座"
case (month == 6 && day >= 22) || (month == 7 && day <= 22):
return "巨蟹座"
case (month == 7 && day >= 23) || (month == 8 && day <= 22):
return "狮子座"
case (month == 8 && day >= 23) || (month == 9 && day <= 22):
return "处女座"
case (month == 9 && day >= 23) || (month == 10 && day <= 23):
return "天秤座"
case (month == 10 && day >= 24) || (month == 11 && day <= 22):
return "天蝎座"
case (month == 11 && day >= 23) || (month == 12 && day <= 21):
return "射手座"
default:
return "魔羯座"
}
}
func ageFromBirthday(s string) string {
if len(s) < 4 {
return ""
}
y, err := strconv.Atoi(s[0:4])
if err != nil || y <= 0 {
return ""
}
age := time.Now().Year() - y
if age < 0 {
age = 0
}
return strconv.Itoa(age)
}

View File

@@ -0,0 +1,58 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"strconv"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/westdex"
)
// ProcessIVYZ2B2TRequest IVYZ2B2T API处理方法 能力资质核验(学历)
func ProcessIVYZ2B2TRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZ2B2TReq
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.WestDexService.Encrypt(paramsDto.Name)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
encryptedIDCard, err := deps.WestDexService.Encrypt(paramsDto.IDCard)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
encryptedQueryReasonId, err := deps.WestDexService.Encrypt(strconv.FormatInt(paramsDto.QueryReasonId, 10))
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
reqData := map[string]interface{}{
"data": map[string]interface{}{
"idCard": encryptedIDCard,
"name": encryptedName,
"queryReasonId": encryptedQueryReasonId,
},
}
respBytes, err := deps.WestDexService.CallAPI(ctx, "G11JX01", reqData)
if err != nil {
if errors.Is(err, westdex.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
} else {
return nil, errors.Join(processors.ErrSystem, err)
}
}
return respBytes, nil
}

View File

@@ -0,0 +1,56 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/zhicha"
)
// ProcessIVYZ2C1PRequest IVYZ2C1P API处理方法 - 风控黑名单
func ProcessIVYZ2C1PRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZ2C1PReq
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)
}
reqData := map[string]interface{}{
"name": encryptedName,
"idCard": encryptedIDCard,
"authorized": paramsDto.Authorized,
}
respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI037", 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)
}
}
// 将响应数据转换为JSON字节
respBytes, err := json.Marshal(respData)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return respBytes, nil
}

View File

@@ -0,0 +1,54 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/zhicha"
)
// ProcessIVYZ2MN6Request IVYZ2MN6 API处理方法
func ProcessIVYZ2MN6Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZ2MN6Req
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)
}
reqData := map[string]interface{}{
"name": encryptedName,
"idCard": encryptedIDCard,
"authorized": paramsDto.Authorized,
}
respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI1004", reqData)
if err != nil {
if errors.Is(err, zhicha.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
}
return nil, errors.Join(processors.ErrSystem, err)
}
respBytes, err := json.Marshal(respData)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return respBytes, nil
}

View File

@@ -0,0 +1,49 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/westdex"
)
// ProcessIVYZ385ERequest IVYZ385E API处理方法
func ProcessIVYZ385ERequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZ385EReq
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.WestDexService.Encrypt(paramsDto.Name)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
encryptedIDCard, err := deps.WestDexService.Encrypt(paramsDto.IDCard)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
reqData := map[string]interface{}{
"xm": encryptedName,
"gmsfzhm": encryptedIDCard,
}
respBytes, err := deps.WestDexService.CallAPI(ctx, "WEST00020", reqData)
if err != nil {
if errors.Is(err, westdex.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
} else {
return nil, errors.Join(processors.ErrSystem, err)
}
}
return respBytes, nil
}

View File

@@ -0,0 +1,56 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/shujubao"
)
// ProcessIVYZ38SRRequest IVYZ38SR 婚姻状态核验(双人) API 处理方法(使用数据宝服务示例)
func ProcessIVYZ38SRRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZ38SRReq
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)
}
fixedData := map[string]interface{}{"msg": "请联系商务咨询"}
fixedRespBytes, err := json.Marshal(fixedData)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return fixedRespBytes, nil
reqParams := map[string]interface{}{
"key": "",
"name": paramsDto.ManName,
"idcard": paramsDto.ManIDCard,
"woman_name": paramsDto.WomanName,
"woman_idcard": paramsDto.WomanIDCard,
}
// 最终请求 URL = https://api.chinadatapay.com/communication + 拼接接口地址值,如 personal/197
apiPath := "/communication/personal/10148"
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)
}
respBytes, err := json.Marshal(data)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return respBytes, nil
}

View File

@@ -0,0 +1,50 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/xingwei"
)
// ProcessIVYZ3A7FRequest IVYZ3A7F API处理方法 - 行为数据查询
func ProcessIVYZ3A7FRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZ3A7FReq
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)
}
// 构建请求数据使用xingwei服务的正确字段名
reqData := map[string]interface{}{
"name": paramsDto.Name,
"idCardNum": paramsDto.IDCard,
}
// 调用行为数据API使用指定的project_id
projectID := "CDJ-1104648854749245440"
respBytes, err := deps.XingweiService.CallAPI(ctx, projectID, reqData)
if err != nil {
if errors.Is(err, xingwei.ErrNotFound) {
// 查空情况,返回特定的查空错误
return nil, errors.Join(processors.ErrNotFound, err)
} else if errors.Is(err, xingwei.ErrDatasource) {
// 数据源错误
return nil, errors.Join(processors.ErrDatasource, err)
} else if errors.Is(err, xingwei.ErrSystem) {
// 系统错误
return nil, errors.Join(processors.ErrSystem, err)
} else {
// 其他未知错误
return nil, errors.Join(processors.ErrSystem, err)
}
}
return respBytes, nil
}

View File

@@ -0,0 +1,64 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/muzi"
)
// ProcessIVYZ3P9MRequest IVYZ3P9M API处理方法 - 学历查询实时版
func ProcessIVYZ3P9MRequest_2(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZ3P9MReq
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.MuziService.Encrypt(paramsDto.Name)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
encryptedCertCode, err := deps.MuziService.Encrypt(paramsDto.IDCard)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
// 处理 returnType 参数,默认为 "1"
returnType := paramsDto.ReturnType
if returnType == "" {
returnType = "1"
}
paramSign := map[string]interface{}{
"returnType": returnType,
"realName": encryptedName,
"certCode": encryptedCertCode,
}
reqData := map[string]interface{}{
"realName": encryptedName,
"certCode": encryptedCertCode,
"returnType": returnType,
}
respData, err := deps.MuziService.CallAPI(ctx, "PC0041", "/academic", reqData, paramSign)
if err != nil {
switch {
case errors.Is(err, muzi.ErrDatasource):
return nil, errors.Join(processors.ErrDatasource, err)
case errors.Is(err, muzi.ErrSystem):
return nil, errors.Join(processors.ErrSystem, err)
default:
return nil, errors.Join(processors.ErrSystem, err)
}
}
return respData, nil
}

View File

@@ -0,0 +1,168 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"strings"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/zhicha"
)
// ProcessIVYZ3P9MRequest IVYZ3P9M API处理方法 - 学历查询实时版
func ProcessIVYZ3P9MRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZ3P9MReq
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)
}
reqData := map[string]interface{}{
"name": encryptedName,
"idCard": encryptedIDCard,
"authorized": "1",
}
respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI1004", reqData)
if err != nil {
if errors.Is(err, zhicha.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
}
return nil, errors.Join(processors.ErrSystem, err)
}
out, err := mapZCI1004ToIVYZ3P9M(respData, paramsDto.Name, paramsDto.IDCard)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return json.Marshal(out)
}
type zci1004Item struct {
EndDate string `json:"endDate"`
EducationLevel string `json:"educationLevel"`
LearningForm string `json:"learningForm"`
}
type ivyz3p9mItem struct {
GraduationDate string `json:"graduationDate"`
StudentName string `json:"studentName"`
EducationLevel string `json:"educationLevel"`
LearningForm string `json:"learningForm"`
IDNumber string `json:"idNumber"`
}
func mapZCI1004ToIVYZ3P9M(respData interface{}, name, idCard string) ([]ivyz3p9mItem, error) {
respBytes, err := json.Marshal(respData)
if err != nil {
return nil, err
}
var source []zci1004Item
if err := json.Unmarshal(respBytes, &source); err != nil {
var wrapped struct {
Data []zci1004Item `json:"data"`
}
if err2 := json.Unmarshal(respBytes, &wrapped); err2 != nil {
return nil, err
}
source = wrapped.Data
}
out := make([]ivyz3p9mItem, 0, len(source))
for _, it := range source {
out = append(out, ivyz3p9mItem{
GraduationDate: normalizeDateDigits(it.EndDate),
StudentName: name,
EducationLevel: mapEducationLevelToCode(it.EducationLevel),
LearningForm: mapLearningFormToCode(it.LearningForm),
IDNumber: idCard,
})
}
return out, nil
}
func mapEducationLevelToCode(level string) string {
v := normalizeText(level)
switch {
case strings.Contains(v, "第二学士"):
return "5"
case strings.Contains(v, "博士"):
return "4"
case strings.Contains(v, "硕士"):
return "3"
case strings.Contains(v, "本科"):
return "2"
case strings.Contains(v, "专科"), strings.Contains(v, "大专"):
return "1"
default:
return "99"
}
}
func mapLearningFormToCode(form string) string {
v := normalizeText(form)
switch {
case strings.Contains(v, "脱产"):
return "1"
case strings.Contains(v, "普通全日制"):
return "2"
case strings.Contains(v, "全日制"):
return "3"
case strings.Contains(v, "开放教育"), strings.Contains(v, "开放大学"):
return "4"
case strings.Contains(v, "夜大学"), strings.Contains(v, "夜大"):
return "5"
case strings.Contains(v, "函授"):
return "6"
case strings.Contains(v, "网络教育"), strings.Contains(v, "网教"), strings.Contains(v, "远程教育"):
return "7"
case strings.Contains(v, "非全日制"):
return "8"
case strings.Contains(v, "业余"):
return "9"
case strings.Contains(v, "自学考试"), strings.Contains(v, "自考"):
// 自考在既有枚举中无直对应,兼容并入“业余”
return "9"
default:
return "99"
}
}
func normalizeDateDigits(s string) string {
trimmed := strings.TrimSpace(s)
if trimmed == "" {
return ""
}
var b strings.Builder
for _, ch := range trimmed {
if ch >= '0' && ch <= '9' {
b.WriteRune(ch)
}
}
return b.String()
}
func normalizeText(s string) string {
v := strings.TrimSpace(strings.ToLower(s))
v = strings.ReplaceAll(v, " ", "")
v = strings.ReplaceAll(v, "-", "")
v = strings.ReplaceAll(v, "_", "")
return v
}

View File

@@ -0,0 +1,58 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/shujubao"
)
// ProcessIVYZ48SRRequest IVYZ48SR 婚姻状态核验V2双人 API 处理方法(使用数据宝服务示例)
func ProcessIVYZ48SRRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZ48SRReq
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)
}
fixedData := map[string]interface{}{"msg": "请联系商务咨询"}
fixedRespBytes, err := json.Marshal(fixedData)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return fixedRespBytes, nil
reqParams := map[string]interface{}{
"key": "",
"name": paramsDto.ManName,
"idcard": paramsDto.ManIDCard,
"woman_name": paramsDto.WomanName,
"woman_idcard": paramsDto.WomanIDCard,
"marital_type": paramsDto.MaritalType,
"auth_authorize_file_code": paramsDto.AuthAuthorizeFileCode,
}
// 最终请求 URL = https://api.chinadatapay.com/communication + 拼接接口地址值,如 personal/197
apiPath := "/communication/personal/10332"
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)
}
respBytes, err := json.Marshal(data)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return respBytes, nil
}

View File

@@ -0,0 +1,84 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"fmt"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/westdex"
"github.com/tidwall/gjson"
)
// ProcessIVYZ4E8BRequest IVYZ4E8B API处理方法
func ProcessIVYZ4E8BRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZ4E8BReq
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.WestDexService.Encrypt(paramsDto.Name)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
encryptedIDCard, err := deps.WestDexService.Encrypt(paramsDto.IDCard)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
reqData := map[string]interface{}{
"data": map[string]interface{}{
"name": encryptedName,
"idNo": encryptedIDCard,
},
}
respBytes, err := deps.WestDexService.CallAPI(ctx, "G09GZ02", reqData)
if err != nil {
if errors.Is(err, westdex.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
} else {
return nil, errors.Join(processors.ErrSystem, err)
}
}
// 解析响应提取data字段中的hyzk
var respMap map[string]interface{}
if err := json.Unmarshal(respBytes, &respMap); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
dataStr, ok := respMap["data"].(string)
if !ok {
return nil, fmt.Errorf("%s: data字段格式错误", processors.ErrDatasource)
}
// 使用gjson解析data字符串
hyzk := ""
{
result := gjson.Get(dataStr, "hyzk")
if !result.Exists() {
return nil, fmt.Errorf("%s: data中缺少hyzk字段", processors.ErrDatasource)
}
hyzk = result.String()
}
// 返回格式为 {"status": hyzk}
resp := map[string]interface{}{
"status": hyzk,
}
finalBytes, err := json.Marshal(resp)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return finalBytes, nil
}

View File

@@ -0,0 +1,83 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/westdex"
)
// ProcessIVYZ5733Request IVYZ5733 API处理方法
func ProcessIVYZ5733Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZ5733Req
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.WestDexService.Encrypt(paramsDto.Name)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
encryptedIDCard, err := deps.WestDexService.Encrypt(paramsDto.IDCard)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
reqData := map[string]interface{}{
"data": map[string]interface{}{
"name": encryptedName,
"idNo": encryptedIDCard,
},
}
respBytes, err := deps.WestDexService.CallAPI(ctx, "G09GZ02", reqData)
if err != nil {
if errors.Is(err, westdex.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
} else {
return nil, errors.Join(processors.ErrSystem, err)
}
}
// 解析新源响应数据
var newResp struct {
Status string `json:"status"`
}
if err := json.Unmarshal(respBytes, &newResp); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
// 转换状态码
var statusCode string
switch newResp.Status {
case "结婚":
statusCode = "IA"
case "离婚":
statusCode = "IB"
case "未查得":
statusCode = "INR"
default:
statusCode = "INR"
}
// 构建旧格式响应
oldResp := map[string]interface{}{
"code": "0",
"data": map[string]interface{}{
"data": statusCode + ":匹配不成功",
},
"seqNo": "",
"message": "成功",
}
// 返回旧格式响应
return json.Marshal(oldResp)
}

View File

@@ -0,0 +1,57 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/westdex"
)
// ProcessIVYZ5A9ORequest IVYZ5A9O API处理方法 全国⾃然⼈⻛险评估评分模型
func ProcessIVYZ5A9ORequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZ5A9OReq
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.WestDexService.Encrypt(paramsDto.Name)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
encryptedIDCard, err := deps.WestDexService.Encrypt(paramsDto.IDCard)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
encryptedAuthAuthorizeFileCode, err := deps.WestDexService.Encrypt(paramsDto.AuthAuthorizeFileCode)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
reqData := map[string]interface{}{
"data": map[string]interface{}{
"idcard": encryptedIDCard,
"name": encryptedName,
"auth_authorizeFileCode": encryptedAuthAuthorizeFileCode,
},
}
respBytes, err := deps.WestDexService.CallAPI(ctx, "G01SC01", reqData)
if err != nil {
if errors.Is(err, westdex.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
} else {
return nil, errors.Join(processors.ErrSystem, err)
}
}
return respBytes, nil
}

View File

@@ -0,0 +1,66 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/zhicha"
)
// ProcessIVYZ5E22Request API处理方法 - 双人婚姻评估查询
func ProcessIVYZ5E22Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZ5E22Req
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)
}
encryptedManName, err := deps.ZhichaService.Encrypt(paramsDto.ManName)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
encryptedManIDCard, err := deps.ZhichaService.Encrypt(paramsDto.ManIDCard)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
encryptedWomanName, err := deps.ZhichaService.Encrypt(paramsDto.WomanName)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
encryptedWomanIDCard, err := deps.ZhichaService.Encrypt(paramsDto.WomanIDCard)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
reqData := map[string]interface{}{
"nameMan": encryptedManName,
"idCardMan": encryptedManIDCard,
"nameWoman": encryptedWomanName,
"idCardWoman": encryptedWomanIDCard,
"authorized": paramsDto.Authorized,
}
respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI042", 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)
}
}
// 将响应数据转换为JSON字节
respBytes, err := json.Marshal(respData)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return respBytes, nil
}

View File

@@ -0,0 +1,56 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/zhicha"
)
// ProcessIVYZ5E3FRequest IVYZ5E3F API处理方法 - 婚姻评估查询
func ProcessIVYZ5E3FRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZ5E3FReq
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)
}
reqData := map[string]interface{}{
"name": encryptedName,
"idCard": encryptedIDCard,
"authorized": paramsDto.Authorized,
}
respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI029", 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)
}
}
// 将响应数据转换为JSON字节
respBytes, err := json.Marshal(respData)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return respBytes, nil
}

View File

@@ -0,0 +1,46 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/xingwei"
)
// ProcessIVYZ6G7HRequest IVYZ6G7H API处理方法 - 个人婚姻状况查询v2
func ProcessIVYZ6G7HRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZ6G7HReq
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)
}
// 构建请求数据,将项目规范的字段名转换为 XingweiService 需要的字段名
reqData := map[string]interface{}{
"name": paramsDto.Name,
"idCardNum": paramsDto.IDCard,
}
// 调用行为数据API使用指定的project_id
projectID := "CDJ-1104646268587536384"
respBytes, err := deps.XingweiService.CallAPI(ctx, projectID, reqData)
if err != nil {
if errors.Is(err, xingwei.ErrNotFound) {
return nil, errors.Join(processors.ErrNotFound, err)
} else if errors.Is(err, xingwei.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
} else if errors.Is(err, xingwei.ErrSystem) {
return nil, errors.Join(processors.ErrSystem, err)
} else {
return nil, errors.Join(processors.ErrSystem, err)
}
}
return respBytes, nil
}

View File

@@ -0,0 +1,46 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/xingwei"
)
// ProcessIVYZ6M8PRequest IVYZ6M8P 职业资格证书API处理方法
func ProcessIVYZ6M8PRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZ6M8PReq
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)
}
// 构建请求数据,将项目规范的字段名转换为 XingweiService 需要的字段名
reqData := map[string]interface{}{
"name": paramsDto.Name,
"idCardNum": paramsDto.IDCard,
}
// 调用行为数据API使用指定的project_id
projectID := "CDJ-1147725836315455488"
respBytes, err := deps.XingweiService.CallAPI(ctx, projectID, reqData)
if err != nil {
if errors.Is(err, xingwei.ErrNotFound) {
return nil, errors.Join(processors.ErrNotFound, err)
} else if errors.Is(err, xingwei.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
} else if errors.Is(err, xingwei.ErrSystem) {
return nil, errors.Join(processors.ErrSystem, err)
} else {
return nil, errors.Join(processors.ErrSystem, err)
}
}
return respBytes, nil
}

View File

@@ -0,0 +1,47 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/zhicha"
)
// ProcessIVYZ7C9DRequest IVYZ7C9D API处理方法 - 人脸识别
func ProcessIVYZ7C9DRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZ7C9DReq
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)
}
reqData := map[string]interface{}{
"name": paramsDto.Name,
"idCard": paramsDto.IDCard,
"returnUrl": paramsDto.ReturnURL,
"orderId": paramsDto.UniqueID,
}
respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI013", 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)
}
}
// 将响应数据转换为JSON字节
respBytes, err := json.Marshal(respData)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return respBytes, nil
}

View File

@@ -0,0 +1,95 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"fmt"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/westdex"
"github.com/tidwall/gjson"
)
// ProcessIVYZ7F2ARequest IVYZ7F2A API处理方法
func ProcessIVYZ7F2ARequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZ7F2AReq
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)
}
encryptedManName, err := deps.WestDexService.Encrypt(paramsDto.ManName)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
encryptedManIDCard, err := deps.WestDexService.Encrypt(paramsDto.ManIDCard)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
encryptedWomanName, err := deps.WestDexService.Encrypt(paramsDto.WomanName)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
encryptedWomanIDCard, err := deps.WestDexService.Encrypt(paramsDto.WomanIDCard)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
reqData := map[string]interface{}{
"data": map[string]interface{}{
"manName": encryptedManName,
"manIdcard": encryptedManIDCard,
"womanName": encryptedWomanName,
"womanIdcard": encryptedWomanIDCard,
},
}
respBytes, err := deps.WestDexService.CallAPI(ctx, "G10GZ02", reqData)
if err != nil {
if errors.Is(err, westdex.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
} else {
return nil, errors.Join(processors.ErrSystem, err)
}
}
var respMap map[string]interface{}
if err := json.Unmarshal(respBytes, &respMap); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
dataStr, ok := respMap["data"].(string)
if !ok {
return nil, fmt.Errorf("%s: data字段格式错误", processors.ErrDatasource)
}
// 使用gjson解析data字符串
hyzk := ""
{
result := gjson.Get(dataStr, "hyzk")
if !result.Exists() {
return nil, fmt.Errorf("%s: data中缺少hyzk字段", processors.ErrDatasource)
}
hyzk = result.String()
}
// 返回格式为 {"status": hyzk}
resp := map[string]interface{}{
"status": hyzk,
}
finalBytes, err := json.Marshal(resp)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return finalBytes, nil
return respBytes, nil
}

View File

@@ -0,0 +1,56 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/zhicha"
)
// ProcessIVYZ7F3ARequest IVYZ7F3A API处理方法 - 学历信息查询B
func ProcessIVYZ7F3ARequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZ7F3AReq
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)
}
reqData := map[string]interface{}{
"name": encryptedName,
"idCard": encryptedIDCard,
"authorized": paramsDto.Authorized,
}
respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI035", 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)
}
}
// 将响应数据转换为JSON字节
respBytes, err := json.Marshal(respData)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return respBytes, nil
}

View File

@@ -0,0 +1,96 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/zhicha"
)
// ProcessIVYZ81NCRequest IVYZ81NC API处理方法
func ProcessIVYZ81NCRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZ81NCReq
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)
}
reqData := map[string]interface{}{
"name": encryptedName,
"idCard": encryptedIDCard,
"authorized": "1", // 默认值
}
respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI029", 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)
}
}
// 解析响应数据,期望格式为 {"state": "1"}
var stateResp struct {
State string `json:"state"`
RegTime string `json:"regTime"`
}
// 将 respData 转换为 JSON 字节再解析
respDataBytes, err := json.Marshal(respData)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
if err := json.Unmarshal(respDataBytes, &stateResp); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
// 根据 state 值转换为 81nc 格式
var opType, opTypeDesc string
switch stateResp.State {
case "1": // 已婚
opType = "IA"
opTypeDesc = "结婚"
case "2": // 未婚/未在民政局登记
opType = "INR"
opTypeDesc = "匹配不成功"
case "3": // 离异
opType = "IB"
opTypeDesc = "离婚"
default:
opType = "INR"
opTypeDesc = "匹配不成功"
}
// 构建 81nc 格式响应
result := map[string]interface{}{
"code": "0",
"data": map[string]interface{}{
"op_date": stateResp.RegTime,
"op_type": opType,
"op_type_desc": opTypeDesc,
},
"message": "成功",
"seqNo": "",
}
// 返回 81nc 格式响应
return json.Marshal(result)
}

View File

@@ -0,0 +1,47 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/xingwei"
)
// ProcessIVYZ8I9JRequest IVYZ8I9J API处理方法 - 互联网行为推测
func ProcessIVYZ8I9JRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZ8I9JReq
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)
}
// 构建请求数据,将项目规范的字段名转换为 XingweiService 需要的字段名
reqData := map[string]interface{}{
"name": paramsDto.Name,
"idCardNum": paramsDto.IDCard,
"phoneNumber": paramsDto.MobileNo,
}
// 调用行为数据API使用指定的project_id
projectID := "CDJ-1074522823015198720"
respBytes, err := deps.XingweiService.CallAPI(ctx, projectID, reqData)
if err != nil {
if errors.Is(err, xingwei.ErrNotFound) {
return nil, errors.Join(processors.ErrNotFound, err)
} else if errors.Is(err, xingwei.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
} else if errors.Is(err, xingwei.ErrSystem) {
return nil, errors.Join(processors.ErrSystem, err)
} else {
return nil, errors.Join(processors.ErrSystem, err)
}
}
return respBytes, nil
}

View File

@@ -0,0 +1,68 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"strings"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/westdex"
)
// ProcessIVYZ9363Request IVYZ9363 API处理方法
func ProcessIVYZ9363Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZ9363Req
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)
}
// 新增:身份证一致性校验
if strings.EqualFold(strings.TrimSpace(paramsDto.ManIDCard), strings.TrimSpace(paramsDto.WomanIDCard)) {
return nil, errors.Join(processors.ErrInvalidParam, errors.New("请正确填写身份信息"))
}
encryptedManName, err := deps.WestDexService.Encrypt(paramsDto.ManName)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
encryptedManIDCard, err := deps.WestDexService.Encrypt(paramsDto.ManIDCard)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
encryptedWomanName, err := deps.WestDexService.Encrypt(paramsDto.WomanName)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
encryptedWomanIDCard, err := deps.WestDexService.Encrypt(paramsDto.WomanIDCard)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
reqData := map[string]interface{}{
"data": map[string]interface{}{
"name_man": encryptedManName,
"idcard_man": encryptedManIDCard,
"name_woman": encryptedWomanName,
"idcard_woman": encryptedWomanIDCard,
},
}
respBytes, err := deps.WestDexService.CallAPI(ctx, "G10XM02", reqData)
if err != nil {
if errors.Is(err, westdex.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
} else {
return nil, errors.Join(processors.ErrSystem, err)
}
}
return respBytes, nil
}

View File

@@ -0,0 +1,51 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/westdex"
)
// ProcessIVYZ9A2BRequest IVYZ9A2B API处理方法
func ProcessIVYZ9A2BRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZ9A2BReq
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.WestDexService.Encrypt(paramsDto.Name)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
encryptedIDCard, err := deps.WestDexService.Encrypt(paramsDto.IDCard)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
reqData := map[string]interface{}{
"data": map[string]interface{}{
"name_value": encryptedName,
"id_card_value": encryptedIDCard,
},
}
respBytes, err := deps.WestDexService.CallAPI(ctx, "G11BJ06", reqData)
if err != nil {
if errors.Is(err, westdex.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
} else {
return nil, errors.Join(processors.ErrSystem, err)
}
}
return respBytes, nil
}

View File

@@ -0,0 +1,51 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/xingwei"
)
// ProcessIVYZ9D2ERequest IVYZ9D2E API处理方法 - 行为数据查询
func ProcessIVYZ9D2ERequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZ9D2EReq
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)
}
// 构建请求数据使用xingwei服务的正确字段名
reqData := map[string]interface{}{
"name": paramsDto.Name,
"idCardNum": paramsDto.IDCard,
"scenario": paramsDto.UseScenario,
}
// 调用行为数据API使用指定的project_id
projectID := "CDJ-1104648845446279168"
respBytes, err := deps.XingweiService.CallAPI(ctx, projectID, reqData)
if err != nil {
if errors.Is(err, xingwei.ErrNotFound) {
// 查空情况,返回特定的查空错误
return nil, errors.Join(processors.ErrNotFound, err)
} else if errors.Is(err, xingwei.ErrDatasource) {
// 数据源错误
return nil, errors.Join(processors.ErrDatasource, err)
} else if errors.Is(err, xingwei.ErrSystem) {
// 系统错误
return nil, errors.Join(processors.ErrSystem, err)
} else {
// 其他未知错误
return nil, errors.Join(processors.ErrSystem, err)
}
}
return respBytes, nil
}

View File

@@ -0,0 +1,47 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/jiguang"
)
// ProcessIVYZ9H2MRequest IVYZ9H2M API处理方法 - 极光个人婚姻查询V2版
func ProcessIVYZ9H2MRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZ9H2MReq
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)
}
// 构建请求参数
reqData := map[string]interface{}{
"id_no": paramsDto.IDCard,
"name": paramsDto.Name,
}
// 调用极光API
// apiCode: marriage-single-v2 (用于请求头)
// apiPath: marriage/single-v2 (用于URL路径)
respBytes, err := deps.JiguangService.CallAPI(ctx, "marriage-single-v2", "marriage/single-v2", reqData)
if err != nil {
// 根据错误类型返回相应的错误
if errors.Is(err, jiguang.ErrNotFound) {
return nil, errors.Join(processors.ErrNotFound, err)
} else if errors.Is(err, jiguang.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
} else {
return nil, errors.Join(processors.ErrSystem, err)
}
}
// 极光服务已经返回了 data 字段的 JSON直接返回即可
return respBytes, nil
}

View File

@@ -0,0 +1,103 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"strconv"
"time"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/westdex"
"github.com/tidwall/gjson"
)
// ProcessIVYZ9K2LRequest IVYZ9K2L API处理方法 - 身份认证三要素(人脸图像版)
func ProcessIVYZ9K2LRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZ9K2LReq
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.WestDexService.Encrypt(paramsDto.Name)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
// 加密身份证号
encryptedIDCard, err := deps.WestDexService.Encrypt(paramsDto.IDCard)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
// 生成时间戳(毫秒)
timestamp := strconv.FormatInt(time.Now().UnixNano()/int64(time.Millisecond), 10)
// 获取自定义编号(从 WestDexService 配置中获取 secret_id
config := deps.WestDexService.GetConfig()
customNumber := config.SecretID
// 构建请求数据
reqData := map[string]interface{}{
"data": map[string]interface{}{
"timeStamp": timestamp,
"customNumber": customNumber,
"xM": encryptedName,
"gMSFZHM": encryptedIDCard,
"photoData": paramsDto.PhotoData,
},
}
respBytes, err := deps.WestDexService.CallAPI(ctx, "idCardThreeElements", reqData)
if err != nil {
switch {
case errors.Is(err, westdex.ErrDatasource):
return nil, errors.Join(processors.ErrDatasource, err)
case errors.Is(err, westdex.ErrSystem):
return nil, errors.Join(processors.ErrSystem, err)
default:
return nil, errors.Join(processors.ErrSystem, err)
}
}
// 使用gjson提取authResult字段
// 尝试多个可能的路径
var authResult string
paths := []string{
"WEST00037.WEST00038.authResult",
"WEST00036.WEST00037.WEST00038.authResult",
"authResult",
}
for _, path := range paths {
result := gjson.GetBytes(respBytes, path)
if result.Exists() {
authResult = result.String()
break
}
}
// 如果找不到authResult返回ErrDatasource
if authResult == "" {
return nil, errors.Join(processors.ErrDatasource, errors.New("响应中未找到authResult字段"))
}
// 构建返回格式 {result: XXXX}
response := map[string]interface{}{
"result": authResult,
}
responseBytes, err := json.Marshal(response)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return responseBytes, nil
}

View File

@@ -0,0 +1,48 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/shumai"
)
// ProcessIVYZ9K7FRequest IVYZ9K7F 身份证实名认证即时版 API处理方法
func ProcessIVYZ9K7FRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZ9K7FReq
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)
}
reqFormData := map[string]interface{}{
"idcard": paramsDto.IDCard,
"name": paramsDto.Name,
}
// 以表单方式调用数脉 API参数在 CallAPIForm 内转为 application/x-www-form-urlencoded
apiPath := "/v4/id_card/check" // 接口路径,根据数脉文档填写(如 v4/xxx
respBytes, err := deps.ShumaiService.CallAPIForm(ctx, apiPath, reqFormData)
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)
} else {
// 其他未知错误
return nil, errors.Join(processors.ErrSystem, err)
}
}
return respBytes, nil
}

View File

@@ -0,0 +1,49 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/shumai"
)
// ProcessIVYZA1B3Request IVYZA1B3 公安三要素人脸识别API处理方法
func ProcessIVYZA1B3Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZA1B3Req
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)
}
reqFormData := map[string]interface{}{
"idcard": paramsDto.IDCard,
"name": paramsDto.Name,
"image": paramsDto.PhotoData,
}
// 以表单方式调用数脉 API参数在 CallAPIForm 内转为 application/x-www-form-urlencoded
apiPath := "/v4/face_id_card/compare" // 接口路径,根据数脉文档填写(如 v4/xxx
respBytes, err := deps.ShumaiService.CallAPIForm(ctx, apiPath, reqFormData)
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)
} else {
// 其他未知错误
return nil, errors.Join(processors.ErrSystem, err)
}
}
return respBytes, nil
}

View File

@@ -0,0 +1,38 @@
package ivyz
import (
"context"
"errors"
"hyapi-server/internal/domains/api/services/processors"
)
// ProcessIVYZADEERequest IVYZADEE API处理方法
func ProcessIVYZADEERequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
return nil, errors.Join(processors.ErrSystem, errors.New("服务已停用"))
// var paramsDto dto.IVYZADEEReq
// 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)
// }
// reqData := map[string]interface{}{
// "name": paramsDto.Name,
// "idCard": paramsDto.IDCard,
// "mobile": paramsDto.Mobile,
// }
// respBytes, err := deps.WestDexService.CallAPI(ctx, "IVYZADEE", reqData)
// if err != nil {
// if errors.Is(err, westdex.ErrDatasource) {
// return nil, errors.Join(processors.ErrDatasource, err)
// } else {
// return nil, errors.Join(processors.ErrSystem, err)
// }
// }
// return respBytes, nil
}

View File

@@ -0,0 +1,51 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/xingwei"
)
// ProcessIVYZBPQ2Request IVYZBPQ2 人脸比对V2API处理方法
func ProcessIVYZBPQ2Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZBPQ2Req
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)
}
// 构建请求数据使用xingwei服务的正确字段名
reqData := map[string]interface{}{
"name": paramsDto.Name,
"idCardNum": paramsDto.IDCard,
"image": paramsDto.PhotoData,
}
// 调用行为数据API使用指定的project_id
projectID := "CDJ-1104321425593790464"
respBytes, err := deps.XingweiService.CallAPI(ctx, projectID, reqData)
if err != nil {
if errors.Is(err, xingwei.ErrNotFound) {
// 查空情况,返回特定的查空错误
return nil, errors.Join(processors.ErrNotFound, err)
} else if errors.Is(err, xingwei.ErrDatasource) {
// 数据源错误
return nil, errors.Join(processors.ErrDatasource, err)
} else if errors.Is(err, xingwei.ErrSystem) {
// 系统错误
return nil, errors.Join(processors.ErrSystem, err)
} else {
// 其他未知错误
return nil, errors.Join(processors.ErrSystem, err)
}
}
return respBytes, nil
}

View File

@@ -0,0 +1,55 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"strings"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-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, &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)
}
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
}

View File

@@ -0,0 +1,51 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/westdex"
)
// ProcessIVYZGZ08Request IVYZGZ08 API处理方法
func ProcessIVYZGZ08Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZGZ08Req
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.WestDexService.Encrypt(paramsDto.Name)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
encryptedIDCard, err := deps.WestDexService.Encrypt(paramsDto.IDCard)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
reqData := map[string]interface{}{
"data": map[string]interface{}{
"xm": encryptedName,
"gmsfzhm": encryptedIDCard,
},
}
respBytes, err := deps.WestDexService.CallAPI(ctx, "G08SC02", reqData)
if err != nil {
if errors.Is(err, westdex.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
} else {
return nil, errors.Join(processors.ErrSystem, err)
}
}
return respBytes, nil
}

View File

@@ -0,0 +1,121 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/shumai"
)
// ProcessIVYZN2P8Request IVYZN2P8 身份证实名认证政务版 API处理方法
func ProcessIVYZN2P8Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZ9K7FReq
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)
}
reqData := map[string]interface{}{
"name": paramsDto.Name,
"idcard": paramsDto.IDCard,
}
// 以表单方式调用数脉 API参数在 CallAPIForm 内转为 application/x-www-form-urlencoded
apiPath := "/v4/id_card/check"
// 先尝试使用政务接口app_id2 和 app_secret2
respBytes, err := deps.ShumaiService.CallAPIForm(ctx, apiPath, reqData, true)
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 respBytes, nil
}
// respBytes, err := deps.AlicloudService.CallAPI("api-mall/api/id_card/check", reqData)
// if err != nil {
// if errors.Is(err, alicloud.ErrDatasource) {
// return nil, errors.Join(processors.ErrDatasource, err)
// }
// return nil, errors.Join(processors.ErrSystem, err)
// }
// return respBytes, nil
// // 对齐 yysybe08test 的原始响应结构,取 data 字段映射为 ivyzn2p8 返回
// var aliyunData struct {
// Code int `json:"code"`
// Data struct {
// Birthday string `json:"birthday"`
// Result interface{} `json:"result"`
// Address string `json:"address"`
// OrderNo string `json:"orderNo"`
// Sex string `json:"sex"`
// Desc string `json:"desc"`
// } `json:"data"`
// Result interface{} `json:"result"`
// Desc string `json:"desc"`
// }
// if err := json.Unmarshal(respBytes, &aliyunData); err != nil {
// return nil, errors.Join(processors.ErrSystem, err)
// }
// rawResult := aliyunData.Result
// rawDesc := aliyunData.Desc
// if aliyunData.Code == 200 {
// rawResult = aliyunData.Data.Result
// rawDesc = aliyunData.Data.Desc
// }
// response := map[string]interface{}{
// "result": normalizeResult(rawResult),
// "order_no": aliyunData.Data.OrderNo,
// "desc": rawDesc,
// "sex": aliyunData.Data.Sex,
// "birthday": aliyunData.Data.Birthday,
// "address": aliyunData.Data.Address,
// }
// return json.Marshal(response)
// }
// func normalizeResult(v interface{}) int {
// switch r := v.(type) {
// case float64:
// return int(r)
// case int:
// return r
// case int32:
// return int(r)
// case int64:
// return int(r)
// case json.Number:
// n, err := r.Int64()
// if err == nil {
// return int(n)
// }
// case string:
// s := strings.TrimSpace(r)
// if s == "" {
// return 1
// }
// n, err := strconv.Atoi(s)
// if err == nil {
// return n
// }
// }
// // 默认按不一致处理
// return 1
// }

View File

@@ -0,0 +1,48 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/shujubao"
)
// ProcessIVYZOCR1Request IVYZOCR1 身份证OCR API 处理方法(使用数据宝服务示例)
func ProcessIVYZOCR1Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZOCR1Req
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)
}
// 构建数据宝入参姓名、身份证、手机号、银行卡号sign 外的业务参数可按需 AES 加密后作为 bodyData
reqParams := map[string]interface{}{
"key": "8782f2a32463f75b53096323461df735",
"imageId": paramsDto.PhotoData,
}
// 最终请求 URL = https://api.chinadatapay.com/communication + 拼接接口地址值,如 personal/197
apiPath := "/trade/user/1985"
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)
}
respBytes, err := json.Marshal(data)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return respBytes, nil
}

View File

@@ -0,0 +1,56 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/shumai"
)
// ProcessIVYZOCR2Request IVYZOCR2 OCR识别API处理方法数卖
func ProcessIVYZOCR2Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZOCR1Req
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)
}
if paramsDto.PhotoData == "" && paramsDto.ImageUrl == "" {
return nil, errors.Join(processors.ErrInvalidParam, errors.New("photo_data or image_url is required"))
}
// 2选1有值的用对应 key空则用另一个
reqFormData := make(map[string]interface{})
if paramsDto.PhotoData != "" {
reqFormData["image"] = paramsDto.PhotoData
} else {
reqFormData["url"] = paramsDto.ImageUrl
}
// 以表单方式调用数脉 API参数在 CallAPIForm 内转为 application/x-www-form-urlencoded
apiPath := "/v4/idcard/ocr" // 接口路径,根据数脉文档填写(如 v4/xxx
respBytes, err := deps.ShumaiService.CallAPIForm(ctx, apiPath, reqFormData)
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)
} else {
// 其他未知错误
return nil, errors.Join(processors.ErrSystem, err)
}
}
return respBytes, nil
}

View File

@@ -0,0 +1,84 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/shumai"
)
// ProcessIVYZP2Q6Request IVYZP2Q6 API处理方法 - 身份认证二要素
func ProcessIVYZP2Q6Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZP2Q6Req
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)
}
reqFormData := map[string]interface{}{
"idcard": paramsDto.IDCard,
"name": paramsDto.Name,
}
// 以表单方式调用数脉 API参数在 CallAPIForm 内转为 application/x-www-form-urlencoded
apiPath := "/v4/id_card/check" // 接口路径,根据数脉文档填写(如 v4/xxx
// 先尝试使用政务接口app_id2 和 app_secret2
respBytes, err := deps.ShumaiService.CallAPIForm(ctx, apiPath, reqFormData, true)
if err != nil {
// 使用实时接口app_id 和 app_secret重试
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)
} else {
// 其他未知错误
return nil, errors.Join(processors.ErrSystem, err)
}
}
}
// 数据源返回 result(0-一致/1-不一致/2-无记录),映射为 state(1-匹配/2-不匹配/3-异常情况)
var dsResp struct {
Result int `json:"result"` // 0-一致 1-不一致 2-无记录(预留)
}
if err := json.Unmarshal(respBytes, &dsResp); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
state := resultToState(dsResp.Result)
out := map[string]interface{}{
"errMsg": "",
"state": state,
}
return json.Marshal(out)
}
// resultToState 将数据源 result 映射为接口 state1-匹配 2-不匹配 3-异常情况
func resultToState(result int) int {
switch result {
case 0: // 一致 → 匹配
return 1
case 1: // 不一致 → 不匹配
return 2
case 2: // 无记录(预留) → 异常情况
return 3
default:
return 3 // 未知/异常 → 异常情况
}
}

View File

@@ -0,0 +1,52 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/xingwei"
)
// ProcessIVYZSFELRequest IVYZSFEL 全国自然人人像三要素核验_V1API处理方法
func ProcessIVYZSFELRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZSFELReq
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)
}
// 构建请求数据使用xingwei服务的正确字段名
reqData := map[string]interface{}{
"name": paramsDto.Name,
"idCardNum": paramsDto.IDCard,
"photo": paramsDto.PhotoData,
"authAuthorizeFileCode": paramsDto.AuthAuthorizeFileCode,
}
// 调用行为数据API使用指定的project_id
projectID := "CDJ-1068350101927161856"
respBytes, err := deps.XingweiService.CallAPI(ctx, projectID, reqData)
if err != nil {
if errors.Is(err, xingwei.ErrNotFound) {
// 查空情况,返回特定的查空错误
return nil, errors.Join(processors.ErrNotFound, err)
} else if errors.Is(err, xingwei.ErrDatasource) {
// 数据源错误
return nil, errors.Join(processors.ErrDatasource, err)
} else if errors.Is(err, xingwei.ErrSystem) {
// 系统错误
return nil, errors.Join(processors.ErrSystem, err)
} else {
// 其他未知错误
return nil, errors.Join(processors.ErrSystem, err)
}
}
return respBytes, nil
}

View File

@@ -0,0 +1,63 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/shumai"
"hyapi-server/internal/shared/logger"
"go.uber.org/zap"
)
// ProcessIVYZX5Q2Request IVYZX5Q2 活体识别步骤二API处理方法
func ProcessIVYZX5Q2Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZX5Q2Req
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)
}
reqFormData := map[string]interface{}{
"token": paramsDto.Token,
}
// 以表单方式调用数脉 API参数在 CallAPIForm 内转为 application/x-www-form-urlencoded
apiPath := "/v4/liveness/h5/v4/result" // 接口路径,根据数脉文档填写(如 v4/xxx
respBytes, err := deps.ShumaiService.CallAPIForm(ctx, apiPath, reqFormData)
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)
} else {
// 其他未知错误
return nil, errors.Join(processors.ErrSystem, err)
}
}
// result==2 时手动抛出错误(不通过/无记录,不返回正常响应)
var body struct {
Result int `json:"result"`
}
if err := json.Unmarshal(respBytes, &body); err == nil && body.Result == 2 {
log := logger.GetGlobalLogger()
log.Warn("IVYZX5Q2 活体检测 result=2 无记录或不通过,返回错误",
zap.Int("result", body.Result),
zap.ByteString("response", respBytes))
return nil, errors.Join(processors.ErrNotFound, errors.New("活体检测 result=2 无记录或不通过"))
}
return respBytes, nil
}

View File

@@ -0,0 +1,48 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/shumai"
)
// ProcessIVYZx5qzRequest IVYZx5qz 活体识别API处理方法
func ProcessIVYZX5QZRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZX5QZReq
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)
}
reqFormData := map[string]interface{}{
"returnUrl": paramsDto.ReturnURL,
}
// 以表单方式调用数脉 API参数在 CallAPIForm 内转为 application/x-www-form-urlencoded
apiPath := "/v4/liveness/h5/v4/token" // 接口路径,根据数脉文档填写(如 v4/xxx
respBytes, err := deps.ShumaiService.CallAPIForm(ctx, apiPath, reqFormData)
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)
} else {
// 其他未知错误
return nil, errors.Join(processors.ErrSystem, err)
}
}
return respBytes, nil
}

View File

@@ -0,0 +1,212 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"fmt"
"math"
"strconv"
"strings"
"time"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/shumai"
)
// ProcessIVYZZQT3Request IVYZZQT3 人脸比对V3API处理方法
func ProcessIVYZZQT3Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZZQT3Req
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)
}
// 使用数脉接口进行人脸身份证比对
reqFormData := map[string]interface{}{
"idcard": paramsDto.IDCard,
"name": paramsDto.Name,
"image": paramsDto.PhotoData,
}
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)
}
}
outBytes, err := mapShumaiFaceCompareToIVYZZQT3(respBytes)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return outBytes, nil
}
type shumaiFaceCompareResp struct {
OrderNo string `json:"order_no"`
Score interface{} `json:"score"`
Msg string `json:"msg"`
Incorrect interface{} `json:"incorrect"`
}
type ivyzzqt3Out struct {
HandleTime string `json:"handleTime"`
ResultData ivyzzqt3OutResultData `json:"resultData"`
OrderNo string `json:"orderNo"`
}
type ivyzzqt3OutResultData struct {
VerificationCode string `json:"verification_code"`
VerificationResult string `json:"verification_result"`
VerificationMessage string `json:"verification_message"`
Similarity string `json:"similarity"`
}
func mapShumaiFaceCompareToIVYZZQT3(respBytes []byte) ([]byte, error) {
var r shumaiFaceCompareResp
if err := json.Unmarshal(respBytes, &r); err != nil {
return nil, err
}
score := parseScoreToFloat64(r.Score)
similarity := strconv.Itoa(int(math.Round(mapScoreToSimilarity(score))))
verificationResult := mapScoreToVerificationResult(score)
verificationMessage := strings.TrimSpace(r.Msg)
if verificationMessage == "" {
verificationMessage = mapScoreToVerificationMessage(score)
}
out := ivyzzqt3Out{
HandleTime: time.Now().Format("2006-01-02 15:04:05"),
OrderNo: strings.TrimSpace(r.OrderNo),
ResultData: ivyzzqt3OutResultData{
VerificationCode: mapVerificationCode(verificationResult, r.Incorrect),
VerificationResult: verificationResult,
VerificationMessage: verificationMessage,
Similarity: similarity,
},
}
return json.Marshal(out)
}
func mapScoreToVerificationResult(score float64) string {
if score >= 0.45 {
return "valid"
}
// 旧结构仅支持 valid/invalid不能确定场景按 invalid 返回
return "invalid"
}
func mapScoreToVerificationMessage(score float64) string {
if score < 0.40 {
return "系统判断为不同人"
}
if score < 0.45 {
return "不能确定是否为同一人"
}
return "系统判断为同一人"
}
func mapScoreToSimilarity(score float64) float64 {
// 将 score(0~1) 分段映射到 similarity(0~1000),并对齐业务阈值:
// 0.40 -> 6000.45 -> 700
if score <= 0 {
return 0
}
if score >= 1 {
return 1000
}
if score < 0.40 {
// [0, 0.40) -> [0, 600)
return (score / 0.40) * 600
}
if score < 0.45 {
// [0.40, 0.45) -> [600, 700)
return 600 + ((score-0.40)/0.05)*100
}
// [0.45, 1] -> [700, 1000]
return 700 + ((score-0.45)/0.55)*300
}
func parseScoreToFloat64(v interface{}) float64 {
switch t := v.(type) {
case float64:
return t
case float32:
return float64(t)
case int:
return float64(t)
case int32:
return float64(t)
case int64:
return float64(t)
case json.Number:
if f, err := t.Float64(); err == nil {
return f
}
case string:
s := strings.TrimSpace(t)
if s == "" {
return 0
}
if f, err := strconv.ParseFloat(s, 64); err == nil {
return f
}
}
return 0
}
func valueToString(v interface{}) string {
switch t := v.(type) {
case string:
return strings.TrimSpace(t)
case json.Number:
return t.String()
case float64:
return strconv.FormatFloat(t, 'f', -1, 64)
case float32:
return strconv.FormatFloat(float64(t), 'f', -1, 64)
case int:
return strconv.Itoa(t)
case int32:
return strconv.FormatInt(int64(t), 10)
case int64:
return strconv.FormatInt(t, 10)
default:
if v == nil {
return ""
}
return strings.TrimSpace(fmt.Sprint(v))
}
}
func mapVerificationCode(verificationResult string, upstreamIncorrect interface{}) string {
if verificationResult == "valid" {
return "1000"
}
if verificationResult == "invalid" {
return "2006"
}
// 兜底:若后续扩展出其它结果,保持可追溯
if s := valueToString(upstreamIncorrect); s != "" {
return s
}
return "2006"
}