diff --git a/mjkf-xinke-plugin/mjkf-xinke-plugin-auth/src/main/java/mjkf/xinke/auth/modular/login/service/impl/AuthServiceImpl.java b/mjkf-xinke-plugin/mjkf-xinke-plugin-auth/src/main/java/mjkf/xinke/auth/modular/login/service/impl/AuthServiceImpl.java index b6c5aaa..77af7a7 100644 --- a/mjkf-xinke-plugin/mjkf-xinke-plugin-auth/src/main/java/mjkf/xinke/auth/modular/login/service/impl/AuthServiceImpl.java +++ b/mjkf-xinke-plugin/mjkf-xinke-plugin-auth/src/main/java/mjkf/xinke/auth/modular/login/service/impl/AuthServiceImpl.java @@ -42,7 +42,6 @@ import java.util.stream.Collectors; /** * 登录Service接口实现类 * - * * @date 2021/12/23 21:52 */ @Service @@ -52,6 +51,8 @@ public class AuthServiceImpl implements AuthService { private static final String AUTH_VALID_CODE_CACHE_KEY = "auth-validCode:"; + private static final String LOGIN_ERROR_TIMES_KEY_PREFIX = "login-error-times:"; + @Resource(name = "loginUserApi") private SaBaseLoginUserApi loginUserApi; @@ -120,7 +121,7 @@ public class AuthServiceImpl implements AuthService { /** * 校验验证码方法 * - * + * * @date 2022/8/25 15:26 **/ private void validValidCode(String phoneOrEmail, String validCode, String validCodeReqNo) { @@ -150,7 +151,7 @@ public class AuthServiceImpl implements AuthService { /** * 校验手机号与验证码等参数 * - * + * * @date 2022/8/25 14:29 **/ private void validPhoneValidCodeParam(String phoneOrEmail, String validCode, String validCodeReqNo, String type) { @@ -180,6 +181,8 @@ public class AuthServiceImpl implements AuthService { @Override public String doLogin(AuthAccountPasswordLoginParam authAccountPasswordLoginParam, String type) { + // 判断账号是否被封禁 + isDisableTime(authAccountPasswordLoginParam.getAccount()); // 获取账号 String account = authAccountPasswordLoginParam.getAccount(); // 获取密码 @@ -227,8 +230,12 @@ public class AuthServiceImpl implements AuthService { throw new CommonException(AuthExceptionEnum.ACCOUNT_ERROR.getValue()); } if (!saBaseLoginUser.getPassword().equals(passwordHash)) { + // 记录登录次数 和 过期时间 + saveLoginTimes(account); throw new CommonException(AuthExceptionEnum.PWD_ERROR.getValue()); } + // 删除redis 中的key + clearLoginErrorTimes(account); // 执行B端登录 return execLoginB(saBaseLoginUser, device); } else { @@ -276,10 +283,57 @@ public class AuthServiceImpl implements AuthService { } } + /** + * 是否封禁状态 + * 如果被封禁了,执行以下逻辑,返回前端还需等待的时间 + */ + private void isDisableTime(String userAccount) { + // disableTime = -2表示未被封禁 + long disableTime = StpUtil.getDisableTime(userAccount); + if (disableTime > 0) { + if (disableTime > 60) { + throw new CommonException(userAccount + "账号已被封禁, 请再"+ disableTime/60+ "分钟后重新尝试登录!!"); + } + throw new CommonException(userAccount + "账号已被封禁, 请再"+ disableTime+ "秒后重新尝试登录!!"); + } + } + + // redis中保存登录错误次数 + private void saveLoginTimes(String userAccount){ + String loginErrorKey = LOGIN_ERROR_TIMES_KEY_PREFIX + userAccount; + Integer number = (Integer) commonCacheOperator.get(loginErrorKey); + if (number == null) { + // 如果redis中没有保存,代表失败第一次 + number = 2; + commonCacheOperator.put(loginErrorKey, number,5 * 60); + return; + } + if (number < 5) { + number++; + commonCacheOperator.put(loginErrorKey, number,5 * 60); + return; + } + // 第五次封禁账号,第六次进入isDisableTime方法,返回用户还需等待时间 + StpUtil.disable(userAccount, 5 * 60); + // 删除redis 中的key + clearLoginErrorTimes(userAccount); + + } + + /** + * 登录成功、清空登录次数 + * @param userAccount 账号 + */ + private void clearLoginErrorTimes(String userAccount) { + String loginErrorKey = LOGIN_ERROR_TIMES_KEY_PREFIX + userAccount; + // 删除redis中的key + commonCacheOperator.remove(loginErrorKey); + } + /** * 执行B端登录 * - * + * * @date 2022/8/25 14:36 **/ private String execLoginB(SaBaseLoginUser saBaseLoginUser, String device) { @@ -318,7 +372,7 @@ public class AuthServiceImpl implements AuthService { /** * 执行C端登录 * - * + * * @date 2022/8/25 14:37 **/ private String execLoginC(SaBaseClientLoginUser saBaseClientLoginUser, String device) { @@ -357,7 +411,7 @@ public class AuthServiceImpl implements AuthService { /** * 获取B端登录用户信息 * - * + * * @date 2021/10/12 15:59 **/ @Override @@ -372,7 +426,7 @@ public class AuthServiceImpl implements AuthService { /** * 获取C端登录用户信息 * - * + * * @date 2021/10/12 15:59 **/ @Override diff --git a/mjkf-xinke-plugin/mjkf-xinke-plugin-auth/src/main/java/mjkf/xinke/auth/modular/monitor/service/impl/AuthSessionServiceImpl.java b/mjkf-xinke-plugin/mjkf-xinke-plugin-auth/src/main/java/mjkf/xinke/auth/modular/monitor/service/impl/AuthSessionServiceImpl.java index 7c76d43..94ca389 100644 --- a/mjkf-xinke-plugin/mjkf-xinke-plugin-auth/src/main/java/mjkf/xinke/auth/modular/monitor/service/impl/AuthSessionServiceImpl.java +++ b/mjkf-xinke-plugin/mjkf-xinke-plugin-auth/src/main/java/mjkf/xinke/auth/modular/monitor/service/impl/AuthSessionServiceImpl.java @@ -96,10 +96,10 @@ public class AuthSessionServiceImpl implements AuthSessionService { Page defaultPage = CommonPageRequest.defaultPage(); long current = defaultPage.getCurrent(); int total = StpUtil.searchSessionId("", -1, Convert.toInt(defaultPage.getSize()), true).size(); - if(ObjectUtil.isNotEmpty(total)) { + if (ObjectUtil.isNotEmpty(total)) { defaultPage = new Page<>(current, defaultPage.getSize(), total); String keyword = ""; - if(ObjectUtil.isNotEmpty(authSessionPageParam.getUserId())) { + if (ObjectUtil.isNotEmpty(authSessionPageParam.getUserId())) { keyword = authSessionPageParam.getUserId(); } List userIdList = StpUtil.searchSessionId(keyword, @@ -113,31 +113,37 @@ public class AuthSessionServiceImpl implements AuthSessionService { authSessionPageResult.setSessionId(saSession.getId()); authSessionPageResult.setSessionCreateTime(DateTime.of(saSession.getCreateTime())); long sessionTimeOut = saSession.getTimeout(); - if(sessionTimeOut == -1) { + if (sessionTimeOut == -1) { authSessionPageResult.setSessionTimeout("永久"); } else { authSessionPageResult.setSessionTimeout(CommonTimeFormatUtil.formatSeconds(saSession.getTimeout())); } - List tokenInfoList = saSession.getTokenSignList().stream().map(tokenSign -> { - AuthSessionPageResult.TokenSignInfo tokenSignInfo = new AuthSessionPageResult.TokenSignInfo(); - tokenSignInfo.setTokenValue(tokenSign.getValue()); - tokenSignInfo.setTokenDevice(tokenSign.getDevice()); - long tokenTimeout = SaManager.getSaTokenDao().getTimeout(StpUtil.stpLogic.splicingKeyTokenValue(tokenSign.getValue())); - long tokenTimeoutConfig = StpUtil.stpLogic.getConfig().getTimeout(); - if(tokenTimeout == -1) { - tokenSignInfo.setTokenTimeout("永久"); - tokenSignInfo.setTokenTimeoutPercent(100d); - } else { - tokenSignInfo.setTokenTimeout(CommonTimeFormatUtil.formatSeconds(SaManager.getSaTokenDao() - .getTimeout(StpUtil.stpLogic.splicingKeyTokenValue(tokenSign.getValue())))); - if(tokenTimeoutConfig == -1) { - tokenSignInfo.setTokenTimeoutPercent(0d); - } else { - tokenSignInfo.setTokenTimeoutPercent(NumberUtil.div(tokenTimeout, tokenTimeoutConfig)); - } - } - return tokenSignInfo; - }).collect(Collectors.toList()); + List tokenInfoList = saSession.getTokenSignList().stream() + .filter(tokenSign -> { + long tokenTimeout = SaManager.getSaTokenDao().getTimeout(StpUtil.stpLogic.splicingKeyTokenValue(tokenSign.getValue())); + return tokenTimeout != -2; // 过滤掉tokenTimeout为-2的元素 + }) + .map(tokenSign -> { + AuthSessionPageResult.TokenSignInfo tokenSignInfo = new AuthSessionPageResult.TokenSignInfo(); + tokenSignInfo.setTokenValue(tokenSign.getValue()); + tokenSignInfo.setTokenDevice(tokenSign.getDevice()); + long tokenTimeout = SaManager.getSaTokenDao().getTimeout(StpUtil.stpLogic.splicingKeyTokenValue(tokenSign.getValue())); + long tokenTimeoutConfig = StpUtil.stpLogic.getConfig().getTimeout(); + if (tokenTimeout == -1) { + tokenSignInfo.setTokenTimeout("永久"); + tokenSignInfo.setTokenTimeoutPercent(100d); + } else { + tokenSignInfo.setTokenTimeout(CommonTimeFormatUtil.formatSeconds(SaManager.getSaTokenDao() + .getTimeout(StpUtil.stpLogic.splicingKeyTokenValue(tokenSign.getValue())))); + if (tokenTimeoutConfig == -1) { + tokenSignInfo.setTokenTimeoutPercent(0d); + } else { + tokenSignInfo.setTokenTimeoutPercent(NumberUtil.div(tokenTimeout, tokenTimeoutConfig)); + } + } + return tokenSignInfo; + }) + .collect(Collectors.toList()); authSessionPageResult.setTokenCount(tokenInfoList.size()); authSessionPageResult.setTokenSignList(tokenInfoList); return authSessionPageResult; @@ -153,10 +159,10 @@ public class AuthSessionServiceImpl implements AuthSessionService { Page defaultPage = CommonPageRequest.defaultPage(); long current = defaultPage.getCurrent(); int total = StpClientUtil.searchSessionId("", -1, Convert.toInt(defaultPage.getSize()), true).size(); - if(ObjectUtil.isNotEmpty(total)) { + if (ObjectUtil.isNotEmpty(total)) { defaultPage = new Page<>(current, defaultPage.getSize(), total); String keyword = ""; - if(ObjectUtil.isNotEmpty(authSessionPageParam.getUserId())) { + if (ObjectUtil.isNotEmpty(authSessionPageParam.getUserId())) { keyword = authSessionPageParam.getUserId(); } List userIdList = StpClientUtil.searchSessionId(keyword, @@ -170,24 +176,27 @@ public class AuthSessionServiceImpl implements AuthSessionService { authSessionPageResult.setSessionId(saSession.getId()); authSessionPageResult.setSessionCreateTime(DateTime.of(saSession.getCreateTime())); long sessionTimeOut = saSession.getTimeout(); - if(sessionTimeOut == -1) { + if (sessionTimeOut == -1) { authSessionPageResult.setSessionTimeout("永久"); } else { authSessionPageResult.setSessionTimeout(CommonTimeFormatUtil.formatSeconds(saSession.getTimeout())); } - List tokenInfoList = saSession.getTokenSignList().stream().map(tokenSign -> { + List tokenInfoList = saSession.getTokenSignList().stream().filter(tokenSign -> { + long tokenTimeout = SaManager.getSaTokenDao().getTimeout(StpUtil.stpLogic.splicingKeyTokenValue(tokenSign.getValue())); + return tokenTimeout != -2; // 过滤掉tokenTimeout为-2的元素 + }).map(tokenSign -> { AuthSessionPageResult.TokenSignInfo tokenSignInfo = new AuthSessionPageResult.TokenSignInfo(); tokenSignInfo.setTokenValue(tokenSign.getValue()); tokenSignInfo.setTokenDevice(tokenSign.getDevice()); long tokenTimeout = SaManager.getSaTokenDao().getTimeout(StpClientUtil.stpLogic.splicingKeyTokenValue(tokenSign.getValue())); long tokenTimeoutConfig = StpClientUtil.stpLogic.getConfig().getTimeout(); - if(tokenTimeout == -1) { + if (tokenTimeout == -1) { tokenSignInfo.setTokenTimeout("永久"); tokenSignInfo.setTokenTimeoutPercent(100d); } else { tokenSignInfo.setTokenTimeout(CommonTimeFormatUtil.formatSeconds(SaManager.getSaTokenDao() .getTimeout(StpClientUtil.stpLogic.splicingKeyTokenValue(tokenSign.getValue())))); - if(tokenTimeoutConfig == -1) { + if (tokenTimeoutConfig == -1) { tokenSignInfo.setTokenTimeoutPercent(0d); } else { tokenSignInfo.setTokenTimeoutPercent(NumberUtil.div(tokenTimeout, tokenTimeoutConfig)); diff --git a/mjkf-xinke-plugin/mjkf-xinke-plugin-biz/src/main/java/mjkf/xinke/biz/modular/dict/service/impl/BizDictServiceImpl.java b/mjkf-xinke-plugin/mjkf-xinke-plugin-biz/src/main/java/mjkf/xinke/biz/modular/dict/service/impl/BizDictServiceImpl.java index 5e042f7..ec47a54 100644 --- a/mjkf-xinke-plugin/mjkf-xinke-plugin-biz/src/main/java/mjkf/xinke/biz/modular/dict/service/impl/BizDictServiceImpl.java +++ b/mjkf-xinke-plugin/mjkf-xinke-plugin-biz/src/main/java/mjkf/xinke/biz/modular/dict/service/impl/BizDictServiceImpl.java @@ -52,8 +52,8 @@ public class BizDictServiceImpl extends ServiceImpl impl queryWrapper.lambda().select(BizDict::getId, BizDict::getParentId, BizDict::getCategory, BizDict::getDictLabel, BizDict::getDictValue, BizDict::getSortCode).eq(BizDict::getCategory, BizDictCategoryEnum.BIZ.getValue()); if (ObjectUtil.isNotEmpty(bizDictPageParam.getParentId())) { - queryWrapper.lambda().eq(BizDict::getParentId, bizDictPageParam.getParentId()) - .or().eq(BizDict::getId, bizDictPageParam.getParentId()); + queryWrapper.lambda().and(q -> q.eq(BizDict::getParentId, bizDictPageParam.getParentId()) + .or().eq(BizDict::getId, bizDictPageParam.getParentId())); } if (ObjectUtil.isNotEmpty(bizDictPageParam.getSearchKey())) { queryWrapper.lambda().like(BizDict::getDictLabel, bizDictPageParam.getSearchKey()); diff --git a/mjkf-xinke-plugin/mjkf-xinke-plugin-biz/src/main/java/mjkf/xinke/biz/modular/user/service/impl/BizUserServiceImpl.java b/mjkf-xinke-plugin/mjkf-xinke-plugin-biz/src/main/java/mjkf/xinke/biz/modular/user/service/impl/BizUserServiceImpl.java index 7655083..5088085 100644 --- a/mjkf-xinke-plugin/mjkf-xinke-plugin-biz/src/main/java/mjkf/xinke/biz/modular/user/service/impl/BizUserServiceImpl.java +++ b/mjkf-xinke-plugin/mjkf-xinke-plugin-biz/src/main/java/mjkf/xinke/biz/modular/user/service/impl/BizUserServiceImpl.java @@ -120,8 +120,8 @@ public class BizUserServiceImpl extends ServiceImpl impl public Page page(BizUserPageParam bizUserPageParam) { QueryWrapper queryWrapper = new QueryWrapper<>(); if (ObjectUtil.isNotEmpty(bizUserPageParam.getSearchKey())) { - queryWrapper.lambda().like(BizUser::getAccount, bizUserPageParam.getSearchKey()).or() - .like(BizUser::getName, bizUserPageParam.getSearchKey()); + queryWrapper.lambda().and(q -> q.like(BizUser::getAccount, bizUserPageParam.getSearchKey()) + .or().like(BizUser::getName, bizUserPageParam.getSearchKey())); } if (ObjectUtil.isNotEmpty(bizUserPageParam.getOrgId())) { queryWrapper.lambda().eq(BizUser::getOrgId, bizUserPageParam.getOrgId()); @@ -412,9 +412,9 @@ public class BizUserServiceImpl extends ServiceImpl impl queryWrapper.lambda().in(BizUser::getId, StrUtil.split(bizUserExportParam.getUserIds(), StrUtil.COMMA)); } else { if (ObjectUtil.isNotEmpty(bizUserExportParam.getSearchKey())) { - queryWrapper.lambda().like(BizUser::getAccount, bizUserExportParam.getSearchKey()) + queryWrapper.lambda().and(q -> q.like(BizUser::getAccount, bizUserExportParam.getSearchKey()) .or().like(BizUser::getName, bizUserExportParam.getSearchKey()) - .or().like(BizUser::getPhone, bizUserExportParam.getSearchKey()); + .or().like(BizUser::getPhone, bizUserExportParam.getSearchKey())); } if (ObjectUtil.isNotEmpty(bizUserExportParam.getUserStatus())) { queryWrapper.lambda().eq(BizUser::getUserStatus, bizUserExportParam.getUserStatus()); diff --git a/mjkf-xinke-plugin/mjkf-xinke-plugin-dev/src/main/java/mjkf/xinke/dev/modular/dict/service/impl/DevDictServiceImpl.java b/mjkf-xinke-plugin/mjkf-xinke-plugin-dev/src/main/java/mjkf/xinke/dev/modular/dict/service/impl/DevDictServiceImpl.java index 0d846cb..4aba85b 100644 --- a/mjkf-xinke-plugin/mjkf-xinke-plugin-dev/src/main/java/mjkf/xinke/dev/modular/dict/service/impl/DevDictServiceImpl.java +++ b/mjkf-xinke-plugin/mjkf-xinke-plugin-dev/src/main/java/mjkf/xinke/dev/modular/dict/service/impl/DevDictServiceImpl.java @@ -52,8 +52,8 @@ public class DevDictServiceImpl extends ServiceImpl impl queryWrapper.lambda().select(DevDict::getId, DevDict::getParentId, DevDict::getCategory, DevDict::getDictLabel, DevDict::getDictValue, DevDict::getSortCode); if (ObjectUtil.isNotEmpty(devDictPageParam.getParentId())) { - queryWrapper.lambda().eq(DevDict::getParentId, devDictPageParam.getParentId()) - .or().eq(DevDict::getId, devDictPageParam.getParentId()); + queryWrapper.lambda().and(q -> q.eq(DevDict::getParentId, devDictPageParam.getParentId()) + .or().eq(DevDict::getId, devDictPageParam.getParentId())); } if (ObjectUtil.isNotEmpty(devDictPageParam.getCategory())) { queryWrapper.lambda().eq(DevDict::getCategory, devDictPageParam.getCategory()); diff --git a/mjkf-xinke-plugin/mjkf-xinke-plugin-dev/src/main/java/mjkf/xinke/dev/modular/sms/util/DevSmsTencentUtil.java b/mjkf-xinke-plugin/mjkf-xinke-plugin-dev/src/main/java/mjkf/xinke/dev/modular/sms/util/DevSmsTencentUtil.java index 8fbc63e..6524d04 100644 --- a/mjkf-xinke-plugin/mjkf-xinke-plugin-dev/src/main/java/mjkf/xinke/dev/modular/sms/util/DevSmsTencentUtil.java +++ b/mjkf-xinke-plugin/mjkf-xinke-plugin-dev/src/main/java/mjkf/xinke/dev/modular/sms/util/DevSmsTencentUtil.java @@ -35,7 +35,7 @@ public class DevSmsTencentUtil { /** * 初始化操作的客户端 * - * + * @author xuyuxiang * @date 2022/1/5 23:24 */ private static void initClient() { @@ -77,7 +77,7 @@ public class DevSmsTencentUtil { * @param templateCode 短信服务控制台配置且审核通过的模板编码 * @param templateParam 短信模板变量对应的顺序。支持传入多个参数,逗号拼接,示例:"张三,15038****76,进行中" * @return 发送的结果信息集合 com.tencentcloudapi.sms.v20210111.models.SendStatus - * + * @author xuyuxiang * @date 2022/2/24 13:42 **/ public static String sendSms(String sdkAppId, String phoneNumbers, String signName, String templateCode, String templateParam) { @@ -86,8 +86,8 @@ public class DevSmsTencentUtil { if(ObjectUtil.isEmpty(sdkAppId)) { // sdkAppId为空,则获取默认sdkAppId DevConfigApi devConfigApi = SpringUtil.getBean(DevConfigApi.class); - signName = devConfigApi.getValueByKey(SNOWY_SMS_TENCENT_DEFAULT_SDK_APP_ID_KEY); - if(ObjectUtil.isEmpty(signName)) { + sdkAppId = devConfigApi.getValueByKey(SNOWY_SMS_TENCENT_DEFAULT_SDK_APP_ID_KEY); + if(ObjectUtil.isEmpty(sdkAppId)) { throw new CommonException("腾讯云短信操作客户端未正确配置:sdkAppId为空"); } } @@ -117,4 +117,4 @@ public class DevSmsTencentUtil { throw new CommonException(e.getMessage()); } } -} +} \ No newline at end of file diff --git a/mjkf-xinke-plugin/mjkf-xinke-plugin-gen/src/main/resources/mobile/form.vue.btl b/mjkf-xinke-plugin/mjkf-xinke-plugin-gen/src/main/resources/mobile/form.vue.btl index 96de9e1..7dce148 100644 --- a/mjkf-xinke-plugin/mjkf-xinke-plugin-gen/src/main/resources/mobile/form.vue.btl +++ b/mjkf-xinke-plugin/mjkf-xinke-plugin-gen/src/main/resources/mobile/form.vue.btl @@ -1,6 +1,6 @@