diff --git a/src/modules/common/controller/account.go b/src/modules/common/controller/account.go index abfba11c..f41d38d6 100644 --- a/src/modules/common/controller/account.go +++ b/src/modules/common/controller/account.go @@ -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 } diff --git a/src/modules/common/controller/bootloader.go b/src/modules/common/controller/bootloader.go index daa12daa..0c9f5205 100644 --- a/src/modules/common/controller/bootloader.go +++ b/src/modules/common/controller/bootloader.go @@ -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 } diff --git a/src/modules/common/service/account.go b/src/modules/common/service/account.go index 48443e3b..dce06a02 100644 --- a/src/modules/common/service/account.go +++ b/src/modules/common/service/account.go @@ -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 } diff --git a/src/modules/common/service/account.impl.go b/src/modules/common/service/account.impl.go deleted file mode 100644 index b91c8f14..00000000 --- a/src/modules/common/service/account.impl.go +++ /dev/null @@ -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 -} diff --git a/src/modules/system/controller/sys_log_login.go b/src/modules/system/controller/sys_log_login.go index 59e9a73d..0444d327 100644 --- a/src/modules/system/controller/sys_log_login.go +++ b/src/modules/system/controller/sys_log_login.go @@ -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 // 账号身份操作服务 } // 系统登录日志列表 diff --git a/src/modules/system/controller/sys_profile.go b/src/modules/system/controller/sys_profile.go index 55095bcf..34626a2c 100644 --- a/src/modules/system/controller/sys_profile.go +++ b/src/modules/system/controller/sys_profile.go @@ -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 { diff --git a/src/modules/system/controller/sys_user.go b/src/modules/system/controller/sys_user.go index c6c521b4..34f6834a 100644 --- a/src/modules/system/controller/sys_user.go +++ b/src/modules/system/controller/sys_user.go @@ -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 {