309 lines
7.4 KiB
Go
309 lines
7.4 KiB
Go
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() {
|
||
|
||
}
|