123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453 |
- package utils
- import (
- "adm-data/consts"
- "adm-data/model"
- "fmt"
- "regexp"
- "strconv"
- "strings"
- "sync"
- "time"
- "unicode"
- "git.getensh.com/common/gopkgsv2/database"
- )
- type standard struct {
- mu sync.Mutex
- ts int64
- fuelType map[string]string
- fuelTypeCode map[string]string
- emissionStandard map[string]string
- plateType map[string]string
- plateTypeCode map[string]string
- vehicleType map[string]string
- vehicleTypeCode map[string]string
- useProperty map[string]string
- usePropertyCode map[string]string
- vehicleBodyColor map[string]string
- vehicleBodyColorCode map[string]string
- }
- // 时间格式常量定义
- const (
- DataLen = len("2006-01-02")
- MonthLen = len("2006-01")
- DaySecLen = len("2006-01-02 15:04:05")
- DayLayout = "2006-01-02"
- DaySecLayout = "2006-01-02 15:04:05"
- DayLayout2 = "2006/1/2"
- DaySecond = 24 * 60 * 60
- SecondTime = 60
- )
- var std standard
- func reload() {
- if std.ts == 0 || time.Now().Unix()-std.ts > 10*60 {
- std = standard{
- mu: sync.Mutex{},
- fuelType: map[string]string{},
- fuelTypeCode: map[string]string{},
- emissionStandard: map[string]string{},
- plateType: map[string]string{},
- plateTypeCode: map[string]string{},
- vehicleType: map[string]string{},
- vehicleTypeCode: map[string]string{},
- useProperty: map[string]string{},
- usePropertyCode: map[string]string{},
- vehicleBodyColorCode: map[string]string{},
- vehicleBodyColor: map[string]string{},
- }
- } else {
- return
- }
- std.mu.Lock()
- defer std.mu.Unlock()
- std.ts = time.Now().Unix()
- list, err := model.NewAds22Model().List(database.DB())
- if err != nil {
- return
- }
- for _, v := range list {
- switch v.Type {
- case consts.FuelType:
- if _, ok := std.fuelTypeCode[v.Source]; !ok {
- std.fuelTypeCode[v.Source] = v.Standard
- }
- std.fuelType[v.Standard] = v.Source
- case consts.EmissionStandard:
- std.emissionStandard[v.Source] = v.Standard
- case consts.PlateType:
- if _, ok := std.plateTypeCode[v.Source]; !ok {
- std.plateTypeCode[v.Source] = v.Standard
- }
- std.plateType[v.Standard] = v.Source
- case consts.VehicleType:
- if _, ok := std.vehicleTypeCode[v.Source]; !ok {
- std.vehicleTypeCode[v.Source] = v.Standard
- }
- std.vehicleType[v.Standard] = v.Source
- case consts.UseProperty:
- if _, ok := std.usePropertyCode[v.Source]; !ok {
- std.usePropertyCode[v.Source] = v.Standard
- }
- std.useProperty[v.Standard] = v.Source
- case consts.VehicleBodyColor:
- if _, ok := std.vehicleBodyColorCode[v.Source]; !ok {
- std.vehicleBodyColorCode[v.Source] = v.Standard
- }
- std.vehicleBodyColor[v.Standard] = v.Source
- }
- }
- }
- func ParseFuel(fuel string) (string, string) {
- reload()
- fuel = strings.ToUpper(fuel)
- fuel = strings.Replace(fuel, "CNG", "天然气", -1)
- fuel = strings.Replace(fuel, "NG", "天然气", -1)
- return ParseCodeDetail(fuel, std.fuelTypeCode, std.fuelType, fuelType)
- }
- func fuelType(s string) (string, string) {
- if value, ok := std.fuelType[s]; ok {
- return value, s
- }
- return "", s
- }
- func getColorCodeDetail(color string) (string, string) {
- if value, ok := std.vehicleBodyColor[color]; ok {
- return value, color
- }
- /*for k, _ := range std.vehicleBodyColor {
- if strings.Contains(color, k) {
- return std.vehicleBodyColor[k], color
- }
- }*/
- for _,v := range color{
- if value, ok := std.vehicleBodyColor[string(v)]; ok {
- return value, color
- }
- }
- if strings.Contains(color, "银") || strings.Contains(color, "灰") {
- return std.vehicleBodyColor["灰"], "灰"
- }
- if strings.Contains(color, "橙") || strings.Contains(color, "金") {
- return std.vehicleBodyColor["黄"], "黄"
- }
- if strings.Contains(color, "青") {
- return std.vehicleBodyColor["绿"], "绿"
- }
- if strings.Contains(color, "兰") || strings.Contains(color, "深篮") || strings.Contains(color, "篮") {
- return std.vehicleBodyColor["蓝"], "蓝"
- }
- if strings.Contains(color, "咖啡") {
- return std.vehicleBodyColor["棕"], "棕"
- }
- return "", color
- }
- func ParseColor(color string) (string, string) {
- reload()
- color = strings.ToUpper(color)
- return ParseCodeDetail(color,std.vehicleBodyColorCode, std.vehicleBodyColor, getColorCodeDetail)
- }
- func ParseProperty(property string) (string, string) {
- reload()
- property = strings.ToUpper(property)
- return ParseCodeDetail(property, std.usePropertyCode, std.useProperty, propertyCodeDetail)
- }
- func TrimNumberic(data string) string {
- pat := "[0-9]"
- re, _ := regexp.Compile(pat)
- str := re.ReplaceAllString(data, "")
- return str
- }
- func ClearData(data string) string {
- data = strings.Replace(data, " ", "", -1)
- data = strings.Replace(data, "/", "", -1)
- data = strings.Replace(data, "+", "", -1)
- data = strings.Replace(data, ",", "", -1)
- data = strings.Replace(data, ".", "", -1)
- data = strings.Replace(data, ",", "", -1)
- data = strings.Replace(data, "、", "", -1)
- return data
- }
- func GetArray(data string) []string {
- data = strings.Replace(data, " ", ";", -1)
- data = strings.Replace(data, "/", ";", -1)
- data = strings.Replace(data, "+", ";", -1)
- data = strings.Replace(data, ",", ";", -1)
- data = strings.Replace(data, ".", ";", -1)
- data = strings.Replace(data, ",", ";", -1)
- data = strings.Replace(data, ",", ";", -1)
- data = strings.Replace(data, "、", ";", -1)
- data = strings.Replace(data, "-", ";", -1)
- data = strings.Replace(data, "(", ";", -1)
- data = strings.Replace(data, "(", ";", -1)
- data = strings.Replace(data, ")", ";", -1)
- data = strings.Replace(data, ")", ";", -1)
- return strings.Split(data, ";")
- }
- func ParseCodeDetail(data string, codeMap map[string]string, detailMap map[string]string, f func(string) (string, string)) (string, string) {
- data = TrimNumberic(data)
- if IsHan(data) {
- array := GetArray(data)
- ret := ""
- for _, v := range array {
- code := ""
- if f != nil {
- code, _ = f(v)
- } else {
- code, _ = detailMap[v]
- }
- if strings.Contains(ret, code) {
- continue
- }
- ret = ret + code
- }
- return ret, data
- }
- if value, ok := codeMap[data]; ok {
- return value, data
- }
- ret := ""
- retCode := ""
- data = ClearData(data)
- for _, v := range data {
- code := fmt.Sprintf("%c", v)
- if ret == "" {
- if detail, ok := codeMap[code]; ok {
- ret = detail
- retCode = code
- }
- } else if detail, ok := codeMap[code]; ok {
- ret = fmt.Sprintf("%s+%s", ret, detail)
- retCode = retCode + code
- }
- }
- return ret,retCode
- }
- func propertyCodeDetail(data string) (string, string) {
- if value, ok := std.useProperty[data]; ok {
- return value, data
- }
- if strings.Contains(data, "非营业") {
- return std.useProperty["非营运"], "非营运"
- }
- if strings.Contains(data, "营业公路客运") {
- return std.useProperty["公路客运"], "公路客运"
- }
- if strings.Contains(data, "营业城市公交") {
- return std.useProperty["营业城市公交"], "营业城市公交"
- }
- if strings.Contains(data, "营业出租租赁") {
- return std.useProperty["出租客运"], "出租客运"
- }
- if strings.Contains(data, "营业挂车") {
- return std.useProperty["货运"], "货运"
- }
- if strings.Contains(data, "营业货车") {
- return std.useProperty["货运"], "货运"
- }
- if strings.Contains(data, "运输型") {
- return std.useProperty["货运"], "货运"
- }
- if strings.Contains(data, "化工") {
- return std.useProperty["危化品运输"], "危化品运输"
- }
- return "", data
- }
- func calcEmissionStandard(s string) string{
- a := strings.Split(s,".")
- if len(a) == 1 {
- return s
- }
- if len(a[1]) > 0 {
- hearder := a[1][0:1]
- switch hearder {
- case "1":
- return "国一"
- case "2":
- return "国二"
- case "3":
- return "国三"
- case "4":
- return "国四"
- case "5":
- return "国五"
- case "6":
- return "国六"
- }
- }
- return s
- }
- func EmissionStandard(s string) string {
- reload()
- s = strings.Replace(s," ","",-1)
- a := strings.Split(s, "国")
- if len(a) == 1 {
- a = strings.Split(s, "第")
- if len(a) == 1 {
- if v, ok := std.emissionStandard[s]; ok {
- return v
- }
- return calcEmissionStandard(s)
- }
- }
- condition := a[1]
- switch {
- case strings.Index(a[1], "阶段") > -1:
- if arr := strings.Split(a[1], "阶段"); len(arr) > 1 {
- condition = arr[0]
- }
- case strings.Index(a[1], ")") > -1:
- if arr := strings.Split(a[1], ")"); len(arr) > 1 {
- condition = arr[0]
- }
- case strings.Index(a[1], ")") > -1:
- if arr := strings.Split(a[1], ")"); len(arr) > 1 {
- condition = arr[0]
- }
- case strings.Index(a[1], ",") > -1:
- if arr := strings.Split(a[1], ","); len(arr) > 1 {
- condition = arr[0]
- }
- case strings.Index(a[1], ",") > -1:
- if arr := strings.Split(a[1], ","); len(arr) > 1 {
- condition = arr[0]
- }
- }
- if v, ok := std.emissionStandard[condition]; ok {
- return "国" + v
- }
- return s
- }
- // pl = 1000
- // plL = 1.0L or 1.0T
- func Displacement(pl, plL string) int {
- multiple := 1
- if pl == "" {
- pl = plL
- multiple = 1000
- }
- tmp := strings.Replace(pl, "L", "", -1)
- tmp = strings.Replace(tmp, "T", "", -1)
- t, _ := strconv.ParseFloat(tmp, 64)
- t *= float64(multiple)
- return int(t)
- }
- func IsHan(data string) bool {
- for _, r := range data {
- if unicode.Is(unicode.Scripts["Han"], r) {
- return true
- }
- }
- return false
- }
- func VehicleType(vehicleType string) (string, string) {
- reload()
- if vehicleType == "轿车" {
- return std.vehicleType["小型轿车"], vehicleType
- }
- vehicleType = strings.ToUpper(vehicleType)
- if IsHan(vehicleType) {
- if value, ok := std.vehicleType[vehicleType]; ok {
- return value, vehicleType
- }
- return "", vehicleType
- }
- if value, ok := std.vehicleTypeCode[vehicleType]; ok {
- return value, vehicleType
- }
- return "", vehicleType
- }
- func PlateType(plateType string) (string, string) {
- reload()
- if IsHan(plateType) {
- if value, ok := std.plateType[plateType]; ok {
- return value, plateType
- }
- return "", plateType
- }
- if value, ok := std.plateTypeCode[plateType]; ok {
- return value, plateType
- }
- return "", plateType
- }
- // 日期格式化
- func FormatDate(date string) string {
- date = strings.TrimSpace(date)
- if date == "" {
- return date
- }
- if strings.HasPrefix(date, "1970-01-01"){
- return ""
- }
- if strings.Contains(date, "-") {
- // 获取年月日时间格式
- if len(date) == MonthLen{
- return date + "-01 00:00:00"
- }
- newDate := strings.Split(date, " ")[0]
- if len(newDate) < DataLen {
- date = strings.Replace(date, "-", "/", -1)
- }
- }
- if strings.Contains(date, "/") {
- newDate := strings.Split(date, " ")[0]
- time1, _ := time.Parse(DayLayout2, newDate)
- date = time1.Format(DayLayout)
- } else {
- if len(date) == DaySecLen {
- return date
- }
- }
- if len(date) >= DataLen {
- date = date[:DataLen] + " 00:00:00"
- }
- return date
- }
|