Files
be.ems/src/framework/utils/parse/parse.go
2024-09-12 11:50:49 +08:00

261 lines
6.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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)
}