package utils import ( "regexp" "strconv" "strings" "unicode" "unicode/utf8" "gd_vehicle/common.in/jsonrpc2" ) const ( VINLEN = 17 PLATELEN = 6 PLATENEWLEN = 7 SF = "京津冀晋蒙辽吉黑沪苏浙皖闽赣鲁豫鄂湘粤桂琼渝川贵云藏陕甘青宁新" ) var RUNMODE = "prod" func SetRunmode(runMode string) { RUNMODE = runMode } func ParsePlate(plate string) (string, string) { var index int for i, r := range plate { if !unicode.Is(unicode.Scripts["Han"], r) { index = i break } } sf := plate[0:index] hphm := plate[index:] return sf, hphm } func CheckVinFormat(vin string) (string, error) { vin = strings.TrimSpace(vin) vin = strings.ToUpper(vin) strconv.Itoa(len(vin)) r, _ := regexp.Compile(`[0-9A-Z]{` + strconv.Itoa(len(vin)) + `}`) if r.MatchString(vin) { return vin, nil } return vin, jsonrpc2.NewJsonError(20003, "请求参数格式不对,车架号包含特殊字符") } func CheckVinFormat17Bit(vin string) (string, error) { vin = strings.TrimSpace(vin) vin = strings.ToUpper(vin) if len(vin) != VINLEN { return vin, jsonrpc2.NewJsonError(20003, "请求参数格式不对,车架号不为17位") } r, _ := regexp.Compile(`[0-9A-Z]{17}`) if r.MatchString(vin) { return vin, nil } return vin, jsonrpc2.NewJsonError(20003, "请求参数格式不对,车架号包含特殊字符") } func IsCommonPlateType(plateType string) bool { switch plateType { case "51": return true case "52": return true case "01": return true case "02": return true default: return false } } func isUnknowPlateType(plateType string) bool { switch plateType { case "02": return false case "03": return false case "04": return false case "15": return false case "16": return false case "23": return false case "24": return false case "26": return false case "27": return false default: return true } } func getPlateType(plateNo string) string { switch { case strings.HasPrefix(plateNo, "使"): return "03" case strings.HasSuffix(plateNo, "使"): return "03" // 领馆汽车 case strings.HasSuffix(plateNo, "领"): return "04" case strings.HasSuffix(plateNo, "挂"): return "15" case strings.HasSuffix(plateNo, "学"): return "16" case strings.HasSuffix(plateNo, "警"): return "23" case strings.HasSuffix(plateNo, "港"): return "26" case strings.HasSuffix(plateNo, "澳"): return "27" default: return "02" } } func isSupportPlateType(plateType, plateNumber string) bool { /*switch plateType { case "01": return true case "02": return true case "03": return true case "04": return true case "05": return true case "06": return true case "07": return true case "08": return true case "09": return true case "10": return true case "11": return true case "12": return true case "13": return true case "14": return true case "15": return true case "16": return true case "17": return true case "20": return true case "21": return true case "22": return true case "23": return true case "24": return true case "25": return true case "26": return true case "27": return true case "51": return true case "52": return true case "99": return true default: return false }*/ if plateType != "" { if plateType != "02" && plateType != "52" { return false } } else { for _, r := range plateNumber { if unicode.Is(unicode.Scripts["Han"], r) { return false } } } return true } func CheckPlateNoFormat(plateNo *string, plateType string, merchantId int64) (string, error) { *plateNo = strings.TrimSpace(*plateNo) *plateNo = strings.ToUpper(*plateNo) return plateType, nil if RUNMODE != "prod" { if strings.HasPrefix(*plateNo, "测") { return plateType, nil } } sf, plateNumber := ParsePlate(*plateNo) plateLen := utf8.RuneCountInString(plateNumber) if strings.HasSuffix(*plateNo, "使") { if plateType == "" { plateType = "03" } } if plateType == "" && plateLen == PLATENEWLEN { if plateNumber[1] > 64 && plateNumber[1] < 91 { plateType = "52" } else if plateNumber[PLATENEWLEN-1] > 64 && plateNumber[PLATENEWLEN-1] < 91 { plateType = "51" } else { return plateType, jsonrpc2.NewJsonError(20003, "请求参数格式不对,新能源汽车车牌格式不正确") } } if !isSupportPlateType(plateType, plateNumber) && merchantId != 15 { //15号GD商户 return "", jsonrpc2.NewJsonError(20004, "参数错误,暂不支持非小型车号牌调用") } // 判断车牌号码合法性 if len(sf) == 0 && !strings.HasSuffix(*plateNo, "使") { return plateType, jsonrpc2.NewJsonError(20003, "请求参数格式不对,车牌号码格式不正确") } else if sf != "使" { if !strings.Contains(SF, sf) { return plateType, jsonrpc2.NewJsonError(20003, "请求参数格式不对,不支持的省份") } } // 检查车牌是否包含i o字符 if strings.Contains(plateNumber, "I") || strings.Contains(plateNumber, "O") { return plateType, jsonrpc2.NewJsonError(20003, "请求参数格式不对,车牌号码包含I或O字符") } count := 0 for _, v := range plateNumber { if 64 < v && v < 91 { count++ } } if strings.HasPrefix(*plateNo, "使") || strings.HasSuffix(*plateNo, "使") { if plateType == "" { return "03", nil } else { if plateType != "03" { return "", jsonrpc2.NewJsonError(20003, "请求参数格式不对,车牌和车牌类型不匹配") } return plateType, nil } } else if strings.HasSuffix(*plateNo, "领") { if plateType == "" { return "04", nil } else { if plateType != "04" { return "", jsonrpc2.NewJsonError(20003, "请求参数格式不对,车牌和车牌类型不匹配") } return plateType, nil } } else if plateType == "51" || plateType == "52" { if count > 3 { return plateType, jsonrpc2.NewJsonError(20003, "请求参数格式不对,新能源车牌号码超过3个字母") } else if plateLen != PLATENEWLEN { return plateType, jsonrpc2.NewJsonError(20003, "请求参数格式不对,新能源车牌号码长度不正确") } else { if plateNumber[1] > 64 && plateNumber[1] < 91 { if plateType != "52" { return plateType, jsonrpc2.NewJsonError(20003, "请求参数格式不对,新能源车牌号码和车牌类型不匹配") } } else if plateNumber[PLATENEWLEN-1] > 64 && plateNumber[PLATENEWLEN-1] < 91 { if plateType != "51" { return plateType, jsonrpc2.NewJsonError(20003, "请求参数格式不对,新能源车牌号码和车牌类型不匹配") } } else { return plateType, jsonrpc2.NewJsonError(20003, "请求参数格式不对,新能源汽车车牌格式不正确") } } } else { if count > 3 { return plateType, jsonrpc2.NewJsonError(20003, "请求参数格式不对,车牌号码超过3个字母") } else if plateLen != PLATELEN { return plateType, jsonrpc2.NewJsonError(20003, "请求参数格式不对,车牌号码长度不正确") } } if strings.Contains("0123456789", plateNumber[0:1]) { return plateType, jsonrpc2.NewJsonError(20003, "请求参数格式不对,号牌号码第一位不能为数字") } if plateType == "51" || plateType == "52" { return plateType, nil } if plateType != "" && isUnknowPlateType(plateType) { return plateType, nil } plateTypeNew := getPlateType(*plateNo) if plateType != "" && plateTypeNew != plateType { return plateType, jsonrpc2.NewJsonError(20003, "请求参数格式不对,车牌号码和车牌类型不匹配") } return plateTypeNew, nil } func VehicleDefaultPlateType(plateNo *string) (plateType string, err error) { *plateNo = strings.TrimSpace(*plateNo) *plateNo = strings.ToUpper(*plateNo) sf, plateNumber := ParsePlate(*plateNo) if len(sf) == 0 { return "", jsonrpc2.NewJsonError(20003, "参数格式不对,车牌号码无省份") } plateLen := utf8.RuneCountInString(plateNumber) if plateLen == PLATENEWLEN { if plateNumber[1] > 64 && plateNumber[1] < 91 { plateType = "52" return plateType, nil } else if plateNumber[PLATENEWLEN-1] > 64 && plateNumber[PLATENEWLEN-1] < 91 { plateType = "51" return plateType, nil } else { return plateType, jsonrpc2.NewJsonError(20003, "参数格式不对,新能源汽车车牌格式不正确") } } else if plateLen == PLATELEN { plateType = getPlateType(*plateNo) return plateType, nil } else { return plateType, jsonrpc2.NewJsonError(20003, "参数格式不对,车牌长度不正确") } return plateType, nil } func CheckEngineFormat(engineNo string) error { if len(engineNo) < 6 { return jsonrpc2.NewJsonError(20003, "参数格式不对,发动机号小于6位") } for _, r := range engineNo { if unicode.Is(unicode.Scripts["Han"], r) { return jsonrpc2.NewJsonError(20003, "参数格式不对,发动机号包括汉字") } } return nil } // 获取车辆是车型,0 烧油,1 电动 func GetDefaultPlateType(plateno string) int { _, plateNumber := ParsePlate(plateno) plateLen := len(strings.TrimSpace(plateNumber)) if plateLen == PLATELEN { return 0 } else if plateLen == PLATENEWLEN { return 1 } return 2 } func AddSySource(sySoucre, sourceName string) string { if sySoucre == "" { sySoucre = sourceName } else if !strings.Contains(sySoucre, sourceName) { sySoucre = sySoucre + "," + sourceName } return sySoucre } func ParseEngineNo(engineNo, engineType string) string { if strings.HasPrefix(engineNo, engineType) { engineNo = strings.TrimSpace(engineNo[len(engineType):]) } var re string for _, v := range engineNo { if (v >= '0' && v <= '9') || (v >= 'a' && v <= 'z') || (v >= 'A' && v <= 'Z') || v == '/' { re = re + string(v) } } return re } func GetSeat(seatStr string) int { seatList := strings.Split(seatStr, "-") maxSeat := 0 for _, v := range seatList { seat, _ := strconv.Atoi(v) if seat > maxSeat { maxSeat = seat } } return maxSeat } func PlateNoMasking(s string) string { if s == "" { return s } runes := []rune(s) length := len(runes) if length <= 4 { return s } return string(runes[:2]) + strings.Repeat("*", length-4) + string(runes[length-2:]) }