This commit is contained in:
2024-02-25 08:30:34 +08:00
commit 4947f39e74
273 changed files with 45396 additions and 0 deletions

124
pkg/util/common.go Normal file
View File

@ -0,0 +1,124 @@
package util
import (
"math/rand"
"path/filepath"
"regexp"
"strings"
"time"
)
func init() {
rand.Seed(time.Now().UnixNano())
}
// RandStringRunes 返回随机字符串
func RandStringRunes(n int) string {
var letterRunes = []rune("1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
b := make([]rune, n)
for i := range b {
b[i] = letterRunes[rand.Intn(len(letterRunes))]
}
return string(b)
}
// ContainsUint 返回list中是否包含
func ContainsUint(s []uint, e uint) bool {
for _, a := range s {
if a == e {
return true
}
}
return false
}
// IsInExtensionList 返回文件的扩展名是否在给定的列表范围内
func IsInExtensionList(extList []string, fileName string) bool {
ext := strings.ToLower(filepath.Ext(fileName))
// 无扩展名时
if len(ext) == 0 {
return false
}
if ContainsString(extList, ext[1:]) {
return true
}
return false
}
// ContainsString 返回list中是否包含
func ContainsString(s []string, e string) bool {
for _, a := range s {
if a == e {
return true
}
}
return false
}
// Replace 根据替换表执行批量替换
func Replace(table map[string]string, s string) string {
for key, value := range table {
s = strings.Replace(s, key, value, -1)
}
return s
}
// BuildRegexp 构建用于SQL查询用的多条件正则
func BuildRegexp(search []string, prefix, suffix, condition string) string {
var res string
for key, value := range search {
res += prefix + regexp.QuoteMeta(value) + suffix
if key < len(search)-1 {
res += condition
}
}
return res
}
// BuildConcat 根据数据库类型构建字符串连接表达式
func BuildConcat(str1, str2 string, DBType string) string {
switch DBType {
case "mysql":
return "CONCAT(" + str1 + "," + str2 + ")"
default:
return str1 + "||" + str2
}
}
// SliceIntersect 求两个切片交集
func SliceIntersect(slice1, slice2 []string) []string {
m := make(map[string]int)
nn := make([]string, 0)
for _, v := range slice1 {
m[v]++
}
for _, v := range slice2 {
times, _ := m[v]
if times == 1 {
nn = append(nn, v)
}
}
return nn
}
// SliceDifference 求两个切片差集
func SliceDifference(slice1, slice2 []string) []string {
m := make(map[string]int)
nn := make([]string, 0)
inter := SliceIntersect(slice1, slice2)
for _, v := range inter {
m[v]++
}
for _, value := range slice1 {
times, _ := m[value]
if times == 0 {
nn = append(nn, value)
}
}
return nn
}

46
pkg/util/io.go Normal file
View File

@ -0,0 +1,46 @@
package util
import (
"io"
"os"
"path/filepath"
)
// Exists reports whether the named file or directory exists.
func Exists(name string) bool {
if _, err := os.Stat(name); err != nil {
if os.IsNotExist(err) {
return false
}
}
return true
}
// CreatNestedFile 给定path创建文件如果目录不存在就递归创建
func CreatNestedFile(path string) (*os.File, error) {
basePath := filepath.Dir(path)
if !Exists(basePath) {
err := os.MkdirAll(basePath, 0700)
if err != nil {
Log().Warning("Failed to create directory: %s", err)
return nil, err
}
}
return os.Create(path)
}
// IsEmpty 返回给定目录是否为空目录
func IsEmpty(name string) (bool, error) {
f, err := os.Open(name)
if err != nil {
return false, err
}
defer f.Close()
_, err = f.Readdirnames(1) // Or f.Readdir(1)
if err == io.EOF {
return true, nil
}
return false, err // Either not empty or error, suits both cases
}

150
pkg/util/logger.go Normal file
View File

@ -0,0 +1,150 @@
package util
import (
"fmt"
"github.com/fatih/color"
"sync"
"time"
)
const (
// LevelError 错误
LevelError = iota
// LevelWarning 警告
LevelWarning
// LevelInformational 提示
LevelInformational
// LevelDebug 除错
LevelDebug
)
var GloablLogger *Logger
var Level = LevelDebug
// Logger 日志
type Logger struct {
level int
mu sync.Mutex
}
// 日志颜色
var colors = map[string]func(a ...interface{}) string{
"Warning": color.New(color.FgYellow).Add(color.Bold).SprintFunc(),
"Panic": color.New(color.BgRed).Add(color.Bold).SprintFunc(),
"Error": color.New(color.FgRed).Add(color.Bold).SprintFunc(),
"Info": color.New(color.FgCyan).Add(color.Bold).SprintFunc(),
"Debug": color.New(color.FgWhite).Add(color.Bold).SprintFunc(),
}
// 不同级别前缀与时间的间隔,保持宽度一致
var spaces = map[string]string{
"Warning": "",
"Panic": " ",
"Error": " ",
"Info": " ",
"Debug": " ",
}
// Println 打印
func (ll *Logger) Println(prefix string, msg string) {
// TODO Release时去掉
// color.NoColor = false
c := color.New()
ll.mu.Lock()
defer ll.mu.Unlock()
_, _ = c.Printf(
"%s%s %s %s\n",
colors[prefix]("["+prefix+"]"),
spaces[prefix],
time.Now().Format("2006-01-02 15:04:05"),
msg,
)
}
// Panic 极端错误
func (ll *Logger) Panic(format string, v ...interface{}) {
if LevelError > ll.level {
return
}
msg := fmt.Sprintf(format, v...)
ll.Println("Panic", msg)
panic(msg)
}
// Error 错误
func (ll *Logger) Error(format string, v ...interface{}) {
if LevelError > ll.level {
return
}
msg := fmt.Sprintf(format, v...)
ll.Println("Error", msg)
}
// Warning 警告
func (ll *Logger) Warning(format string, v ...interface{}) {
if LevelWarning > ll.level {
return
}
msg := fmt.Sprintf(format, v...)
ll.Println("Warning", msg)
}
// Info 信息
func (ll *Logger) Info(format string, v ...interface{}) {
if LevelInformational > ll.level {
return
}
msg := fmt.Sprintf(format, v...)
ll.Println("Info", msg)
}
// Debug 校验
func (ll *Logger) Debug(format string, v ...interface{}) {
if LevelDebug > ll.level {
return
}
msg := fmt.Sprintf(format, v...)
ll.Println("Debug", msg)
}
// Print GORM 的 Logger实现
//func (ll *Logger) Print(v ...interface{}) {
// if LevelDebug > ll.level {
// return
// }
// msg := fmt.Sprintf("[SQL] %s", v...)
// ll.Println(msg)
//}
// BuildLogger 构建logger
func BuildLogger(level string) {
intLevel := LevelError
switch level {
case "error":
intLevel = LevelError
case "warning":
intLevel = LevelWarning
case "info":
intLevel = LevelInformational
case "debug":
intLevel = LevelDebug
}
l := Logger{
level: intLevel,
}
GloablLogger = &l
}
// Log 返回日志对象
func Log() *Logger {
if GloablLogger == nil {
l := Logger{
level: Level,
}
GloablLogger = &l
}
return GloablLogger
}

58
pkg/util/path.go Normal file
View File

@ -0,0 +1,58 @@
package util
import (
"os"
"path"
"path/filepath"
"strings"
)
// DotPathToStandardPath 将","分割的路径转换为标准路径
func DotPathToStandardPath(path string) string {
return "/" + strings.Replace(path, ",", "/", -1)
}
// FillSlash 给路径补全`/`
func FillSlash(path string) string {
if path == "/" {
return path
}
return path + "/"
}
// RemoveSlash 移除路径最后的`/`
func RemoveSlash(path string) string {
if len(path) > 1 {
return strings.TrimSuffix(path, "/")
}
return path
}
// SplitPath 分割路径为列表
func SplitPath(path string) []string {
if len(path) == 0 || path[0] != '/' {
return []string{}
}
if path == "/" {
return []string{"/"}
}
pathSplit := strings.Split(path, "/")
pathSplit[0] = "/"
return pathSplit
}
// FormSlash 将path中的反斜杠'\'替换为'/'
func FormSlash(old string) string {
return path.Clean(strings.ReplaceAll(old, "\\", "/"))
}
// RelativePath 获取相对可执行文件的路径
func RelativePath(name string) string {
if filepath.IsAbs(name) {
return name
}
e, _ := os.Executable()
return filepath.Join(filepath.Dir(e), name)
}

39
pkg/util/session.go Normal file
View File

@ -0,0 +1,39 @@
package util
import (
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
)
// SetSession 设置session
func SetSession(c *gin.Context, list map[string]interface{}) {
s := sessions.Default(c)
for key, value := range list {
s.Set(key, value)
}
err := s.Save()
if err != nil {
Log().Warning("无法设置 Session 值:%s", err)
}
}
// GetSession 获取session
func GetSession(c *gin.Context, key string) interface{} {
s := sessions.Default(c)
return s.Get(key)
}
// DeleteSession 删除session
func DeleteSession(c *gin.Context, key string) {
s := sessions.Default(c)
s.Delete(key)
s.Save()
}
// ClearSession 清空session
func ClearSession(c *gin.Context) {
s := sessions.Default(c)
s.Clear()
s.Save()
}

35
pkg/util/ztool.go Normal file
View File

@ -0,0 +1,35 @@
package util
import "strings"
type (
// 可取长度类型
LenAble interface{ string | []any | chan any }
)
// 计算切片元素总长度
/*
传入字符串切片, 返回其所有元素长度之和
e.g. LenArray({`ele3`,`ele2`,`ele1`}) => 12
*/
func LenArray[T LenAble](a []T) int {
var o int
for i, r := 0, len(a); i < r; i++ {
o += len(a[i])
}
return o
}
// 字符串快速拼接
/*
传入多个字符串参数, 返回拼接后的结果
e.g: StrConcat("str1", "str2", "str3") => "str1str2str3"
*/
func StrConcat(a ...string) string {
var b strings.Builder
b.Grow(LenArray(a))
for i, r := 0, len(a); i < r; i++ {
b.WriteString(a[i])
}
return b.String()
}