f
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
package yysy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"hyapi-server/internal/domains/api/dto"
|
||||
"hyapi-server/internal/domains/api/services/processors"
|
||||
"hyapi-server/internal/infrastructure/external/shujubao"
|
||||
)
|
||||
|
||||
// YYSY09CDResponse 最终返回结构
|
||||
// code: 1000一致 1001不一致 1002查无
|
||||
type YYSY09CDResponse struct {
|
||||
Code string `json:"code"`
|
||||
Data YYSY09CDResponseData `json:"data"`
|
||||
}
|
||||
|
||||
type YYSY09CDResponseData struct {
|
||||
Msg string `json:"msg"` // 一致/不一致/查无
|
||||
PhoneType string `json:"phoneType"` // CMCC/CUCC/CTCC/CBN
|
||||
Code int `json:"code"` // 1000/1001/1002
|
||||
EncryptType string `json:"encryptType"` // MD5
|
||||
}
|
||||
|
||||
// ProcessYYSY09CDRequest YYSY09CD API处理方法 - 运营商三要素查询
|
||||
func ProcessYYSY09CDRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.YYSY09CDReq
|
||||
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)
|
||||
}
|
||||
reqParams := map[string]interface{}{
|
||||
"key": "c115708d915451da8f34a23e144dda6b",
|
||||
"name": paramsDto.Name,
|
||||
"idcard": paramsDto.IDCard,
|
||||
"mobile": paramsDto.MobileNo,
|
||||
}
|
||||
|
||||
apiPath := "/communication/personal/1979"
|
||||
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)
|
||||
}
|
||||
|
||||
out, err := mapYYSYK9R4ToYYSY09CD(data)
|
||||
if err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
return json.Marshal(out)
|
||||
}
|
||||
|
||||
// yysyk9r4Resp 数据宝 YYSYK9R4 接口 data 结构
|
||||
// state: 1-验证一致 2-验证不一致 3-异常情况
|
||||
type yysyk9r4Resp struct {
|
||||
State string `json:"state"`
|
||||
}
|
||||
|
||||
// mapYYSYK9R4ToYYSY09CD 数据宝 YYSYK9R4 的 data -> YYSY09CD 最终格式
|
||||
// state: 1->1000一致 2->1001不一致 其它->1002查无
|
||||
func mapYYSYK9R4ToYYSY09CD(data interface{}) (*YYSY09CDResponse, error) {
|
||||
var r yysyk9r4Resp
|
||||
|
||||
b, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := json.Unmarshal(b, &r); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// code/msg: 1000一致 1001不一致 1002查无
|
||||
var codeStr string
|
||||
var codeInt int
|
||||
var msg string
|
||||
switch strings.TrimSpace(r.State) {
|
||||
case "1":
|
||||
codeStr = "1000"
|
||||
codeInt = 1000
|
||||
msg = "一致"
|
||||
case "2":
|
||||
codeStr = "1001"
|
||||
codeInt = 1001
|
||||
msg = "不一致"
|
||||
default:
|
||||
codeStr = "1002"
|
||||
codeInt = 1002
|
||||
msg = "查无"
|
||||
}
|
||||
|
||||
return &YYSY09CDResponse{
|
||||
Code: codeStr,
|
||||
Data: YYSY09CDResponseData{
|
||||
Msg: msg,
|
||||
PhoneType: "",
|
||||
Code: codeInt,
|
||||
EncryptType: "MD5",
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package yysy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"hyapi-server/internal/domains/api/dto"
|
||||
"hyapi-server/internal/domains/api/services/processors"
|
||||
"hyapi-server/internal/infrastructure/external/shumai"
|
||||
)
|
||||
|
||||
// ProcessYYSY35TARequest YYSY35TA API 运营商归属地数卖处理方法数脉
|
||||
func ProcessYYSY35TARequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.YYSY35TAReq
|
||||
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)
|
||||
}
|
||||
|
||||
reqFormData := map[string]interface{}{
|
||||
"mobile": paramsDto.MobileNo,
|
||||
}
|
||||
|
||||
// 以表单方式调用数脉 API;参数在 CallAPIForm 内转为 application/x-www-form-urlencoded
|
||||
apiPath := "/v4/phone/number" // 接口路径,根据数脉文档填写(如 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
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package yysy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"hyapi-server/internal/domains/api/dto"
|
||||
"hyapi-server/internal/domains/api/services/processors"
|
||||
"hyapi-server/internal/infrastructure/external/shumai"
|
||||
)
|
||||
|
||||
// ProcessYYSY3E7FRequest YYSY3E7F API处理方法 - 空号检测
|
||||
func ProcessYYSY3E7FRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.YYSY3E7FReq
|
||||
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)
|
||||
}
|
||||
reqFormData := map[string]interface{}{
|
||||
"mobile": paramsDto.MobileNo,
|
||||
}
|
||||
|
||||
// 以表单方式调用数脉 API;参数在 CallAPIForm 内转为 application/x-www-form-urlencoded
|
||||
apiPath := "/v4/mobile_empty/check" // 接口路径,根据数脉文档填写(
|
||||
respBytes, err := deps.ShumaiService.CallAPIForm(ctx, apiPath, reqFormData)
|
||||
if err != nil {
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package yysy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"hyapi-server/internal/domains/api/dto"
|
||||
"hyapi-server/internal/domains/api/services/processors"
|
||||
"hyapi-server/internal/infrastructure/external/shumai"
|
||||
)
|
||||
|
||||
// ProcessYYSY3M8SRequest YYSY3M8S 运营商二要素 API处理方法
|
||||
func ProcessYYSY3M8SRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.YYSY3M8SReq
|
||||
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)
|
||||
}
|
||||
reqFormData := map[string]interface{}{
|
||||
"mobile": paramsDto.MobileNo,
|
||||
"name": paramsDto.Name,
|
||||
}
|
||||
|
||||
// 以表单方式调用数脉 API;参数在 CallAPIForm 内转为 application/x-www-form-urlencoded
|
||||
apiPath := "/v4/mobile_two/check" // 接口路径,根据数脉文档填写(如 v4/xxx)
|
||||
respBytes, err := deps.ShumaiService.CallAPIForm(ctx, apiPath, reqFormData)
|
||||
if err != nil {
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package yysy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"hyapi-server/internal/domains/api/dto"
|
||||
"hyapi-server/internal/domains/api/services/processors"
|
||||
"hyapi-server/internal/infrastructure/external/westdex"
|
||||
)
|
||||
|
||||
// ProcessYYSY4B21Request YYSY4B21 API处理方法
|
||||
func ProcessYYSY4B21Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.YYSY4B21Req
|
||||
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)
|
||||
}
|
||||
|
||||
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{}{
|
||||
"phone": encryptedMobileNo,
|
||||
},
|
||||
}
|
||||
|
||||
respBytes, err := deps.WestDexService.CallAPI(ctx, "G25BJ02", 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
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package yysy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"hyapi-server/internal/domains/api/dto"
|
||||
"hyapi-server/internal/domains/api/services/processors"
|
||||
"hyapi-server/internal/infrastructure/external/westdex"
|
||||
)
|
||||
|
||||
// ProcessYYSY4B37Request YYSY4B37 API处理方法
|
||||
func ProcessYYSY4B37Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.YYSY4B37Req
|
||||
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)
|
||||
}
|
||||
|
||||
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{}{
|
||||
"phone": encryptedMobileNo,
|
||||
},
|
||||
}
|
||||
|
||||
respBytes, err := deps.WestDexService.CallAPI(ctx, "G02BJ02", 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
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package yysy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"hyapi-server/internal/domains/api/dto"
|
||||
"hyapi-server/internal/domains/api/services/processors"
|
||||
"hyapi-server/internal/infrastructure/external/zhicha"
|
||||
)
|
||||
|
||||
// ProcessYYSY4F2ERequest YYSY4F2E API处理方法 - 运营商三要素验证(详版)
|
||||
func ProcessYYSY4F2ERequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.YYSY4F2EReq
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
encryptedMobileNo, err := deps.ZhichaService.Encrypt(paramsDto.MobileNo)
|
||||
if err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
reqData := map[string]interface{}{
|
||||
"name": encryptedName,
|
||||
"idCard": encryptedIDCard,
|
||||
"phone": encryptedMobileNo,
|
||||
"authorized": paramsDto.Authorized,
|
||||
}
|
||||
|
||||
respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI002", 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
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package yysy
|
||||
|
||||
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"
|
||||
)
|
||||
|
||||
// shumaiMobileTransferResp 数脉 /v4/mobile-transfer/query 返回结构
|
||||
type shumaiMobileTransferResp struct {
|
||||
OrderNo string `json:"order_no"`
|
||||
Channel string `json:"channel"` // 移动/电信/联通
|
||||
Status int `json:"status"` // 0-在网 1-不在网
|
||||
Desc string `json:"desc"` // 不在网原因(status=1时有效)
|
||||
}
|
||||
|
||||
// ProcessYYSY6D9ARequest YYSY6D9A API处理方法 - 全网手机号状态验证A
|
||||
func ProcessYYSY6D9ARequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.YYSY6D9AReq
|
||||
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)
|
||||
}
|
||||
|
||||
reqFormData := map[string]interface{}{
|
||||
"mobile": paramsDto.MobileNo,
|
||||
}
|
||||
|
||||
// 以表单方式调用数脉 API;参数在 CallAPIForm 内转为 application/x-www-form-urlencoded
|
||||
apiPath := "/v4/mobile-transfer/query"
|
||||
respBytes, err := deps.ShumaiService.CallAPIForm(ctx, apiPath, reqFormData)
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
mapped, err := mapShumaiToYYSY6D9A(respBytes)
|
||||
if err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
return json.Marshal(mapped)
|
||||
}
|
||||
|
||||
// mapShumaiToYYSY6D9A 将数脉 mobile-transfer 响应映射为最终 state/operators 格式
|
||||
// state: 1-正常 2-不在网(空号) 3-无短信能力 4-欠费 5-长时间关机 6-关机 7-通话中 -1-查询失败
|
||||
// operators: 1-移动 2-联通 3-电信
|
||||
func mapShumaiToYYSY6D9A(dataBytes []byte) (map[string]string, error) {
|
||||
var r shumaiMobileTransferResp
|
||||
if err := json.Unmarshal(dataBytes, &r); err != nil {
|
||||
return map[string]string{"state": "-1", "operators": ""}, nil // 解析失败视为查询失败
|
||||
}
|
||||
|
||||
operators := ispNameToCode(strings.TrimSpace(r.Channel))
|
||||
state := statusDescToState(r.Status, r.Desc)
|
||||
|
||||
return map[string]string{
|
||||
"state": state,
|
||||
"operators": operators,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// statusDescToState status: 0-在网 1-不在网;desc 为不在网原因
|
||||
func statusDescToState(status int, desc string) string {
|
||||
if status == 0 {
|
||||
return "1" // 正常
|
||||
}
|
||||
// status == 1 不在网,根据 desc 推断 state
|
||||
d := strings.TrimSpace(desc)
|
||||
if strings.Contains(d, "销号") || strings.Contains(d, "空号") {
|
||||
return "2" // 不在网(空号)
|
||||
}
|
||||
if strings.Contains(d, "无短信") || strings.Contains(d, "在网不可用") {
|
||||
return "3" // 无短信能力
|
||||
}
|
||||
if strings.Contains(d, "欠费") {
|
||||
return "4" // 欠费
|
||||
}
|
||||
if strings.Contains(d, "长时间关机") {
|
||||
return "5" // 长时间关机
|
||||
}
|
||||
if strings.Contains(d, "关机") {
|
||||
return "6" // 关机
|
||||
}
|
||||
if strings.Contains(d, "通话中") {
|
||||
return "7" // 通话中
|
||||
}
|
||||
return "2" // 不在网但未明确原因,默认空号
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package yysy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"hyapi-server/internal/domains/api/dto"
|
||||
"hyapi-server/internal/domains/api/services/processors"
|
||||
"hyapi-server/internal/infrastructure/external/zhicha"
|
||||
)
|
||||
|
||||
// ProcessYYSY6F2BRequestYYSY 6F2B API处理方法 - 手机消费区间验证
|
||||
func ProcessYYSY6F2BRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.YYSY6F2BReq
|
||||
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)
|
||||
}
|
||||
|
||||
encryptedMobileNo, err := deps.ZhichaService.Encrypt(paramsDto.MobileNo)
|
||||
if err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
reqData := map[string]interface{}{
|
||||
"phone": encryptedMobileNo,
|
||||
}
|
||||
|
||||
respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI041", 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
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package yysy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"hyapi-server/internal/domains/api/dto"
|
||||
"hyapi-server/internal/domains/api/services/processors"
|
||||
"hyapi-server/internal/infrastructure/external/westdex"
|
||||
)
|
||||
|
||||
// ProcessYYSY6F2ERequest YYSY6F2E API处理方法
|
||||
func ProcessYYSY6F2ERequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.YYSY6F2EReq
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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,
|
||||
"idNo": encryptedIDCard,
|
||||
"phone": encryptedMobileNo,
|
||||
"phoneType": paramsDto.MobileType,
|
||||
},
|
||||
}
|
||||
|
||||
respBytes, err := deps.WestDexService.CallAPI(ctx, "G15BJ02", 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
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
package yysy
|
||||
|
||||
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"
|
||||
)
|
||||
|
||||
// shumaiMobileTransferResp 数脉 /v4/mobile-transfer/query 携号转网返回结构
|
||||
type shumaiMobileTransfer7d3eResp struct {
|
||||
OrderNo string `json:"order_no"`
|
||||
Mobile string `json:"mobile"`
|
||||
Area *string `json:"area"`
|
||||
IspType string `json:"ispType"` // 转网前运营商
|
||||
NewIspType string `json:"newIspType"` // 转网后运营商
|
||||
}
|
||||
|
||||
// yysy7d3eResp 携号转网查询对外响应结构
|
||||
type yysy7d3eResp struct {
|
||||
BatchNo string `json:"batchNo"`
|
||||
QueryResult []yysy7d3eQueryItem `json:"queryResult"`
|
||||
}
|
||||
|
||||
type yysy7d3eQueryItem struct {
|
||||
Mobile string `json:"mobile"`
|
||||
Result string `json:"result"` // 0:否 1:是
|
||||
After string `json:"after"` // 转网后:-1未知 1移动 2联通 3电信 4广电
|
||||
Before string `json:"before"` // 转网前:同上
|
||||
}
|
||||
|
||||
// ProcessYYSY7D3ERequest YYSY7D3E API处理方法 - 携号转网查询
|
||||
func ProcessYYSY7D3ERequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.YYSY7D3EReq
|
||||
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)
|
||||
}
|
||||
|
||||
reqFormData := map[string]interface{}{
|
||||
"mobile": paramsDto.MobileNo,
|
||||
}
|
||||
|
||||
// 以表单方式调用数脉 API;参数在 CallAPIForm 内转为 application/x-www-form-urlencoded
|
||||
apiPath := "/v4/mobile-transfer/query"
|
||||
respBytes, err := deps.ShumaiService.CallAPIForm(ctx, apiPath, reqFormData)
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
mapped, err := mapShumaiToYYSY7D3E(respBytes)
|
||||
if err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
return json.Marshal(mapped)
|
||||
}
|
||||
|
||||
// mapShumaiToYYSY7D3E 将数脉携号转网响应映射为 batchNo + queryResult 格式
|
||||
func mapShumaiToYYSY7D3E(dataBytes []byte) (*yysy7d3eResp, error) {
|
||||
var r shumaiMobileTransfer7d3eResp
|
||||
if err := json.Unmarshal(dataBytes, &r); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
before := ispNameToCodeTransfer(strings.TrimSpace(r.IspType))
|
||||
after := ispNameToCodeTransfer(strings.TrimSpace(r.NewIspType))
|
||||
result := "0"
|
||||
if r.IspType != "" && r.NewIspType != "" && strings.TrimSpace(r.IspType) != strings.TrimSpace(r.NewIspType) {
|
||||
result = "1" // 转网前与转网后不同即为携号转网
|
||||
}
|
||||
|
||||
out := &yysy7d3eResp{
|
||||
BatchNo: r.OrderNo,
|
||||
QueryResult: []yysy7d3eQueryItem{
|
||||
{
|
||||
Mobile: r.Mobile,
|
||||
Result: result,
|
||||
After: after,
|
||||
Before: before,
|
||||
},
|
||||
},
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// ispNameToCodeTransfer 运营商名称转编码:-1未知 1移动 2联通 3电信 4广电
|
||||
func ispNameToCodeTransfer(name string) string {
|
||||
switch name {
|
||||
case "移动":
|
||||
return "1"
|
||||
case "联通":
|
||||
return "2"
|
||||
case "电信":
|
||||
return "3"
|
||||
case "广电":
|
||||
return "4"
|
||||
default:
|
||||
return "-1"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
package yysy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"hyapi-server/internal/domains/api/dto"
|
||||
"hyapi-server/internal/domains/api/services/processors"
|
||||
"hyapi-server/internal/infrastructure/external/shumai"
|
||||
)
|
||||
|
||||
// ProcessYYSY8B1CRequest YYSY8B1C API处理方法 - 手机在网时长
|
||||
func ProcessYYSY8B1CRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.YYSY8B1CReq
|
||||
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)
|
||||
}
|
||||
reqFormData := map[string]interface{}{
|
||||
"mobile": paramsDto.MobileNo,
|
||||
}
|
||||
|
||||
// 以表单方式调用数脉 API;参数在 CallAPIForm 内转为 application/x-www-form-urlencoded
|
||||
apiPath := "/v2/mobile_online/check" // 接口路径,根据数脉文档填写(如 v4/xxx)
|
||||
respBytes, err := deps.ShumaiService.CallAPIForm(ctx, apiPath, reqFormData)
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
var shumaiResp struct {
|
||||
OrderNo string `json:"order_no"`
|
||||
Channel string `json:"channel"` // cmcc/cucc/ctcc/gdcc
|
||||
Time string `json:"time"` // [0,3),[3,6),[6,12),[12,24),[24,-1)
|
||||
}
|
||||
if err := json.Unmarshal(respBytes, &shumaiResp); err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
// 映射 channel -> operators
|
||||
operators := channelToOperators(shumaiResp.Channel)
|
||||
// 映射 time 区间 -> inTime
|
||||
inTime := timeIntervalToInTime(shumaiResp.Time)
|
||||
|
||||
out := map[string]string{
|
||||
"inTime": inTime,
|
||||
"operators": operators,
|
||||
}
|
||||
return json.Marshal(out)
|
||||
}
|
||||
|
||||
// channelToOperators 运营商编码转名称:cmcc-移动 cucc-联通 ctcc-电信 gdcc-广电
|
||||
func channelToOperators(channel string) string {
|
||||
switch channel {
|
||||
case "cmcc":
|
||||
return "移动"
|
||||
case "cucc":
|
||||
return "联通"
|
||||
case "ctcc":
|
||||
return "电信"
|
||||
case "gdcc":
|
||||
return "广电"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
// timeIntervalToInTime 在网时间区间转 inTime 值
|
||||
// [0,3)->0, [3,6)->3, [6,12)->6, [12,24)->12, [24,-1)->24
|
||||
// 空或异常->99, 查无记录->-1(此处按空/未知处理为99)
|
||||
func timeIntervalToInTime(timeInterval string) string {
|
||||
switch timeInterval {
|
||||
case "[0,3)":
|
||||
return "0"
|
||||
case "[3,6)":
|
||||
return "3"
|
||||
case "[6,12)":
|
||||
return "6"
|
||||
case "[12,24)":
|
||||
return "12"
|
||||
case "[24,-1)":
|
||||
return "24"
|
||||
case "":
|
||||
return "-1"
|
||||
default:
|
||||
return "99"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package yysy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"hyapi-server/internal/domains/api/dto"
|
||||
"hyapi-server/internal/domains/api/services/processors"
|
||||
"hyapi-server/internal/infrastructure/external/xingwei"
|
||||
)
|
||||
|
||||
// ProcessYYSY8C2DRequest YYSY8C2D API处理方法 - 运营商三要素查询
|
||||
func ProcessYYSY8C2DRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.YYSY8C2DReq
|
||||
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)
|
||||
}
|
||||
|
||||
// 构建请求数据,将项目规范的字段名转换为 XingweiService 需要的字段名
|
||||
reqData := map[string]interface{}{
|
||||
"name": paramsDto.Name,
|
||||
"idCardNum": paramsDto.IDCard,
|
||||
"phoneNumber": paramsDto.MobileNo,
|
||||
}
|
||||
|
||||
// 调用行为数据API,使用指定的project_id
|
||||
projectID := "CDJ-1100244702166183936"
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package yysy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"hyapi-server/internal/domains/api/dto"
|
||||
"hyapi-server/internal/domains/api/services/processors"
|
||||
"hyapi-server/internal/infrastructure/external/xingwei"
|
||||
)
|
||||
|
||||
// ProcessYYSY8F3ARequest YYSY8F3A API处理方法 - 行为数据查询
|
||||
func ProcessYYSY8F3ARequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.YYSY8F3AReq
|
||||
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)
|
||||
}
|
||||
|
||||
// 构建请求数据,直接传递姓名、身份证、手机号
|
||||
reqData := map[string]interface{}{
|
||||
"name": paramsDto.Name,
|
||||
"idCardNum": paramsDto.IDCard,
|
||||
"phoneNumber": paramsDto.MobileNo,
|
||||
}
|
||||
|
||||
// 调用行为数据API,使用指定的project_id
|
||||
projectID := "CDJ-1100244697766359040"
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
package yysy
|
||||
|
||||
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"
|
||||
)
|
||||
|
||||
// shumaiMobileThreeResp 数脉 /v4/mobile_three/check 返回的 data 结构
|
||||
// result: 0-一致 1-不一致 2-无记录;channel: cmcc/cucc/ctcc/gdcc
|
||||
type shumaiMobileThreeResp struct {
|
||||
OrderNo string `json:"order_no"`
|
||||
Result string `json:"result"`
|
||||
Desc string `json:"desc"`
|
||||
Channel string `json:"channel"`
|
||||
Sex string `json:"sex"`
|
||||
Birthday string `json:"birthday"`
|
||||
Address string `json:"address"`
|
||||
}
|
||||
|
||||
// yysy9a1bOut 最终返回格式
|
||||
// result: 01一致 02不一致 03不确定 04失败/虚拟号;type: 1移动 2联通 3电信 4广电
|
||||
type yysy9a1bOut struct {
|
||||
OrderNo string `json:"orderNo"`
|
||||
HandleTime string `json:"handleTime"`
|
||||
Type string `json:"type"` // 1:移动 2:联通 3:电信 4:广电
|
||||
Result string `json:"result"`
|
||||
Gender string `json:"gender"`
|
||||
Age string `json:"age"`
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
|
||||
// ProcessYYSY9A1BRequest YYSY9A1B API处理方法 - 运营商三要素查询
|
||||
func ProcessYYSY9A1BRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.YYSY9A1BReq
|
||||
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)
|
||||
}
|
||||
reqFormData := map[string]interface{}{
|
||||
"idcard": paramsDto.IDCard,
|
||||
"name": paramsDto.Name,
|
||||
"mobile": paramsDto.MobileNo,
|
||||
}
|
||||
|
||||
// 以表单方式调用数脉 API;参数在 CallAPIForm 内转为 application/x-www-form-urlencoded
|
||||
apiPath := "/v4/mobile_three/check"
|
||||
|
||||
// 先尝试使用政务接口(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.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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 将数脉 data 映射为最终返回格式
|
||||
out, err := mapShumaiMobileThreeToYYSY9A1B(respBytes)
|
||||
if err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
return json.Marshal(out)
|
||||
}
|
||||
|
||||
// mapShumaiMobileThreeToYYSY9A1B 数脉 mobile_three/check 的 data -> 最终格式
|
||||
// result: 0->01 1->02 2->04 其它->04;remark: 认证一致/认证不一致/无记录/虚拟号;gender: 男->1 女->2;type: cmcc->1 cucc->2 ctcc->3 gdcc->4
|
||||
func mapShumaiMobileThreeToYYSY9A1B(dataBytes []byte) (*yysy9a1bOut, error) {
|
||||
var r shumaiMobileThreeResp
|
||||
if err := json.Unmarshal(dataBytes, &r); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// result: 01一致 02不一致 03不确定 04失败/虚拟号;原 2-无记录 及 其它 均映射为 04
|
||||
// remark: 认证一致;认证不一致;无记录;虚拟号
|
||||
var res, remark string
|
||||
switch strings.TrimSpace(r.Result) {
|
||||
case "0":
|
||||
res = "01"
|
||||
remark = "认证一致"
|
||||
case "1":
|
||||
res = "02"
|
||||
remark = "认证不一致"
|
||||
case "2":
|
||||
res = "04"
|
||||
remark = "无记录"
|
||||
default:
|
||||
res = "04"
|
||||
remark = "虚拟号"
|
||||
}
|
||||
|
||||
// type: 运营商 channel -> 1移动 2联通 3电信 4广电(cmcc/cucc/ctcc/gdcc),未知为空
|
||||
ch := strings.ToLower(strings.TrimSpace(r.Channel))
|
||||
var chType string
|
||||
switch ch {
|
||||
case "cmcc":
|
||||
chType = "1"
|
||||
case "cucc":
|
||||
chType = "2"
|
||||
case "ctcc":
|
||||
chType = "3"
|
||||
case "gdcc":
|
||||
chType = "4"
|
||||
}
|
||||
|
||||
// gender: 男->1 女->2
|
||||
sex := strings.TrimSpace(r.Sex)
|
||||
var gender string
|
||||
if sex == "男" {
|
||||
gender = "1"
|
||||
} else if sex == "女" {
|
||||
gender = "2"
|
||||
}
|
||||
|
||||
return &yysy9a1bOut{
|
||||
OrderNo: r.OrderNo,
|
||||
HandleTime: time.Now().Format("2006-01-02 15:04:05"),
|
||||
Type: chType,
|
||||
Result: res,
|
||||
Gender: gender,
|
||||
Age: ageFromBirthday(r.Birthday),
|
||||
Remark: remark,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func ageFromBirthday(s string) string {
|
||||
s = strings.TrimSpace(s)
|
||||
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)
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package yysy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"hyapi-server/internal/domains/api/dto"
|
||||
"hyapi-server/internal/domains/api/services/processors"
|
||||
"hyapi-server/internal/infrastructure/external/zhicha"
|
||||
)
|
||||
|
||||
// ProcessYYSY9E4ARequest YYSY9E4A API处理方法 - 手机号归属地查询
|
||||
func ProcessYYSY9E4ARequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.YYSY9E4AReq
|
||||
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)
|
||||
}
|
||||
|
||||
encryptedMobileNo, err := deps.ZhichaService.Encrypt(paramsDto.MobileNo)
|
||||
if err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
reqData := map[string]interface{}{
|
||||
"phone": encryptedMobileNo,
|
||||
}
|
||||
|
||||
respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI026", 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 字符串的情况:如果是字符串则尝试再反序列化一次
|
||||
if str, ok := respData.(string); ok && str != "" {
|
||||
var parsed interface{}
|
||||
if err := json.Unmarshal([]byte(str), &parsed); err == nil {
|
||||
respData = parsed
|
||||
}
|
||||
}
|
||||
|
||||
// 将响应数据转换为JSON字节
|
||||
respBytes, err := json.Marshal(respData)
|
||||
if err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
return respBytes, nil
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
package yysy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"hyapi-server/internal/domains/api/dto"
|
||||
"hyapi-server/internal/domains/api/services/processors"
|
||||
"hyapi-server/internal/infrastructure/external/shumai"
|
||||
)
|
||||
|
||||
// ProcessYYSY9F1BYequest YYSY9F1B API处理方法 - 手机二要素验证
|
||||
|
||||
func ProcessYYSY9F1BYequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.YYSY9F1BReq
|
||||
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)
|
||||
}
|
||||
reqFormData := map[string]interface{}{
|
||||
"mobile": paramsDto.MobileNo,
|
||||
"name": paramsDto.Name,
|
||||
}
|
||||
|
||||
// 3m8s 运营商二要素:order_no, fee, result(0-一致 1-不一致)。失败则直接返回,不再调携号转网接口。
|
||||
apiPath := "/v4/mobile_two/check"
|
||||
respBytes, err := deps.ShumaiService.CallAPIForm(ctx, apiPath, reqFormData)
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
// s9w1 手机携号转网(仅在上方二要素成功后再调)
|
||||
apiPath2 := "/v4/mobile-transfer/query"
|
||||
respBytes2, err := deps.ShumaiService.CallAPIForm(ctx, apiPath2, reqFormData)
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
var twoFactorResp struct {
|
||||
OrderNo string `json:"order_no"`
|
||||
Fee int `json:"fee"`
|
||||
Result int `json:"result"` // 0-一致 1-不一致
|
||||
}
|
||||
if err := json.Unmarshal(respBytes, &twoFactorResp); err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
var transferResp struct {
|
||||
OrderNo string `json:"order_no"`
|
||||
Mobile string `json:"mobile"`
|
||||
Area *string `json:"area"`
|
||||
IspType string `json:"ispType"` // 转网前运营商
|
||||
NewIspType string `json:"newIspType"` // 转网后运营商
|
||||
}
|
||||
if err := json.Unmarshal(respBytes2, &transferResp); err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
// state: 1-一致 2-不一致 3-异常
|
||||
state := "3"
|
||||
switch twoFactorResp.Result {
|
||||
case 0:
|
||||
state = "1"
|
||||
case 1:
|
||||
state = "2"
|
||||
}
|
||||
|
||||
operator := ispNameToCode(transferResp.IspType)
|
||||
operatorReal := ispNameToCode(transferResp.NewIspType)
|
||||
|
||||
// is_xhzw: 0-否 1-是(转网前与转网后运营商不同即为携号转网)
|
||||
isXhzw := "0"
|
||||
if transferResp.IspType != "" && transferResp.NewIspType != "" && transferResp.IspType != transferResp.NewIspType {
|
||||
isXhzw = "1"
|
||||
}
|
||||
|
||||
out := map[string]string{
|
||||
"operator_real": operatorReal,
|
||||
"state": state,
|
||||
"is_xhzw": isXhzw,
|
||||
"operator": operator,
|
||||
}
|
||||
return json.Marshal(out)
|
||||
}
|
||||
|
||||
// ispNameToCode 运营商名称转编码:1-移动 2-联通 3-电信
|
||||
func ispNameToCode(name string) string {
|
||||
switch name {
|
||||
case "移动":
|
||||
return "1"
|
||||
case "联通":
|
||||
return "2"
|
||||
case "电信":
|
||||
return "3"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
package yysy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"hyapi-server/internal/domains/api/dto"
|
||||
"hyapi-server/internal/domains/api/services/processors"
|
||||
)
|
||||
|
||||
// ProcessYYSYBE08Request YYSYBE08 API处理方法 - 使用数脉二要素验证
|
||||
func ProcessYYSYBE08Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.YYSYBE08Req
|
||||
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)
|
||||
}
|
||||
|
||||
reqFormData := map[string]interface{}{
|
||||
"idcard": paramsDto.IDCard,
|
||||
"name": paramsDto.Name,
|
||||
}
|
||||
|
||||
// 以表单方式调用数脉 API;参数在 CallAPIForm 内转为 application/x-www-form-urlencoded
|
||||
apiPath := "/v4/id_card/check"
|
||||
|
||||
// 先尝试使用政务接口(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 {
|
||||
return callAliyunIDCardCheckRaw(ctx, deps, paramsDto.Name, paramsDto.IDCard)
|
||||
}
|
||||
}
|
||||
|
||||
// 解析数脉 /v4/id_card/check 的 data 内容(CallAPIForm 返回的即 data 对象)
|
||||
// 数卖响应: result 0-一致 1-不一致 2-无记录(预留); desc 如 "一致"/"不一致"
|
||||
var shumaiData struct {
|
||||
Result interface{} `json:"result"`
|
||||
OrderNo string `json:"order_no"`
|
||||
Desc string `json:"desc"`
|
||||
Sex string `json:"sex"`
|
||||
Birthday string `json:"birthday"`
|
||||
Address string `json:"address"`
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(respBytes, &shumaiData); err != nil {
|
||||
// 解析失败,返回系统错误 - 转换为目标格式
|
||||
errorResponse := map[string]interface{}{
|
||||
"ctidRequest": map[string]interface{}{
|
||||
"ctidAuth": map[string]interface{}{
|
||||
"idCard": paramsDto.IDCard,
|
||||
"name": paramsDto.Name,
|
||||
"resultCode": "500",
|
||||
"resultMsg": "响应解析失败",
|
||||
"verifyResult": "",
|
||||
},
|
||||
},
|
||||
}
|
||||
return json.Marshal(errorResponse)
|
||||
}
|
||||
|
||||
// 按数卖 result 验证结果处理: 0-一致 1-不一致 2-无记录(预留)
|
||||
// resultCode: 0XXX=一致, 5XXX=不一致/无记录
|
||||
resultCode, verifyResult, resultMsg := mapIDCardCheckResult(shumaiData.Result, shumaiData.Desc)
|
||||
|
||||
// 构建目标格式的响应
|
||||
response := map[string]interface{}{
|
||||
"ctidRequest": map[string]interface{}{
|
||||
"ctidAuth": map[string]interface{}{
|
||||
"idCard": paramsDto.IDCard,
|
||||
"name": paramsDto.Name,
|
||||
"resultCode": resultCode,
|
||||
"resultMsg": resultMsg,
|
||||
"verifyResult": verifyResult,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
return json.Marshal(response)
|
||||
}
|
||||
|
||||
func mapIDCardCheckResult(rawResult interface{}, desc string) (resultCode, verifyResult, resultMsg string) {
|
||||
if isResultZero(rawResult) {
|
||||
resultCode = "0XXX"
|
||||
verifyResult = "一致"
|
||||
resultMsg = desc
|
||||
if resultMsg == "" {
|
||||
resultMsg = "成功"
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
resultCode = "5XXX"
|
||||
verifyResult = "不一致"
|
||||
resultMsg = desc
|
||||
if resultMsg == "" {
|
||||
resultMsg = "不一致"
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func isResultZero(v interface{}) bool {
|
||||
switch r := v.(type) {
|
||||
case float64:
|
||||
return r == 0
|
||||
case int:
|
||||
return r == 0
|
||||
case int32:
|
||||
return r == 0
|
||||
case int64:
|
||||
return r == 0
|
||||
case json.Number:
|
||||
n, err := r.Int64()
|
||||
return err == nil && n == 0
|
||||
case string:
|
||||
s := strings.TrimSpace(r)
|
||||
if s == "" {
|
||||
return false
|
||||
}
|
||||
n, err := strconv.ParseFloat(s, 64)
|
||||
return err == nil && n == 0
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package yysy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"hyapi-server/internal/domains/api/dto"
|
||||
"hyapi-server/internal/domains/api/services/processors"
|
||||
"hyapi-server/internal/infrastructure/external/alicloud"
|
||||
)
|
||||
|
||||
// ProcessYYSYBE08testRequest 与 YYSYBE08 相同入参,底层使用阿里云市场身份证二要素校验;响应映射为 ctidRequest.ctidAuth 格式
|
||||
func ProcessYYSYBE08testRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.YYSYBE08Req
|
||||
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)
|
||||
}
|
||||
|
||||
return callAliyunIDCardCheckRaw(ctx, deps, paramsDto.Name, paramsDto.IDCard)
|
||||
}
|
||||
|
||||
// callAliyunIDCardCheckRaw POST api-mall/api/id_card/check(form: name、idcard),并映射为 ctidRequest.ctidAuth 响应
|
||||
func callAliyunIDCardCheckRaw(ctx context.Context, deps *processors.ProcessorDependencies, name, idCard string) ([]byte, error) {
|
||||
_ = ctx
|
||||
reqData := map[string]interface{}{
|
||||
"name": name,
|
||||
"idcard": idCard,
|
||||
}
|
||||
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)
|
||||
}
|
||||
|
||||
var aliyunData struct {
|
||||
Msg string `json:"msg"`
|
||||
Success bool `json:"success"`
|
||||
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
|
||||
// 优先使用 code=200 时 data 内的字段;兼容旧格式直接返回 result/desc
|
||||
if aliyunData.Code == 200 {
|
||||
rawResult = aliyunData.Data.Result
|
||||
rawDesc = aliyunData.Data.Desc
|
||||
}
|
||||
|
||||
resultCode, verifyResult, resultMsg := mapIDCardCheckResult(rawResult, rawDesc)
|
||||
response := map[string]interface{}{
|
||||
"ctidRequest": map[string]interface{}{
|
||||
"ctidAuth": map[string]interface{}{
|
||||
"idCard": idCard,
|
||||
"name": name,
|
||||
"resultCode": resultCode,
|
||||
"resultMsg": resultMsg,
|
||||
"verifyResult": verifyResult,
|
||||
},
|
||||
},
|
||||
}
|
||||
return json.Marshal(response)
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package yysy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"hyapi-server/internal/domains/api/dto"
|
||||
"hyapi-server/internal/domains/api/services/processors"
|
||||
"hyapi-server/internal/infrastructure/external/shumai"
|
||||
)
|
||||
|
||||
// ProcessYYSYC4R9Request YYSYC4R9 运营商三要素详版API处理方法
|
||||
func ProcessYYSYC4R9Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.YYSYC4R9Req
|
||||
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)
|
||||
}
|
||||
reqFormData := map[string]interface{}{
|
||||
"idcard": paramsDto.IDCard,
|
||||
"name": paramsDto.Name,
|
||||
"mobile": paramsDto.MobileNo,
|
||||
}
|
||||
|
||||
// 以表单方式调用数脉 API;参数在 CallAPIForm 内转为 application/x-www-form-urlencoded
|
||||
apiPath := "/v2/mobile_three/check/detail" // 接口路径,根据数脉文档填写(如 v4/xxx)
|
||||
respBytes, err := deps.ShumaiService.CallAPIForm(ctx, apiPath, reqFormData)
|
||||
if err != nil {
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package yysy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"hyapi-server/internal/domains/api/dto"
|
||||
"hyapi-server/internal/domains/api/services/processors"
|
||||
"hyapi-server/internal/infrastructure/external/westdex"
|
||||
)
|
||||
|
||||
// ProcessYYSYD50FRequest YYSYD50F API处理方法
|
||||
func ProcessYYSYD50FRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.YYSYD50FReq
|
||||
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)
|
||||
}
|
||||
|
||||
encryptedMobileNo, err := deps.WestDexService.Encrypt(paramsDto.MobileNo)
|
||||
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{}{
|
||||
"phone": encryptedMobileNo,
|
||||
"idNo": encryptedIDCard,
|
||||
},
|
||||
}
|
||||
|
||||
respBytes, err := deps.WestDexService.CallAPI(ctx, "G18BJ02", 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
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package yysy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"hyapi-server/internal/domains/api/dto"
|
||||
"hyapi-server/internal/domains/api/services/processors"
|
||||
"hyapi-server/internal/infrastructure/external/shumai"
|
||||
)
|
||||
|
||||
// ProcessYYSYE7V5Request YYSYE7V5 手机在网状态查询API处理方法
|
||||
func ProcessYYSYE7V5Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.YYSYE7V5Req
|
||||
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)
|
||||
}
|
||||
reqFormData := map[string]interface{}{
|
||||
"mobile": paramsDto.MobileNo,
|
||||
}
|
||||
|
||||
// 以表单方式调用数脉 API;参数在 CallAPIForm 内转为 application/x-www-form-urlencoded
|
||||
apiPath := "/v1/mobile_status/check" // 接口路径,根据数脉文档填写(
|
||||
respBytes, err := deps.ShumaiService.CallAPIForm(ctx, apiPath, reqFormData)
|
||||
if err != nil {
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package yysy
|
||||
|
||||
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"
|
||||
)
|
||||
|
||||
// ProcessYYSYF2T7Request YYSYF2T7 手机二次放号检测查询API处理方法
|
||||
func ProcessYYSYF2T7Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.YYSYF2T7Req
|
||||
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)
|
||||
}
|
||||
// 从入参 date_range(YYYYMMDD-YYYYMMDD)提取右区间作为 date
|
||||
parts := strings.SplitN(paramsDto.DateRange, "-", 2)
|
||||
dateEnd := strings.TrimSpace(parts[1]) // 校验已保证格式正确,取结束日期
|
||||
reqFormData := map[string]interface{}{
|
||||
"mobile": paramsDto.MobileNo,
|
||||
"date": dateEnd,
|
||||
}
|
||||
|
||||
// 以表单方式调用数脉 API;参数在 CallAPIForm 内转为 application/x-www-form-urlencoded
|
||||
apiPath := "/v4/mobile_twice/check" // 接口路径,根据数脉文档填写(
|
||||
respBytes, err := deps.ShumaiService.CallAPIForm(ctx, apiPath, reqFormData)
|
||||
if err != nil {
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
package yysy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"hyapi-server/internal/domains/api/dto"
|
||||
"hyapi-server/internal/domains/api/services/processors"
|
||||
"hyapi-server/internal/infrastructure/external/shumai"
|
||||
)
|
||||
|
||||
// westdexG19BJ02Resp 上游 G19BJ02 实际返回结构:order_no->guid, result->code, channel->phoneType, desc->msg
|
||||
type westdexG19BJ02Resp struct {
|
||||
Result int `json:"result"` // 0-是二次卡 1-不是二次卡 2-数据库中无信息(预留)
|
||||
OrderNo string `json:"orderNo"`
|
||||
Channel string `json:"channel"` // cmcc/cucc/ctcc
|
||||
Desc string `json:"desc"`
|
||||
}
|
||||
|
||||
// YYSYF7DBResponse 手机二次卡查询成功响应(最终返回结构)
|
||||
type YYSYF7DBResponse struct {
|
||||
Code string `json:"code"`
|
||||
Data YYSYF7DBResponseData `json:"data"`
|
||||
}
|
||||
|
||||
// YYSYF7DBResponseData 手机二次卡 data 结构
|
||||
type YYSYF7DBResponseData struct {
|
||||
Code int `json:"code"`
|
||||
EncryptType string `json:"encryptType"`
|
||||
Guid string `json:"guid"` // 来自 order_no
|
||||
Msg string `json:"msg"` // 来自 desc,按 result:0-是二次卡 1-不是二次卡
|
||||
PhoneType string `json:"phoneType"` // 来自 channel:cmcc->CMCC 等
|
||||
}
|
||||
|
||||
// ProcessYYSYF7DBRequest YYSYF7DB API处理方法
|
||||
func ProcessYYSYF7DBRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.YYSYF7DBReq
|
||||
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)
|
||||
}
|
||||
|
||||
// 组装日期:开始日期 + 当前日期(YYYYMMDD-YYYYMMDD)
|
||||
today := time.Now().Format("20060102")
|
||||
// dateRange := startDateYyyymmdd + "-" + today
|
||||
|
||||
reqFormData := map[string]interface{}{
|
||||
"mobile": paramsDto.MobileNo,
|
||||
"date": today,
|
||||
}
|
||||
|
||||
// 以表单方式调用数脉 API;参数在 CallAPIForm 内转为 application/x-www-form-urlencoded
|
||||
apiPath := "/v4/mobile_twice/check" // 接口路径,根据数脉文档填写(
|
||||
respBytes, err := deps.ShumaiService.CallAPIForm(ctx, apiPath, reqFormData)
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
mapped, err := mapWestdexG19BJ02ToYYSYF7DB(respBytes)
|
||||
if err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
return json.Marshal(mapped)
|
||||
}
|
||||
|
||||
// mapWestdexG19BJ02ToYYSYF7DB 将上游 result/orderNo/channel/desc 映射为最终 code/data 结构
|
||||
// result: 0->1025(是二次卡) 1->1026(不是二次卡) 2->1027(数据库中无信息);channel: cmcc->CMCC cucc->CUCC ctcc->CTCC
|
||||
func mapWestdexG19BJ02ToYYSYF7DB(dataBytes []byte) (*YYSYF7DBResponse, error) {
|
||||
var r westdexG19BJ02Resp
|
||||
if err := json.Unmarshal(dataBytes, &r); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var codeStr string
|
||||
var codeInt int
|
||||
var msg string
|
||||
switch r.Result {
|
||||
case 0:
|
||||
codeStr = "1025"
|
||||
codeInt = 1025
|
||||
msg = "二次卡"
|
||||
case 1:
|
||||
codeStr = "1026"
|
||||
codeInt = 1026
|
||||
msg = "不是二次卡"
|
||||
default:
|
||||
codeStr = "1027"
|
||||
codeInt = 1027
|
||||
msg = "不是二次卡"
|
||||
}
|
||||
if r.Desc != "" {
|
||||
msg = strings.TrimSpace(r.Desc)
|
||||
}
|
||||
|
||||
ch := strings.ToLower(strings.TrimSpace(r.Channel))
|
||||
var phoneType string
|
||||
switch ch {
|
||||
case "cmcc":
|
||||
phoneType = "CMCC"
|
||||
case "cucc":
|
||||
phoneType = "CUCC"
|
||||
case "ctcc":
|
||||
phoneType = "CTCC"
|
||||
default:
|
||||
phoneType = "UNKNOWN"
|
||||
}
|
||||
|
||||
return &YYSYF7DBResponse{
|
||||
Code: codeStr,
|
||||
Data: YYSYF7DBResponseData{
|
||||
Code: codeInt,
|
||||
EncryptType: "MD5",
|
||||
Guid: r.OrderNo,
|
||||
Msg: msg,
|
||||
PhoneType: phoneType,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package yysy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"hyapi-server/internal/domains/api/dto"
|
||||
"hyapi-server/internal/domains/api/services/processors"
|
||||
"hyapi-server/internal/infrastructure/external/shumai"
|
||||
)
|
||||
|
||||
// ProcessYYSYH6D2Request YYSYH6D2 运营商三要素简版API处理方法
|
||||
func ProcessYYSYH6D2Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.YYSYH6D2Req
|
||||
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)
|
||||
}
|
||||
reqFormData := map[string]interface{}{
|
||||
"idcard": paramsDto.IDCard,
|
||||
"name": paramsDto.Name,
|
||||
"mobile": paramsDto.MobileNo,
|
||||
}
|
||||
|
||||
// 以表单方式调用数脉 API;参数在 CallAPIForm 内转为 application/x-www-form-urlencoded
|
||||
apiPath := "/v4/mobile_three/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.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
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package yysy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"hyapi-server/internal/domains/api/dto"
|
||||
"hyapi-server/internal/domains/api/services/processors"
|
||||
"hyapi-server/internal/infrastructure/external/shumai"
|
||||
)
|
||||
|
||||
// ProcessYYSYH6F3Request YYSYH6F3 运营商三要素即时版API处理方法
|
||||
func ProcessYYSYH6F3Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.YYSYH6F3Req
|
||||
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)
|
||||
}
|
||||
reqFormData := map[string]interface{}{
|
||||
"idcard": paramsDto.IDCard,
|
||||
"name": paramsDto.Name,
|
||||
"mobile": paramsDto.MobileNo,
|
||||
}
|
||||
|
||||
// 以表单方式调用数脉 API;参数在 CallAPIForm 内转为 application/x-www-form-urlencoded
|
||||
// 走政务接口使用这个
|
||||
|
||||
apiPath := "/v4/mobile_three/check" // 接口路径,根据数脉文档填写(如 v4/xxx)
|
||||
respBytes, err := deps.ShumaiService.CallAPIForm(ctx, apiPath, reqFormData)
|
||||
if err != nil {
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package yysy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"hyapi-server/internal/domains/api/dto"
|
||||
"hyapi-server/internal/domains/api/services/processors"
|
||||
"hyapi-server/internal/infrastructure/external/shumai"
|
||||
)
|
||||
|
||||
// ProcessYYSYK8R3Request YYSYK8R3 手机空号检测查询API处理方法
|
||||
func ProcessYYSYK8R3Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.YYSYK8R3Req
|
||||
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)
|
||||
}
|
||||
reqFormData := map[string]interface{}{
|
||||
"mobile": paramsDto.MobileNo,
|
||||
}
|
||||
|
||||
// 以表单方式调用数脉 API;参数在 CallAPIForm 内转为 application/x-www-form-urlencoded
|
||||
apiPath := "/v4/mobile_empty/check" // 接口路径,根据数脉文档填写(
|
||||
respBytes, err := deps.ShumaiService.CallAPIForm(ctx, apiPath, reqFormData)
|
||||
if err != nil {
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package yysy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"hyapi-server/internal/domains/api/dto"
|
||||
"hyapi-server/internal/domains/api/services/processors"
|
||||
"hyapi-server/internal/infrastructure/external/shujubao"
|
||||
)
|
||||
|
||||
// ProcessYYSYK9R4Request JRZQACAB 全网手机三要素验证1979周更新版 API 处理方法(使用数据宝服务示例)
|
||||
func ProcessYYSYK9R4Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.YYSYK9R4Req
|
||||
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)
|
||||
}
|
||||
|
||||
reqParams := map[string]interface{}{
|
||||
"key": "c115708d915451da8f34a23e144dda6b",
|
||||
"name": paramsDto.Name,
|
||||
"idcard": paramsDto.IDCard,
|
||||
"mobile": paramsDto.MobileNo,
|
||||
}
|
||||
|
||||
// 最终请求 URL = https://api.chinadatapay.com/communication + 拼接接口地址值,如 personal/197
|
||||
apiPath := "/communication/personal/1979"
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package yysy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"hyapi-server/internal/domains/api/dto"
|
||||
"hyapi-server/internal/domains/api/services/processors"
|
||||
"hyapi-server/internal/infrastructure/external/shumai"
|
||||
)
|
||||
|
||||
// ProcessYYSYP0T4Request YYSYP0T4 在网时长API处理方法
|
||||
func ProcessYYSYP0T4Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.YYSYP0T4Req
|
||||
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)
|
||||
}
|
||||
reqFormData := map[string]interface{}{
|
||||
"mobile": paramsDto.MobileNo,
|
||||
}
|
||||
|
||||
// 以表单方式调用数脉 API;参数在 CallAPIForm 内转为 application/x-www-form-urlencoded
|
||||
apiPath := "/v2/mobile_online/check" // 接口路径,根据数脉文档填写(如 v4/xxx)
|
||||
respBytes, err := deps.ShumaiService.CallAPIForm(ctx, apiPath, reqFormData)
|
||||
if err != nil {
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package yysy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"hyapi-server/internal/domains/api/dto"
|
||||
"hyapi-server/internal/domains/api/services/processors"
|
||||
"hyapi-server/internal/infrastructure/external/shumai"
|
||||
)
|
||||
|
||||
// ProcessYYSYS9W1Request YYSYS9W1 手机携号转网查询API处理方法
|
||||
func ProcessYYSYS9W1Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.YYSYS9W1Req
|
||||
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)
|
||||
}
|
||||
reqFormData := map[string]interface{}{
|
||||
"mobile": paramsDto.MobileNo,
|
||||
}
|
||||
|
||||
// 以表单方式调用数脉 API;参数在 CallAPIForm 内转为 application/x-www-form-urlencoded
|
||||
apiPath := "/v4/mobile-transfer/query" // 接口路径,根据数脉文档填写(
|
||||
respBytes, err := deps.ShumaiService.CallAPIForm(ctx, apiPath, reqFormData)
|
||||
if err != nil {
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user