package utils import ( "crypto/md5" "crypto/sha256" "encoding/base64" "encoding/hex" "encoding/json" "errors" "fmt" "math/rand" "net" "os" "reflect" "strconv" "strings" "time" "gd_vehicle/apis" "gd_vehicle/common.in/cache" "gd_vehicle/consts" "github.com/json-iterator/go" ) var ( DB_QUERY_WHERE_EMPTY = errors.New("where is empty") DB_RECORD_NOT_EXISTS = errors.New("record is not exists") DB_DUPLICATE = errors.New("database duplicate") ) var ( idCertMatrix = []int{7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2} idCertVerifyCode = []byte("10X98765432") socialCreditMatrix = []int{1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28} socialCreditMap = map[int]int{'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, 'A': 10, 'B': 11, 'C': 12, 'D': 13, 'E': 14, 'F': 15, 'G': 16, 'H': 17, 'J': 18, 'K': 19, 'L': 20, 'M': 21, 'N': 22, 'P': 23, 'Q': 24, 'R': 25, 'T': 26, 'U': 27, 'W': 28, 'X': 29, 'Y': 30} socialCreditMapKeys = []int{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'T', 'U', 'W', 'X', 'Y'} socialCreditMapValues = []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30} ) const DAYSECOND = 24 * 60 * 60 const MINUTESECOND = 60 func GetUniqueLogID(cmd string) string { return fmt.Sprintf("%d_%s", time.Now().Unix(), cmd) } // 获取偏移天数的某天的某个时刻的时间戳 func GetTimestampInOffsetDay(offsetDay, hour, min, sec int) int64 { nowTime := time.Now() todayZeroTime := time.Date(nowTime.Year(), nowTime.Month(), nowTime.Day(), 0, 0, 0, 0, time.Local) offsetDayZeroTime := todayZeroTime.AddDate(0, 0, offsetDay) return offsetDayZeroTime.Unix() + int64(hour*3600+min*60+sec) } func BeToday(ts int64) bool { theTime := time.Unix(ts, 0) nowTime := time.Now() // 年、月、日都相同,则是同一天 return (theTime.Year() == nowTime.Year() && theTime.Month() == nowTime.Month() && theTime.Day() == nowTime.Day()) } // 获取某个时间戳的0点时间戳、24点时间戳、日期 func Get0_24TimestampAndDate(ts int64) (ts0, ts24 int64, date string) { theTime := time.Unix(ts, 0) theZeroTime := time.Date(theTime.Year(), theTime.Month(), theTime.Day(), 0, 0, 0, 0, time.Local) ts0 = theZeroTime.Unix() // 0点时间戳 ts24 = theZeroTime.AddDate(0, 0, 1).Unix() // 24点时间戳 date = theZeroTime.Format("2006-01-02") // 日期 return } // 获取args对应的json字符串 func MarshalJsonString(args ...interface{}) (result string) { if len(args) > 0 { if r, err := json.Marshal(args); err == nil { result = string(r) } } return } func GetStructNotZeroField(arg interface{}) []string { v := reflect.ValueOf(arg) if v.Kind() == reflect.Ptr { v = v.Elem() } result := make([]string, 0) if v.Kind() == reflect.Struct { numField := v.NumField() for i := 0; i < numField; i++ { if !reflect.DeepEqual(v.Field(i).Interface(), reflect.Zero(v.Field(i).Type()).Interface()) { result = append(result, v.Type().Field(i).Name) } } } return result } // 生成订单号 func GenOrderNO(orderType int) string { nowTime := time.Now() nowDate := nowTime.Format("20060102") ym := string([]byte(nowDate)[3:6]) d := string([]byte(nowDate)[6:]) r := rand.New(rand.NewSource(time.Now().UnixNano())) return fmt.Sprintf("%d%s%d%s%05d", orderType, ym, r.Intn(10), d, r.Intn(10000)) } func GetRuneSubstring(src string, start, length int) string { rs := []rune(src) rl := len(rs) end := 0 if start < 0 { start = rl - 1 + start } end = start + length if start > end { start, end = end, start } if start < 0 { start = 0 } if start > rl { start = rl } if end < 0 { end = 0 } if end > rl { end = rl } return string(rs[start:end]) } func MD5(text string) string { h := md5.New() h.Write([]byte(text)) return hex.EncodeToString(h.Sum(nil)) } func SHA256(text string) string { h := sha256.New() h.Write([]byte(text)) return hex.EncodeToString(h.Sum(nil)) } func GetEnv(name string) string { value := os.Getenv(name) if value == "" { fmt.Printf(`hasn't %s env var\n`, name) os.Exit(1) } return value } func Base64URLDecode(data string) ([]byte, error) { var missing = (4 - len(data)%4) % 4 data += strings.Repeat("=", missing) return base64.URLEncoding.DecodeString(data) } func Base64UrlSafeEncode(source []byte) string { // Base64 Url Safe is the same as Base64 but does not contain '/' and '+' (replaced by '_' and '-') and trailing '=' are removed. bytearr := base64.StdEncoding.EncodeToString(source) safeurl := strings.Replace(string(bytearr), "/", "_", -1) safeurl = strings.Replace(safeurl, "+", "-", -1) safeurl = strings.Replace(safeurl, "=", "", -1) return safeurl } //生成reportId 唯一标识 func GenReportID(module string) string { macAddr := "" for _, addr := range macAddrs() { macAddr += addr } if macAddr == "" { macAddr = RandomString(10) } reportId := macAddr + module + strconv.FormatInt(time.Now().UnixNano(), 10) return MD5(reportId) } func macAddrs() (macAddrs []string) { netInterfaces, err := net.Interfaces() if err != nil { return macAddrs } for _, netInterface := range netInterfaces { macAddr := netInterface.HardwareAddr.String() if len(macAddr) == 0 { continue } macAddrs = append(macAddrs, macAddr) } return macAddrs } //根据length获取随机字符串 func RandomString(length int) string { str := "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" bytes := []byte(str) result := []byte{} r := rand.New(rand.NewSource(time.Now().UnixNano())) for i := 0; i < length; i++ { result = append(result, bytes[r.Intn(len(bytes))]) } return string(result) } //身份证 func CheckIDCert(str string) (res bool) { defer func() { if r := recover(); r != nil { res = false } }() idCert := strings.ToUpper(str) if len(idCert) != 18 { return false } year, err := strconv.Atoi(idCert[6:10]) if err != nil { return false } if !(1900 < year && year < 2100) { return false } check := 0 lastLetter := 0 for index, value := range []byte(idCert) { if index == 17 { lastLetter = int(value) break } if !(value >= 48 && value <= 57) { return false } v := value - 48 check = check + idCertMatrix[index]*int(v) } if !((lastLetter >= 48 && lastLetter <= 57) || lastLetter == 'X') { return false } timeLayout := "20060102" //转化所需模板 loc, _ := time.LoadLocation("Local") //重要:获取时区 _, err = time.ParseInLocation(timeLayout, idCert[6:14], loc) //使用模板在对应时区转化为time.time类型 if err != nil { return false } verifyCode := int(idCertVerifyCode[check%11]) if lastLetter == verifyCode { return true } return false } func IsReuseTime(reuseTime int64, timestamp int64) bool { if timestamp == 0 { return false } reuseSencod := reuseTime * DAYSECOND t := time.Unix(timestamp, 0) now := time.Now() // 60s短时复用 if reuseTime == 0 { if now.Unix()-timestamp > MINUTESECOND { return false } return true } start := time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location()).Unix() end := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()).Unix() if end-start >= reuseSencod { return false } return true } // 时间字符串转化成时间戳 func TimeStringToTs(s string) int64 { if strings.Count(s, "-") == 1 { s += "-01" } location, _ := time.ParseInLocation("2006-01-02", s, time.Local) return location.Unix() } func CheckWorkTime(s string) string { s = strings.ToUpper(s) arr := []rune(s) for _, v := range arr { if v < 65 || v > 70 { return "F" } } return s } func CheckMile(s string) string { s = strings.ToUpper(s) arr := []rune(s) for _, v := range arr { if v < 65 || v > 76 { return "L" } } return s } func CheckMileSixMonth(s string) string { s = strings.ToUpper(s) arr := []rune(s) for _, v := range arr { if v < 65 || v > 73 { return "I" } } return s } func ConvertPlateType(s string) (plateColor string, exist bool) { plateColorMap := map[string]string{ "01": "1", "02": "0", "51": "5", "52": "4", } if v, ok := plateColorMap[s]; ok { return v, true } return } func GetDataByRedis(redisKey string, reuseTime int64, reply interface{}, fn func(data string, dest interface{}) error) (bool, error) { res, err := cache.Redis.Get(redisKey) if err == nil && res != "" { rawData := apis.RawData{} _ = jsoniter.UnmarshalFromString(res, &rawData) if IsReuseTime(reuseTime, rawData.Timestamp) { return true, fn(rawData.Data, reply) } } return false, nil } func StoreDataToRedis(redisKey, data string) { store := apis.RawData{ Data: data, Timestamp: time.Now().Unix(), } str, _ := jsoniter.MarshalToString(store) _, _ = cache.Redis.SetEx(redisKey, consts.RedisDataExipred, str) return }