Files
zmkgC/api/v1/common/tool/tool.go
2025-07-07 20:11:59 +08:00

309 lines
7.4 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 tool
import (
"bytes"
"crypto/md5"
"encoding/base64"
"encoding/hex"
"fmt"
"io"
"io/ioutil"
"log"
"math/rand"
"net/http"
"os"
"os/exec"
"path/filepath"
"reflect"
"regexp"
"runtime"
"sort"
"strconv"
"strings"
"time"
)
/*
判断文件或文件夹是否存在
如果返回的错误为nil,说明文件或文件夹存在
如果返回的错误类型使用os.IsNotExist()判断为true,说明文件或文件夹不存在
如果返回的错误为其它类型,则不确定是否在存在
*/
func PathExists(path string) bool {
_, err := os.Stat(path)
if err == nil {
return true
}
if os.IsNotExist(err) {
return false
}
return false
}
/*
检查字符串是否在某一数组中
*/
func IsContainStr(items []string, item string) bool {
for _, eachItem := range items {
if eachItem == item {
return true
}
}
return false
}
// 调用os.MkdirAll递归创建文件夹
func CreateDir(dirPath string) {
if !isExist(dirPath) {
fmt.Println("路径不存在,创建路径", dirPath)
_ = os.MkdirAll(dirPath, os.ModePerm)
}
}
// 判断所给路径文件/文件夹是否存在(返回true是存在)
func isExist(path string) bool {
_, err := os.Stat(path) //os.Stat获取文件信息
if err != nil {
if os.IsExist(err) {
return true
}
return false
}
return true
}
/*获取uuid*/
func GetUuid() string {
str := GetRandstring(32)
time.Sleep(time.Nanosecond)
return strings.ToLower(Md5V(str))
}
// #取得随机字符串:使用字符串拼接
func GetRandstring(lenNum int) string {
var CHARS = []string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
"1", "2", "3", "4", "5", "6", "7", "8", "9", "0"}
str := strings.Builder{}
length := len(CHARS)
for i := 0; i < lenNum; i++ {
l := CHARS[rand.Intn(length)]
str.WriteString(l)
}
return str.String()
}
// 获取当前执行程序所在的绝对路径
func GetCurrentAbPathByExecutable() string {
exePath, err := os.Executable()
if err != nil {
log.Fatal(err)
}
res, _ := filepath.EvalSymlinks(filepath.Dir(exePath))
return res
}
/*结构体转map且首字母小写*/
func Struct2Map(obj interface{}) map[string]interface{} {
t := reflect.TypeOf(obj)
v := reflect.ValueOf(obj)
var data = make(map[string]interface{})
for i := 0; i < t.NumField(); i++ {
data[strings.ToLower(string(t.Field(i).Name[0]))+t.Field(i).Name[1:]] = v.Field(i).Interface()
//data[t.Field(i).Name] = v.Field(i).Interface()
}
return data
}
func PortInUse(port int) int {
checkStatement := fmt.Sprintf("lsof -i:%d ", port)
output, _ := exec.Command("sh", "-c", checkStatement).CombinedOutput()
fmt.Println(output)
if len(output) > 0 {
return 1
}
return -1
}
/*检测端口是否在使用中*/
// 传入查询的端口号
// 返回端口号对应的进程PID若没有找到相关进程返回-1
func portInUse(portNumber int) int {
res := -1
var outBytes bytes.Buffer
sysType := runtime.GOOS
fmt.Println(sysType)
var cmdStr = ""
if sysType == "linux" {
cmdStr = fmt.Sprintf("lsof -i:%d ", portNumber)
}
//
if sysType == "windows" {
cmdStr = fmt.Sprintf("netstat -ano -p tcp | findstr %d", portNumber)
}
//checkStatement := fmt.Sprintf("lsof -i:%d ", portNumber)
fmt.Println(cmdStr)
cmd := exec.Command("cmd", "/c", cmdStr)
cmd.Stdout = &outBytes
cmd.Run()
resStr := outBytes.String()
fmt.Println(resStr)
r := regexp.MustCompile(`\s\d+\s`).FindAllString(resStr, -1)
if len(r) > 0 {
pid, err := strconv.Atoi(strings.TrimSpace(r[0]))
if err != nil {
res = -1
} else {
res = pid
}
}
return res
}
func GetUnUsePort(port int) int {
isInUse := PortInUse(port)
if isInUse != -1 {
fmt.Println("端口:" + strconv.Itoa(port) + " 被占用")
port++
port = GetUnUsePort(port)
return port
} else {
return port
}
}
// WeekIntervalTime 获取某周的开始和结束时间,week为0本周,-1上周1下周以此类推
func WeekIntervalTime(week int) (startTime, endTime string) {
now := time.Now()
offset := int(time.Monday - now.Weekday())
//周日做特殊判断 因为time.Monday = 0
if offset > 0 {
offset = -6
}
year, month, day := now.Date()
thisWeek := time.Date(year, month, day, 0, 0, 0, 0, time.Local)
startTime = thisWeek.AddDate(0, 0, offset+7*week).Format("2006-01-02") + " 00:00:00"
endTime = thisWeek.AddDate(0, 0, offset+6+7*week).Format("2006-01-02") + " 23:59:59"
return startTime, endTime
}
// GetCurrentTime 获取当前系统时间
func GetCurrentTime() string {
return time.Now().Format("2006-01-02 15:04:05")
}
/*删除文件或文件夹*/
func RemoveFile(path string) {
if isExist(path) {
err := os.Remove(path)
if err != nil {
return
}
}
}
// 检查参数
func Md5V(str string) string {
h := md5.New()
h.Write([]byte(str))
return hex.EncodeToString(h.Sum(nil))
}
// download file会将url下载到本地文件它会在下载时写入而不是将整个文件加载到内存中。
func DownloadFile(filepath string, url string) error {
// Get the data
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
// Create the file
out, err := os.Create(filepath)
if err != nil {
return err
}
defer out.Close()
// Write the body to file
_, err = io.Copy(out, resp.Body)
return err
}
// 通用排序
// 结构体排序必须重写数组Len() Swap() Less()函数
type body_wrapper struct {
Bodys []interface{}
by func(p, q *interface{}) bool //内部Less()函数会用到
}
type SortBodyBy func(p, q *interface{}) bool //定义一个函数类型
// 数组长度Len()
func (acw body_wrapper) Len() int {
return len(acw.Bodys)
}
// 元素交换
func (acw body_wrapper) Swap(i, j int) {
acw.Bodys[i], acw.Bodys[j] = acw.Bodys[j], acw.Bodys[i]
}
// 比较函数使用外部传入的by比较函数
func (acw body_wrapper) Less(i, j int) bool {
return acw.by(&acw.Bodys[i], &acw.Bodys[j])
}
// 自定义排序字段参考SortBodyByCreateTime中的传入函数
func SortBody(bodys []interface{}, by SortBodyBy) {
sort.Sort(body_wrapper{bodys, by})
}
// 格式化时间
type LocalTime time.Time
func (t *LocalTime) MarshalJSON() ([]byte, error) {
tTime := time.Time(*t)
return []byte(fmt.Sprintf("\"%v\"", tTime.Format("2006-01-02 15:04:05"))), nil
}
// 写入文件,保存
func WriteFile(path string, base64_image_content string) (error, string) {
//b, _ := regexp.MatchString(`^data:\s*image\/(\w+);base64,`, base64_image_content)
//if !b {
// return errors.New(""), ""
//}
base64_image_content = "data:image/png;base64," + base64_image_content
re, _ := regexp.Compile(`^data:\s*image\/(\w+);base64,`)
allData := re.FindAllSubmatch([]byte(base64_image_content), 2)
fileType := string(allData[0][1]) //png jpeg 后缀获取
base64Str := re.ReplaceAllString(base64_image_content, "")
//date := time.Now().Format("2006-01-02")
//if ok := IsFileExist(path + "/" + date); !ok {
// os.Mkdir(path+"/"+date, 0666)
//}
curFileStr := strconv.FormatInt(time.Now().UnixNano(), 10)
r := rand.New(rand.NewSource(time.Now().UnixNano()))
n := r.Intn(99999)
var filename = curFileStr + strconv.Itoa(n) + "." + fileType
var file = path + "/" + filename
byte, _ := base64.StdEncoding.DecodeString(base64Str)
err := ioutil.WriteFile(file, byte, 0666)
if err != nil {
log.Println(err)
}
return err, filename
}
func UploadsFile() {
}