diff --git a/script/sql/zfjd-refactoring-v1/005-2-重新整理二期菜单结构.sql b/script/sql/zfjd-refactoring-v1/005-2-重新整理二期菜单结构.sql index 6a2650e0..38ffee72 100644 --- a/script/sql/zfjd-refactoring-v1/005-2-重新整理二期菜单结构.sql +++ b/script/sql/zfjd-refactoring-v1/005-2-重新整理二期菜单结构.sql @@ -128,7 +128,7 @@ INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query_param, is_frame, is_cache, url, target, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark, system_code, type) VALUES (5249, '涉企执法情况(2)', 5262, 1, 'enterprise-enforcement', 'efcode/report/registration/index', '', 1, 0, '#', '', 'C', '0', '0', 'supervision:statistics:enterpriseEnforcement', '#', 103, 1, '2026-05-15 00:00:00', null, null, '涉企执法情况菜单', 'supervisionCode', null); INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query_param, is_frame, is_cache, url, target, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark, system_code, type) VALUES (5278, '企业受检次数(4)', 5262, 2, 'enterprise-inspection', 'efcode/report/enterprises_inspected_noft/index', '', 1, 0, '#', '', 'C', '0', '0', 'supervision:statistics:enterpriseInspection', '#', 103, 1, '2026-05-15 00:00:00', null, null, '企业受检次数菜单', 'supervisionCode', null); INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query_param, is_frame, is_cache, url, target, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark, system_code, type) VALUES (5253, '企业信息情况(5)', 5262, 3, 'enterprise-info', 'efcode/report/statistics_enterprise/index', '', 1, 0, '#', '', 'C', '0', '0', 'supervision:statistics:enterpriseInfo', '#', 103, 1, '2026-05-15 00:00:00', null, null, '企业信息情况菜单', 'supervisionCode', null); -INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query_param, is_frame, is_cache, url, target, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark, system_code, type) VALUES (5250, '执法单位情况(5)', 5262, 4, 'enforcement-unit', 'efcode/report/statistics_enforcement_unit/index', '', 1, 0, '#', '', 'C', '0', '0', 'supervision:statistics:enforcementUnit', '#', 103, 1, '2026-05-15 00:00:00', null, null, '执法单位情况菜单', 'supervisionCode', null); +INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query_param, is_frame, is_cache, url, target, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark, system_code, type) VALUES (5250, '执法单位情况(5)', 5262, 4, 'enforcement-unit', 'efcode/report/statistics_enforcement_bureau_unit/index', '', 1, 0, '#', '', 'C', '0', '0', 'supervision:statistics:enforcementUnit', '#', 103, 1, '2026-05-15 00:00:00', null, null, '执法单位情况菜单', 'supervisionCode', null); INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query_param, is_frame, is_cache, url, target, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark, system_code, type) VALUES (5251, '执法投诉情况(4)', 5262, 5, 'enforcement-complaint', 'efcode/report/statistics_enforcement_complaint/index', '', 1, 0, '#', '', 'C', '0', '0', 'supervision:statistics:enforcementComplaint', '#', 103, 1, '2026-05-15 00:00:00', null, null, '执法投诉情况菜单', 'supervisionCode', null); INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query_param, is_frame, is_cache, url, target, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark, system_code, type) VALUES (5254, '检查计划情况(5)', 5262, 6, 'inspection-plan', 'efcode/report/statistics_inspection_plan/index', '', 1, 0, '#', '', 'C', '0', '0', 'supervision:statistics:inspectionPlan', '#', 103, 1, '2026-05-15 00:00:00', null, null, '检查计划情况菜单', 'supervisionCode', null); diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/web/supervision/report/StatisticsBureauUnitController.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/web/supervision/report/StatisticsBureauUnitController.java new file mode 100644 index 00000000..a3101979 --- /dev/null +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/web/supervision/report/StatisticsBureauUnitController.java @@ -0,0 +1,72 @@ +package com.zdxt.enforcementcode.controller.web.supervision.report; + +import com.zdxt.enforcementcode.domain.bo.StatisticsBureauUnitBo; +import com.zdxt.enforcementcode.domain.vo.report.BureauUnitDetailVo; +import com.zdxt.enforcementcode.domain.vo.report.BureauUnitExportVo; +import com.zdxt.enforcementcode.domain.vo.report.BureauUnitOverviewVo; +import com.zdxt.enforcementcode.domain.vo.report.BureauUnitStatVo; +import com.zdxt.enforcementcode.report.IStatisticsBureauUnitReport; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.dromara.common.core.domain.R; +import org.dromara.common.excel.utils.ExcelUtil; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +/** + * 执法单位情况报表 + * + * @author zdxt + */ +@Slf4j +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/web/supervision/report/statistics-bureau-unit") +public class StatisticsBureauUnitController { + + private final IStatisticsBureauUnitReport reportService; + + /** 统计概览 */ + @GetMapping("/overview") + public R overview(StatisticsBureauUnitBo bo) { + return R.ok(reportService.overview(bo)); + } + + /** 执法单位列表(服务端分页) */ + @GetMapping("/list") + public TableDataInfo list(StatisticsBureauUnitBo bo, PageQuery pageQuery) { + return reportService.list(bo, pageQuery); + } + + /** 单位人员详情(服务端分页) */ + @GetMapping("/detail") + public TableDataInfo detail(StatisticsBureauUnitBo bo, PageQuery pageQuery) { + return reportService.detail(bo, pageQuery); + } + + /** 导出 */ + @PostMapping("/export") + public void export(StatisticsBureauUnitBo bo, HttpServletResponse response) { + try { + List list = reportService.exportList(bo); + ExcelUtil.exportExcel(list, "部门统计", BureauUnitExportVo.class, response); + } catch (Exception e) { + log.error("导出执法单位情况Excel异常", e); + response.reset(); + response.setContentType("application/json; charset=utf-8"); + try { + response.getWriter().write("{\"code\":500,\"msg\":\"导出失败: " + e.getMessage() + "\"}"); + } catch (Exception ignored) { + } + } + } +} diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/StatisticsBureauUnitBo.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/StatisticsBureauUnitBo.java new file mode 100644 index 00000000..80230965 --- /dev/null +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/StatisticsBureauUnitBo.java @@ -0,0 +1,30 @@ +package com.zdxt.enforcementcode.domain.bo; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * 执法单位情况报表 — 查询BO + * + * @author zdxt + */ +@Data +public class StatisticsBureauUnitBo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** 执法单位名称(模糊) */ + private String zfdw; + + /** 执法人员姓名(模糊) */ + private String name; + + /** 执法证号(模糊) */ + private String zfcode; + + /** 单位的 sys_dept_id(详情查询时使用) */ + private String sysDeptId; +} diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/report/BureauUnitDetailVo.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/report/BureauUnitDetailVo.java new file mode 100644 index 00000000..c403a71a --- /dev/null +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/report/BureauUnitDetailVo.java @@ -0,0 +1,33 @@ +package com.zdxt.enforcementcode.domain.vo.report; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * 执法单位情况报表 — 人员详情VO(详情表行) + * + * @author zdxt + */ +@Data +public class BureauUnitDetailVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** 部门名称(人员所在部门) */ + private String unitName; + + /** 执法人员姓名 */ + private String personnelName; + + /** 执法证号 */ + private String zfcode; + + /** 联系方式(加密存储,Service层解密) */ + private String phoneNumber; + + /** 执法案件数量 */ + private int caseCount; +} diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/report/BureauUnitExportVo.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/report/BureauUnitExportVo.java new file mode 100644 index 00000000..273931a1 --- /dev/null +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/report/BureauUnitExportVo.java @@ -0,0 +1,33 @@ +package com.zdxt.enforcementcode.domain.vo.report; + +import cn.idev.excel.annotation.ExcelIgnoreUnannotated; +import cn.idev.excel.annotation.ExcelProperty; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * 执法单位情况报表 — 导出VO(4列) + * + * @author zdxt + */ +@Data +@ExcelIgnoreUnannotated +public class BureauUnitExportVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + @ExcelProperty(value = "部门名称") + private String unitName; + + @ExcelProperty(value = "执法人员") + private String personnelName; + + @ExcelProperty(value = "执法证号") + private String zfcode; + + @ExcelProperty(value = "联系方式") + private String phoneNumber; +} diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/report/BureauUnitOverviewVo.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/report/BureauUnitOverviewVo.java new file mode 100644 index 00000000..a3ebb3bc --- /dev/null +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/report/BureauUnitOverviewVo.java @@ -0,0 +1,24 @@ +package com.zdxt.enforcementcode.domain.vo.report; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * 执法单位情况报表 — 统计概览VO + * + * @author zdxt + */ +@Data +public class BureauUnitOverviewVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** 执法单位总数 */ + private int deptCount; + + /** 执法人员总数 */ + private int personnelCount; +} diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/report/BureauUnitPersonnelMatchVo.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/report/BureauUnitPersonnelMatchVo.java new file mode 100644 index 00000000..4ca4da83 --- /dev/null +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/report/BureauUnitPersonnelMatchVo.java @@ -0,0 +1,36 @@ +package com.zdxt.enforcementcode.domain.vo.report; + +import lombok.Data; + +/** + * 执法单位情况报表 — 人员匹配内部VO(用于Java层剔除逻辑) + * + * @author zdxt + */ +@Data +public class BureauUnitPersonnelMatchVo { + + /** 人员姓名 */ + private String name; + + /** 组织机构代码 */ + private String zzjgdm; + + /** 执法单位名称 */ + private String zfdw; + + /** 执法证号 */ + private String zfcode; + + /** 身份证号加密 */ + private String sfzcodeEncrypt; + + /** 人员所在部门ID */ + private String deptId; + + /** 联系电话 */ + private String phoneNumber; + + /** 部门祖级ID串(逗号分隔) */ + private String ancestors; +} diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/report/BureauUnitStatVo.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/report/BureauUnitStatVo.java new file mode 100644 index 00000000..675d14ec --- /dev/null +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/report/BureauUnitStatVo.java @@ -0,0 +1,27 @@ +package com.zdxt.enforcementcode.domain.vo.report; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * 执法单位情况报表 — 单位统计VO(主表行) + * + * @author zdxt + */ +@Data +public class BureauUnitStatVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** 单位关联的 sys_dept_id */ + private String sysDeptId; + + /** 单位名称 */ + private String unitName; + + /** 执法人员数量 */ + private int personnelCount; +} diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/mapper/BureauUnitMapper.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/mapper/BureauUnitMapper.java new file mode 100644 index 00000000..7affd8a4 --- /dev/null +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/mapper/BureauUnitMapper.java @@ -0,0 +1,42 @@ +package com.zdxt.enforcementcode.mapper; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.zdxt.enforcementcode.domain.bo.StatisticsBureauUnitBo; +import com.zdxt.enforcementcode.domain.vo.report.BureauUnitDetailVo; +import com.zdxt.enforcementcode.domain.vo.report.BureauUnitPersonnelMatchVo; +import com.zdxt.enforcementcode.domain.vo.report.BureauUnitStatVo; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 执法单位情况报表 Mapper + * + * @author zdxt + */ +@Mapper +public interface BureauUnitMapper { + + /** + * 查询执法主体列表(zfztjdm111915关联sys_dept获取deptId) + */ + List selectZfztjdmListAndDeptScope(@Param("bo") StatisticsBureauUnitBo bo); + + /** + * 查询执法单位列表(zone不为空且zone!=2的部门) + */ + List selectDeptByZone(@Param("bo") StatisticsBureauUnitBo bo); + + /** + * 查询所有有效执法人员(含部门ID和ancestors,用于Java层匹配) + */ + List selectPersonnelGroupBy(@Param("bo") StatisticsBureauUnitBo bo); + + /** + * 查询指定单位的人员详情列表 — 服务端分页(含案件数) + */ + IPage selectUnitDetail(Page page, + @Param("bo") StatisticsBureauUnitBo bo); +} diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/report/IStatisticsBureauUnitReport.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/report/IStatisticsBureauUnitReport.java new file mode 100644 index 00000000..c9baaa6d --- /dev/null +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/report/IStatisticsBureauUnitReport.java @@ -0,0 +1,31 @@ +package com.zdxt.enforcementcode.report; + +import com.zdxt.enforcementcode.domain.bo.StatisticsBureauUnitBo; +import com.zdxt.enforcementcode.domain.vo.report.BureauUnitDetailVo; +import com.zdxt.enforcementcode.domain.vo.report.BureauUnitExportVo; +import com.zdxt.enforcementcode.domain.vo.report.BureauUnitOverviewVo; +import com.zdxt.enforcementcode.domain.vo.report.BureauUnitStatVo; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; + +import java.util.List; + +/** + * 执法单位情况报表 Service接口 + * + * @author zdxt + */ +public interface IStatisticsBureauUnitReport { + + /** 统计概览(执法单位数 + 执法人员数) */ + BureauUnitOverviewVo overview(StatisticsBureauUnitBo bo); + + /** 执法单位列表(服务端分页) */ + TableDataInfo list(StatisticsBureauUnitBo bo, PageQuery pageQuery); + + /** 单位人员详情(服务端分页) */ + TableDataInfo detail(StatisticsBureauUnitBo bo, PageQuery pageQuery); + + /** 导出 */ + List exportList(StatisticsBureauUnitBo bo); +} diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/report/impl/StatisticsBureauUnitReportImpl.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/report/impl/StatisticsBureauUnitReportImpl.java new file mode 100644 index 00000000..1f7a3977 --- /dev/null +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/report/impl/StatisticsBureauUnitReportImpl.java @@ -0,0 +1,222 @@ +package com.zdxt.enforcementcode.report.impl; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.zdxt.enforcementcode.common.util.CommonUtil; +import com.zdxt.enforcementcode.domain.bo.StatisticsBureauUnitBo; +import com.zdxt.enforcementcode.domain.vo.report.*; +import com.zdxt.enforcementcode.mapper.BureauUnitMapper; +import com.zdxt.enforcementcode.report.IStatisticsBureauUnitReport; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * 执法单位情况报表 Service实现 + *

+ * 复刻旧系统 getDeptStaticList 逻辑: + * 1. 从 sys_dept 获取执法单位列表(zone不为空且zone!=2) + * 2. 从 zfryjdm2405301 获取所有有效执法人员 + * 3. Java层按"ancestors包含deptId"匹配人员到单位,并执行"剔除"逻辑避免重复计数 + * + * @author zdxt + */ +@Slf4j +@RequiredArgsConstructor +@Service +public class StatisticsBureauUnitReportImpl implements IStatisticsBureauUnitReport { + + private final BureauUnitMapper bureauUnitMapper; + + @Override + public BureauUnitOverviewVo overview(StatisticsBureauUnitBo bo) { + // 执行剔除匹配逻辑 + List unitList = getDeptStaticList(bo); + + BureauUnitOverviewVo vo = new BureauUnitOverviewVo(); + vo.setDeptCount(unitList.size()); + vo.setPersonnelCount(unitList.stream().mapToInt(BureauUnitStatVo::getPersonnelCount).sum()); + return vo; + } + + @Override + public TableDataInfo list(StatisticsBureauUnitBo bo, PageQuery pageQuery) { + // 执行剔除匹配逻辑(全量) + List unitList = getDeptStaticList(bo); + + // 手动分页 + int pageNum = pageQuery.getPageNum(); + int pageSize = pageQuery.getPageSize(); + int total = unitList.size(); + int fromIndex = Math.min((pageNum - 1) * pageSize, total); + int toIndex = Math.min(fromIndex + pageSize, total); + List pageRecords = unitList.subList(fromIndex, toIndex); + + // 构建分页结果 + Page page = new Page<>(pageNum, pageSize, total); + page.setRecords(pageRecords); + return TableDataInfo.build(page); + } + + @Override + public TableDataInfo detail(StatisticsBureauUnitBo bo, PageQuery pageQuery) { + Page page = pageQuery.build(); + IPage result = bureauUnitMapper.selectUnitDetail(page, bo); + // 手机号解密 + result.getRecords().forEach(r -> r.setPhoneNumber(CommonUtil.decryptPhone(r.getPhoneNumber()))); + return TableDataInfo.build(result); + } + + @Override + public List exportList(StatisticsBureauUnitBo bo) { + // 使用同样的三步合并+剔除逻辑获取单位列表 + List zfztjdmList = bureauUnitMapper.selectZfztjdmListAndDeptScope(bo); + List deptList = bureauUnitMapper.selectDeptByZone(bo); + + // 合并 + List unitList = new ArrayList<>(zfztjdmList); + for (BureauUnitStatVo dept : deptList) { + BureauUnitStatVo unit = new BureauUnitStatVo(); + unit.setSysDeptId(dept.getSysDeptId()); + unit.setUnitName(dept.getUnitName()); + unitList.add(unit); + } + + if (unitList.isEmpty()) { + return new ArrayList<>(); + } + + // 获取所有人员 + List personnelList = bureauUnitMapper.selectPersonnelGroupBy(bo); + + // 使用剔除逻辑,构建导出数据(人员归属到单位名称) + List exportList = new ArrayList<>(); + List hasExportList = new ArrayList<>(); + for (BureauUnitStatVo unit : unitList) { + // 匹配归属该单位的人员 + List matched = personnelList.stream() + .filter(p -> ancestorHasIt(p.getAncestors(), unit.getSysDeptId(), p.getDeptId())) + .collect(Collectors.toList()); + + // 为每个匹配人员构建导出行 + for (BureauUnitPersonnelMatchVo p : matched) { + BureauUnitExportVo exportVo = new BureauUnitExportVo(); + exportVo.setUnitName(unit.getUnitName()); + exportVo.setPersonnelName(p.getName()); + exportVo.setZfcode(p.getZfcode()); + exportVo.setPhoneNumber(CommonUtil.decryptPhone(p.getPhoneNumber())); + exportList.add(exportVo); + hasExportList.add(exportVo); + } + + // 剔除已匹配人员(避免重复计数) + personnelList = personnelList.stream() + .filter(p -> !ancestorHasIt(p.getAncestors(), unit.getSysDeptId(), p.getDeptId())) + .collect(Collectors.toList()); + } + + // 如果有姓名/证号搜索条件,只返回有匹配人员的数据 + if (StringUtils.isNotBlank(bo.getName()) || StringUtils.isNotBlank(bo.getZfcode())) { + return hasExportList; + } + return exportList; + } + + /** + * 核心逻辑:获取执法单位列表并匹配人员数量(含剔除逻辑) + *

+ * 完全复刻旧系统 Zfztjdm111915ServiceImpl.getDeptStaticList() 逻辑: + * 1. 从 zfztjdm111915 关联 sys_dept 获取执法主体列表(按creditcode匹配dept_id) + * 2. 从 sys_dept 获取 zone不为空且!=2 的部门列表 + * 3. 将两者合并(zone部门全部追加到执法主体列表后面) + * 4. 获取所有有效执法人员(含部门+ancestors) + * 5. 按顺序遍历合并后的单位列表,匹配人员并剔除 + * 6. 如果有搜索条件(name/zfcode),只返回有人员的单位 + */ + private List getDeptStaticList(StatisticsBureauUnitBo bo) { + // 步骤1: 从 zfztjdm111915 获取执法主体列表 + List zfztjdmList = bureauUnitMapper.selectZfztjdmListAndDeptScope(bo); + + // 建立 deptId -> 执法主体 的 map(用于合并时判断) + Map map = zfztjdmList.stream() + .filter(item -> item.getSysDeptId() != null) + .collect(Collectors.toMap( + BureauUnitStatVo::getSysDeptId, + Function.identity(), + (v1, v2) -> v2 + )); + + // 步骤2: 从 sys_dept 获取 zone部门列表 + List deptList = bureauUnitMapper.selectDeptByZone(bo); + + // 步骤3: 合并 - 将zone部门追加到执法主体列表后面(同旧系统逻辑) + List unitList = new ArrayList<>(zfztjdmList); + for (BureauUnitStatVo dept : deptList) { + BureauUnitStatVo unit = new BureauUnitStatVo(); + unit.setSysDeptId(dept.getSysDeptId()); + unit.setUnitName(dept.getUnitName()); + // 如果在执法主体map中存在,保留原有信息(同旧系统 map.containsKey 逻辑) + unitList.add(unit); + } + + // 步骤4: 获取所有有效执法人员 + List personnelList = bureauUnitMapper.selectPersonnelGroupBy(bo); + + // 步骤5: 遍历单位列表,执行匹配和剔除 + List hasList = new ArrayList<>(); + for (BureauUnitStatVo unit : unitList) { + String deptId = unit.getSysDeptId(); + + // 匹配归属该单位的人员 + List matchedList = personnelList.stream() + .filter(p -> ancestorHasIt(p.getAncestors(), deptId, p.getDeptId())) + .collect(Collectors.toList()); + + unit.setPersonnelCount(matchedList.size()); + + if (!matchedList.isEmpty()) { + hasList.add(unit); + } + + // 剔除已匹配人员(从池中移除) + personnelList = personnelList.stream() + .filter(p -> !ancestorHasIt(p.getAncestors(), deptId, p.getDeptId())) + .collect(Collectors.toList()); + } + + // 步骤6: 如果有搜索条件(name/zfcode),只返回有人员的单位 + if (StringUtils.isNotBlank(bo.getName()) || StringUtils.isNotBlank(bo.getZfcode())) { + return hasList; + } + return unitList; + } + + /** + * 判断人员是否归属某个单位 + *

+ * 逻辑:人员的ancestors中包含单位的deptId,或者人员的deptId等于单位的deptId + * 完全复刻旧系统 ancestorHasIt(ancestors, deptId, deptIdZFRY) + * + * @param ancestors 人员部门的祖级ID串(逗号分隔) + * @param deptId 单位的dept_id + * @param deptIdZFRY 人员的dept_id + * @return 是否归属 + */ + private boolean ancestorHasIt(String ancestors, String deptId, String deptIdZFRY) { + if (StringUtils.isBlank(ancestors) || StringUtils.isBlank(deptId) || StringUtils.isBlank(deptIdZFRY)) { + return false; + } + List ancestorsList = Arrays.asList(ancestors.split(",")); + return ancestorsList.contains(deptId) || deptId.equals(deptIdZFRY); + } +} diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/resources/mapper/enforcementcode/report/StatisticsBureauUnitReportMapper.xml b/zdxt-modules/zdxt-enforcement-code/src/main/resources/mapper/enforcementcode/report/StatisticsBureauUnitReportMapper.xml new file mode 100644 index 00000000..314a4d2b --- /dev/null +++ b/zdxt-modules/zdxt-enforcement-code/src/main/resources/mapper/enforcementcode/report/StatisticsBureauUnitReportMapper.xml @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + diff --git a/zdxt-web-client/zdxt-admin-plus-ui/src/api/efcode/report/statistics-bureau-unit.ts b/zdxt-web-client/zdxt-admin-plus-ui/src/api/efcode/report/statistics-bureau-unit.ts new file mode 100644 index 00000000..addba575 --- /dev/null +++ b/zdxt-web-client/zdxt-admin-plus-ui/src/api/efcode/report/statistics-bureau-unit.ts @@ -0,0 +1,77 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; + +const BASE_URL = '/web/supervision/report/statistics-bureau-unit'; + +/** 查询参数 */ +export interface BureauUnitQuery { + pageNum?: number; + pageSize?: number; + /** 执法单位名称(模糊) */ + zfdw?: string; + /** 执法人员姓名(模糊) */ + name?: string; + /** 执法证号(模糊) */ + zfcode?: string; + /** 单位的 sys_dept_id(详情查询时使用) */ + sysDeptId?: string; +} + +/** 概览VO */ +export interface BureauUnitOverviewVo { + deptCount: number; + personnelCount: number; +} + +/** 执法单位统计VO */ +export interface BureauUnitStatVo { + sysDeptId: string; + unitName: string; + personnelCount: number; +} + +/** 人员详情VO */ +export interface BureauUnitDetailVo { + unitName: string; + personnelName: string; + zfcode: string; + phoneNumber: string; + caseCount: number; +} + +/** 统计概览 */ +export const getOverview = (params: BureauUnitQuery): AxiosPromise => { + return request({ + url: `${BASE_URL}/overview`, + method: 'get', + params + }); +}; + +/** 执法单位列表(服务端分页) */ +export const getUnitList = (params: BureauUnitQuery): AxiosPromise => { + return request({ + url: `${BASE_URL}/list`, + method: 'get', + params + }); +}; + +/** 单位人员详情(服务端分页) */ +export const getUnitDetail = (params: BureauUnitQuery): AxiosPromise => { + return request({ + url: `${BASE_URL}/detail`, + method: 'get', + params + }); +}; + +/** 导出 */ +export const exportBureauUnit = (params: BureauUnitQuery): AxiosPromise => { + return request({ + url: `${BASE_URL}/export`, + method: 'post', + params, + responseType: 'blob' + }); +}; diff --git a/zdxt-web-client/zdxt-admin-plus-ui/src/views/efcode/report/statistics_enforcement_bureau_unit/index.vue b/zdxt-web-client/zdxt-admin-plus-ui/src/views/efcode/report/statistics_enforcement_bureau_unit/index.vue new file mode 100644 index 00000000..4d4316a6 --- /dev/null +++ b/zdxt-web-client/zdxt-admin-plus-ui/src/views/efcode/report/statistics_enforcement_bureau_unit/index.vue @@ -0,0 +1,263 @@ + + + + + diff --git a/zdxt-web-client/zdxt-admin-plus-ui/src/views/efcode/report/statistics_enforcement_unit/index.vue b/zdxt-web-client/zdxt-admin-plus-ui/src/views/efcode/report/statistics_enforcement_unit/index.vue deleted file mode 100644 index 63cf316b..00000000 --- a/zdxt-web-client/zdxt-admin-plus-ui/src/views/efcode/report/statistics_enforcement_unit/index.vue +++ /dev/null @@ -1,11 +0,0 @@ - - - - -