diff --git a/continew-module-system/src/main/java/top/continew/admin/auth/handler/AccountLoginHandler.java b/continew-module-system/src/main/java/top/continew/admin/auth/handler/AccountLoginHandler.java index 39207899..95d012d9 100644 --- a/continew-module-system/src/main/java/top/continew/admin/auth/handler/AccountLoginHandler.java +++ b/continew-module-system/src/main/java/top/continew/admin/auth/handler/AccountLoginHandler.java @@ -16,6 +16,9 @@ package top.continew.admin.auth.handler; +import cn.hutool.core.date.DateField; +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.extra.servlet.JakartaServletUtil; import jakarta.servlet.http.HttpServletRequest; @@ -108,10 +111,9 @@ public class AccountLoginHandler extends AbstractLoginHandler { // 检测是否已被锁定 String key = CacheConstants.USER_PASSWORD_ERROR_KEY_PREFIX + RedisUtils.formatKey(username, JakartaServletUtil .getClientIP(request)); - int lockMinutes = optionService.getValueByCode2Int(PasswordPolicyEnum.PASSWORD_ERROR_LOCK_MINUTES.name()); Integer currentErrorCount = ObjectUtil.defaultIfNull(RedisUtils.get(key), 0); CheckUtils.throwIf(currentErrorCount >= maxErrorCount, PasswordPolicyEnum.PASSWORD_ERROR_LOCK_MINUTES.getMsg() - .formatted(lockMinutes)); + .formatted(this.getUnlockTime(key))); // 登录成功清除计数 if (!isError) { RedisUtils.delete(key); @@ -119,8 +121,24 @@ public class AccountLoginHandler extends AbstractLoginHandler { } // 登录失败递增计数 currentErrorCount++; + int lockMinutes = optionService.getValueByCode2Int(PasswordPolicyEnum.PASSWORD_ERROR_LOCK_MINUTES.name()); RedisUtils.set(key, currentErrorCount, Duration.ofMinutes(lockMinutes)); CheckUtils.throwIf(currentErrorCount >= maxErrorCount, PasswordPolicyEnum.PASSWORD_ERROR_LOCK_COUNT.getMsg() - .formatted(maxErrorCount, lockMinutes)); + .formatted(maxErrorCount, lockMinutes, this.getUnlockTime(key))); + } + + /** + * 获取解锁时间 + * + * @param key 键 + * @return 解锁时间 + */ + private String getUnlockTime(String key) { + long timeToLive = RedisUtils.getTimeToLive(key); + return timeToLive > 0 + ? DateUtil.date() + .offset(DateField.MILLISECOND, (int)timeToLive) + .toString(DatePattern.CHINESE_DATE_TIME_FORMAT) + : ""; } } \ No newline at end of file diff --git a/continew-module-system/src/main/java/top/continew/admin/system/enums/PasswordPolicyEnum.java b/continew-module-system/src/main/java/top/continew/admin/system/enums/PasswordPolicyEnum.java index 66ea7ad1..ff6d0b66 100644 --- a/continew-module-system/src/main/java/top/continew/admin/system/enums/PasswordPolicyEnum.java +++ b/continew-module-system/src/main/java/top/continew/admin/system/enums/PasswordPolicyEnum.java @@ -47,12 +47,12 @@ public enum PasswordPolicyEnum { /** * 密码错误锁定阈值 */ - PASSWORD_ERROR_LOCK_COUNT("密码错误锁定阈值取值范围为 %d-%d", SysConstants.NO, 10, "密码不正确已达 %d 次,账号锁定 %d 分钟"), + PASSWORD_ERROR_LOCK_COUNT("密码错误锁定阈值取值范围为 %d-%d", SysConstants.NO, 10, "由于您连续 %s 次输入错误密码,账号已被锁定 %s 分钟,预计解锁时间为 %s,请稍后再试"), /** * 账号锁定时长(分钟) */ - PASSWORD_ERROR_LOCK_MINUTES("账号锁定时长取值范围为 %d-%d 分钟", 1, 1440, "账号锁定 %d 分钟,请稍后再试"), + PASSWORD_ERROR_LOCK_MINUTES("账号锁定时长取值范围为 %d-%d 分钟", 1, 1440, "您的账号已被锁定,预计解锁时间为 %s,请稍后再试"), /** * 密码有效期(天)