diff --git a/doc/执法码数据权限过滤使用说明.md b/doc/执法码数据权限过滤使用说明.md index 799b2311..c0e832fc 100644 --- a/doc/执法码数据权限过滤使用说明.md +++ b/doc/执法码数据权限过滤使用说明.md @@ -244,13 +244,13 @@ public TableDataInfo directFilterPageList(TestEnfDemoBo bo, PageQ |----------|--------|------| | `getUserDeptId(userId)` | `String` | 获取用户的 dept_id(来源 sys_user 表) | | `getUserOrganId(userId)` | `String` | 查询用户所属执法单位的 organizationId(来源 srz_dept 表,向上递归) | -| `getUserBureauDeptId(userId)` | `String` | 查询用户所在执法单位的 vir_id(来源 efcode_virtual_unit 表) | +| `getUserBureauDeptId(userId)` | `String` | 查询用户所在执法单位的 sys_dept_id(沿 sys_dept 父链向上递归查找 efcode_virtual_unit) | -#### 5.4.1 getUserDeptId +#### 5.4.1 getUserDeptId 获取用户所在的部门ID 通过 `UserService.selectListByIds()` 查询用户的 `dept_id` 并返回字符串。 -#### 5.4.2 getUserOrganId +#### 5.4.2 getUserOrganId 获取用户所在的单位ID,有可能和部门ID相同 ``` userId → getUserDeptId → deptId @@ -261,17 +261,22 @@ deptId → srz_dept.organizationId 匹配 (最大递归深度:4层) ``` -#### 5.4.3 getUserBureauDeptId +#### 5.4.3 getUserBureauDeptId 获取用户所在的执法单位ID有可能和部门ID相同,单位ID相同 ``` userId → getUserDeptId → deptId -deptId → efcode_virtual_unit.sys_dept_id 匹配 - ├─ 筛选 vir_show_at_business='是' 的记录 - │ ├─ 恰好1条 → 返回 vir_id - │ └─ 多条 → 抛出异常 - └─ 无 vir_show_at_business='是' 的记录 - ├─ 总匹配只有1条 → 返回 vir_id - └─ 多条 → 抛出异常 +循环(自身 + 最多4层父节点,共5层): + currentDeptId → efcode_virtual_unit.sys_dept_id 匹配 + ├─ 存在匹配记录 + │ ├─ 筛选 vir_show_at_business='是' 的记录 + │ │ ├─ 恰好1条 → 返回该记录的 sys_dept_id + │ │ └─ 多条 → 抛出异常 + │ └─ 无 vir_show_at_business='是' 的记录 + │ ├─ 总匹配只有1条 → 返回该记录的 sys_dept_id + │ └─ 多条 → 抛出异常 + └─ 无匹配记录 + └─ 通过 sys_dept 查找 parentId → currentDeptId = parentId → 继续下一层 +到达根节点或超过4层仍未找到 → 返回 null ``` ### 5.5 常量定义 diff --git a/script/sql/zfjd-refactoring-v1/013-计划任务表设计.sql b/script/sql/zfjd-refactoring-v1/013-计划任务表设计.sql index d07fa1a8..19de79eb 100644 --- a/script/sql/zfjd-refactoring-v1/013-计划任务表设计.sql +++ b/script/sql/zfjd-refactoring-v1/013-计划任务表设计.sql @@ -1,61 +1,84 @@ -DROP TABLE IF EXISTS `enforcement_law_check_plan`; -CREATE TABLE `enforcement_law_check_plan` ( - `id` varchar(50) NOT NULL COMMENT '主键ID', --- `plan_code` varchar(32) NOT NULL COMMENT '计划编号(唯一)', - `plan_type` tinyint NOT NULL COMMENT '计划类别 1=日常计划 2=专项计划', - `plan_date` varchar(16) NOT NULL COMMENT '计划执行日期(如 2025-05-08)', - `plan_time` tinyint NOT NULL COMMENT '执行时段 1=上午 2=下午 3=其他', - `enforce_content` varchar(1000) NOT NULL COMMENT '执法事项(最多1000字)', - `dept_id` varchar(50) NOT NULL COMMENT '执法单位ID', - `dept_name` varchar(100) NOT NULL COMMENT '执法单位名称', - `company_name` varchar(200) NOT NULL COMMENT '被检查企业/机构名称', - `enforce_user_name` varchar(512) NOT NULL COMMENT '执法人员姓名(多个逗号分隔)', - `enforce_user_code` varchar(512) NOT NULL COMMENT '执法人员证件编号(多个逗号分隔)', - `is_public` tinyint NOT NULL DEFAULT 1 COMMENT '是否公开 1=是 0=否', - `is_union` tinyint NOT NULL DEFAULT 1 COMMENT '是否联合执法 1=是 0=否', - `union_dept` varchar(500) DEFAULT NULL COMMENT '联合执法单位(多个逗号分隔)', - -- `status` tinyint NOT NULL DEFAULT 1 COMMENT '状态 1=草稿 2=已提交 3=已执行 4=已作废', - `reserve_status` tinyint NOT NULL DEFAULT 0 COMMENT '预约状态 0=待预约 1=预约中 2=预约完成 3=停止预约', - `create_by` varchar(64) DEFAULT '' COMMENT '创建者', - `create_dept` varchar(64) DEFAULT NULL COMMENT '创建人部门', - `update_by` varchar(64) DEFAULT '' COMMENT '更新者', - `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - `is_delete` tinyint NOT NULL DEFAULT 0 COMMENT '是否删除 0=否 1=是', - `remark` varchar(255) DEFAULT NULL COMMENT '备注', - PRIMARY KEY (`id`), - KEY `idx_dept_id` (`dept_id`), - KEY `idx_reserve_status` (`reserve_status`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='行政执法检查计划表'; +CREATE TABLE `efcode_cp_plan` +( + `id` varchar(50) NOT NULL COMMENT '主键ID', + `plan_type` tinyint NOT NULL COMMENT '计划类别 1=日常计划 2=专项计划', + `plan_date` varchar(16) NOT NULL COMMENT '计划执行日期(如 2025-05-08)', + `plan_time` tinyint NOT NULL COMMENT '执行时段 1=上午 2=下午 3=其他', + `enforce_content` varchar(1000) NOT NULL COMMENT '执法事项(最多1000字)', + `dept_id` varchar(50) NOT NULL COMMENT '执法单位ID', + `dept_name` varchar(100) NOT NULL COMMENT '执法单位名称', + `company_name` varchar(200) NOT NULL COMMENT '被检查企业/机构名称', + `enforce_user_name` varchar(512) NOT NULL COMMENT '执法人员姓名(多个逗号分隔)', + `enforce_user_code` varchar(512) NOT NULL COMMENT '执法人员证件编号(多个逗号分隔)', + `is_public` tinyint NOT NULL DEFAULT 1 COMMENT '是否公开 1=是 0=否', + `is_union` tinyint NOT NULL DEFAULT 1 COMMENT '是否联合执法 1=是 0=否', + `union_dept` varchar(500) DEFAULT NULL COMMENT '联合执法单位(多个逗号分隔)', + `reserve_status` tinyint NOT NULL DEFAULT 0 COMMENT '预约状态 0=待预约 1=预约中 2=预约完成 3=停止预约', + `create_by` varchar(64) DEFAULT '' COMMENT '创建者', + `create_dept` varchar(64) DEFAULT NULL COMMENT '创建人部门', + `update_by` varchar(64) DEFAULT '' COMMENT '更新者', + `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `is_delete` tinyint NOT NULL DEFAULT 0 COMMENT '是否删除 0=否 1=是', + `remark` varchar(255) DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`id`), + KEY `idx_dept_id` (`dept_id`), + KEY `idx_reserve_status` (`reserve_status`) +) comment '行政执法检查计划-计划表' row_format = DYNAMIC; + +CREATE TABLE `efcode_cp_task`( + +) comment '行政执法检查计划-计划参与人员表' row_format = DYNAMIC; + +CREATE TABLE `efcode_cp_task`( + +) comment '行政执法检查计划-任务表' row_format = DYNAMIC; + +CREATE TABLE `efcode_cp_task`( + +) comment '行政执法检查计划-预约表' row_format = DYNAMIC; + +CREATE TABLE `efcode_cp_task`( + +) comment '行政执法检查计划-预告表' row_format = DYNAMIC; + +CREATE TABLE `efcode_cp_task`( + +) comment '行政执法检查计划-预告交流表' row_format = DYNAMIC; + +CREATE TABLE `efcode_cp_setting`( + +) comment '行政执法检查计划-设置表' row_format = DYNAMIC; DROP TABLE IF EXISTS `enforcement_law_notice`; -CREATE TABLE `enforcement_law_notice` ( - `id` varchar(50) NOT NULL COMMENT '主键ID', - `plan_id` bigint DEFAULT NULL COMMENT '导入的计划ID(关联执法计划表)', - `enforce_date` varchar(16) NOT NULL COMMENT '执法日期', - `enforce_period` tinyint NOT NULL COMMENT '执法时段 1=上午 2=下午 3=其他', - `dept_id` varchar(50) NOT NULL COMMENT '执法单位ID', - `dept_name` varchar(100) NOT NULL COMMENT '执法单位名称', - `enforce_user_names` varchar(512) NOT NULL COMMENT '执法人员姓名(多人员逗号分隔)', - `enforce_user_codes` varchar(512) NOT NULL COMMENT '执法人员证件编号(多人员逗号分隔)', - `company_id` varchar(50) NOT NULL COMMENT '被检查企业ID', - `company_name` varchar(200) NOT NULL COMMENT '被检查企业名称', - `credit_code` varchar(32) DEFAULT NULL COMMENT '企业统一社会信用代码', - `contact_person` varchar(50) NOT NULL COMMENT '企业联系人', - `contact_phone` varchar(20) NOT NULL COMMENT '企业联系电话', - `enforce_content` varchar(1000) NOT NULL COMMENT '执法事项', - `enforce_requirement` varchar(1000) NOT NULL COMMENT '执法要求', - `publish_time` datetime DEFAULT NULL COMMENT '预告发布时间', - `status` tinyint NOT NULL DEFAULT 1 COMMENT '预告状态 1=草稿 2=已发布 3=已取消 4=已执行', - `create_by` varchar(64) DEFAULT '' COMMENT '创建者', - `create_dept` varchar(64) DEFAULT NULL COMMENT '创建人部门', - `update_by` varchar(64) DEFAULT '' COMMENT '更新者', - `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - `is_delete` tinyint NOT NULL DEFAULT 0 COMMENT '是否删除 0=否 1=是', - `remark` varchar(255) DEFAULT NULL COMMENT '备注', - PRIMARY KEY (`id`), - KEY `idx_dept_id` (`dept_id`), - KEY `idx_company_id` (`company_id`), - KEY `idx_credit_code` (`credit_code`) +CREATE TABLE `enforcement_law_notice` +( + `id` varchar(50) NOT NULL COMMENT '主键ID', + `plan_id` bigint DEFAULT NULL COMMENT '导入的计划ID(关联执法计划表)', + `enforce_date` varchar(16) NOT NULL COMMENT '执法日期', + `enforce_period` tinyint NOT NULL COMMENT '执法时段 1=上午 2=下午 3=其他', + `dept_id` varchar(50) NOT NULL COMMENT '执法单位ID', + `dept_name` varchar(100) NOT NULL COMMENT '执法单位名称', + `enforce_user_names` varchar(512) NOT NULL COMMENT '执法人员姓名(多人员逗号分隔)', + `enforce_user_codes` varchar(512) NOT NULL COMMENT '执法人员证件编号(多人员逗号分隔)', + `company_id` varchar(50) NOT NULL COMMENT '被检查企业ID', + `company_name` varchar(200) NOT NULL COMMENT '被检查企业名称', + `credit_code` varchar(32) DEFAULT NULL COMMENT '企业统一社会信用代码', + `contact_person` varchar(50) NOT NULL COMMENT '企业联系人', + `contact_phone` varchar(20) NOT NULL COMMENT '企业联系电话', + `enforce_content` varchar(1000) NOT NULL COMMENT '执法事项', + `enforce_requirement` varchar(1000) NOT NULL COMMENT '执法要求', + `publish_time` datetime DEFAULT NULL COMMENT '预告发布时间', + `status` tinyint NOT NULL DEFAULT 1 COMMENT '预告状态 1=草稿 2=已发布 3=已取消 4=已执行', + `create_by` varchar(64) DEFAULT '' COMMENT '创建者', + `create_dept` varchar(64) DEFAULT NULL COMMENT '创建人部门', + `update_by` varchar(64) DEFAULT '' COMMENT '更新者', + `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `is_delete` tinyint NOT NULL DEFAULT 0 COMMENT '是否删除 0=否 1=是', + `remark` varchar(255) DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`id`), + KEY `idx_dept_id` (`dept_id`), + KEY `idx_company_id` (`company_id`), + KEY `idx_credit_code` (`credit_code`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='行政执法预告表'; diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/common/util/DataFilterUtil.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/common/util/DataFilterUtil.java index 1856f5df..62fbe808 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/common/util/DataFilterUtil.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/common/util/DataFilterUtil.java @@ -20,6 +20,8 @@ import java.util.List; import java.util.Set; import java.util.stream.Collectors; import org.dromara.common.core.utils.StringUtils; +import org.dromara.system.domain.vo.SysDeptVo; +import org.dromara.system.service.ISysDeptService; @NoArgsConstructor(access = AccessLevel.PRIVATE) public class DataFilterUtil { @@ -409,70 +411,81 @@ public class DataFilterUtil { // ======================== 用户执法单位查询方法 ======================== /** - * 查询指定用户所在的执法单位的 vir_id。 + * 查询指定用户所在的执法单位的 sys_dept_id。 *

* 逻辑: *

    *
  1. 通过 userId 查询用户的 dept_id
  2. - *
  3. 用 dept_id 匹配 efcode_virtual_unit.sys_dept_id
  4. - *
  5. 优先返回 vir_show_at_business='是' 的记录的 vir_id
  6. - *
  7. 如果 vir_show_at_business='是' 的有多条,抛出异常
  8. - *
  9. 如果没有 vir_show_at_business='是' 的记录,且只有一条匹配 sys_dept_id 的记录,也直接返回
  10. + *
  11. 用 dept_id 查找 efcode_virtual_unit(按 sys_dept_id 匹配)
  12. + *
  13. 若存在匹配记录,优先返回 vir_show_at_business='是' 的记录的 sys_dept_id; + * 若无 business 记录且只有一条匹配也直接返回
  14. + *
  15. 若不存在匹配记录,通过 sys_dept 查找父节点,再用父节点 dept_id 重复上述查找
  16. + *
  17. 递归向上最多查 4 层父节点
  18. *
* * @param userId 用户ID - * @return 用户所在执法单位的 vir_id;如果用户不存在或未分配部门则返回 null - * @throws IllegalStateException 当匹配到多条 vir_show_at_business='是' 的记录时抛出 + * @return 用户所在执法单位的 sys_dept_id;如果用户不存在、未分配部门或向上 4 层仍未找到则返回 null + * @throws IllegalStateException 当某层匹配到多条 vir_show_at_business='是' 的记录,或多条匹配但无法确定唯一执法单位时抛出 */ public static String getUserBureauDeptId(Long userId) { if (userId == null) { return null; } // 1. 通过 userId 获取用户的 deptId - UserService userService = SpringUtils.getBean(UserService.class); - List users = userService.selectListByIds(Collections.singletonList(userId)); - if (CollUtil.isEmpty(users)) { - return null; - } - UserDTO user = users.get(0); - if (user.getDeptId() == null) { + String deptId = getUserDeptId(userId); + if (StrUtil.isBlank(deptId)) { return null; } - String deptId = String.valueOf(user.getDeptId()); - // 2. 通过 deptId 查询 efcode_virtual_unit 中所有匹配 sys_dept_id 的记录 + // 2. 从当前 deptId 开始,向上查找 sys_dept 父链,最多查 5 层(自身 + 4 层父节点) IEfcodeVirtualUnitService virtualUnitService = SpringUtils.getBean(IEfcodeVirtualUnitService.class); - EfcodeVirtualUnitBo bo = new EfcodeVirtualUnitBo(); - bo.setSysDeptId(deptId); - List allMatched = virtualUnitService.queryList(bo); - if (CollUtil.isEmpty(allMatched)) { - return null; - } + ISysDeptService sysDeptService = SpringUtils.getBean(ISysDeptService.class); - // 3. 筛选 vir_show_at_business='是' 的记录 - List businessUnits = allMatched.stream() - .filter(v -> "是".equals(v.getVirShowAtBusiness())) - .collect(Collectors.toList()); + String currentDeptId = deptId; + for (int i = 0; i < 5; i++) { + if (StrUtil.isBlank(currentDeptId)) { + break; + } - if (businessUnits.size() == 1) { - // 恰好一条业务记录,直接返回 - return businessUnits.get(0).getVirId(); - } - if (businessUnits.size() > 1) { - // 多条业务记录,抛出异常 - throw new IllegalStateException( - "用户(userId=" + userId + ")的部门(deptId=" + deptId - + ")在虚拟单位表中匹配到多条 vir_show_at_business='是' 的记录,无法确定唯一执法单位"); - } + // 查询 efcode_virtual_unit 中所有匹配 sys_dept_id 的记录 + EfcodeVirtualUnitBo bo = new EfcodeVirtualUnitBo(); + bo.setSysDeptId(currentDeptId); + List allMatched = virtualUnitService.queryList(bo); + + if (CollUtil.isNotEmpty(allMatched)) { + // 筛选 vir_show_at_business='是' 的记录 + List businessUnits = allMatched.stream() + .filter(v -> "是".equals(v.getVirShowAtBusiness())) + .collect(Collectors.toList()); + + if (businessUnits.size() == 1) { + return businessUnits.get(0).getSysDeptId(); + } + if (businessUnits.size() > 1) { + throw new IllegalStateException( + "用户(userId=" + userId + ")的部门(deptId=" + currentDeptId + + ")在虚拟单位表中匹配到多条 vir_show_at_business='是' 的记录,无法确定唯一执法单位"); + } + // 没有 business 记录,如果只有一条匹配则返回 + if (allMatched.size() == 1) { + return allMatched.get(0).getSysDeptId(); + } + // 多条匹配但无 business 标记,无法确定唯一执法单位 + throw new IllegalStateException( + "用户(userId=" + userId + ")的部门(deptId=" + currentDeptId + + ")在虚拟单位表中匹配到多条记录且无 vir_show_at_business='是',无法确定唯一执法单位"); + } - // 4. 没有 vir_show_at_business='是' 的记录,如果只有一条匹配记录则返回 - if (allMatched.size() == 1) { - return allMatched.get(0).getVirId(); + // 不存在匹配记录,通过 sys_dept 查找父节点 + SysDeptVo dept = sysDeptService.selectDeptById(currentDeptId); + if (dept == null || StrUtil.isBlank(dept.getParentId()) || "0".equals(dept.getParentId())) { + break; + } + currentDeptId = dept.getParentId(); } - // 多条匹配但无法确定唯一执法单位 - throw new IllegalStateException( - "无法找到当前用户所在的执法单位!"); + // 向上查找 4 层仍未找到对应的虚拟单位 + return null; } // ======================== 私有辅助方法 ========================