/* @Time : 2020/6/28 21:40 @Author : xuyiqing @File : users.py */ package controllers import ( "fmt" "go_blog/models" "go_blog/pkg/util" "go_blog/serializers" "go_blog/themes" "html/template" "net/http" "github.com/gin-contrib/sessions" "github.com/gin-gonic/gin" ) // 登录 func UsersLoginHandler(ctx *gin.Context) { response := Response{Ctx: ctx} var loginUser serializers.Login if err := ctx.ShouldBind(&loginUser); err != nil { response.BadRequest("请求参数错误: " + err.Error()) return } // 验证用户逻辑不变 user := &models.Account{Username: loginUser.Username} if err := models.DB.Where("username = ?", user.Username).First(user).Error; err != nil { response.BadRequest("用户不存在") return } if !user.IsPasswordEqual(loginUser.Password) { response.BadRequest("密码错误") return } // 改为设置Session(替代JWT) session := sessions.Default(ctx) session.Set("user_id", user.ID) // 存储用户ID到Session session.Save() // 表单提交场景:直接跳转(无需设置JWT Cookie) if ctx.ContentType() == "application/x-www-form-urlencoded" { ctx.Redirect(http.StatusFound, "/admin/index") return } // API请求场景:返回登录成功(无需返回token) data, _ := util.PrecisionLost(user) response.Response(data, nil) } // 注册 func UsersRegisterHandler(ctx *gin.Context) { response := Response{Ctx: ctx} var registerUser serializers.Login if err := ctx.ShouldBind(®isterUser); err != nil { response.BadRequest("请求参数错误: " + err.Error()) // 替换 panic 为错误响应 return } user := registerUser.GetUser() status := user.CheckDuplicateUsername() if status == false { response.BadRequest("用户名已存在") return } if err := user.SetPassword(user.Password); err != nil { panic(err) } user.IsActive = true models.DB.Create(&user) response.Response(nil, nil) } // 修改用户信息 func UsersSetInfoHandler(ctx *gin.Context) { response := Response{Ctx: ctx} jsonData, err := util.GetBodyData(ctx) if err != nil { response.BadRequest("参数解析失败") return } fmt.Println(jsonData) if jsonData == nil { response.BadRequest("获取不到参数") return } // 从上下文中获取用户(假设 JWT 中间件已将用户存入 "user" 键) user, exists := ctx.Get("user") if !exists { response.Unauthenticated("未登录") return } currentUser, ok := user.(*models.Account) // 明确类型为 models.Account if !ok { response.ServerError("用户类型错误") return } models.DB.Model(currentUser).Updates(jsonData) response.Response(currentUser, nil) } // 修改密码 func UsersSetPwdHandler(ctx *gin.Context) { response := Response{Ctx: ctx} // 从上下文中获取用户(替换原 jwt.AssertUser 调用) ctxuser, exists := ctx.Get("user") if !exists { response.Unauthenticated("未验证登录") return } currentUser, ok := ctxuser.(*models.Account) if !ok { response.ServerError("用户类型错误") return } if currentUser == nil { response.Unauthenticated("未验证登录") return } var user serializers.Account if err := ctx.ShouldBindJSON(&user); err != nil { response.BadRequest(err.Error()) return } if user.Username != currentUser.Username { response.BadRequest("当前登录用户用户名与输入用户名不符") return } if user.OldPwd == user.NewPwd { response.BadRequest("两次输入的密码相同") return } if isPwd := currentUser.IsPasswordEqual(user.OldPwd); !isPwd { response.BadRequest("原密码错误") return } if err := currentUser.SetPassword(user.NewPwd); err != nil { response.BadRequest(err.Error()) return } models.DB.Save(¤tUser) response.Response(nil, nil) } func UsersListHandler(ctx *gin.Context) { response := Response{Ctx: ctx} var pager serializers.Pager pager.InitPager(ctx) var users []models.Account // 先查询总记录数 var totalCount int64 models.DB.Model(&models.Account{}).Count(&totalCount) pager.Total = int(totalCount) // 正确设置总数 // 分页查询 // 由于 pager.OffSet 是 int 类型,直接使用该变量,无需调用函数 models.DB.Offset(pager.OffSet).Limit(pager.PageSize).Find(&users) pager.GetPager() response.Response(users, pager) } // ShowLoginPage 渲染登录页面 func ShowLoginPage(c *gin.Context) { // 直接加载 web/admin 目录下的 login.tmpl 模板(需确保文件存在) tpl, err := template.ParseFiles("web/admin/login.tmpl") if err != nil { c.String(http.StatusInternalServerError, "加载模板失败: "+err.Error()) return } c.Status(http.StatusOK) c.Header("Content-Type", "text/html; charset=utf-8") err = tpl.Execute(c.Writer, gin.H{ "Title": "用户登录", }) if err != nil { c.String(http.StatusInternalServerError, "渲染模板错误: "+err.Error()) } } // ShowRegisterPage 渲染注册页面 func ShowRegisterPage(c *gin.Context) { tm, exists := c.Get("ThemeManager") if !exists { c.String(http.StatusInternalServerError, "Theme manager not found") return } themeManager, ok := tm.(*themes.ThemeManager) if !ok { c.String(http.StatusInternalServerError, "Invalid theme manager type") return } // 假设主题中存在 register.tmpl 模板(或使用后台固定模板) tpl := themeManager.GetTemplate("register") if tpl == nil { c.String(http.StatusInternalServerError, "Template 'register' not found in current theme. Make sure 'register.html' or 'register.tmpl' exists.") return } c.Status(http.StatusOK) c.Header("Content-Type", "text/html; charset=utf-8") err := tpl.Execute(c.Writer, gin.H{ "Title": "用户注册", }) if err != nil { c.String(http.StatusInternalServerError, "Error rendering template: "+err.Error()) } } // 退出登录 func UsersLogoutHandler(ctx *gin.Context) { response := Response{Ctx: ctx} session := sessions.Default(ctx) // 获取当前请求的Session // 清除Session中的用户ID session.Delete("user_id") // 保存Session修改(必须调用) if err := session.Save(); err != nil { response.ServerError("退出失败: " + err.Error()) return } // 重定向到登录页 ctx.Redirect(http.StatusFound, "/admin/login") }