package utils import ( "bufio" "encoding/json" "errors" "fmt" "github.com/jordan-wright/email" "github.com/kataras/iris/v12" "github.com/shopspring/decimal" "github.com/sirupsen/logrus" "io" "main/config" "main/database" "main/model" "math/rand" "net/http" "net/smtp" "os" "path" "reflect" "regexp" "runtime" "strings" "time" "unsafe" ) // FormatRes 格式化result func FormatRes(code int, msg string, data interface{}) ResponseBean { return ResponseBean{ Code: code, Msg: msg, Data: data, } } // GetEnvDefault 获取带默认值环境变量 func GetEnvDefault(name string, defaultVal string) string { val, ok := os.LookupEnv(name) if ok { return val } else { return defaultVal } } // FileRead 读取文件,返回行列表 func FileRead(file string, condition bool) ([]string, error) { f, err := os.Open(file) var res []string if err != nil { return []string{}, err } defer func(f *os.File) { err = f.Close() if err != nil { return } }(f) reader := bufio.NewReader(f) for { line, _, err := reader.ReadLine() if err != nil { break } if condition && len(line) > 1 { res = append(res, string(line)) } } return res, nil } func SendEmail(receiver []string, subject string, content string) error { emailConfig := config.Config.Email sender := fmt.Sprintf("ylsa <%s>", emailConfig.Username) message := email.NewEmail() message.From = sender message.To = receiver message.Subject = subject message.Text = []byte(content) logrus.Infoln("发送邮件:", sender, receiver) err := message.Send("smtp.163.com:25", smtp.PlainAuth("", emailConfig.Username, emailConfig.Password, "smtp.163.com")) if err != nil { return err } return nil } // DataIsNil 判断数据是否为空 func DataIsNil(arg interface{}) bool { if reflect.ValueOf(arg).Kind().String() == "ptr" || reflect.ValueOf(arg).Kind().String() == "slice" { if reflect.ValueOf(arg).IsValid() { return true } } else { if reflect.ValueOf(arg).IsZero() { return true } } return false } // ErrHandle 错误处理 func ErrHandle(ctx iris.Context, err error) bool { if err != nil { pc, _, _, _ := runtime.Caller(1) f := runtime.FuncForPC(pc).Name() db := database.GetInstance().GetMysqlDb() if err1 := db.Create(&model.SysError{ Username: GetLoginUser(ctx).Username, Time: time.Now(), Function: f, ErrorInfo: err.Error(), }).Error; err1 != nil { logrus.Errorln("sql执行失败:", err1.Error()) } ctx.StatusCode(iris.StatusInternalServerError) ctx.SetErr(err) return true } return false } // NewKey 取n位随机数 func NewKey(n int) string { const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890()-+*/~" var src = rand.NewSource(time.Now().UnixNano()) const ( // 6 bits to represent a letter index letterIdBits = 6 // All 1-bits as many as letterIdBits letterIdMask = 1<= 0; { if remain == 0 { cache, remain = src.Int63(), letterIdMax } if idx := int(cache & letterIdMask); idx < len(letters) { b[i] = letters[idx] i-- } cache >>= letterIdBits remain-- } return *(*string)(unsafe.Pointer(&b)) } // CheckListItem 判断item是否在list内 func CheckListItem[T comparable](data []T, item T) bool { for _, value := range data { if value == item { return true } } return false } // FileIsExist 判断路径是否存在 func FileIsExist(path string) bool { if _, err := os.Stat(path); os.IsNotExist(err) { return false } return true } // Round float取小数 func Round(num float64, n int32) float64 { res, _ := decimal.NewFromFloat(num).Round(n).Float64() return res } // GetFileType 获取文件类型 func GetFileType(f string) string { fileSuffix := path.Ext(f) fileSuffix = strings.ToLower(fileSuffix) patternFileSuffix := fmt.Sprintf("^%s,|,%s,|,%s$|%s", fileSuffix, fileSuffix, fileSuffix, fileSuffix) regFileSuffix := regexp.MustCompile(patternFileSuffix) for _, v := range SysSettings { if strings.HasPrefix(v.Name, "fileType:") && regFileSuffix.MatchString(v.Value) { return strings.Split(v.Name, "fileType:")[1] } } //switch fileSuffix { //case ".png", ".jpg", ".jpeg", ".bmp", ".gif": // return "image" //case ".mp4", ".m2v", ".mkv", ".rmvb", ".avi", ".flv", ".mov", ".m4v", ".wmv", ".f4v": // return "video" //case ".mp3", ".wav", ".flac": // return "audio" //case ".zip", ".rar", ".7z": // return "zip" //} return "doc" } // IntAbs 数字取绝对值 func IntAbs(i int) int { if i < 0 { return -i } else { return i } } // Reverse 字符串反转 func Reverse(s string) string { a := []rune(s) for i, j := 0, len(a)-1; i < j; i, j = i+1, j-1 { a[i], a[j] = a[j], a[i] } return string(a) } func GetRequestIp(ctx iris.Context) string { realIp := ctx.Request().Header.Get("X-Real-IP") if realIp != "" { return realIp } ip := ctx.RemoteAddr() return ip } func GetIpLocation(ip string) (string, error) { var ipLocation resIpLocation data, err := http.Get(fmt.Sprintf("https://opendata.baidu.com/api.php?query=%s&co=&resource_id=6006&oe=utf8", ip)) if err != nil { logrus.Errorln(ip, "ip地址请求失败", err) return "", err } defer func(Body io.ReadCloser) { err = Body.Close() if err != nil { return } }(data.Body) body, err := io.ReadAll(data.Body) if err != nil { logrus.Errorln(ip, "获取IP地址请求读取失败:", err) return "", err } err = json.Unmarshal(body, &ipLocation) if err != nil { logrus.Errorln(ip, "IP地址请求结果解析失败:", err) return "", err } if len(ipLocation.Data) == 0 { logrus.Errorln(ip, "ip地址无效:") return "", errors.New("ip地址无效") } return ipLocation.Data[0].Location, nil }