198 lines
4.5 KiB
Go
198 lines
4.5 KiB
Go
package parse
|
|
|
|
import (
|
|
"fmt"
|
|
"image/color"
|
|
"reflect"
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/robfig/cron/v3"
|
|
)
|
|
|
|
// Number 解析数值型
|
|
func Number(str any) int64 {
|
|
switch str := str.(type) {
|
|
case string:
|
|
if str == "" {
|
|
return 0
|
|
}
|
|
num, err := strconv.ParseInt(str, 10, 64)
|
|
if err != nil {
|
|
return 0
|
|
}
|
|
return num
|
|
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
|
|
return reflect.ValueOf(str).Int()
|
|
case float32, float64:
|
|
return int64(reflect.ValueOf(str).Float())
|
|
default:
|
|
return 0
|
|
}
|
|
}
|
|
|
|
// Boolean 解析布尔型
|
|
func Boolean(str any) bool {
|
|
switch str := str.(type) {
|
|
case string:
|
|
if str == "" || str == "false" || str == "0" {
|
|
return false
|
|
}
|
|
// 尝试将字符串解析为数字
|
|
if num, err := strconv.ParseFloat(str, 64); err == nil {
|
|
return num != 0
|
|
}
|
|
return true
|
|
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
|
|
num := reflect.ValueOf(str).Int()
|
|
return num != 0
|
|
case float32, float64:
|
|
num := reflect.ValueOf(str).Float()
|
|
return num != 0
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
// ConvertToCamelCase 字符串转换驼峰形式
|
|
//
|
|
// 字符串 dict/inline/data/:dictId 结果 DictInlineDataDictId
|
|
func ConvertToCamelCase(str string) string {
|
|
if len(str) == 0 {
|
|
return str
|
|
}
|
|
reg := regexp.MustCompile(`[-_:/]\w`)
|
|
result := reg.ReplaceAllStringFunc(str, func(match string) string {
|
|
return strings.ToUpper(string(match[1]))
|
|
})
|
|
|
|
words := strings.Fields(result)
|
|
for i, word := range words {
|
|
str := word[1:]
|
|
str = strings.ReplaceAll(str, "/", "")
|
|
words[i] = strings.ToUpper(word[:1]) + str
|
|
}
|
|
|
|
return strings.Join(words, "")
|
|
}
|
|
|
|
// Bit 比特位为单位
|
|
func Bit(bit float64) string {
|
|
var GB, MB, KB string
|
|
|
|
if bit > float64(1<<30) {
|
|
GB = fmt.Sprintf("%0.2f", bit/(1<<30))
|
|
}
|
|
|
|
if bit > float64(1<<20) && bit < (1<<30) {
|
|
MB = fmt.Sprintf("%.2f", bit/(1<<20))
|
|
}
|
|
|
|
if bit > float64(1<<10) && bit < (1<<20) {
|
|
KB = fmt.Sprintf("%.2f", bit/(1<<10))
|
|
}
|
|
|
|
if GB != "" {
|
|
return GB + "GB"
|
|
} else if MB != "" {
|
|
return MB + "MB"
|
|
} else if KB != "" {
|
|
return KB + "KB"
|
|
} else {
|
|
return fmt.Sprintf("%vB", bit)
|
|
}
|
|
}
|
|
|
|
// CronExpression 解析 Cron 表达式,返回下一次执行的时间戳(毫秒)
|
|
//
|
|
// 【*/5 * * * * ?】 6个参数
|
|
func CronExpression(expression string) int64 {
|
|
specParser := cron.NewParser(cron.Second | cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow | cron.Descriptor)
|
|
schedule, err := specParser.Parse(expression)
|
|
if err != nil {
|
|
return 0
|
|
}
|
|
return schedule.Next(time.Now()).UnixMilli()
|
|
}
|
|
|
|
// SafeContent 内容值进行安全掩码
|
|
func SafeContent(value string) string {
|
|
if len(value) < 3 {
|
|
return strings.Repeat("*", len(value))
|
|
} else if len(value) < 6 {
|
|
return string(value[0]) + strings.Repeat("*", len(value)-1)
|
|
} else if len(value) < 10 {
|
|
return string(value[0]) + strings.Repeat("*", len(value)-2) + string(value[len(value)-1])
|
|
} else if len(value) < 15 {
|
|
return value[:2] + strings.Repeat("*", len(value)-4) + value[len(value)-2:]
|
|
} else {
|
|
return value[:3] + strings.Repeat("*", len(value)-6) + value[len(value)-3:]
|
|
}
|
|
}
|
|
|
|
// RemoveDuplicates 数组内字符串去重
|
|
func RemoveDuplicates(ids []string) []string {
|
|
uniqueIDs := make(map[string]bool)
|
|
uniqueIDSlice := make([]string, 0)
|
|
|
|
for _, id := range ids {
|
|
_, ok := uniqueIDs[id]
|
|
if !ok && id != "" {
|
|
uniqueIDs[id] = true
|
|
uniqueIDSlice = append(uniqueIDSlice, id)
|
|
}
|
|
}
|
|
|
|
return uniqueIDSlice
|
|
}
|
|
|
|
// Color 解析颜色 #fafafa
|
|
func Color(colorStr string) *color.RGBA {
|
|
// 去除 # 号
|
|
colorStr = colorStr[1:]
|
|
|
|
// 将颜色字符串拆分为 R、G、B 分量
|
|
r, _ := strconv.ParseInt(colorStr[0:2], 16, 0)
|
|
g, _ := strconv.ParseInt(colorStr[2:4], 16, 0)
|
|
b, _ := strconv.ParseInt(colorStr[4:6], 16, 0)
|
|
|
|
return &color.RGBA{
|
|
R: uint8(r),
|
|
G: uint8(g),
|
|
B: uint8(b),
|
|
A: 255, // 不透明
|
|
}
|
|
}
|
|
|
|
// AcceptLanguage 解析 Accept-Language 头部并返回语言标签及其对应的权重值
|
|
// "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7"
|
|
func AcceptLanguage(acceptLanguage string) string {
|
|
language := "en"
|
|
maxQ := 0.0
|
|
for _, tag := range strings.Split(acceptLanguage, ",") {
|
|
parts := strings.Split(strings.TrimSpace(tag), ";q=")
|
|
lang := parts[0]
|
|
if strings.Contains(lang, "-") {
|
|
langParts := strings.Split(strings.TrimSpace(lang), "-")
|
|
lang = langParts[0]
|
|
}
|
|
q := 0.0 // 默认权重值
|
|
if len(parts) > 1 {
|
|
// 解析权重值
|
|
qValue := parts[1]
|
|
_, err := fmt.Sscanf(qValue, "%f", &q)
|
|
if err != nil {
|
|
q = 0.0 // 若解析失败,则使用默认值
|
|
}
|
|
}
|
|
// 取最大
|
|
if q > maxQ {
|
|
maxQ = q
|
|
language = lang
|
|
}
|
|
}
|
|
return language
|
|
}
|