Files
web_ylsa/api_iris/utils/utils.go
2025-07-11 16:54:11 +08:00

256 lines
5.8 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 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<<letterIdBits - 1
letterIdMax = 63 / letterIdBits
)
b := make([]byte, n)
// A rand.Int63() generates 63 random bits, enough for letterIdMax letters!
for i, cache, remain := n-1, src.Int63(), letterIdMax; i >= 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
}