初始化项目文件
This commit is contained in:
70
api_iris/utils/aes.go
Normal file
70
api_iris/utils/aes.go
Normal file
@ -0,0 +1,70 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
)
|
||||
|
||||
func pkcs7Padding(data []byte, blockSize int) []byte {
|
||||
padding := blockSize - len(data)%blockSize
|
||||
padText := bytes.Repeat([]byte{byte(padding)}, padding)
|
||||
return append(data, padText...)
|
||||
}
|
||||
|
||||
func pkcs7UnPadding(data []byte) ([]byte, error) {
|
||||
length := len(data)
|
||||
if length == 0 {
|
||||
return nil, errors.New("加密字符串为空!")
|
||||
}
|
||||
unPadding := int(data[length-1])
|
||||
return data[:(length - unPadding)], nil
|
||||
}
|
||||
|
||||
func aesEncrypt(data []byte, key []byte) ([]byte, error) {
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blockSize := block.BlockSize()
|
||||
encryptBytes := pkcs7Padding(data, blockSize)
|
||||
encrypted := make([]byte, len(encryptBytes))
|
||||
blockMode := cipher.NewCBCEncrypter(block, key[:blockSize])
|
||||
blockMode.CryptBlocks(encrypted, encryptBytes)
|
||||
return encrypted, nil
|
||||
}
|
||||
|
||||
func aesDecrypt(data []byte, key []byte) ([]byte, error) {
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blockSize := block.BlockSize()
|
||||
blockMode := cipher.NewCBCDecrypter(block, key[:blockSize])
|
||||
decrypted := make([]byte, len(data))
|
||||
blockMode.CryptBlocks(decrypted, data)
|
||||
//fmt.Println(data, decrypted)
|
||||
decrypted, err = pkcs7UnPadding(decrypted)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return decrypted, err
|
||||
}
|
||||
|
||||
func EncryptByAes(data []byte, key []byte) (string, error) {
|
||||
res, err := aesEncrypt(data, key)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return base64.StdEncoding.EncodeToString(res), nil
|
||||
}
|
||||
|
||||
func DecryptByAes(data string, key []byte) ([]byte, error) {
|
||||
dataByte, err := base64.StdEncoding.DecodeString(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return aesDecrypt(dataByte, key)
|
||||
}
|
55
api_iris/utils/holidays.go
Normal file
55
api_iris/utils/holidays.go
Normal file
@ -0,0 +1,55 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
var holidays []ResHolidays
|
||||
|
||||
func CheckHoliday(date string) (bool, string) {
|
||||
year, err := strconv.Atoi(date[:4])
|
||||
if len(holidays) == 0 {
|
||||
err = getHolidays(year)
|
||||
if err != nil {
|
||||
return false, ""
|
||||
}
|
||||
}
|
||||
for _, holiday := range holidays {
|
||||
if date == holiday.Date {
|
||||
return true, holiday.HolidayNameCn
|
||||
}
|
||||
}
|
||||
return false, ""
|
||||
}
|
||||
|
||||
func getHolidays(year int) error {
|
||||
var res map[string]resHolidaysApi
|
||||
//var holidays []ResHolidays
|
||||
data, err := http.Get(fmt.Sprintf("https://api.jiejiariapi.com/v1/holidays/%s", strconv.Itoa(year)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func(Body io.ReadCloser) {
|
||||
err = Body.Close()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}(data.Body)
|
||||
body, _ := io.ReadAll(data.Body)
|
||||
//解析json结构
|
||||
err = json.Unmarshal(body, &res)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, j := range res {
|
||||
holidays = append(holidays, ResHolidays{
|
||||
Date: j.Date,
|
||||
HolidayNameCn: j.Name,
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
43
api_iris/utils/menus.go
Normal file
43
api_iris/utils/menus.go
Normal file
@ -0,0 +1,43 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"github.com/sirupsen/logrus"
|
||||
"main/database"
|
||||
"main/model"
|
||||
)
|
||||
|
||||
var MenuList []model.Menus
|
||||
|
||||
func UpdateMenuList() {
|
||||
db := database.GetInstance().GetMysqlDb()
|
||||
if err := db.Order("menu_id").Find(&MenuList).Error; err != nil {
|
||||
logrus.Errorln("sql执行失败:", err)
|
||||
}
|
||||
logrus.Infoln("更新暂存MenuList列表")
|
||||
if len(MenuList) == 0 {
|
||||
logrus.Warningln("数据库MenuList为空,添加初始数据")
|
||||
if err := db.Create(&model.Menus{
|
||||
MenuId: "999",
|
||||
Name: "系统管理",
|
||||
Icon: "bi-gear",
|
||||
Path: "",
|
||||
UserType: "admin",
|
||||
WhiteList: "",
|
||||
}).Error; err != nil {
|
||||
logrus.Errorln("sql执行失败:", err)
|
||||
}
|
||||
if err := db.Create(&model.Menus{
|
||||
MenuId: "99901",
|
||||
Name: "菜单管理",
|
||||
Icon: "bi-list",
|
||||
Path: "/admin/menus",
|
||||
UserType: "admin",
|
||||
WhiteList: "",
|
||||
}).Error; err != nil {
|
||||
logrus.Errorln("sql执行失败:", err)
|
||||
}
|
||||
if err := db.Order("menu_id").Find(&MenuList).Error; err != nil {
|
||||
logrus.Errorln("sql执行失败:", err)
|
||||
}
|
||||
}
|
||||
}
|
127
api_iris/utils/rsa.go
Normal file
127
api_iris/utils/rsa.go
Normal file
@ -0,0 +1,127 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"encoding/base64"
|
||||
"github.com/sirupsen/logrus"
|
||||
"main/database"
|
||||
"main/model"
|
||||
"reflect"
|
||||
"time"
|
||||
)
|
||||
|
||||
func GetPrivateKeys(user string, date string) (model.DayKeys, error) {
|
||||
var resKey model.DayKeys
|
||||
//today := time.Now().Format("2006-01-02")
|
||||
db := database.GetInstance().GetMysqlDb()
|
||||
if err := db.Where("date = ? and user = ?", date, user).Order("id").First(&resKey).Error; err != nil {
|
||||
logrus.Errorln("sql执行失败:", err)
|
||||
}
|
||||
if reflect.DeepEqual(resKey, model.DayKeys{}) {
|
||||
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
return model.DayKeys{}, err
|
||||
}
|
||||
x509PrivateKey := x509.MarshalPKCS1PrivateKey(privateKey)
|
||||
base64PrivateKey := base64.StdEncoding.EncodeToString(x509PrivateKey)
|
||||
resKey = model.DayKeys{
|
||||
Date: date,
|
||||
Key: base64PrivateKey,
|
||||
AesKey: NewKey(32),
|
||||
User: user,
|
||||
}
|
||||
if err1 := db.Create(&resKey).Error; err1 != nil {
|
||||
logrus.Errorln("sql执行失败:", err1)
|
||||
}
|
||||
logrus.Warnln(date + "resKey为空,创建resKey")
|
||||
return resKey, nil
|
||||
} else {
|
||||
if err := db.Where("date = ? and user = ? and id <> ?", date, user, resKey.ID).Delete(&model.DayKeys{}).Error; err != nil {
|
||||
logrus.Errorln("sql执行失败:", err)
|
||||
}
|
||||
}
|
||||
logrus.Infoln("resKey存在,返回私钥")
|
||||
return resKey, nil
|
||||
}
|
||||
|
||||
func GetPublicKey(user string) (string, error) {
|
||||
var userLogin model.User
|
||||
db := database.GetInstance().GetMysqlDb()
|
||||
if err := db.Where("username = ?", user).First(&userLogin).Error; err != nil {
|
||||
logrus.Errorln("sql执行失败:", err)
|
||||
}
|
||||
if userLogin.Date == "" {
|
||||
logrus.Infoln(user + ":用户之前未登录系统")
|
||||
userLogin.Date = time.Now().Format("2006-01-02")
|
||||
}
|
||||
sPrivateKey, err := GetPrivateKeys(user, userLogin.Date)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
deBase64privateKey, err := base64.StdEncoding.DecodeString(sPrivateKey.Key)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
privateKey, err := x509.ParsePKCS1PrivateKey(deBase64privateKey)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
publicKey := privateKey.PublicKey
|
||||
x509PublicKey, err := x509.MarshalPKIXPublicKey(&publicKey)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
base64PublicKey := base64.StdEncoding.EncodeToString(x509PublicKey)
|
||||
logrus.Infoln(user + ":获取公钥成功")
|
||||
return base64PublicKey, nil
|
||||
}
|
||||
|
||||
func RsaEncrypt(s string, user string) (string, error) {
|
||||
sPublicKey, err := GetPublicKey(user)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
deBase64Public, err := base64.StdEncoding.DecodeString(sPublicKey)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
publicKey, err := x509.ParsePKIXPublicKey(deBase64Public)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
res, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey.(*rsa.PublicKey), []byte(s))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return base64.StdEncoding.EncodeToString(res), nil
|
||||
}
|
||||
|
||||
func RsaDecrypt(s string, sPrivateKey string) (string, error) {
|
||||
//sPrivateKey, err := GetPrivateKeys(user)
|
||||
//if err != nil {
|
||||
// return "", err
|
||||
//}
|
||||
deBase64Private, err := base64.StdEncoding.DecodeString(sPrivateKey)
|
||||
if err != nil {
|
||||
logrus.Errorln("rsa私钥: base64 decode err:", err)
|
||||
return "", err
|
||||
}
|
||||
privateKey, err := x509.ParsePKCS1PrivateKey(deBase64Private)
|
||||
if err != nil {
|
||||
logrus.Errorln("rsa私钥: x509 decode err:", err)
|
||||
return "", err
|
||||
}
|
||||
des, err := base64.StdEncoding.DecodeString(s)
|
||||
if err != nil {
|
||||
logrus.Errorln("rsa: base64 decode err:", err)
|
||||
return "", err
|
||||
}
|
||||
res, err := rsa.DecryptPKCS1v15(rand.Reader, privateKey, des)
|
||||
if err != nil {
|
||||
logrus.Errorln("rsa: 解密失败:", err)
|
||||
return "", err
|
||||
}
|
||||
return string(res), nil
|
||||
}
|
34
api_iris/utils/sudoku.go
Normal file
34
api_iris/utils/sudoku.go
Normal file
@ -0,0 +1,34 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/sirupsen/logrus"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
func CheckSudoku(sudoku string) (error, ResSudoku) {
|
||||
resp, err := http.Get(fmt.Sprintf("https://git-ylsa0.cn/api_ylsa/get_sudoku_check/?sudoku=%s", url.QueryEscape(sudoku)))
|
||||
if err != nil {
|
||||
logrus.Errorln("请求get_sudoku_check接口失败:", err)
|
||||
return err, ResSudoku{}
|
||||
}
|
||||
defer func(Body io.ReadCloser) {
|
||||
err = Body.Close()
|
||||
if err != nil {
|
||||
logrus.Errorln(err.Error())
|
||||
}
|
||||
}(resp.Body)
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
var r ResSudoku
|
||||
//解析json结构
|
||||
err = json.Unmarshal(body, &r)
|
||||
if err != nil {
|
||||
logrus.Errorln("请求结果json解析失败:", err)
|
||||
return err, ResSudoku{}
|
||||
}
|
||||
logrus.Infoln("数独检查完成")
|
||||
return nil, r
|
||||
}
|
38
api_iris/utils/sysSettings.go
Normal file
38
api_iris/utils/sysSettings.go
Normal file
@ -0,0 +1,38 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"github.com/sirupsen/logrus"
|
||||
"main/database"
|
||||
"main/model"
|
||||
)
|
||||
|
||||
var SysSettings []model.SysSettings
|
||||
|
||||
func UpdateSysSettings() {
|
||||
db := database.GetInstance().GetMysqlDb()
|
||||
if err := db.Order("name").Find(&SysSettings).Error; err != nil {
|
||||
logrus.Errorln("sql执行失败:", err)
|
||||
}
|
||||
if len(SysSettings) == 0 {
|
||||
if err := db.Create(&model.SysSettings{
|
||||
Name: "user_type",
|
||||
CnName: "系统管理员",
|
||||
Value: "admin",
|
||||
DType: "",
|
||||
}).Error; err != nil {
|
||||
logrus.Errorln("sql执行失败:", err)
|
||||
}
|
||||
if err := db.Create(&model.SysSettings{
|
||||
Name: "user_type",
|
||||
CnName: "系统用户",
|
||||
Value: "user",
|
||||
DType: "",
|
||||
}).Error; err != nil {
|
||||
logrus.Errorln("sql执行失败:", err)
|
||||
}
|
||||
if err := db.Order("name").Find(&SysSettings).Error; err != nil {
|
||||
logrus.Errorln("sql执行失败:", err)
|
||||
}
|
||||
}
|
||||
logrus.Infoln("更新系统配置列表")
|
||||
}
|
45
api_iris/utils/type.d.go
Normal file
45
api_iris/utils/type.d.go
Normal file
@ -0,0 +1,45 @@
|
||||
package utils
|
||||
|
||||
// ResponseBean result结构
|
||||
type ResponseBean struct {
|
||||
Code int `json:"code"`
|
||||
Msg string `json:"msg"`
|
||||
Data interface{} `json:"data"`
|
||||
}
|
||||
|
||||
type ResApiUtils struct {
|
||||
Flag bool `json:"flag"`
|
||||
Data interface{} `json:"data"`
|
||||
Msg string `json:"msg"`
|
||||
}
|
||||
|
||||
// ResSudoku sudoku --------------------------------------------------------------------
|
||||
type ResSudoku struct {
|
||||
Flag bool `json:"flag"`
|
||||
Data resSudokuData
|
||||
}
|
||||
type resSudokuData struct {
|
||||
Check bool `json:"check"`
|
||||
Result string `json:"result"`
|
||||
}
|
||||
|
||||
// ResHolidays holidays -------------------------------------------------------------------
|
||||
type ResHolidays struct {
|
||||
Date string `json:"date"`
|
||||
HolidayNameCn string `json:"holiday_name_cn"`
|
||||
}
|
||||
type resHolidaysApi struct {
|
||||
Date string `json:"date"`
|
||||
Name string `json:"name"`
|
||||
IsOffDay bool `json:"isOffDay"`
|
||||
}
|
||||
|
||||
// ipLocation
|
||||
type resIpLocation struct {
|
||||
Status string `json:"status"`
|
||||
Data []resIpLocationData `json:"data"`
|
||||
}
|
||||
type resIpLocationData struct {
|
||||
OriginQuery string `json:"origin_query"`
|
||||
Location string `json:"location"`
|
||||
}
|
68
api_iris/utils/user.go
Normal file
68
api_iris/utils/user.go
Normal file
@ -0,0 +1,68 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
"github.com/kataras/iris/v12"
|
||||
"github.com/sirupsen/logrus"
|
||||
"main/database"
|
||||
"main/model"
|
||||
)
|
||||
|
||||
var UserList []model.Userinfo
|
||||
|
||||
// GetLoginUser 根据token获取用户,返回用户信息
|
||||
func GetLoginUser(ctx iris.Context) model.Userinfo {
|
||||
if ctx.Values().Get("jwt") == nil {
|
||||
ctx.StatusCode(iris.StatusUnauthorized)
|
||||
ctx.SetErr(errors.New("未登录"))
|
||||
logrus.Warningln("请求未携带token信息")
|
||||
return model.Userinfo{}
|
||||
}
|
||||
var tokens []model.JwtKeys
|
||||
db := database.GetInstance().GetMysqlDb()
|
||||
auth := ctx.Values().Get("jwt").(*jwt.Token)
|
||||
if err := db.Where("token = ?", auth.Raw).Find(&tokens).Error; err != nil {
|
||||
logrus.Errorln("sql执行失败:", err)
|
||||
}
|
||||
if len(tokens) == 0 {
|
||||
ctx.StatusCode(iris.StatusUnauthorized)
|
||||
ctx.SetErr(errors.New("未登录"))
|
||||
logrus.Warningln("token信息无效")
|
||||
return model.Userinfo{}
|
||||
}
|
||||
foobar := auth.Claims.(jwt.MapClaims)
|
||||
for key, value := range foobar {
|
||||
if key == "username" {
|
||||
return GetUserInfo(value.(string))
|
||||
}
|
||||
}
|
||||
ctx.StatusCode(iris.StatusInternalServerError)
|
||||
ctx.SetErr(errors.New("系统错误,请联系管理员"))
|
||||
logrus.Errorln("token存在但获取用户信息失败")
|
||||
return model.Userinfo{}
|
||||
}
|
||||
|
||||
// GetUserInfo 根据用户名获取用户信息,先更新本地数据
|
||||
func GetUserInfo(username string) model.Userinfo {
|
||||
if len(UserList) == 0 {
|
||||
logrus.Warnln("暂存用户列表为空,刷新数据")
|
||||
UpdateUserInfo()
|
||||
}
|
||||
for _, u := range UserList {
|
||||
if u.Username == username {
|
||||
return u
|
||||
}
|
||||
}
|
||||
logrus.Warnln("未找到对应的用户信息")
|
||||
return model.Userinfo{}
|
||||
}
|
||||
|
||||
// UpdateUserInfo 更新当前用户信息
|
||||
func UpdateUserInfo() {
|
||||
db := database.GetInstance().GetMysqlDb()
|
||||
if err := db.Find(&UserList).Error; err != nil {
|
||||
logrus.Errorln("sql执行失败:", err)
|
||||
}
|
||||
logrus.Infoln("刷新暂存用户列表")
|
||||
}
|
255
api_iris/utils/utils.go
Normal file
255
api_iris/utils/utils.go
Normal file
@ -0,0 +1,255 @@
|
||||
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
|
||||
}
|
Reference in New Issue
Block a user