fix: 系统用户信息修改导致Sex/Password字段为空

This commit is contained in:
TsMask
2024-10-15 11:43:35 +08:00
parent 873dadf014
commit 065895e1d2
7 changed files with 224 additions and 230 deletions

View File

@@ -17,7 +17,7 @@ import (
// 实例化控制层 AccountController 结构体
var NewAccount = &AccountController{
accountService: commonService.NewAccountImpl,
accountService: commonService.NewAccount,
sysLogLoginService: systemService.NewSysLogLoginImpl,
}
@@ -25,8 +25,7 @@ var NewAccount = &AccountController{
//
// PATH /
type AccountController struct {
// 账号身份操作服务
accountService commonService.IAccount
accountService *commonService.Account // 账号身份操作服务
// 系统登录访问
sysLogLoginService systemService.ISysLogLogin
}

View File

@@ -18,7 +18,7 @@ import (
// 实例化控制层 BootloaderController 结构体
var NewBootloader = &BootloaderController{
accountService: commonService.NewAccountImpl,
accountService: commonService.NewAccount,
sysUserService: systemService.NewSysUserImpl,
}
@@ -26,8 +26,7 @@ var NewBootloader = &BootloaderController{
//
// PATH /bootloader
type BootloaderController struct {
// 账号身份操作服务
accountService commonService.IAccount
accountService *commonService.Account // 账号身份操作服务
// 用户信息服务
sysUserService systemService.ISysUser
}

View File

@@ -1,24 +1,194 @@
package service
import "be.ems/src/framework/vo"
import (
"fmt"
"time"
// 账号身份操作服务 服务层接口
type IAccount interface {
// ValidateCaptcha 校验验证码
ValidateCaptcha(code, uuid string) error
"be.ems/src/framework/config"
adminConstants "be.ems/src/framework/constants/admin"
"be.ems/src/framework/constants/cachekey"
"be.ems/src/framework/constants/common"
"be.ems/src/framework/redis"
"be.ems/src/framework/utils/crypto"
"be.ems/src/framework/utils/parse"
"be.ems/src/framework/vo"
"be.ems/src/modules/system/model"
systemService "be.ems/src/modules/system/service"
)
// LoginByUsername 登录生成token
LoginByUsername(username, password string) (vo.LoginUser, error)
// UpdateLoginDateAndIP 更新登录时间和IP
UpdateLoginDateAndIP(loginUser *vo.LoginUser) bool
// ClearLoginRecordCache 清除错误记录次数
ClearLoginRecordCache(username string) bool
// RoleAndMenuPerms 角色和菜单数据权限
RoleAndMenuPerms(userId string, isAdmin bool) ([]string, []string)
// RouteMenus 前端路由所需要的菜单
RouteMenus(userId string, isAdmin bool) []vo.Router
// 实例化服务层 Account 结构体
var NewAccount = &Account{
sysUserService: systemService.NewSysUserImpl,
sysConfigService: systemService.NewSysConfigImpl,
sysRoleService: systemService.NewSysRoleImpl,
sysMenuService: systemService.NewSysMenuImpl,
}
// 账号身份操作服务 服务层处理
type Account struct {
// 用户信息服务
sysUserService systemService.ISysUser
// 参数配置服务
sysConfigService systemService.ISysConfig
// 角色服务
sysRoleService systemService.ISysRole
// 菜单服务
sysMenuService systemService.ISysMenu
}
// ValidateCaptcha 校验验证码
func (s *Account) ValidateCaptcha(code, uuid string) error {
// 验证码检查,从数据库配置获取验证码开关 true开启false关闭
captchaEnabledStr := s.sysConfigService.SelectConfigValueByKey("sys.account.captchaEnabled")
if !parse.Boolean(captchaEnabledStr) {
return nil
}
if code == "" || uuid == "" {
// 验证码信息错误
return fmt.Errorf("captcha.err")
}
verifyKey := cachekey.CAPTCHA_CODE_KEY + uuid
captcha, _ := redis.Get("", verifyKey)
if captcha == "" {
// 验证码已失效
return fmt.Errorf("captcha.errValid")
}
redis.Del("", verifyKey)
if captcha != code {
// 验证码错误
return fmt.Errorf("captcha.err")
}
return nil
}
// LoginByUsername 登录创建用户信息
func (s *Account) LoginByUsername(username, password string) (vo.LoginUser, error) {
loginUser := vo.LoginUser{}
// 检查密码重试次数
retrykey, retryCount, lockTime, err := s.passwordRetryCount(username)
if err != nil {
return loginUser, err
}
// 查询用户登录账号
sysUser := s.sysUserService.SelectUserByUserName(username)
if sysUser.UserName != username {
return loginUser, fmt.Errorf("login.errNameOrPasswd")
}
if sysUser.DelFlag == common.STATUS_YES {
// 对不起,您的账号已被删除
return loginUser, fmt.Errorf("login.errDelFlag")
}
if sysUser.Status == common.STATUS_NO {
return loginUser, fmt.Errorf("login.errStatus")
}
// 检验用户密码
compareBool := crypto.BcryptCompare(password, sysUser.Password)
if !compareBool {
redis.SetByExpire("", retrykey, retryCount+1, lockTime)
// 用户不存在或密码错误
return loginUser, fmt.Errorf("login.errNameOrPasswd")
} else {
// 清除错误记录次数
s.ClearLoginRecordCache(username)
}
// 登录用户信息
loginUser.UserID = sysUser.UserID
loginUser.DeptID = sysUser.DeptID
loginUser.User = sysUser
// 用户权限组标识
isAdmin := config.IsAdmin(sysUser.UserID)
if isAdmin {
loginUser.Permissions = []string{adminConstants.PERMISSION}
} else {
perms := s.sysMenuService.SelectMenuPermsByUserId(sysUser.UserID)
loginUser.Permissions = parse.RemoveDuplicates(perms)
}
return loginUser, nil
}
// UpdateLoginDateAndIP 更新登录时间和IP
func (s *Account) UpdateLoginDateAndIP(loginUser *vo.LoginUser) bool {
sysUser := loginUser.User
userInfo := model.SysUser{
UserID: sysUser.UserID,
LoginIP: sysUser.LoginIP,
LoginDate: sysUser.LoginDate,
UpdateBy: sysUser.UserName,
Sex: sysUser.Sex,
PhoneNumber: sysUser.PhoneNumber,
Email: sysUser.Email,
Remark: sysUser.Remark,
}
rows := s.sysUserService.UpdateUser(userInfo)
return rows > 0
}
// ClearLoginRecordCache 清除错误记录次数
func (s *Account) ClearLoginRecordCache(username string) bool {
cacheKey := cachekey.PWD_ERR_CNT_KEY + username
hasKey, _ := redis.Has("", cacheKey)
if hasKey {
delOk, _ := redis.Del("", cacheKey)
return delOk
}
return false
}
// passwordRetryCount 密码重试次数
func (s *Account) passwordRetryCount(username string) (string, int64, time.Duration, error) {
// 从数据库配置获取登录次数和错误锁定时间
maxRetryCountStr := s.sysConfigService.SelectConfigValueByKey("sys.user.maxRetryCount")
lockTimeStr := s.sysConfigService.SelectConfigValueByKey("sys.user.lockTime")
// 验证登录次数和错误锁定时间
maxRetryCount := parse.Number(maxRetryCountStr)
lockTime := parse.Number(lockTimeStr)
// 验证缓存记录次数
retrykey := cachekey.PWD_ERR_CNT_KEY + username
retryCount, err := redis.Get("", retrykey)
if retryCount == "" || err != nil {
retryCount = "0"
}
// 是否超过错误值
retryCountInt64 := parse.Number(retryCount)
if retryCountInt64 >= maxRetryCount {
// 密码输入错误多次,帐户已被锁定
errorMsg := fmt.Errorf("login.errRetryPasswd")
return retrykey, retryCountInt64, time.Duration(lockTime) * time.Minute, errorMsg
}
return retrykey, retryCountInt64, time.Duration(lockTime) * time.Minute, nil
}
// RoleAndMenuPerms 角色和菜单数据权限
func (s *Account) RoleAndMenuPerms(userId string, isAdmin bool) ([]string, []string) {
if isAdmin {
return []string{adminConstants.ROLE_KEY}, []string{adminConstants.PERMISSION}
} else {
// 角色key
roleGroup := []string{}
roles := s.sysRoleService.SelectRoleListByUserId(userId)
for _, role := range roles {
roleGroup = append(roleGroup, role.RoleKey)
}
// 菜单权限key
perms := s.sysMenuService.SelectMenuPermsByUserId(userId)
return parse.RemoveDuplicates(roleGroup), parse.RemoveDuplicates(perms)
}
}
// RouteMenus 前端路由所需要的菜单
func (s *Account) RouteMenus(userId string, isAdmin bool) []vo.Router {
var buildMenus []vo.Router
if isAdmin {
menus := s.sysMenuService.SelectMenuTreeByUserId("*")
buildMenus = s.sysMenuService.BuildRouteMenus(menus, "")
} else {
menus := s.sysMenuService.SelectMenuTreeByUserId(userId)
buildMenus = s.sysMenuService.BuildRouteMenus(menus, "")
}
return buildMenus
}

View File

@@ -1,190 +0,0 @@
package service
import (
"fmt"
"time"
"be.ems/src/framework/config"
adminConstants "be.ems/src/framework/constants/admin"
"be.ems/src/framework/constants/cachekey"
"be.ems/src/framework/constants/common"
"be.ems/src/framework/redis"
"be.ems/src/framework/utils/crypto"
"be.ems/src/framework/utils/parse"
"be.ems/src/framework/vo"
"be.ems/src/modules/system/model"
systemService "be.ems/src/modules/system/service"
)
// 实例化服务层 AccountImpl 结构体
var NewAccountImpl = &AccountImpl{
sysUserService: systemService.NewSysUserImpl,
sysConfigService: systemService.NewSysConfigImpl,
sysRoleService: systemService.NewSysRoleImpl,
sysMenuService: systemService.NewSysMenuImpl,
}
// 账号身份操作服务 服务层处理
type AccountImpl struct {
// 用户信息服务
sysUserService systemService.ISysUser
// 参数配置服务
sysConfigService systemService.ISysConfig
// 角色服务
sysRoleService systemService.ISysRole
// 菜单服务
sysMenuService systemService.ISysMenu
}
// ValidateCaptcha 校验验证码
func (s *AccountImpl) ValidateCaptcha(code, uuid string) error {
// 验证码检查,从数据库配置获取验证码开关 true开启false关闭
captchaEnabledStr := s.sysConfigService.SelectConfigValueByKey("sys.account.captchaEnabled")
if !parse.Boolean(captchaEnabledStr) {
return nil
}
if code == "" || uuid == "" {
// 验证码信息错误
return fmt.Errorf("captcha.err")
}
verifyKey := cachekey.CAPTCHA_CODE_KEY + uuid
captcha, _ := redis.Get("", verifyKey)
if captcha == "" {
// 验证码已失效
return fmt.Errorf("captcha.errValid")
}
redis.Del("", verifyKey)
if captcha != code {
// 验证码错误
return fmt.Errorf("captcha.err")
}
return nil
}
// LoginByUsername 登录创建用户信息
func (s *AccountImpl) LoginByUsername(username, password string) (vo.LoginUser, error) {
loginUser := vo.LoginUser{}
// 检查密码重试次数
retrykey, retryCount, lockTime, err := s.passwordRetryCount(username)
if err != nil {
return loginUser, err
}
// 查询用户登录账号
sysUser := s.sysUserService.SelectUserByUserName(username)
if sysUser.UserName != username {
return loginUser, fmt.Errorf("login.errNameOrPasswd")
}
if sysUser.DelFlag == common.STATUS_YES {
// 对不起,您的账号已被删除
return loginUser, fmt.Errorf("login.errDelFlag")
}
if sysUser.Status == common.STATUS_NO {
return loginUser, fmt.Errorf("login.errStatus")
}
// 检验用户密码
compareBool := crypto.BcryptCompare(password, sysUser.Password)
if !compareBool {
redis.SetByExpire("", retrykey, retryCount+1, lockTime)
// 用户不存在或密码错误
return loginUser, fmt.Errorf("login.errNameOrPasswd")
} else {
// 清除错误记录次数
s.ClearLoginRecordCache(username)
}
// 登录用户信息
loginUser.UserID = sysUser.UserID
loginUser.DeptID = sysUser.DeptID
loginUser.User = sysUser
// 用户权限组标识
isAdmin := config.IsAdmin(sysUser.UserID)
if isAdmin {
loginUser.Permissions = []string{adminConstants.PERMISSION}
} else {
perms := s.sysMenuService.SelectMenuPermsByUserId(sysUser.UserID)
loginUser.Permissions = parse.RemoveDuplicates(perms)
}
return loginUser, nil
}
// UpdateLoginDateAndIP 更新登录时间和IP
func (s *AccountImpl) UpdateLoginDateAndIP(loginUser *vo.LoginUser) bool {
sysUser := loginUser.User
userInfo := model.SysUser{
UserID: sysUser.UserID,
LoginIP: sysUser.LoginIP,
LoginDate: sysUser.LoginDate,
UpdateBy: sysUser.UserName,
}
rows := s.sysUserService.UpdateUser(userInfo)
return rows > 0
}
// ClearLoginRecordCache 清除错误记录次数
func (s *AccountImpl) ClearLoginRecordCache(username string) bool {
cacheKey := cachekey.PWD_ERR_CNT_KEY + username
hasKey, _ := redis.Has("", cacheKey)
if hasKey {
delOk, _ := redis.Del("", cacheKey)
return delOk
}
return false
}
// passwordRetryCount 密码重试次数
func (s *AccountImpl) passwordRetryCount(username string) (string, int64, time.Duration, error) {
// 从数据库配置获取登录次数和错误锁定时间
maxRetryCountStr := s.sysConfigService.SelectConfigValueByKey("sys.user.maxRetryCount")
lockTimeStr := s.sysConfigService.SelectConfigValueByKey("sys.user.lockTime")
// 验证登录次数和错误锁定时间
maxRetryCount := parse.Number(maxRetryCountStr)
lockTime := parse.Number(lockTimeStr)
// 验证缓存记录次数
retrykey := cachekey.PWD_ERR_CNT_KEY + username
retryCount, err := redis.Get("", retrykey)
if retryCount == "" || err != nil {
retryCount = "0"
}
// 是否超过错误值
retryCountInt64 := parse.Number(retryCount)
if retryCountInt64 >= maxRetryCount {
// 密码输入错误多次,帐户已被锁定
errorMsg := fmt.Errorf("login.errRetryPasswd")
return retrykey, retryCountInt64, time.Duration(lockTime) * time.Minute, errorMsg
}
return retrykey, retryCountInt64, time.Duration(lockTime) * time.Minute, nil
}
// RoleAndMenuPerms 角色和菜单数据权限
func (s *AccountImpl) RoleAndMenuPerms(userId string, isAdmin bool) ([]string, []string) {
if isAdmin {
return []string{adminConstants.ROLE_KEY}, []string{adminConstants.PERMISSION}
} else {
// 角色key
roleGroup := []string{}
roles := s.sysRoleService.SelectRoleListByUserId(userId)
for _, role := range roles {
roleGroup = append(roleGroup, role.RoleKey)
}
// 菜单权限key
perms := s.sysMenuService.SelectMenuPermsByUserId(userId)
return parse.RemoveDuplicates(roleGroup), parse.RemoveDuplicates(perms)
}
}
// RouteMenus 前端路由所需要的菜单
func (s *AccountImpl) RouteMenus(userId string, isAdmin bool) []vo.Router {
var buildMenus []vo.Router
if isAdmin {
menus := s.sysMenuService.SelectMenuTreeByUserId("*")
buildMenus = s.sysMenuService.BuildRouteMenus(menus, "")
} else {
menus := s.sysMenuService.SelectMenuTreeByUserId(userId)
buildMenus = s.sysMenuService.BuildRouteMenus(menus, "")
}
return buildMenus
}

View File

@@ -22,7 +22,7 @@ import (
// 实例化控制层 SysLogLoginController 结构体
var NewSysLogLogin = &SysLogLoginController{
sysLogLoginService: service.NewSysLogLoginImpl,
accountService: commonService.NewAccountImpl,
accountService: commonService.NewAccount,
}
// 系统登录日志信息
@@ -31,8 +31,7 @@ var NewSysLogLogin = &SysLogLoginController{
type SysLogLoginController struct {
// 系统登录日志服务
sysLogLoginService service.ISysLogLogin
// 账号身份操作服务
accountService commonService.IAccount
accountService *commonService.Account // 账号身份操作服务
}
// 系统登录日志列表

View File

@@ -157,6 +157,7 @@ func (s *SysProfileController) UpdateProfile(c *gin.Context) {
PhoneNumber: body.PhoneNumber,
Email: body.Email,
Sex: body.Sex,
Remark: loginUser.User.Remark,
}
rows := s.sysUserService.UpdateUser(sysUser)
if rows > 0 {
@@ -229,9 +230,13 @@ func (s *SysProfileController) UpdatePwd(c *gin.Context) {
// 修改新密码
sysUser := model.SysUser{
UserID: userId,
UpdateBy: userName,
Password: body.NewPassword,
UserID: userId,
UpdateBy: userName,
Password: body.NewPassword,
Sex: user.Sex,
PhoneNumber: user.PhoneNumber,
Email: user.Email,
Remark: user.Remark,
}
rows := s.sysUserService.UpdateUser(sysUser)
if rows > 0 {
@@ -268,9 +273,13 @@ func (s *SysProfileController) Avatar(c *gin.Context) {
// 更新头像地址
sysUser := model.SysUser{
UserID: loginUser.UserID,
UpdateBy: loginUser.User.UserName,
Avatar: filePath,
UserID: loginUser.UserID,
UpdateBy: loginUser.User.UserName,
Avatar: filePath,
Sex: loginUser.User.Sex,
PhoneNumber: loginUser.User.PhoneNumber,
Email: loginUser.User.Email,
Remark: loginUser.User.Remark,
}
rows := s.sysUserService.UpdateUser(sysUser)
if rows > 0 {

View File

@@ -411,9 +411,13 @@ func (s *SysUserController) ResetPwd(c *gin.Context) {
userName := ctx.LoginUserToUserName(c)
info := model.SysUser{
UserID: body.UserID,
Password: body.Password,
UpdateBy: userName,
UserID: body.UserID,
Password: body.Password,
UpdateBy: userName,
Sex: user.Sex,
PhoneNumber: user.PhoneNumber,
Email: user.Email,
Remark: user.Remark,
}
rows := s.sysUserService.UpdateUser(info)
if rows > 0 {
@@ -454,9 +458,13 @@ func (s *SysUserController) Status(c *gin.Context) {
userName := ctx.LoginUserToUserName(c)
info := model.SysUser{
UserID: body.UserID,
Status: body.Status,
UpdateBy: userName,
UserID: body.UserID,
Status: body.Status,
UpdateBy: userName,
Sex: user.Sex,
PhoneNumber: user.PhoneNumber,
Email: user.Email,
Remark: user.Remark,
}
rows := s.sysUserService.UpdateUser(info)
if rows > 0 {