搭建Go后端框架:数据模型、JWT鉴权、租户隔离、WebSocket、REST API路由

This commit is contained in:
yml2213
2026-07-14 11:23:05 +08:00
parent 81c32cfdea
commit 05ab468498
16 changed files with 1692 additions and 1 deletions
+103
View File
@@ -0,0 +1,103 @@
package handler
import (
"net/http"
"github.com/gin-gonic/gin"
"kefu-sys/server/internal/middleware"
"kefu-sys/server/internal/model"
"golang.org/x/crypto/bcrypt"
)
type AuthHandler struct{}
func NewAuthHandler() *AuthHandler { return &AuthHandler{} }
type LoginReq struct {
Username string `json:"username" binding:"required"`
Password string `json:"password" binding:"required"`
}
type RegisterReq struct {
Username string `json:"username" binding:"required"`
Password string `json:"password" binding:"required"`
Nickname string `json:"nickname" binding:"required"`
TenantID uint `json:"tenant_id" binding:"required"`
Role string `json:"role"`
}
func (h *AuthHandler) Login(c *gin.Context) {
var req LoginReq
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "参数错误"})
return
}
var user model.User
if err := model.DB.Where("username = ?", req.Username).First(&user).Error; err != nil {
c.JSON(http.StatusUnauthorized, gin.H{"code": 401, "message": "用户名或密码错误"})
return
}
if err := bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(req.Password)); err != nil {
c.JSON(http.StatusUnauthorized, gin.H{"code": 401, "message": "用户名或密码错误"})
return
}
if user.Status == "disabled" {
c.JSON(http.StatusForbidden, gin.H{"code": 403, "message": "账号已被禁用"})
return
}
token, err := middleware.GenerateToken(user.ID, user.TenantID, user.Role)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": "生成token失败"})
return
}
c.JSON(http.StatusOK, gin.H{
"code": 0,
"message": "登录成功",
"data": gin.H{
"token": token,
"user_id": user.ID,
"tenant_id": user.TenantID,
"nickname": user.Nickname,
"role": user.Role,
},
})
}
func (h *AuthHandler) Register(c *gin.Context) {
var req RegisterReq
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "参数错误"})
return
}
if req.Role == "" {
req.Role = "agent"
}
hash, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": "加密失败"})
return
}
user := model.User{
Username: req.Username,
PasswordHash: string(hash),
Nickname: req.Nickname,
TenantID: req.TenantID,
Role: req.Role,
Status: "online",
}
if err := model.DB.Create(&user).Error; err != nil {
c.JSON(http.StatusConflict, gin.H{"code": 409, "message": "用户名已存在"})
return
}
c.JSON(http.StatusOK, gin.H{"code": 0, "message": "注册成功"})
}