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" ) // 实例化服务层 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 }