261 lines
6.0 KiB
Go
261 lines
6.0 KiB
Go
package parse
|
||
|
||
import (
|
||
"encoding/json"
|
||
"fmt"
|
||
"image/color"
|
||
"os"
|
||
"path/filepath"
|
||
"reflect"
|
||
"regexp"
|
||
"strconv"
|
||
"strings"
|
||
"time"
|
||
|
||
"github.com/robfig/cron/v3"
|
||
"gopkg.in/yaml.v3"
|
||
)
|
||
|
||
// Number 解析数值型
|
||
func Number(value any) int64 {
|
||
switch v := value.(type) {
|
||
case string:
|
||
if v == "" {
|
||
return 0
|
||
}
|
||
num, err := strconv.ParseInt(v, 10, 64)
|
||
if err != nil {
|
||
return 0
|
||
}
|
||
return num
|
||
case int, int8, int16, int32, int64:
|
||
return reflect.ValueOf(v).Int()
|
||
case uint, uint8, uint16, uint32, uint64:
|
||
return int64(reflect.ValueOf(v).Uint())
|
||
case float32, float64:
|
||
return int64(reflect.ValueOf(v).Float())
|
||
case bool:
|
||
if v {
|
||
return 1
|
||
}
|
||
return 0
|
||
default:
|
||
return 0
|
||
}
|
||
}
|
||
|
||
// Boolean 解析布尔型
|
||
func Boolean(value any) bool {
|
||
switch v := value.(type) {
|
||
case string:
|
||
b, err := strconv.ParseBool(v)
|
||
if err != nil {
|
||
return false
|
||
}
|
||
return b
|
||
case int, int8, int16, int32, int64:
|
||
num := reflect.ValueOf(v).Int()
|
||
return num != 0
|
||
case uint, uint8, uint16, uint32, uint64:
|
||
num := int64(reflect.ValueOf(v).Uint())
|
||
return num != 0
|
||
case float32, float64:
|
||
num := reflect.ValueOf(v).Float()
|
||
return num != 0
|
||
case bool:
|
||
return v
|
||
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, // 不透明
|
||
}
|
||
}
|
||
|
||
// ConvertIPMask 转换IP网络地址掩码 24->"255.255.255.0" 20->"255.255.240.0"
|
||
func ConvertIPMask(bits int64) string {
|
||
if bits < 0 || bits > 32 {
|
||
return "255.255.255.255"
|
||
}
|
||
|
||
// 构建一个32位的uint32类型掩码,指定前bits位为1,其余为0
|
||
mask := uint32((1<<bits - 1) << (32 - bits))
|
||
|
||
// 将掩码转换为四个八位分组
|
||
groups := []string{
|
||
fmt.Sprintf("%d", mask>>24),
|
||
fmt.Sprintf("%d", (mask>>16)&255),
|
||
fmt.Sprintf("%d", (mask>>8)&255),
|
||
fmt.Sprintf("%d", mask&255),
|
||
}
|
||
|
||
// 将分组用点号连接起来形成掩码字符串
|
||
return strings.Join(groups, ".")
|
||
}
|
||
|
||
// ConvertConfigToMap 将配置内容转换为Map结构数据
|
||
//
|
||
// configType 类型支持:txt json yaml yml
|
||
func ConvertConfigToMap(configType, content string) (map[string]any, error) {
|
||
// 类型支持:viper.SupportedExts
|
||
// config := viper.New()
|
||
// config.SetConfigType(configType)
|
||
// err := config.ReadConfig(bytes.NewBuffer([]byte(content)))
|
||
// return config.AllSettings(), err
|
||
|
||
var configMap map[string]interface{}
|
||
var err error
|
||
if configType == "" || configType == "txt" {
|
||
configMap = map[string]interface{}{
|
||
"txt": content,
|
||
}
|
||
}
|
||
if configType == "yaml" || configType == "yml" {
|
||
err = yaml.Unmarshal([]byte(content), &configMap)
|
||
}
|
||
if configType == "json" {
|
||
err = json.Unmarshal([]byte(content), &configMap)
|
||
}
|
||
return configMap, err
|
||
}
|
||
|
||
// ConvertConfigToFile 将数据写入到指定文件内
|
||
//
|
||
// configType 类型支持:txt json yaml yml
|
||
func ConvertConfigToFile(configType, filePath string, data any) error {
|
||
// viper.SupportedExts
|
||
// config := viper.New()
|
||
// config.SetConfigType(configType)
|
||
// for key, value := range mapData {
|
||
// config.Set(key, value)
|
||
// }
|
||
// return config.WriteConfigAs(filePath)
|
||
|
||
var dataByte []byte
|
||
var err error
|
||
if configType == "" || configType == "txt" {
|
||
dataByte = []byte(data.(string))
|
||
}
|
||
if configType == "yaml" || configType == "yml" {
|
||
dataByte, err = yaml.Marshal(data)
|
||
}
|
||
if configType == "json" {
|
||
dataByte, err = json.Marshal(data)
|
||
}
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
if err := os.MkdirAll(filepath.Dir(filePath), 0775); err != nil {
|
||
return err
|
||
}
|
||
return os.WriteFile(filePath, dataByte, 0644)
|
||
}
|