diff --git a/internal/domains/api/dto/api_request_dto.go b/internal/domains/api/dto/api_request_dto.go index 24858d9..46860cc 100644 --- a/internal/domains/api/dto/api_request_dto.go +++ b/internal/domains/api/dto/api_request_dto.go @@ -200,8 +200,9 @@ type QCXG3M7ZReq struct { PlateColor string `json:"plate_color" validate:"omitempty"` } type QCXG7K2NReq struct { - PlateNo string `json:"plate_no" validate:"required"` - Name string `json:"name" validate:"required,min=1,validName"` + PlateNo string `json:"plate_no" validate:"required"` + Name string `json:"name" validate:"required,min=1,validName"` + PlateType string `json:"plate_type" validate:"omitempty,oneof=01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 20 21 22 23 24 38 51 52"` } type QCXG3B8ZReq struct { PlateNo string `json:"plate_no" validate:"required"` diff --git a/internal/domains/api/services/processors/qcxg/qcxg7k2n_plate_type.go b/internal/domains/api/services/processors/qcxg/qcxg7k2n_plate_type.go new file mode 100644 index 0000000..fbc540e --- /dev/null +++ b/internal/domains/api/services/processors/qcxg/qcxg7k2n_plate_type.go @@ -0,0 +1,53 @@ +package qcxg + +import "strings" + +const defaultPlateType = "02" + +// plateTypeToPlateColor 将车牌类型编码转换为 ETC 人车关系核验所需的车牌颜色。 +func plateTypeToPlateColor(plateType string) string { + code := normalizePlateType(plateType) + if color, ok := plateTypePlateColorMap[code]; ok { + return color + } + return "0" +} + +// normalizePlateType 归一化车牌类型,空值默认小型汽车(02)。 +func normalizePlateType(plateType string) string { + code := strings.TrimSpace(plateType) + if code == "" { + return defaultPlateType + } + return code +} + +// plateTypePlateColorMap 车牌类型 -> ETC 车牌颜色 +// 0蓝 1黄 2黑 3白 4渐变绿 5黄绿双拼 6蓝白渐变 7临时 11绿 12红 +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", // 新能源小型车 -> 绿色 +} diff --git a/internal/domains/api/services/processors/qcxg/qcxg7k2n_plate_type_test.go b/internal/domains/api/services/processors/qcxg/qcxg7k2n_plate_type_test.go new file mode 100644 index 0000000..d4a6485 --- /dev/null +++ b/internal/domains/api/services/processors/qcxg/qcxg7k2n_plate_type_test.go @@ -0,0 +1,34 @@ +package qcxg + +import "testing" + +func TestPlateTypeToPlateColor(t *testing.T) { + tests := []struct { + plateType string + want string + }{ + {"", "0"}, + {"02", "0"}, + {"01", "1"}, + {"52", "11"}, + {"51", "5"}, + {"23", "3"}, + {"22", "7"}, + {"99", "0"}, + } + + for _, tt := range tests { + if got := plateTypeToPlateColor(tt.plateType); got != tt.want { + t.Fatalf("plateTypeToPlateColor(%q) = %q, want %q", tt.plateType, got, tt.want) + } + } +} + +func TestNormalizePlateType(t *testing.T) { + if got := normalizePlateType(""); got != "02" { + t.Fatalf("normalizePlateType empty = %q, want 02", got) + } + if got := normalizePlateType(" 51 "); got != "51" { + t.Fatalf("normalizePlateType trim = %q, want 51", got) + } +} diff --git a/internal/domains/api/services/processors/qcxg/qcxg7k2n_processor.go b/internal/domains/api/services/processors/qcxg/qcxg7k2n_processor.go index c283cff..83c7697 100644 --- a/internal/domains/api/services/processors/qcxg/qcxg7k2n_processor.go +++ b/internal/domains/api/services/processors/qcxg/qcxg7k2n_processor.go @@ -22,11 +22,15 @@ func ProcessQCXG7K2NRequest(ctx context.Context, params []byte, deps *processors return nil, errors.Join(processors.ErrInvalidParam, err) } - data, err := deps.ShujubaoService.CallAPI(ctx, "/communication/personal/10093", map[string]interface{}{ - "key": "a2f32fc54b44ebc85b97a2aaff1734ec", - "carNo": paramsDto.PlateNo, - "name": paramsDto.Name, - }) + plateType := normalizePlateType(paramsDto.PlateType) + etcParams := map[string]interface{}{ + "key": "a2f32fc54b44ebc85b97a2aaff1734ec", + "carNo": paramsDto.PlateNo, + "name": paramsDto.Name, + "plateColor": plateTypeToPlateColor(paramsDto.PlateType), + } + + data, err := deps.ShujubaoService.CallAPI(ctx, "/communication/personal/10093", etcParams) if err == nil { respBytes, marshalErr := json.Marshal(data) if marshalErr != nil { @@ -45,8 +49,9 @@ func ProcessQCXG7K2NRequest(ctx context.Context, params []byte, deps *processors return nil, errors.Join(processors.ErrSystem, errors.New("海宇API服务未初始化")) } respBytes, err := deps.HaiyuapiService.CallAPI(ctx, "QCXGX2X6", map[string]interface{}{ - "plate_no": paramsDto.PlateNo, - "name": paramsDto.Name, + "plate_no": paramsDto.PlateNo, + "name": paramsDto.Name, + "vehicle_type": plateType, }) if err != nil { if errors.Is(err, haiyuapi.ErrNotFound) {