qnc-server-old/utils/common.go

173 lines
4.2 KiB
Go
Raw Permalink Normal View History

2024-09-14 10:48:09 +08:00
package utils
import (
"context"
"encoding/base64"
"encoding/json"
uuid2 "github.com/google/uuid"
"image/png"
"net/url"
"os"
"qnc-server/db"
"strings"
"time"
"unicode"
"unicode/utf8"
)
func IsJSON(s string) bool {
var js interface{}
return json.Unmarshal([]byte(s), &js) == nil
}
// 校验统一社会信用代码的函数
func ValidateUnifiedSocialCreditCode(code string) bool {
if len(code) != 18 {
return false
}
// 定义字符与对应的数值映射
charValues := map[rune]int{
'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9,
'A': 10, 'B': 11, 'C': 12, 'D': 13, 'E': 14, 'F': 15, 'G': 16, 'H': 17, 'J': 18, 'K': 19,
'L': 20, 'M': 21, 'N': 22, 'P': 23, 'Q': 24, 'R': 25, 'T': 26, 'U': 27, 'W': 28, 'X': 29, 'Y': 30,
}
// 定义权重因子
weights := []int{1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28}
// 计算前 17 位与权重因子的乘积之和
sum := 0
for i, char := range code[:17] {
if value, ok := charValues[char]; ok {
sum += value * weights[i]
} else {
return false // 包含非法字符
}
}
// 计算校验码
mod := sum % 31
checkChar := '0'
for k, v := range charValues {
if v == (31-mod)%31 {
checkChar = k
break
}
}
return unicode.ToUpper(rune(code[17])) == checkChar
}
func EncryptName(name string) string {
// 获取名字的字符长度
nameLength := utf8.RuneCountInString(name)
// 如果名字只有一个字,返回原始名字
if nameLength <= 1 {
return name
}
// 将名字转换为rune切片
runes := []rune(name)
// 如果名字是两个字,保留第一个字,第二个字加密
if nameLength == 2 {
return string(runes[0]) + "*"
}
// 如果名字有三个或更多字,保留第一个和最后一个字,中间的加密
firstChar := string(runes[0])
lastChar := string(runes[nameLength-1])
// 中间的字用*代替
middleChars := strings.Repeat("*", nameLength-2)
return firstChar + middleChars + lastChar
}
func EncryptIDCard(idCard string) string {
if len(idCard) < 8 {
return idCard // 如果身份证号码长度不足8位则不进行加密
}
midStart := (len(idCard) - 8) / 2
midEnd := midStart + 8
return idCard[:midStart] + "********" + idCard[midEnd:]
}
// 解析时间字符串为 time.Time
func ParseTime(t string) (time.Time, error) {
return time.Parse("15:04", t)
}
// 判断当前时间是否在指定时间范围内
func IsInTimeRange(start, end time.Time) bool {
now := time.Now()
start = time.Date(now.Year(), now.Month(), now.Day(), start.Hour(), start.Minute(), 0, 0, now.Location())
end = time.Date(now.Year(), now.Month(), now.Day(), end.Hour(), end.Minute(), 0, 0, now.Location())
if end.Before(start) {
end = end.Add(24 * time.Hour) // 处理跨午夜的情况
}
return now.After(start) && now.Before(end)
}
// decodeBase64ToPNG 将 Base64 字符串解码为 PNG 图片并保存为临时文件
func DecodeBase64ToPNG(encodedBase64Str string, fileName string) (string, error) {
// 去掉 Base64 前缀,如 "data:image/png;base64,"
encodedBase64Str = strings.TrimPrefix(encodedBase64Str, "data:image/png;base64,")
// 进行 URL 解码,恢复 encodeURIComponent 编码的数据
base64Str, err := url.QueryUnescape(encodedBase64Str)
if err != nil {
return "", err
}
// 解码 Base64 数据
data, err := base64.StdEncoding.DecodeString(base64Str)
if err != nil {
return "", err
}
// 创建 PNG 文件
file, err := os.Create(fileName)
if err != nil {
return "", err
}
defer file.Close()
// 将解码后的字节流写入图片文件
img, err := png.Decode(strings.NewReader(string(data)))
if err != nil {
return "", err
}
// 将 PNG 编码写入文件
err = png.Encode(file, img)
if err != nil {
return "", err
}
return fileName, nil
}
func SetCacheData(ctx context.Context, data interface{}) (uuid string) {
jsonData, _ := json.Marshal(data)
// 生成一个唯一的UUID
uniqueID := uuid2.New().String()
db.RedisClient.Set(ctx, uniqueID, jsonData, 5*time.Minute)
return uniqueID
}
func GetCacheData(ctx context.Context, uniqueID string) (data interface{}, err error) {
val, err := db.RedisClient.Get(ctx, uniqueID).Result()
if err != nil {
return nil, err
}
err = json.Unmarshal([]byte(val), &data)
if err != nil {
return nil, err
}
return data, nil
}