From 8178c8e737eb0e743f41c430e1c70272dc592d0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BA=84=E9=94=90=E6=B3=A2?= <10549902+zhuangruibo@user.noreply.gitee.com> Date: Tue, 9 Jun 2026 09:06:21 +0800 Subject: [PATCH] =?UTF-8?q?=E7=9B=91=E7=9D=A3=E7=AB=AF-=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E7=BB=9F=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/core/service/UserService.java | 25 +++++++ .../EfcodeDataFilterInterceptor.java | 3 + .../common/util/DataFilterUtil.java | 10 ++- .../system/service/ISysRoleService.java | 43 +++++++++++ .../service/impl/SysRoleServiceImpl.java | 31 +++++++- .../service/impl/SysUserServiceImpl.java | 73 +++++++++++++++++++ .../src/views/system/dict/data.vue | 2 +- .../src/views/system/oss/index.vue | 2 +- .../src/views/system/role/authUser.vue | 2 +- .../views/system/role/index-dept-separate.vue | 2 +- .../src/views/system/role/index.vue | 2 +- .../src/views/system/user/authRole.vue | 2 +- .../src/views/system/user/index.vue | 2 +- 13 files changed, 185 insertions(+), 14 deletions(-) diff --git a/zdxt-common/zdxt-common-core/src/main/java/org/dromara/common/core/service/UserService.java b/zdxt-common/zdxt-common-core/src/main/java/org/dromara/common/core/service/UserService.java index c61b1ed9..3eb0523a 100644 --- a/zdxt-common/zdxt-common-core/src/main/java/org/dromara/common/core/service/UserService.java +++ b/zdxt-common/zdxt-common-core/src/main/java/org/dromara/common/core/service/UserService.java @@ -4,6 +4,7 @@ import org.dromara.common.core.domain.dto.UserDTO; import java.util.List; import java.util.Map; +import java.util.Set; /** * 通用 用户服务 @@ -100,4 +101,28 @@ public interface UserService { */ Map selectUserNicksByIds(List userIds); + /** + * 通过角色Key查询用户ID列表 + * + * @param roleKey 角色权限字符串 + * @return 用户ID列表 + */ + List selectUserIdsByRoleKey(String roleKey); + + /** + * 通过角色Key查询用户列表 + * + * @param roleKey 角色权限字符串 + * @return 用户列表 + */ + List selectUsersByRoleKey(String roleKey); + + /** + * 通过用户ID查询用户所有的角色Key + * + * @param userId 用户ID + * @return 角色Key集合 + */ + Set selectRoleKeysByUserId(Long userId); + } diff --git a/zdxt-modules/zdxt-enforcement-code-common/src/main/java/com/zdxt/enforcementcode/common/annotation/EfcodeDataFilterInterceptor.java b/zdxt-modules/zdxt-enforcement-code-common/src/main/java/com/zdxt/enforcementcode/common/annotation/EfcodeDataFilterInterceptor.java index b87f5ae8..7efdd1ee 100644 --- a/zdxt-modules/zdxt-enforcement-code-common/src/main/java/com/zdxt/enforcementcode/common/annotation/EfcodeDataFilterInterceptor.java +++ b/zdxt-modules/zdxt-enforcement-code-common/src/main/java/com/zdxt/enforcementcode/common/annotation/EfcodeDataFilterInterceptor.java @@ -40,6 +40,9 @@ public class EfcodeDataFilterInterceptor implements InnerInterceptor { return; } + // 立即清除 ThreadLocal,防止 buildFilterSql 内部查询再次触发本拦截器导致无限递归 + EfcodeDataFilterHelper.removeFilter(); + // 构建过滤 SQL 片段 String filterSql = buildFilterSql(filter); if (filterSql == null) { diff --git a/zdxt-modules/zdxt-enforcement-code-common/src/main/java/com/zdxt/enforcementcode/common/util/DataFilterUtil.java b/zdxt-modules/zdxt-enforcement-code-common/src/main/java/com/zdxt/enforcementcode/common/util/DataFilterUtil.java index d343b8f6..5d0618d3 100644 --- a/zdxt-modules/zdxt-enforcement-code-common/src/main/java/com/zdxt/enforcementcode/common/util/DataFilterUtil.java +++ b/zdxt-modules/zdxt-enforcement-code-common/src/main/java/com/zdxt/enforcementcode/common/util/DataFilterUtil.java @@ -264,13 +264,17 @@ public class DataFilterUtil { // ViewFilterDataRole → 构建子查询条件 if (needFilter()) { - String userDeptId = LoginHelper.getDeptId(); - if (StrUtil.isBlank(userDeptId)) { + //String userDeptId = LoginHelper.getDeptId(); + String userBureauDeptId = getUserBureauDeptId(LoginHelper.getUserId()); + //String userBureauDeptId = "20210922211918204-7059-2B73EBA45"; + + + if (StrUtil.isBlank(userBureauDeptId)) { return "1 = 0"; } String columnRef = buildColumnRef(tableAlias, column); - String escapedDeptId = escapeSql(userDeptId); + String escapedDeptId = escapeSql(userBureauDeptId); // 使用子查询:通过 userDeptId 找到 virId,再通过 FIND_IN_SET 查子孙节点的 sys_dept_id StringBuilder sb = new StringBuilder(); diff --git a/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/service/ISysRoleService.java b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/service/ISysRoleService.java index abbfc798..153ea22e 100644 --- a/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/service/ISysRoleService.java +++ b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/service/ISysRoleService.java @@ -16,6 +16,49 @@ import java.util.Set; */ public interface ISysRoleService { + // ======================== 角色 role_key 常量 ======================== + + /** 查看全部业务数据角色 */ + String ROLE_KEY_VIEW_ALL_DATA = "ViewAllDataRole"; + + /** 查看本级和下级业务数据角色 */ + String ROLE_KEY_VIEW_FILTER_DATA = "ViewFilterDataRole"; + + /** 查看福田区全部数据角色 */ + String ROLE_KEY_VIEW_EF_DATA_FU_TIAN_QU = "ViewEFDataRole_Area_FuTianQu"; + + /** 查看罗湖区全部数据角色 */ + String ROLE_KEY_VIEW_EF_DATA_LUO_HU_QU = "ViewEFDataRole_Area_LuoHuQu"; + + /** 查看盐田区全部数据角色 */ + String ROLE_KEY_VIEW_EF_DATA_YAN_TIAN_QU = "ViewEFDataRole_Area_YanTianQu"; + + /** 查看南山区全部数据角色 */ + String ROLE_KEY_VIEW_EF_DATA_NAN_SHAN_QU = "ViewEFDataRole_Area_NanShanQu"; + + /** 查看宝安区全部数据角色 */ + String ROLE_KEY_VIEW_EF_DATA_BAO_AN_QU = "ViewEFDataRole_Area_BaoAnQu"; + + /** 查看龙岗区全部数据角色 */ + String ROLE_KEY_VIEW_EF_DATA_LONG_GANG_QU = "ViewEFDataRole_Area_LongGangQu"; + + /** 查看龙华区全部数据角色 */ + String ROLE_KEY_VIEW_EF_DATA_LONG_HUA_QU = "ViewEFDataRole_Area_LongHuaQu"; + + /** 查看坪山区全部数据角色 */ + String ROLE_KEY_VIEW_EF_DATA_PING_SHAN_QU = "ViewEFDataRole_Area_PingsHanQu"; + + /** 查看光明区全部数据角色 */ + String ROLE_KEY_VIEW_EF_DATA_GUANG_MING_QU = "ViewEFDataRole_Area_GuangMingQu"; + + /** 查看大鹏新区全部数据角色 */ + String ROLE_KEY_VIEW_EF_DATA_DA_PENG_XIN_QU = "ViewEFDataRole_Area_DapengXinQu"; + + /** 查看深汕特别合作区全部数据角色 */ + String ROLE_KEY_VIEW_EF_DATA_SHEN_SHAN_TE_BIE_HE_ZUO_QU = "ViewEFDataRole_Area_ShenShanTeBieHeZuoQu"; + + // ======================== 业务方法 ======================== + /** * 分页查询角色列表 * diff --git a/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java index 8a8d1dc2..0d5d0d9e 100644 --- a/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java +++ b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java @@ -500,7 +500,18 @@ public class SysRoleServiceImpl implements ISysRoleService, RoleService { if (ids.contains(LoginHelper.getUserId())) { throw new ServiceException("不允许修改当前用户角色!"); } - List list = StreamUtils.toList(ids, userId -> { + // 排除已经关联该角色的用户,避免主键冲突 + List existUserIds = userRoleMapper.selectList( + new LambdaQueryWrapper() + .eq(SysUserRole::getRoleId, roleId) + .in(SysUserRole::getUserId, ids) + .select(SysUserRole::getUserId) + ).stream().map(SysUserRole::getUserId).toList(); + List newUserIds = ids.stream().filter(id -> !existUserIds.contains(id)).toList(); + if (CollUtil.isEmpty(newUserIds)) { + return 0; + } + List list = StreamUtils.toList(newUserIds, userId -> { SysUserRole ur = new SysUserRole(); ur.setUserId(userId); ur.setRoleId(roleId); @@ -510,7 +521,7 @@ public class SysRoleServiceImpl implements ISysRoleService, RoleService { rows = userRoleMapper.insertBatch(list) ? list.size() : 0; } if (rows > 0) { - cleanOnlineUser(ids); + cleanOnlineUser(newUserIds); } return rows; } @@ -544,7 +555,13 @@ public class SysRoleServiceImpl implements ISysRoleService, RoleService { if (StpUtil.stpLogic.getTokenActiveTimeoutByToken(token) < -1) { return; } - LoginUser loginUser = LoginHelper.getLoginUser(token); + LoginUser loginUser; + try { + loginUser = LoginHelper.getLoginUser(token); + } catch (Exception e) { + // DevTools热重启可能导致类加载器不一致,跳过无法反序列化的token + return; + } if (ObjectUtil.isNull(loginUser) || CollUtil.isEmpty(loginUser.getRoles())) { return; } @@ -580,7 +597,13 @@ public class SysRoleServiceImpl implements ISysRoleService, RoleService { if (StpUtil.stpLogic.getTokenActiveTimeoutByToken(token) < -1) { return; } - LoginUser loginUser = LoginHelper.getLoginUser(token); + LoginUser loginUser; + try { + loginUser = LoginHelper.getLoginUser(token); + } catch (Exception e) { + // DevTools热重启可能导致类加载器不一致,跳过无法反序列化的token + return; + } if (ObjectUtil.isNull(loginUser)) { return; } diff --git a/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java index 03f246e3..277d309c 100644 --- a/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java +++ b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java @@ -23,6 +23,7 @@ import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.system.domain.SysUser; +import org.dromara.system.domain.SysRole; import org.dromara.system.domain.SysUserPost; import org.dromara.system.domain.SysUserRole; import org.dromara.system.domain.bo.QuerySysUserBo; @@ -894,4 +895,76 @@ public class SysUserServiceImpl implements ISysUserService, UserService { } } + + /** + * 通过角色Key查询用户ID列表 + * + * @param roleKey 角色权限字符串 + * @return 用户ID列表 + */ + @Override + public List selectUserIdsByRoleKey(String roleKey) { + if (StringUtils.isBlank(roleKey)) { + return List.of(); + } + // 通过 roleKey 查询角色ID列表 + List roles = roleMapper.selectList( + new LambdaQueryWrapper() + .select(SysRole::getRoleId) + .eq(SysRole::getRoleKey, roleKey) + .eq(SysRole::getStatus, SystemConstants.NORMAL)); + if (CollUtil.isEmpty(roles)) { + return List.of(); + } + List roleIds = StreamUtils.toList(roles, SysRole::getRoleId); + return this.selectUserIdsByRoleIds(roleIds); + } + + /** + * 通过角色Key查询用户列表 + * + * @param roleKey 角色权限字符串 + * @return 用户列表 + */ + @Override + public List selectUsersByRoleKey(String roleKey) { + if (StringUtils.isBlank(roleKey)) { + return List.of(); + } + // 通过 roleKey 查询角色ID列表 + List roles = roleMapper.selectList( + new LambdaQueryWrapper() + .select(SysRole::getRoleId) + .eq(SysRole::getRoleKey, roleKey) + .eq(SysRole::getStatus, SystemConstants.NORMAL)); + if (CollUtil.isEmpty(roles)) { + return List.of(); + } + List roleIds = StreamUtils.toList(roles, SysRole::getRoleId); + return this.selectUsersByRoleIds(roleIds); + } + + /** + * 通过用户ID查询用户所有的角色Key + * + * @param userId 用户ID + * @return 角色Key集合 + */ + @Override + public Set selectRoleKeysByUserId(Long userId) { + if (userId == null) { + return Set.of(); + } + List roles = roleMapper.selectRolesByUserId(userId); + if (CollUtil.isEmpty(roles)) { + return Set.of(); + } + Set roleKeys = new HashSet<>(); + for (SysRoleVo role : roles) { + if (role != null && StringUtils.isNotBlank(role.getRoleKey())) { + roleKeys.add(role.getRoleKey().trim()); + } + } + return roleKeys; + } } diff --git a/zdxt-web-client/zdxt-admin-plus-ui/src/views/system/dict/data.vue b/zdxt-web-client/zdxt-admin-plus-ui/src/views/system/dict/data.vue index be5c87a9..33489dc5 100644 --- a/zdxt-web-client/zdxt-admin-plus-ui/src/views/system/dict/data.vue +++ b/zdxt-web-client/zdxt-admin-plus-ui/src/views/system/dict/data.vue @@ -238,7 +238,7 @@ const handleClose = () => { params: undefined, query: undefined, redirectedFrom: undefined, - path: '/system/dict' + path: '/system-setting/dict' }; proxy?.$tab.closeOpenPage(obj); }; diff --git a/zdxt-web-client/zdxt-admin-plus-ui/src/views/system/oss/index.vue b/zdxt-web-client/zdxt-admin-plus-ui/src/views/system/oss/index.vue index f5966d78..57a8f62b 100644 --- a/zdxt-web-client/zdxt-admin-plus-ui/src/views/system/oss/index.vue +++ b/zdxt-web-client/zdxt-admin-plus-ui/src/views/system/oss/index.vue @@ -280,7 +280,7 @@ const handleOrderChange = (prop: string, order: string) => { }; /** 任务日志列表查询 */ const handleOssConfig = () => { - router.push('/system/oss-config/index'); + router.push('/system-setting/oss-config/index'); }; /** 文件按钮操作 */ const handleFile = () => { diff --git a/zdxt-web-client/zdxt-admin-plus-ui/src/views/system/role/authUser.vue b/zdxt-web-client/zdxt-admin-plus-ui/src/views/system/role/authUser.vue index 7c7fbeb7..9632107d 100644 --- a/zdxt-web-client/zdxt-admin-plus-ui/src/views/system/role/authUser.vue +++ b/zdxt-web-client/zdxt-admin-plus-ui/src/views/system/role/authUser.vue @@ -104,7 +104,7 @@ const getList = async () => { // 返回按钮 const handleClose = () => { const obj: RouteLocationNormalized = { - path: '/system/role', + path: '/org-permission/role', fullPath: '', hash: '', matched: [], diff --git a/zdxt-web-client/zdxt-admin-plus-ui/src/views/system/role/index-dept-separate.vue b/zdxt-web-client/zdxt-admin-plus-ui/src/views/system/role/index-dept-separate.vue index 9ba2944e..f90d9eb5 100644 --- a/zdxt-web-client/zdxt-admin-plus-ui/src/views/system/role/index-dept-separate.vue +++ b/zdxt-web-client/zdxt-admin-plus-ui/src/views/system/role/index-dept-separate.vue @@ -412,7 +412,7 @@ const handleStatusChange = async (row: RoleVO) => { /** 分配用户 */ const handleAuthUser = (row: RoleVO) => { - router.push('/system/role-auth/user/' + row.roleId); + router.push('/org-permission/role-auth/user/' + row.roleId); }; /** 查询菜单树结构 */ diff --git a/zdxt-web-client/zdxt-admin-plus-ui/src/views/system/role/index.vue b/zdxt-web-client/zdxt-admin-plus-ui/src/views/system/role/index.vue index 702bc580..05487dd6 100644 --- a/zdxt-web-client/zdxt-admin-plus-ui/src/views/system/role/index.vue +++ b/zdxt-web-client/zdxt-admin-plus-ui/src/views/system/role/index.vue @@ -335,7 +335,7 @@ const handleStatusChange = async (row: RoleVO) => { /** 分配用户 */ const handleAuthUser = (row: RoleVO) => { - router.push('/system/role-auth/user/' + row.roleId); + router.push('/org-permission/role-auth/user/' + row.roleId); }; /** 查询菜单树结构 */ diff --git a/zdxt-web-client/zdxt-admin-plus-ui/src/views/system/user/authRole.vue b/zdxt-web-client/zdxt-admin-plus-ui/src/views/system/user/authRole.vue index d322942b..a23de283 100644 --- a/zdxt-web-client/zdxt-admin-plus-ui/src/views/system/user/authRole.vue +++ b/zdxt-web-client/zdxt-admin-plus-ui/src/views/system/user/authRole.vue @@ -109,7 +109,7 @@ const close = () => { params: undefined, query: undefined, redirectedFrom: undefined, - path: '/system/user' + path: '/org-permission/auth-user' }; proxy?.$tab.closeOpenPage(obj); }; diff --git a/zdxt-web-client/zdxt-admin-plus-ui/src/views/system/user/index.vue b/zdxt-web-client/zdxt-admin-plus-ui/src/views/system/user/index.vue index 981dfc63..f41a6266 100644 --- a/zdxt-web-client/zdxt-admin-plus-ui/src/views/system/user/index.vue +++ b/zdxt-web-client/zdxt-admin-plus-ui/src/views/system/user/index.vue @@ -565,7 +565,7 @@ const handleStatusChange = async (row: UserVO) => { /** 跳转角色分配 */ const handleAuthRole = (row: UserVO) => { const userId = row.userId; - router.push('/system/user-auth/role/' + userId); + router.push('/org-permission/user-auth/role/' + userId); }; /** 重置密码按钮操作 */