This commit is contained in:
2026-07-06 11:56:53 +08:00
7 changed files with 208 additions and 0 deletions

View File

@@ -0,0 +1,76 @@
package qcxg
import "strings"
const defaultPlateType = "02"
func normalizePlateType(plateType string) string {
code := strings.TrimSpace(plateType)
if code == "" {
return defaultPlateType
}
return code
}
func etcPlateColorParam(plateType string) (color string, include bool) {
code := strings.TrimSpace(plateType)
if code == "" || code == "02" {
return "", false
}
color, ok := plateTypePlateColorMap[code]
if !ok || color == "0" {
return "", false
}
return color, true
}
var plateTypePlateColorMap = map[string]string{
"01": "1",
"02": "0",
"03": "2",
"04": "2",
"05": "2",
"06": "2",
"07": "1",
"08": "0",
"09": "2",
"10": "2",
"11": "2",
"12": "2",
"13": "1",
"14": "1",
"15": "1",
"16": "1",
"17": "1",
"20": "7",
"21": "7",
"22": "7",
"23": "3",
"24": "3",
"38": "0",
"51": "5",
"52": "11",
}
func buildETCShujubaoParams(plateNo, name, plateType string) map[string]interface{} {
params := map[string]interface{}{
"key": "a2f32fc54b44ebc85b97a2aaff1734ec",
"carNo": plateNo,
"name": name,
}
if color, include := etcPlateColorParam(plateType); include {
params["plateColor"] = color
}
return params
}
func buildETCTianyuanParams(plateNo, name, plateType string) map[string]string {
params := map[string]string{
"plate_no": plateNo,
"name": name,
}
if color, include := etcPlateColorParam(plateType); include {
params["plate_color"] = color
}
return params
}

View File

@@ -0,0 +1,58 @@
package qcxg
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
)
// ProcessQCXG7K2NRequest QCXG7K2N 人车核验加强版:
// 优先经天远调用 QCXG3M7Z人车关系核验 ETC查无结果时降级调用本地 QCXGX2X6行驶证信息核验V2
func ProcessQCXG7K2NRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.QCXG7K2NReq
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)
}
plateType := normalizePlateType(paramsDto.PlateType)
etcParams, err := json.Marshal(buildETCTianyuanParams(paramsDto.PlateNo, paramsDto.Name, paramsDto.PlateType))
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
respBytes, err := processors.CallTianyuanByProduct(ctx, deps, "QCXG3M7Z", etcParams)
if err == nil {
return respBytes, nil
}
if !errors.Is(err, processors.ErrNotFound) {
return nil, err
}
x2x6Params, err := json.Marshal(dto.QCXGX2X6Req{
PlateNo: paramsDto.PlateNo,
Name: paramsDto.Name,
VehicleType: plateType,
})
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
respBytes, err = ProcessQCXGX2X6Request(ctx, x2x6Params, deps)
if err != nil {
return nil, err
}
transformed, err := transformX2X6To3M7Z(respBytes)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return transformed, nil
}

View File

@@ -0,0 +1,29 @@
package qcxg
import (
"encoding/json"
"fmt"
)
// transformX2X6To3M7Z 将行驶证信息核验V2响应转换为 ETC 人车关系核验格式。
// checkResult: 00 姓名一致 -> status 101 姓名不一致 -> status 2。
func transformX2X6To3M7Z(respBytes []byte) ([]byte, error) {
var raw map[string]interface{}
if err := json.Unmarshal(respBytes, &raw); err != nil {
return nil, err
}
status := mapCheckResultToStatus(raw["checkResult"])
return json.Marshal(map[string]string{"status": status})
}
func mapCheckResultToStatus(checkResult interface{}) string {
switch fmt.Sprint(checkResult) {
case "00":
return "1"
case "01":
return "2"
default:
return "2"
}
}

View File

@@ -0,0 +1,38 @@
package qcxg
import (
"encoding/json"
"testing"
)
func TestTransformX2X6To3M7Z(t *testing.T) {
tests := []struct {
name string
input string
wantStat string
}{
{"姓名一致", `{"checkResult":"00","plate":"桂A12345"}`, "1"},
{"姓名不一致", `{"checkResult":"01","plate":"桂A12345"}`, "2"},
{"未知结果默认不一致", `{"checkResult":"99"}`, "2"},
{"缺少checkResult默认不一致", `{"plate":"桂A12345"}`, "2"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := transformX2X6To3M7Z([]byte(tt.input))
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
var out map[string]string
if err := json.Unmarshal(got, &out); err != nil {
t.Fatalf("invalid json: %v", err)
}
if len(out) != 1 {
t.Fatalf("expected only status field, got %v", out)
}
if out["status"] != tt.wantStat {
t.Fatalf("status = %q, want %q", out["status"], tt.wantStat)
}
})
}
}