2025-10-16 13:28:24 +08:00

276 lines
5.9 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 (
"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
}