act测试

This commit is contained in:
张超
2025-06-23 17:04:31 +08:00
parent 8241b8c61f
commit ab66b9e39d
4 changed files with 98 additions and 136 deletions

View File

@@ -4,11 +4,6 @@ database:
DSN: "blog:qI7=bL4@iJ@tcp(47.93.160.42:3630)/blog?charset=utf8mb4&parseTime=True&loc=Local" DSN: "blog:qI7=bL4@iJ@tcp(47.93.160.42:3630)/blog?charset=utf8mb4&parseTime=True&loc=Local"
# Prefix: gin_ # This line is commented out in the original .ini file # Prefix: gin_ # This line is commented out in the original .ini file
jwt:
SecretKey: "\x13\xbf\xd2 1\xce\x8b\xc1\t\xc1=\xec\x07\x93\xd4\x9e\xbco\xb0Z"
security:
JWTSecret: "jwt_secret"
project: project:
StaticUrlMapPath: StaticUrlMapPath:
- assets/static/: static/ - assets/static/: static/

View File

@@ -1,81 +0,0 @@
/*
@Time : 2020/6/28 22:37
@Author : xuyiqing
@File : response.py
*/
package controllers
import (
"github.com/gin-gonic/gin"
)
const (
Success = 200
BadRequest = 400
Unauthenticated = 401
NoPermisson = 403
NotFund = 404
ServerError = 500
)
type Response struct {
Ctx *gin.Context
}
// 定义基础返回结构体
type JsonResponse struct {
Code int `json:"code"`
Msg string `json:"msg"`
Data interface{} `json:"data,omitempty"`
Pager interface{} `json:"pager,omitempty"`
}
func (resp *Response) Response(data interface{}, pager interface{}) {
resp.Ctx.JSON(Success, JsonResponse{
Code: Success,
Msg: "返回成功",
Data: data,
Pager: pager,
})
}
// 400错误请求
func (resp *Response) BadRequest(msg string) {
resp.Ctx.AbortWithStatusJSON(Success, JsonResponse{
Code: BadRequest,
Msg: msg,
})
}
// 401未登录验证
func (resp *Response) Unauthenticated(msg string) {
resp.Ctx.AbortWithStatusJSON(Success, JsonResponse{
Code: Unauthenticated,
Msg: msg,
})
}
// 403没有权限
func (resp *Response) NoPermisson(msg string) {
resp.Ctx.AbortWithStatusJSON(Success, JsonResponse{
Code: NoPermisson,
Msg: msg,
})
}
// 404资源不存在
func (resp *Response) NotFund(msg string) {
resp.Ctx.AbortWithStatusJSON(Success, JsonResponse{
Code: NotFund,
Msg: msg,
})
}
// 500服务器出错
func (resp *Response) ServerError(msg string) {
resp.Ctx.AbortWithStatusJSON(200, JsonResponse{
Code: ServerError,
Msg: msg,
})
}

View File

@@ -21,21 +21,29 @@ import (
// 登录 // 登录
func UsersLoginHandler(ctx *gin.Context) { func UsersLoginHandler(ctx *gin.Context) {
response := Response{Ctx: ctx}
var loginUser serializers.Login var loginUser serializers.Login
if err := ctx.ShouldBind(&loginUser); err != nil { if err := ctx.ShouldBind(&loginUser); err != nil {
response.BadRequest("请求参数错误: " + err.Error()) ctx.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"msg": "请求参数错误: " + err.Error(),
})
return return
} }
// 验证用户逻辑不变 // 验证用户逻辑不变
user := &models.Account{Username: loginUser.Username} user := &models.Account{Username: loginUser.Username}
if err := models.DB.Where("username = ?", user.Username).First(user).Error; err != nil { if err := models.DB.Where("username = ?", user.Username).First(user).Error; err != nil {
response.BadRequest("用户不存在") ctx.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"msg": "用户不存在",
})
return return
} }
if !user.IsPasswordEqual(loginUser.Password) { if !user.IsPasswordEqual(loginUser.Password) {
response.BadRequest("密码错误") ctx.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"msg": "密码错误",
})
return return
} }
@@ -52,21 +60,26 @@ func UsersLoginHandler(ctx *gin.Context) {
// API请求场景返回登录成功无需返回token // API请求场景返回登录成功无需返回token
data, _ := util.PrecisionLost(user) data, _ := util.PrecisionLost(user)
response.Response(data, nil) ctx.JSON(http.StatusOK, gin.H{"code": http.StatusOK, "msg": "登录成功", "data": data})
} }
// 注册 // 注册
func UsersRegisterHandler(ctx *gin.Context) { func UsersRegisterHandler(ctx *gin.Context) {
response := Response{Ctx: ctx}
var registerUser serializers.Login var registerUser serializers.Login
if err := ctx.ShouldBind(&registerUser); err != nil { if err := ctx.ShouldBind(&registerUser); err != nil {
response.BadRequest("请求参数错误: " + err.Error()) // 替换 panic 为错误响应 ctx.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"msg": "请求参数错误: " + err.Error(),
}) // 替换 panic 为错误响应
return return
} }
user := registerUser.GetUser() user := registerUser.GetUser()
status := user.CheckDuplicateUsername() status := user.CheckDuplicateUsername()
if status == false { if status == false {
response.BadRequest("用户名已存在") ctx.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"msg": "用户名已存在",
})
return return
} }
if err := user.SetPassword(user.Password); err != nil { if err := user.SetPassword(user.Password); err != nil {
@@ -74,84 +87,124 @@ func UsersRegisterHandler(ctx *gin.Context) {
} }
user.IsActive = true user.IsActive = true
models.DB.Create(&user) models.DB.Create(&user)
response.Response(nil, nil) ctx.JSON(http.StatusOK, gin.H{"code": http.StatusOK, "msg": "注册成功"})
} }
// 修改用户信息 // 修改用户信息
func UsersSetInfoHandler(ctx *gin.Context) { func UsersSetInfoHandler(ctx *gin.Context) {
response := Response{Ctx: ctx}
jsonData, err := util.GetBodyData(ctx) jsonData, err := util.GetBodyData(ctx)
if err != nil { if err != nil {
response.BadRequest("参数解析失败") ctx.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"msg": "参数解析失败",
})
return return
} }
fmt.Println(jsonData) fmt.Println(jsonData)
if jsonData == nil { if jsonData == nil {
response.BadRequest("获取不到参数") ctx.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"msg": "获取不到参数",
})
return return
} }
// 从上下文中获取用户(假设 JWT 中间件已将用户存入 "user" 键) // 从上下文中获取用户(假设 JWT 中间件已将用户存入 "user" 键)
user, exists := ctx.Get("user") user, exists := ctx.Get("user")
if !exists { if !exists {
response.Unauthenticated("未登录") ctx.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
"code": http.StatusUnauthorized,
"msg": "未登录",
})
return return
} }
currentUser, ok := user.(*models.Account) // 明确类型为 models.Account currentUser, ok := user.(*models.Account) // 明确类型为 models.Account
if !ok { if !ok {
response.ServerError("用户类型错误") ctx.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
"code": http.StatusInternalServerError,
"msg": "用户类型错误",
})
return return
} }
models.DB.Model(currentUser).Updates(jsonData) models.DB.Model(currentUser).Updates(jsonData)
response.Response(currentUser, nil) ctx.JSON(http.StatusOK, gin.H{
"code": http.StatusOK,
"msg": "更新成功",
})
} }
// 修改密码 // 修改密码
func UsersSetPwdHandler(ctx *gin.Context) { func UsersSetPwdHandler(ctx *gin.Context) {
response := Response{Ctx: ctx}
// 从上下文中获取用户(替换原 jwt.AssertUser 调用) // 从上下文中获取用户(替换原 jwt.AssertUser 调用)
ctxuser, exists := ctx.Get("user") ctxuser, exists := ctx.Get("user")
if !exists { if !exists {
response.Unauthenticated("未验证登录") ctx.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
"code": http.StatusUnauthorized,
"msg": "未验证登录",
})
return return
} }
currentUser, ok := ctxuser.(*models.Account) currentUser, ok := ctxuser.(*models.Account)
if !ok { if !ok {
response.ServerError("用户类型错误") ctx.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
"code": http.StatusInternalServerError,
"msg": "用户类型错误",
})
return return
} }
if currentUser == nil { if currentUser == nil {
response.Unauthenticated("未验证登录") ctx.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
"code": http.StatusUnauthorized,
"msg": "未验证登录",
})
return return
} }
var user serializers.Account var user serializers.Account
if err := ctx.ShouldBindJSON(&user); err != nil { if err := ctx.ShouldBindJSON(&user); err != nil {
response.BadRequest(err.Error()) ctx.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"msg": "参数解析失败",
})
return return
} }
if user.Username != currentUser.Username { if user.Username != currentUser.Username {
response.BadRequest("当前登录用户用户名与输入用户名不符") ctx.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"msg": "当前登录用户用户名与输入用户名不符",
})
return return
} }
if user.OldPwd == user.NewPwd { if user.OldPwd == user.NewPwd {
response.BadRequest("两次输入的密码相同") ctx.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"msg": "两次输入的密码相同",
})
return return
} }
if isPwd := currentUser.IsPasswordEqual(user.OldPwd); !isPwd { if isPwd := currentUser.IsPasswordEqual(user.OldPwd); !isPwd {
response.BadRequest("原密码错误") ctx.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"msg": "原密码错误",
})
return return
} }
if err := currentUser.SetPassword(user.NewPwd); err != nil { if err := currentUser.SetPassword(user.NewPwd); err != nil {
response.BadRequest(err.Error()) ctx.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"msg": err.Error(),
})
return return
} }
models.DB.Save(&currentUser) models.DB.Save(&currentUser)
response.Response(nil, nil) ctx.JSON(http.StatusOK, gin.H{
"code": http.StatusOK,
"msg": "密码修改成功",
})
} }
func UsersListHandler(ctx *gin.Context) { func UsersListHandler(ctx *gin.Context) {
response := Response{Ctx: ctx}
var pager serializers.Pager var pager serializers.Pager
pager.InitPager(ctx) pager.InitPager(ctx)
var users []models.Account var users []models.Account
@@ -165,7 +218,12 @@ func UsersListHandler(ctx *gin.Context) {
// 由于 pager.OffSet 是 int 类型,直接使用该变量,无需调用函数 // 由于 pager.OffSet 是 int 类型,直接使用该变量,无需调用函数
models.DB.Offset(pager.OffSet).Limit(pager.PageSize).Find(&users) models.DB.Offset(pager.OffSet).Limit(pager.PageSize).Find(&users)
pager.GetPager() pager.GetPager()
response.Response(users, pager) ctx.JSON(http.StatusOK, gin.H{
"Code": http.StatusOK,
"Msg": "返回成功",
"Data": users,
"Pager": pager,
})
} }
// ShowLoginPage 渲染登录页面 // ShowLoginPage 渲染登录页面
@@ -219,14 +277,16 @@ func ShowRegisterPage(c *gin.Context) {
// 退出登录 // 退出登录
func UsersLogoutHandler(ctx *gin.Context) { func UsersLogoutHandler(ctx *gin.Context) {
response := Response{Ctx: ctx}
session := sessions.Default(ctx) // 获取当前请求的Session session := sessions.Default(ctx) // 获取当前请求的Session
// 清除Session中的用户ID // 清除Session中的用户ID
session.Delete("user_id") session.Delete("user_id")
// 保存Session修改必须调用 // 保存Session修改必须调用
if err := session.Save(); err != nil { if err := session.Save(); err != nil {
response.ServerError("退出失败: " + err.Error()) ctx.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
"code": http.StatusInternalServerError,
"msg": "退出失败: " + err.Error(),
})
return return
} }

12
main.go
View File

@@ -91,18 +91,6 @@ func main() {
router.Run(":" + conf.Server.Port) router.Run(":" + conf.Server.Port)
} }
// 自定义模板渲染器
// func createTemplateRenderer(currentTheme string) gin.HTMLRender {
// return gin.HTMLTemplates{
// Root: "web/templates",
// Extension: ".html",
// FuncMap: template.FuncMap{
// "safe": func(s string) template.HTML { return template.HTML(s) },
// },
// Directory: "web/themes/" + currentTheme,
// }
// }
// 数据库中间件 // 数据库中间件
func databaseMiddleware(db *gorm.DB) gin.HandlerFunc { func databaseMiddleware(db *gorm.DB) gin.HandlerFunc {
return func(c *gin.Context) { return func(c *gin.Context) {