From 02d75e7e95438f5f8270436aa3792597c8aadc9b Mon Sep 17 00:00:00 2001 From: weicw1996 Date: Tue, 20 Oct 2026 11:54:23 +0800 Subject: [PATCH] =?UTF-8?q?:bug:=20=E4=BF=AE=E5=A4=8D=E9=9D=9E=E8=B6=85?= =?UTF-8?q?=E7=AE=A1=E3=80=8C=E5=85=A8=E9=83=A8=E7=BB=84=E7=BB=87=E3=80=8D?= =?UTF-8?q?=E8=B4=A6=E6=88=B7=E8=B7=A8=E7=BB=84=E7=BB=87=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E4=BB=8D=E6=8A=A5=E6=97=A0=E6=9D=83=E6=93=8D=E4=BD=9C=E5=85=B6?= =?UTF-8?q?=E4=BB=96=E7=BB=84=E7=BB=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 配载提交按子运单组织逐个校验当前会话组织,且列表默认不按组织过滤, 超管能勾到他组织运单、提交却被拦;用户档案的「数据权限范围」此前只被 组织树消费,设成全部组织对业务无效。 统一为 hasAllDeptScope():超管或 data_scope_range=2 免组织校验, 写校验、allDept 门禁、列表组织过滤共用该口径;其余用户仍严格要求等于当前组织。 --- .../support/TransportBusinessSupport.java | 39 +++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/support/TransportBusinessSupport.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/support/TransportBusinessSupport.java index f5b9b143..ad497230 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/support/TransportBusinessSupport.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/support/TransportBusinessSupport.java @@ -28,7 +28,9 @@ import org.springblade.core.secure.utils.AuthUtil; import org.springblade.core.tool.constant.RoleConstant; import org.springblade.core.tool.utils.Func; import org.springblade.system.cache.SysCache; +import org.springblade.system.cache.UserCache; import org.springblade.system.pojo.entity.Dept; +import org.springblade.system.pojo.entity.User; import java.math.BigDecimal; import java.time.LocalDate; @@ -50,6 +52,8 @@ public final class TransportBusinessSupport { public static final String DATA_SOURCE_EXTERNAL = "外部系统"; private static final Pattern PHONE_PATTERN = Pattern.compile("^(1\\d{10}|0\\d{2,3}-?\\d{7,8})$"); + /** 用户档案「数据权限范围」的取值:全部组织,与组织树过滤口径一致 */ + private static final int DATA_SCOPE_ALL = 2; private static final BigDecimal MIN_LONGITUDE = new BigDecimal("-180"); private static final BigDecimal MAX_LONGITUDE = new BigDecimal("180"); private static final BigDecimal MIN_LATITUDE = new BigDecimal("-90"); @@ -76,6 +80,26 @@ public final class TransportBusinessSupport { return false; } + /** + * 是否被授予跨组织数据权限:超级管理员,或用户档案「数据权限范围」为全部组织。 + *

+ * 「数据权限范围」在用户管理里配置,组织树已按它过滤(DeptServiceImpl 的组织树数据权限); + * 运输业务的列表过滤与写入校验必须与组织树同一口径。 + * + * @return true-不限组织 + */ + public static boolean hasAllDeptScope() { + if (isAdministrator()) { + return true; + } + Long userId = AuthUtil.getUserId(); + if (Func.isEmpty(userId) || userId <= 0) { + return false; + } + User user = UserCache.getUser(userId); + return Objects.equals(user == null ? null : user.getDataScopeRange(), DATA_SCOPE_ALL); + } + public static Long currentDeptId(String moduleName) { Long deptId = Func.firstLong(AuthUtil.getDeptId()); if (Func.isEmpty(deptId) || deptId <= 0) { @@ -92,14 +116,22 @@ public final class TransportBusinessSupport { return dept; } + /** + * 校验目标业务数据属于当前用户可操作的组织。 + *

+ * 超管与「数据权限范围=全部组织」的用户不限组织;其余用户仍严格要求与当前会话组织相等。 + */ public static void assertCurrentDept(Long deptId, String moduleName) { + if (hasAllDeptScope()) { + return; + } if (!Objects.equals(deptId, currentDeptId(moduleName))) { throw new ServiceException("无权操作其他组织" + moduleName); } } public static void validateAllDept(Integer allDept, String moduleName) { - if (Objects.equals(allDept, 1) && !isAdministrator()) { + if (Objects.equals(allDept, 1) && !hasAllDeptScope()) { throw new ServiceException("无权查看全部组织" + moduleName); } } @@ -107,7 +139,8 @@ public final class TransportBusinessSupport { /** * 解析列表组织筛选 ID。 *

- * 普通用户 allDept!=1 时强制当前组织;超管默认不按组织过滤,仅在 allDept=1 且传入 deptId 时精确匹配该组织。 + * 普通用户 allDept!=1 时强制当前组织;超管与「全部组织」用户默认不按组织过滤, + * 仅在 allDept=1 且传入 deptId 时精确匹配该组织。 * * @param allDept 是否查看全部组织 * @param deptId 筛选组织 ID @@ -116,7 +149,7 @@ public final class TransportBusinessSupport { */ public static List resolveDeptFilterIds(Integer allDept, Long deptId, String moduleName) { validateAllDept(allDept, moduleName); - if (isAdministrator()) { + if (hasAllDeptScope()) { if (Objects.equals(allDept, 1) && Func.isNotEmpty(deptId) && deptId > 0) { return Collections.singletonList(deptId); }