132 lines
3.1 KiB
Go
132 lines
3.1 KiB
Go
package utils
|
||
|
||
import (
|
||
"encoding/json"
|
||
"fmt"
|
||
"os"
|
||
"reflect"
|
||
"strconv"
|
||
"strings"
|
||
"time"
|
||
|
||
"github.com/civet148/gotools/randoms"
|
||
|
||
"github.com/mssola/user_agent"
|
||
)
|
||
|
||
// 验证码位数
|
||
const AuthCodeNum = 6
|
||
|
||
const (
|
||
UNIT_EiB = "EiB"
|
||
UNIT_PIB = "PiB"
|
||
UNIT_DOLLAR = "$"
|
||
UNIT_BILLION = "billion"
|
||
)
|
||
|
||
const (
|
||
UNIT_ALL = UNIT_EiB + "|" + UNIT_PIB + "|" + UNIT_DOLLAR + "|" + UNIT_BILLION
|
||
)
|
||
|
||
func JsonMarshal(v interface{}) string {
|
||
var data []byte
|
||
data, _ = json.Marshal(v)
|
||
return string(data)
|
||
}
|
||
|
||
func MakeTimestampSuffix(strKey string) string {
|
||
now := time.Now().Unix()
|
||
return fmt.Sprintf("%s_%d", strKey, now)
|
||
}
|
||
|
||
func ConvertFloat64NonUnit(strNumber string) float64 {
|
||
units := strings.Split(UNIT_ALL, "|")
|
||
for _, unit := range units {
|
||
strNumber = strings.Replace(strNumber, unit, "", -1)
|
||
}
|
||
strNumber = strings.TrimSpace(strNumber)
|
||
number, err := strconv.ParseFloat(strNumber, 64)
|
||
if err != nil {
|
||
fmt.Printf("parse float (%s) error [%s]", strNumber, err)
|
||
return 0
|
||
}
|
||
return number
|
||
}
|
||
|
||
func CheckDurationMinutes(strDuration string) (ok bool, minutes int64, err error) {
|
||
if strings.Contains(strDuration, "m") {
|
||
ok = true
|
||
strMinutes := strings.TrimSuffix(strDuration, "m")
|
||
minutes, err = strconv.ParseInt(strMinutes, 10, 32)
|
||
}
|
||
return
|
||
}
|
||
|
||
func CheckDurationHours(strDuration string) (ok bool, hours int64, err error) {
|
||
if strings.Contains(strDuration, "h") {
|
||
ok = true
|
||
strHours := strings.TrimSuffix(strDuration, "h")
|
||
hours, err = strconv.ParseInt(strHours, 10, 32)
|
||
}
|
||
return
|
||
}
|
||
|
||
func ParseUserAgent(userAgent string) (osi user_agent.OSInfo, isMobile bool) {
|
||
ua := user_agent.New(userAgent)
|
||
return ua.OSInfo(), ua.Mobile()
|
||
}
|
||
|
||
func StructToMap(s interface{}) map[string]interface{} {
|
||
result := make(map[string]interface{})
|
||
valueOf := reflect.ValueOf(s)
|
||
typeOf := reflect.TypeOf(s)
|
||
|
||
for i := 0; i < valueOf.NumField(); i++ {
|
||
fieldValue := valueOf.Field(i)
|
||
fieldName := typeOf.Field(i).Name
|
||
result[fieldName] = fieldValue.Interface()
|
||
}
|
||
return result
|
||
}
|
||
|
||
func GenAuthCode() (code string) {
|
||
return randoms.RandomAlphaOrNumeric(AuthCodeNum, false, true)
|
||
}
|
||
|
||
// GetMBUUID 尝试从系统中获取主板/系统唯一标识符(适用于 Linux)
|
||
func GetMBUUID() string {
|
||
paths := []string{
|
||
"/sys/class/dmi/id/product_uuid", // 系统 UUID
|
||
"/sys/class/dmi/id/product_serial", // 系统序列号
|
||
"/sys/class/dmi/id/board_serial", // 主板序列号
|
||
"/sys/class/dmi/id/chassis_serial", // 机箱序列号
|
||
"/etc/machine-id", // fallback
|
||
}
|
||
|
||
for _, path := range paths {
|
||
if val, ok := readAndValidateHardwareID(path); ok {
|
||
return val
|
||
}
|
||
}
|
||
return "unknown"
|
||
}
|
||
|
||
// readAndValidateHardwareID 从文件中读取并验证内容是否是有效硬件ID
|
||
func readAndValidateHardwareID(path string) (string, bool) {
|
||
data, err := os.ReadFile(path)
|
||
if err != nil {
|
||
return "", false
|
||
}
|
||
val := strings.TrimSpace(string(data))
|
||
lower := strings.ToLower(val)
|
||
|
||
if val == "" ||
|
||
strings.Contains(lower, "to be filled") ||
|
||
strings.Contains(lower, "not specified") ||
|
||
strings.Contains(lower, "default") ||
|
||
lower == "ffffffff-ffff-ffff-ffff-ffffffffffff" {
|
||
return "", false
|
||
}
|
||
return val, true
|
||
}
|