✨ 新增项目预付核销,并修复平台公司多选、常用线路组织过滤与登录 IP 连坐锁

结算附件支持项目预付核销并扣减可付款金额;加固项目平台公司多选字段扩容脚本;常用线路新增归属组织与列表筛选对齐;登录失败仅按账号锁定,取消 IP 级连坐。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-16 02:01:58 +08:00
parent 0657cfe69f
commit 93a6555293
24 changed files with 817 additions and 29 deletions
@@ -84,16 +84,11 @@ public class BladeAuthorizationHandler extends AbstractAuthorizationHandler {
if (bladeProperties.isProd() && isWeakPassword(request.getPassword())) {
return buildValidationFailure(ExceptionCode.INVALID_USER_PASSWORD);
}
// 判断账号是否锁定
// 仅按账号锁定;不做 IP 锁定,避免同出口/网关 IP 下一人失败牵连全部未登录用户
OAuth2Validation accountValidation = lockHandler.validateAccountLock(request.getTenantId(), request.getUsername());
if (!accountValidation.isSuccess()) {
return accountValidation;
}
// 判断IP是否锁定
OAuth2Validation ipValidation = lockHandler.validateIpLock(request.getTenantId());
if (!ipValidation.isSuccess()) {
return ipValidation;
}
}
return super.preValidation(request);
}
@@ -105,7 +100,13 @@ public class BladeAuthorizationHandler extends AbstractAuthorizationHandler {
*/
@Override
public void preFailure(OAuth2Request request, OAuth2Validation validation) {
// 处理认证失败,增加错误次数
// 已因锁定失败时不再累加失败次数,避免其他账号重试时被误计并连带锁定
if (validation != null && !validation.isSuccess()
&& ExceptionCode.USER_TOO_MANY_FAILS.getCode() == validation.getCode()) {
log.error("用户:{},认证失败,失败原因:{}", request.getUsername(), validation.getMessage());
return;
}
// 处理认证失败,增加错误次数(仅账号维度)
lockHandler.handleAuthFailure(request.getTenantId(), request.getUsername());
log.error("用户:{},认证失败,失败原因:{}", request.getUsername(), validation.getMessage());
@@ -90,7 +90,7 @@ public class BladeLockHandler {
/**
* 处理认证失败
* 同时增加账号和IP错误次数
* 仅增加账号错误次数;不再累计 IP 失败次数,避免共享出口 IP 误伤其他用户。
*
* @param tenantId 租户id
* @param account 账号
@@ -102,7 +102,6 @@ public class BladeLockHandler {
CompletableFuture.runAsync(() -> {
try {
authLockClient.addAccountFailCount(tenantId, account, userId, ip, userAgent);
authLockClient.addIpFailCount(tenantId, ip, userAgent);
} catch (Exception e) {
log.warn("认证失败计数异常: {}", e.getMessage());
}