276 lines
5.9 KiB
Go
276 lines
5.9 KiB
Go
package utils
|
||
|
||
import (
|
||
"bytes"
|
||
"crypto/md5"
|
||
"encoding/base64"
|
||
"encoding/hex"
|
||
"fmt"
|
||
"net"
|
||
"net/http"
|
||
"strings"
|
||
"time"
|
||
|
||
"github.com/tealeg/xlsx"
|
||
"golang.org/x/crypto/bcrypt"
|
||
)
|
||
|
||
// GenerateAdminHashedPassword [管理端]生成密码
|
||
func GenerateAdminHashedPassword(password string) (string, error) {
|
||
salt := "7M&7p7euU=MM"
|
||
passwordWithSalt := password + salt
|
||
|
||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(passwordWithSalt), bcrypt.DefaultCost)
|
||
if err != nil {
|
||
return "", err
|
||
}
|
||
|
||
return string(hashedPassword), nil
|
||
}
|
||
|
||
// VerifyAdminHashedPassword [管理端]验证密码
|
||
func VerifyAdminHashedPassword(hashedPassword, password string) bool {
|
||
salt := "7M&7p7euU=MM"
|
||
passwordWithSalt := password + salt
|
||
|
||
err := bcrypt.CompareHashAndPassword([]byte(hashedPassword+salt), []byte(passwordWithSalt))
|
||
return err == nil
|
||
}
|
||
|
||
// GenerateDoctorHashedPassword [医生端]生成密码
|
||
func GenerateDoctorHashedPassword(password string) (string, error) {
|
||
salt := "9M&9p9euU=DD"
|
||
passwordWithSalt := password + salt
|
||
|
||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(passwordWithSalt), bcrypt.DefaultCost)
|
||
if err != nil {
|
||
return "", err
|
||
}
|
||
|
||
return string(hashedPassword), nil
|
||
}
|
||
|
||
// VerifyDoctorHashedPassword [医生端]验证密码
|
||
func VerifyDoctorHashedPassword(hashedPassword, password string) bool {
|
||
salt := "9M&9p9euU=DD"
|
||
passwordWithSalt := password + salt
|
||
|
||
err := bcrypt.CompareHashAndPassword([]byte(hashedPassword+salt), []byte(passwordWithSalt))
|
||
return err == nil
|
||
}
|
||
|
||
// GeneratePatientHashedPassword [患者端]生成密码
|
||
func GeneratePatientHashedPassword(password string) (string, error) {
|
||
salt := "8T&8p8euU=PP"
|
||
passwordWithSalt := password + salt
|
||
|
||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(passwordWithSalt), bcrypt.DefaultCost)
|
||
if err != nil {
|
||
return "", err
|
||
}
|
||
|
||
return string(hashedPassword), nil
|
||
}
|
||
|
||
// VerifyPatientHashedPassword [患者端]验证密码
|
||
func VerifyPatientHashedPassword(hashedPassword, password string) bool {
|
||
salt := "8T&8p8euU=PP"
|
||
passwordWithSalt := password + salt
|
||
|
||
err := bcrypt.CompareHashAndPassword([]byte(hashedPassword+salt), []byte(passwordWithSalt))
|
||
return err == nil
|
||
}
|
||
|
||
// ToExcel 生成 Excel
|
||
func ToExcel(titleList []string, dataList []interface{}) []byte {
|
||
// 生成一个新的文件
|
||
file := xlsx.NewFile()
|
||
|
||
// 添加sheet页
|
||
sheet, _ := file.AddSheet("Sheet1")
|
||
|
||
// 插入表头
|
||
titleRow := sheet.AddRow()
|
||
for _, v := range titleList {
|
||
cell := titleRow.AddCell()
|
||
cell.Value = v
|
||
}
|
||
|
||
// 插入内容
|
||
for _, v := range dataList {
|
||
row := sheet.AddRow()
|
||
row.WriteStruct(v, -1)
|
||
}
|
||
|
||
var buffer bytes.Buffer
|
||
_ = file.Write(&buffer)
|
||
return buffer.Bytes()
|
||
}
|
||
|
||
func MD5(text string) string {
|
||
hash := md5.New()
|
||
hash.Write([]byte(text))
|
||
hashBytes := hash.Sum(nil)
|
||
return hex.EncodeToString(hashBytes)
|
||
}
|
||
|
||
// GetIP 尝试从 HTTP 请求中获取真实的客户端 IP 地址
|
||
func GetIP(r *http.Request) string {
|
||
// 从 X-Forwarded-For 头部获取IP地址
|
||
xForwardedFor := r.Header.Get("X-Forwarded-For")
|
||
if xForwardedFor != "" {
|
||
// 可能有多个IP地址,通常第一个是客户端的真实IP
|
||
ips := strings.Split(xForwardedFor, ",")
|
||
if len(ips) > 0 {
|
||
return strings.TrimSpace(ips[0])
|
||
}
|
||
}
|
||
|
||
// 如果没有 X-Forwarded-For 头部,尝试从 X-Real-IP 获取
|
||
xRealIP := r.Header.Get("X-Real-IP")
|
||
if xRealIP != "" {
|
||
return strings.TrimSpace(xRealIP)
|
||
}
|
||
|
||
// 如果没有代理头部,最后退回到 RemoteAddr
|
||
ip, _, err := net.SplitHostPort(r.RemoteAddr)
|
||
if err != nil {
|
||
// 如果处理RemoteAddr出错,返回空字符串
|
||
return ""
|
||
}
|
||
return ip
|
||
}
|
||
|
||
// FriendlyTimeAgo 友好时间
|
||
func FriendlyTimeAgo(date time.Time) string {
|
||
now := time.Now()
|
||
|
||
if date.After(now) {
|
||
return "未来的日期"
|
||
}
|
||
|
||
diff := now.Sub(date)
|
||
minutes := int(diff.Minutes())
|
||
hours := int(diff.Hours())
|
||
days := int(hours / 24)
|
||
|
||
// 小于1分钟
|
||
if minutes < 1 {
|
||
return "刚刚"
|
||
}
|
||
|
||
// 小于1小时
|
||
if hours < 1 {
|
||
return fmt.Sprintf("%d分钟", minutes)
|
||
}
|
||
|
||
// 小于1天
|
||
if hours < 24 {
|
||
return fmt.Sprintf("%d小时", hours)
|
||
}
|
||
|
||
// 小于1周
|
||
if days < 7 {
|
||
return fmt.Sprintf("%d天", days)
|
||
}
|
||
|
||
// 小于1个月
|
||
if days < 30 {
|
||
return fmt.Sprintf("%d周", days/7)
|
||
}
|
||
|
||
// 小于1年
|
||
if days < 365 {
|
||
months := int(days / 30)
|
||
if months < 1 {
|
||
return fmt.Sprintf("%d天", days)
|
||
}
|
||
|
||
return fmt.Sprintf("%d个月", months)
|
||
}
|
||
|
||
// 大于等于1年
|
||
years := days / 365
|
||
remainingDays := days % 365
|
||
months := remainingDays / 30
|
||
|
||
if months == 0 {
|
||
return fmt.Sprintf("%d年", years)
|
||
}
|
||
return fmt.Sprintf("%d年%d个月", years, months)
|
||
}
|
||
|
||
// FriendlySubTime 时间相减
|
||
func FriendlySubTime(birthday, date time.Time) string {
|
||
diff := date.Sub(birthday)
|
||
minutes := int(diff.Minutes())
|
||
hours := int(diff.Hours())
|
||
days := int(hours / 24)
|
||
|
||
// 小于1分钟
|
||
if minutes < 1 {
|
||
return "刚刚"
|
||
}
|
||
|
||
// 小于1小时
|
||
if hours < 1 {
|
||
return fmt.Sprintf("%d分钟", minutes)
|
||
}
|
||
|
||
// 小于1天
|
||
if hours < 24 {
|
||
return fmt.Sprintf("%d小时", hours)
|
||
}
|
||
|
||
// 小于1周
|
||
if days < 7 {
|
||
return fmt.Sprintf("%d天", days)
|
||
}
|
||
|
||
// 小于1个月
|
||
if days < 30 {
|
||
return fmt.Sprintf("%d周", days/7)
|
||
}
|
||
|
||
// 小于1年
|
||
if days < 365 {
|
||
months := int(days / 30)
|
||
if months < 1 {
|
||
return fmt.Sprintf("%d天", days)
|
||
}
|
||
|
||
return fmt.Sprintf("%d个月", months)
|
||
}
|
||
|
||
// 大于等于1年
|
||
years := days / 365
|
||
remainingDays := days % 365
|
||
months := remainingDays / 30
|
||
|
||
if months == 0 {
|
||
return fmt.Sprintf("%d岁", years)
|
||
}
|
||
return fmt.Sprintf("%d岁%d个月", years, months)
|
||
}
|
||
|
||
func XorEncrypt(phone, key string) string {
|
||
result := make([]byte, len(phone))
|
||
for i := 0; i < len(phone); i++ {
|
||
result[i] = phone[i] ^ key[i%len(key)]
|
||
}
|
||
return base64.StdEncoding.EncodeToString(result)
|
||
}
|
||
|
||
func XorDecrypt(encrypted, key string) (string, error) {
|
||
data, err := base64.StdEncoding.DecodeString(encrypted)
|
||
if err != nil {
|
||
return "", err
|
||
}
|
||
|
||
result := make([]byte, len(data))
|
||
for i := 0; i < len(data); i++ {
|
||
result[i] = data[i] ^ key[i%len(key)]
|
||
}
|
||
return string(result), nil
|
||
}
|