feat: add account reset

This commit is contained in:
engigu
2026-03-12 10:40:25 +08:00
parent a0aa9102ca
commit 22018856cc
6 changed files with 266 additions and 67 deletions
+6 -4
View File
@@ -168,13 +168,15 @@ func (ac *AuthController) Logout(c *gin.Context) {
}
func (ac *AuthController) GetCurrentUser(c *gin.Context) {
username, exists := c.Get("username")
if !exists {
utils.Unauthorized(c, "未登录")
userID := c.GetString("userID")
var user models.User
if err := database.DB.Where("id = ?", userID).First(&user).Error; err != nil {
utils.Unauthorized(c, "会话无效")
return
}
utils.Success(c, gin.H{
"username": username,
"username": user.Username,
"role": user.Role,
})
}
+47 -8
View File
@@ -42,17 +42,19 @@ func NewSettingsController(userService *services.UserService, loginLogService *s
}
}
// ChangePassword 修改密码
// ChangePassword 修改密码及账号信息
func (sc *SettingsController) ChangePassword(c *gin.Context) {
// 演示模式下禁止修改密码
// 演示模式下禁止修改
if constant.DemoMode {
utils.BadRequest(c, "演示模式下不能修改密码")
utils.BadRequest(c, "演示模式下不能修改账号或密码")
return
}
var req struct {
OldUsername string `json:"old_username"`
Username string `json:"username"`
OldPassword string `json:"old_password" binding:"required"`
NewPassword string `json:"new_password" binding:"required,min=6"`
NewPassword string `json:"new_password"`
}
if err := c.ShouldBindJSON(&req); err != nil {
@@ -67,13 +69,46 @@ func (sc *SettingsController) ChangePassword(c *gin.Context) {
return
}
if !sc.userService.ValidatePassword(user, req.OldPassword) {
// 统一校验原账密
if req.OldUsername != "" && req.OldUsername != user.Username {
utils.BadRequest(c, "原账号不正确")
return
}
if !sc.userService.AuthenticateUser(user.Username, req.OldPassword) {
utils.BadRequest(c, "原密码错误")
return
}
if err := sc.userService.UpdatePassword(user.ID, req.NewPassword); err != nil {
utils.ServerError(c, "修改密码失败")
var updated bool
var logoutRequired bool
// 1. 处理用户名修改
if req.Username != "" && req.Username != user.Username {
if err := sc.userService.UpdateAccount(user.ID, req.Username); err != nil {
utils.BadRequest(c, err.Error())
return
}
updated = true
logoutRequired = true
}
// 2. 处理密码修改
if req.NewPassword != "" {
if len(req.NewPassword) < 6 {
utils.BadRequest(c, "新密码至少6位")
return
}
if err := sc.userService.UpdatePassword(user.ID, req.NewPassword); err != nil {
utils.ServerError(c, "修改密码失败")
return
}
updated = true
logoutRequired = true
}
if !updated {
utils.SuccessMsg(c, "未检测到变更内容")
return
}
@@ -84,7 +119,11 @@ func (sc *SettingsController) ChangePassword(c *gin.Context) {
},
})
utils.SuccessMsg(c, "密码修改成功")
msg := "保存成功"
if logoutRequired {
msg += ",请重新登录"
}
utils.SuccessMsg(c, msg)
}
// CleanLogs 清理日志 - 已移除,改为任务级别的日志清理配置
+27
View File
@@ -3,6 +3,7 @@ package services
import (
"crypto/sha256"
"encoding/hex"
"fmt"
"strings"
"golang.org/x/crypto/bcrypt"
@@ -110,3 +111,29 @@ func (us *UserService) UpdatePassword(userID string, newPassword string) error {
func (us *UserService) InvalidateUserTokens(userID string) error {
return database.DB.Model(&models.User{}).Where("id = ?", userID).Update("token_version", gorm.Expr("token_version + 1")).Error
}
func (us *UserService) UpdateAccount(userID string, newUsername string) error {
var user models.User
if err := database.DB.Where("id = ?", userID).First(&user).Error; err != nil {
return err
}
updates := make(map[string]interface{})
if newUsername != "" && newUsername != user.Username {
// 检查用户名是否已存在
var count int64
database.DB.Model(&models.User{}).Where("username = ? AND id <> ?", newUsername, userID).Count(&count)
if count > 0 {
return fmt.Errorf("用户名 [%s] 已被占用", newUsername)
}
updates["username"] = newUsername
// 用户名变更,必须失效所有 Token,因为 Token 中包含 Username 且中间件会校验
updates["token_version"] = gorm.Expr("token_version + 1")
}
if len(updates) == 0 {
return nil
}
return database.DB.Model(&user).Updates(updates).Error
}