Files
go_blog/controllers/admin/users.go
2025-07-12 15:56:36 +08:00

252 lines
6.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
@Time : 2020/6/28 21:40
@Author : xuyiqing
@File : users.py
*/
package admin
import (
"go_blog/models"
"go_blog/pkg/util"
"go_blog/utils"
"html/template"
"net/http"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
)
// 登录
func UsersLoginHandler(ctx *gin.Context) {
var loginUser models.Account
if err := ctx.ShouldBind(&loginUser); err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"msg": "请求参数错误: " + err.Error(),
})
return
}
user := &models.Account{Username: loginUser.Username}
if err := models.DB.Where("username = ?", user.Username).First(user).Error; err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"msg": "用户不存在",
})
return
}
if !user.IsPasswordEqual(loginUser.Password) {
ctx.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"msg": "密码错误",
})
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)
ctx.JSON(http.StatusOK, gin.H{"code": http.StatusOK, "msg": "登录成功", "data": data})
}
// 注册
func UsersRegisterHandler(ctx *gin.Context) {
var registerUser models.Account
if err := ctx.ShouldBind(&registerUser); err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"msg": "请求参数错误: " + err.Error(),
}) // 替换 panic 为错误响应
return
}
status := registerUser.CheckDuplicateUsername()
if status == false {
ctx.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"msg": "用户名已存在",
})
return
}
if err := registerUser.SetPassword(registerUser.Password); err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"msg": "密码设置错误: " + err.Error(),
})
return
}
registerUser.IsActive = true
models.DB.Create(&registerUser)
ctx.JSON(http.StatusOK, gin.H{"code": http.StatusOK, "msg": "注册成功"})
}
// 修改密码
func UsersSetPwdHandler(ctx *gin.Context) {
// 从上下文中获取用户(替换原 jwt.AssertUser 调用)
ctxuser, exists := ctx.Get("user")
if !exists {
ctx.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
"code": http.StatusUnauthorized,
"msg": "未验证登录",
})
return
}
currentUser, ok := ctxuser.(*models.Account)
if !ok {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
"code": http.StatusInternalServerError,
"msg": "用户类型错误",
})
return
}
if currentUser == nil {
ctx.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
"code": http.StatusUnauthorized,
"msg": "未验证登录",
})
return
}
var user models.Account
if err := ctx.ShouldBindJSON(&user); err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"msg": "参数解析失败",
})
return
}
if user.Username != currentUser.Username {
ctx.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"msg": "当前登录用户用户名与输入用户名不符",
})
return
}
if ctx.GetString("OldPwd") == ctx.GetString("NewPwd") {
ctx.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"msg": "两次输入的密码相同",
})
return
}
if isPwd := currentUser.IsPasswordEqual(user.Password); !isPwd {
ctx.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"msg": "原密码错误",
})
return
}
if err := currentUser.SetPassword(ctx.GetString("NewPwd")); err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"msg": err.Error(),
})
return
}
models.DB.Save(&currentUser)
ctx.JSON(http.StatusOK, gin.H{
"code": http.StatusOK,
"msg": "密码修改成功",
})
}
func UsersListHandler(ctx *gin.Context) {
var pager utils.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()
ctx.JSON(http.StatusOK, gin.H{
"Code": http.StatusOK,
"Msg": "返回成功",
"Data": users,
"Pager": 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.(*utils.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) {
session := sessions.Default(ctx) // 获取当前请求的Session
// 清除Session中的用户ID
session.Delete("user_id")
// 保存Session修改必须调用
if err := session.Save(); err != nil {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
"code": http.StatusInternalServerError,
"msg": "退出失败: " + err.Error(),
})
return
}
// 重定向到登录页
ctx.Redirect(http.StatusFound, "/admin/login")
}