后端重构
This commit is contained in:
+65
-32
@@ -1,47 +1,80 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-kratos/kratos/v2/errors"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// Response 统一响应格式
|
||||
// Response 统一响应结构(与 gva 保持一致)
|
||||
type Response struct {
|
||||
Code int `json:"code"`
|
||||
Data interface{} `json:"data"`
|
||||
Msg string `json:"msg"`
|
||||
Data interface{} `json:"data,omitempty"`
|
||||
}
|
||||
|
||||
// Encoder 响应编码器,包装响应为 {code, msg, data} 格式
|
||||
func Encoder(w http.ResponseWriter, r *http.Request, v interface{}) error {
|
||||
if v == nil {
|
||||
v = struct{}{}
|
||||
}
|
||||
reply := Response{
|
||||
Code: 0,
|
||||
Msg: "success",
|
||||
Data: v,
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
return json.NewEncoder(w).Encode(reply)
|
||||
const (
|
||||
ERROR = 7
|
||||
SUCCESS = 0
|
||||
)
|
||||
|
||||
// Result 返回结果
|
||||
func Result(code int, data interface{}, msg string, c *gin.Context) {
|
||||
c.JSON(http.StatusOK, Response{
|
||||
code,
|
||||
data,
|
||||
msg,
|
||||
})
|
||||
}
|
||||
|
||||
// ErrorEncoder 错误编码器,统一错误响应格式
|
||||
func ErrorEncoder(w http.ResponseWriter, r *http.Request, err error) {
|
||||
se := errors.FromError(err)
|
||||
code := int(se.Code)
|
||||
if code >= 400 && code < 500 {
|
||||
code = 7
|
||||
} else if code >= 500 {
|
||||
code = 7
|
||||
}
|
||||
reply := Response{
|
||||
Code: code,
|
||||
Msg: se.Message,
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(int(se.Code))
|
||||
json.NewEncoder(w).Encode(reply)
|
||||
// Ok 成功响应
|
||||
func Ok(c *gin.Context) {
|
||||
Result(SUCCESS, map[string]interface{}{}, "操作成功", c)
|
||||
}
|
||||
|
||||
// OkWithMessage 成功响应带消息
|
||||
func OkWithMessage(message string, c *gin.Context) {
|
||||
Result(SUCCESS, map[string]interface{}{}, message, c)
|
||||
}
|
||||
|
||||
// OkWithData 成功响应带数据
|
||||
func OkWithData(data interface{}, c *gin.Context) {
|
||||
Result(SUCCESS, data, "成功", c)
|
||||
}
|
||||
|
||||
// OkWithDetailed 成功响应带数据和消息
|
||||
func OkWithDetailed(data interface{}, message string, c *gin.Context) {
|
||||
Result(SUCCESS, data, message, c)
|
||||
}
|
||||
|
||||
// Fail 失败响应
|
||||
func Fail(c *gin.Context) {
|
||||
Result(ERROR, map[string]interface{}{}, "操作失败", c)
|
||||
}
|
||||
|
||||
// FailWithMessage 失败响应带消息
|
||||
func FailWithMessage(message string, c *gin.Context) {
|
||||
Result(ERROR, map[string]interface{}{}, message, c)
|
||||
}
|
||||
|
||||
// FailWithDetailed 失败响应带数据和消息
|
||||
func FailWithDetailed(data interface{}, message string, c *gin.Context) {
|
||||
Result(ERROR, data, message, c)
|
||||
}
|
||||
|
||||
// NoAuth 未授权响应
|
||||
func NoAuth(message string, c *gin.Context) {
|
||||
c.JSON(http.StatusUnauthorized, Response{
|
||||
7,
|
||||
nil,
|
||||
message,
|
||||
})
|
||||
}
|
||||
|
||||
// PageResult 分页响应结构
|
||||
type PageResult struct {
|
||||
List interface{} `json:"list"`
|
||||
Total int64 `json:"total"`
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"pageSize"`
|
||||
}
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"kra/pkg/jwt"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// 全局 JWT 实例(需要在初始化时设置)
|
||||
var jwtInstance *jwt.JWT
|
||||
|
||||
// 全局日志实例(需要在初始化时设置)
|
||||
var logger *zap.Logger
|
||||
|
||||
// SetJWT 设置全局 JWT 实例
|
||||
func SetJWT(j *jwt.JWT) {
|
||||
jwtInstance = j
|
||||
}
|
||||
|
||||
// SetLogger 设置全局日志实例
|
||||
func SetLogger(l *zap.Logger) {
|
||||
logger = l
|
||||
}
|
||||
|
||||
// ClearToken 清除 token
|
||||
func ClearToken(c *gin.Context) {
|
||||
// 增加cookie x-token 向来源的web添加
|
||||
host, _, err := net.SplitHostPort(c.Request.Host)
|
||||
if err != nil {
|
||||
host = c.Request.Host
|
||||
}
|
||||
|
||||
if net.ParseIP(host) != nil {
|
||||
c.SetCookie("x-token", "", -1, "/", "", false, false)
|
||||
} else {
|
||||
c.SetCookie("x-token", "", -1, "/", host, false, false)
|
||||
}
|
||||
}
|
||||
|
||||
// SetToken 设置 token 到 cookie
|
||||
func SetToken(c *gin.Context, token string, maxAge int) {
|
||||
// 增加cookie x-token 向来源的web添加
|
||||
host, _, err := net.SplitHostPort(c.Request.Host)
|
||||
if err != nil {
|
||||
host = c.Request.Host
|
||||
}
|
||||
|
||||
if net.ParseIP(host) != nil {
|
||||
c.SetCookie("x-token", token, maxAge, "/", "", false, false)
|
||||
} else {
|
||||
c.SetCookie("x-token", token, maxAge, "/", host, false, false)
|
||||
}
|
||||
}
|
||||
|
||||
// GetToken 从请求中获取 token
|
||||
func GetToken(c *gin.Context) string {
|
||||
token := c.Request.Header.Get("x-token")
|
||||
if token == "" {
|
||||
token, _ = c.Cookie("x-token")
|
||||
if token != "" && jwtInstance != nil {
|
||||
claims, err := jwtInstance.ParseToken(token)
|
||||
if err != nil {
|
||||
if logger != nil {
|
||||
logger.Error("重新写入cookie token失败,未能成功解析token,请检查请求头是否存在x-token且claims是否为规定结构")
|
||||
}
|
||||
return token
|
||||
}
|
||||
SetToken(c, token, int(claims.ExpiresAt.Unix()-time.Now().Unix()))
|
||||
}
|
||||
}
|
||||
return token
|
||||
}
|
||||
|
||||
// GetClaims 从 context 获取 claims
|
||||
func GetClaims(c *gin.Context) (*jwt.CustomClaims, error) {
|
||||
token := GetToken(c)
|
||||
if jwtInstance == nil {
|
||||
return nil, jwt.ErrTokenInvalid
|
||||
}
|
||||
claims, err := jwtInstance.ParseToken(token)
|
||||
if err != nil {
|
||||
if logger != nil {
|
||||
logger.Error("从Gin的Context中获取从jwt解析信息失败, 请检查请求头是否存在x-token且claims是否为规定结构")
|
||||
}
|
||||
}
|
||||
return claims, err
|
||||
}
|
||||
|
||||
// GetUserID 从 Gin 的 Context 中获取从 jwt 解析出来的用户 ID
|
||||
func GetUserID(c *gin.Context) uint {
|
||||
if claims, exists := c.Get("claims"); !exists {
|
||||
if cl, err := GetClaims(c); err != nil {
|
||||
return 0
|
||||
} else {
|
||||
return cl.BaseClaims.ID
|
||||
}
|
||||
} else {
|
||||
waitUse := claims.(*jwt.CustomClaims)
|
||||
return waitUse.BaseClaims.ID
|
||||
}
|
||||
}
|
||||
|
||||
// GetUserUuid 从 Gin 的 Context 中获取从 jwt 解析出来的用户 UUID
|
||||
func GetUserUuid(c *gin.Context) uuid.UUID {
|
||||
if claims, exists := c.Get("claims"); !exists {
|
||||
if cl, err := GetClaims(c); err != nil {
|
||||
return uuid.UUID{}
|
||||
} else {
|
||||
uid, _ := uuid.Parse(cl.BaseClaims.UUID)
|
||||
return uid
|
||||
}
|
||||
} else {
|
||||
waitUse := claims.(*jwt.CustomClaims)
|
||||
uid, _ := uuid.Parse(waitUse.BaseClaims.UUID)
|
||||
return uid
|
||||
}
|
||||
}
|
||||
|
||||
// GetUserAuthorityId 从 Gin 的 Context 中获取从 jwt 解析出来的用户角色 id
|
||||
func GetUserAuthorityId(c *gin.Context) uint {
|
||||
if claims, exists := c.Get("claims"); !exists {
|
||||
if cl, err := GetClaims(c); err != nil {
|
||||
return 0
|
||||
} else {
|
||||
return cl.BaseClaims.AuthorityID
|
||||
}
|
||||
} else {
|
||||
waitUse := claims.(*jwt.CustomClaims)
|
||||
return waitUse.BaseClaims.AuthorityID
|
||||
}
|
||||
}
|
||||
|
||||
// GetUserInfo 从 Gin 的 Context 中获取从 jwt 解析出来的用户信息
|
||||
func GetUserInfo(c *gin.Context) *jwt.CustomClaims {
|
||||
if claims, exists := c.Get("claims"); !exists {
|
||||
if cl, err := GetClaims(c); err != nil {
|
||||
return nil
|
||||
} else {
|
||||
return cl
|
||||
}
|
||||
} else {
|
||||
waitUse := claims.(*jwt.CustomClaims)
|
||||
return waitUse
|
||||
}
|
||||
}
|
||||
|
||||
// GetUserName 从 Gin 的 Context 中获取从 jwt 解析出来的用户名
|
||||
func GetUserName(c *gin.Context) string {
|
||||
if claims, exists := c.Get("claims"); !exists {
|
||||
if cl, err := GetClaims(c); err != nil {
|
||||
return ""
|
||||
} else {
|
||||
return cl.Username
|
||||
}
|
||||
} else {
|
||||
waitUse := claims.(*jwt.CustomClaims)
|
||||
return waitUse.Username
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user