This commit is contained in:
huangjin
2026-06-29 17:34:59 +08:00
commit fe3ad20fe2
271 changed files with 51767 additions and 0 deletions

View File

@@ -0,0 +1,101 @@
// JWT Token 生成与解析 + 业务工具函数
package utils
import (
"crypto/rand"
"encoding/hex"
"fmt"
"time"
"github.com/golang-jwt/jwt/v5"
)
// JWTClaims JWT 载荷,包含用户 ID 和角色列表
type JWTClaims struct {
UserID uint `json:"user_id"`
RoleCode string `json:"role_code"` // 角色(visitor/employee/guard)
jwt.RegisteredClaims
}
// AdminJWTClaims 管理员 JWT 载荷
type AdminJWTClaims struct {
AdminID uint `json:"admin_id"`
Account string `json:"account"`
jwt.RegisteredClaims
}
// GenerateAdminToken 生成管理员 JWT
func GenerateAdminToken(adminID uint, account string, secret string, expireHours int) (string, error) {
claims := AdminJWTClaims{
AdminID: adminID,
Account: account,
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Duration(expireHours) * time.Hour)),
IssuedAt: jwt.NewNumericDate(time.Now()),
Issuer: "lktx-admin",
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString([]byte(secret))
}
// ParseAdminToken 解析管理员 JWT
func ParseAdminToken(tokenString string, secret string) (*AdminJWTClaims, error) {
token, err := jwt.ParseWithClaims(tokenString, &AdminJWTClaims{}, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
}
return []byte(secret), nil
})
if err != nil {
return nil, err
}
if claims, ok := token.Claims.(*AdminJWTClaims); ok && token.Valid {
return claims, nil
}
return nil, fmt.Errorf("invalid token")
}
// GenerateToken 生成 JWT单角色兼容旧版
func GenerateToken(userID uint, roleCode string, secret string, expireHours int) (string, error) {
claims := JWTClaims{
UserID: userID,
RoleCode: roleCode,
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Duration(expireHours) * time.Hour)),
IssuedAt: jwt.NewNumericDate(time.Now()),
Issuer: "lktx-mp",
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString([]byte(secret))
}
// ParseToken 解析并验证 JWT
func ParseToken(tokenString string, secret string) (*JWTClaims, error) {
token, err := jwt.ParseWithClaims(tokenString, &JWTClaims{}, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
}
return []byte(secret), nil
})
if err != nil {
return nil, err
}
if claims, ok := token.Claims.(*JWTClaims); ok && token.Valid {
return claims, nil
}
return nil, fmt.Errorf("invalid token")
}
// GenerateInviteCode 生成 16 位随机邀请码
func GenerateInviteCode() string {
b := make([]byte, 8)
rand.Read(b)
return hex.EncodeToString(b)
}
// GenerateQRCodeContent 生成二维码内容
func GenerateQRCodeContent(appointmentID uint) string {
return fmt.Sprintf("LKTX:APPT:%d:%d", appointmentID, time.Now().Unix())
}