diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/web/supervision/report/RegistrationController.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/web/supervision/report/RegistrationController.java index 681661f7..a6ef0e63 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/web/supervision/report/RegistrationController.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/web/supervision/report/RegistrationController.java @@ -5,6 +5,7 @@ import com.zdxt.enforcementcode.domain.vo.EnforcementRegistrationVo; import com.zdxt.enforcementcode.domain.vo.report.ChartDataVo; import com.zdxt.enforcementcode.domain.vo.report.RegistrationAnalysisVo; import com.zdxt.enforcementcode.domain.vo.report.RegistrationExportVo; +import com.zdxt.enforcementcode.domain.vo.report.RegistrationExportV2Vo; import com.zdxt.enforcementcode.domain.vo.report.RegistrationStatisticsVo; import com.zdxt.enforcementcode.report.IEnforcementRegistrationReport; import jakarta.servlet.http.HttpServletResponse; @@ -45,24 +46,50 @@ public class RegistrationController { } /** - * 接口2:涉企执法统计列表(分页) + * 接口2-V1:涉企执法统计列表(全量加载+Java字典序排序+手动分页,暂保留) + */ + @GetMapping("/listV1") + public TableDataInfo listV1(EnforcementRegistrationBo bo, PageQuery pageQuery) { + return registrationReport.listForV1(bo, pageQuery); + } + + /** + * 接口2-V2:涉企执法统计列表(SQL JOIN字典表排序 + 服务端分页,当前使用) */ @GetMapping("/list") public TableDataInfo list(EnforcementRegistrationBo bo, PageQuery pageQuery) { - return registrationReport.list(bo, pageQuery); + return registrationReport.listForV2(bo, pageQuery); + } + + /** + * 接口3-V1:涉企执法统计列表导出(旧系统格式,10列,暂保留) + */ + @PostMapping("/exportListV1") + public void exportListV1(EnforcementRegistrationBo bo, HttpServletResponse response) { + try { + List list = registrationReport.exportListV1(bo); + ExcelUtil.exportExcel(list, "涉企执法统计", RegistrationExportVo.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) { + } + } } /** - * 接口3:涉企执法统计列表导出(旧系统格式,10列) + * 接口3-V2:涉企执法统计列表导出(15列,V2排序,当前使用) */ @PostMapping("/exportList") public void exportList(EnforcementRegistrationBo bo, HttpServletResponse response) { try { - List list = registrationReport.exportList(bo); - ExcelUtil.exportExcel(list, "涉企执法统计", RegistrationExportVo.class, response); + List list = registrationReport.exportListV2(bo); + ExcelUtil.exportExcel(list, "涉企执法情况", RegistrationExportV2Vo.class, response); } catch (Exception e) { log.error("导出涉企执法统计Excel异常", e); - // 重置response,避免content-type冲突 response.reset(); response.setContentType("application/json; charset=utf-8"); try { diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/report/RegistrationExportV2Vo.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/report/RegistrationExportV2Vo.java new file mode 100644 index 00000000..c91d5f37 --- /dev/null +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/report/RegistrationExportV2Vo.java @@ -0,0 +1,111 @@ +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 V2(与列表展示一致,共15列) + * + * @author zdxt + */ +@Data +@ExcelIgnoreUnannotated +public class RegistrationExportV2Vo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 执法单位 + */ + @ExcelProperty(value = "执法单位") + private String bureauDeptName; + + /** + * 被执法企业名称 + */ + @ExcelProperty(value = "被执法企业名称") + private String enterpriseName; + + /** + * 统一社会信用代码 + */ + @ExcelProperty(value = "统一社会信用代码") + private String enterpriseNumber; + + /** + * 企业所属区域 + */ + @ExcelProperty(value = "企业所属区域") + private String district; + + /** + * 企业所属街道 + */ + @ExcelProperty(value = "企业所属街道") + private String street; + + /** + * 执法人员 + */ + @ExcelProperty(value = "执法人员") + private String lawEnforcer; + + /** + * 执法事项 + */ + @ExcelProperty(value = "执法事项") + private String lawEnforcementItemText; + + /** + * 执法时间 + */ + @ExcelProperty(value = "执法时间") + private String enforcementTime; + + /** + * 联合执法 + */ + @ExcelProperty(value = "联合执法") + private String hasUnion; + + /** + * 受委托 + */ + @ExcelProperty(value = "受委托") + private String hasAuto; + + /** + * 委托单位 + */ + @ExcelProperty(value = "委托单位") + private String entrustDeptName; + + /** + * 行政执法类别 + */ + @ExcelProperty(value = "行政执法类别") + private String lawEnforceCategory; + + /** + * 任务来源 + */ + @ExcelProperty(value = "任务来源") + private String checkCategory; + + /** + * 未扫码原因 + */ + @ExcelProperty(value = "未扫码原因") + private String noScanReason; + + /** + * 是否投诉 + */ + @ExcelProperty(value = "是否投诉") + private String isComplaint; +} diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/mapper/EnforcementRegistrationMapper.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/mapper/EnforcementRegistrationMapper.java index 1c8d3eaf..1d8eb254 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/mapper/EnforcementRegistrationMapper.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/mapper/EnforcementRegistrationMapper.java @@ -99,6 +99,14 @@ public interface EnforcementRegistrationMapper extends BaseMapperPlus selectReportPageV2(@Param("page") Page page, + @Param("bo") EnforcementRegistrationBo bo, + @Param("dataFilter") String dataFilter); + /** * 报表-全量列表查询(用于统计/导出) */ diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/report/IEnforcementRegistrationReport.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/report/IEnforcementRegistrationReport.java index 031b09c3..2a2464a4 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/report/IEnforcementRegistrationReport.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/report/IEnforcementRegistrationReport.java @@ -5,6 +5,7 @@ import com.zdxt.enforcementcode.domain.vo.EnforcementRegistrationVo; import com.zdxt.enforcementcode.domain.vo.report.ChartDataVo; import com.zdxt.enforcementcode.domain.vo.report.RegistrationAnalysisVo; import com.zdxt.enforcementcode.domain.vo.report.RegistrationExportVo; +import com.zdxt.enforcementcode.domain.vo.report.RegistrationExportV2Vo; import com.zdxt.enforcementcode.domain.vo.report.RegistrationStatisticsVo; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; @@ -24,9 +25,14 @@ public interface IEnforcementRegistrationReport { RegistrationStatisticsVo statistics(EnforcementRegistrationBo bo); /** - * 统计列表(分页) + * 统计列表V1(全量加载 + Java字典序排序 + 手动分页,兼容旧系统enterprise_address解析) */ - TableDataInfo list(EnforcementRegistrationBo bo, PageQuery pageQuery); + TableDataInfo listForV1(EnforcementRegistrationBo bo, PageQuery pageQuery); + + /** + * 统计列表V2(SQL JOIN字典表排序 + 服务端分页,依赖district/street字段已回填) + */ + TableDataInfo listForV2(EnforcementRegistrationBo bo, PageQuery pageQuery); /** * 统计列表(全量,用于导出) @@ -34,9 +40,14 @@ public interface IEnforcementRegistrationReport { List listAll(EnforcementRegistrationBo bo); /** - * 导出列表(旧系统格式,10列精简) + * 导出列表V1(旧系统格式,10列精简) + */ + List exportListV1(EnforcementRegistrationBo bo); + + /** + * 导出列表V2(与列表展示一致,15列,V2排序) */ - List exportList(EnforcementRegistrationBo bo); + List exportListV2(EnforcementRegistrationBo bo); /** * 执法类别分布(饼图数据) diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/report/impl/EnforcementRegistrationReportImpl.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/report/impl/EnforcementRegistrationReportImpl.java index 4e4bc953..38f197fb 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/report/impl/EnforcementRegistrationReportImpl.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/report/impl/EnforcementRegistrationReportImpl.java @@ -8,6 +8,7 @@ import com.zdxt.enforcementcode.domain.vo.EnforcementRegistrationVo; import com.zdxt.enforcementcode.domain.vo.report.ChartDataVo; import com.zdxt.enforcementcode.domain.vo.report.RegistrationAnalysisVo; import com.zdxt.enforcementcode.domain.vo.report.RegistrationExportVo; +import com.zdxt.enforcementcode.domain.vo.report.RegistrationExportV2Vo; import com.zdxt.enforcementcode.domain.vo.report.RegistrationStatisticsVo; import com.zdxt.enforcementcode.mapper.EnforcementRegistrationMapper; import com.zdxt.enforcementcode.report.IEnforcementRegistrationReport; @@ -65,23 +66,142 @@ public class EnforcementRegistrationReportImpl implements IEnforcementRegistrati } @Override - public TableDataInfo list(EnforcementRegistrationBo bo, PageQuery pageQuery) { - // 数据权限由 @EfcodeDataFilter 拦截器自动处理 + public TableDataInfo listForV1(EnforcementRegistrationBo bo, PageQuery pageQuery) { + // 与旧系统一致:加载全量数据 → 填充区域/街道 → 按字典顺序排序 → 手动分页 + List allRecords = loadAndSortAll(bo); + + // 手动分页 + int pageNum = pageQuery.getPageNum(); + int pageSize = pageQuery.getPageSize(); + int total = allRecords.size(); + int fromIndex = (pageNum - 1) * pageSize; + int toIndex = Math.min(fromIndex + pageSize, total); + List pageData = fromIndex < total ? allRecords.subList(fromIndex, toIndex) : Collections.emptyList(); + + return new TableDataInfo<>(pageData, (long) total); + } + + @Override + public TableDataInfo listForV2(EnforcementRegistrationBo bo, PageQuery pageQuery) { + // V2:SQL层JOIN字典表排序 + 服务端分页(依赖district/street已回填) Page page = pageQuery.build(); - IPage result = registrationMapper.selectReportPage(page, bo, null); + IPage result = registrationMapper.selectReportPageV2(page, bo, null); return TableDataInfo.build(result); } @Override public List listAll(EnforcementRegistrationBo bo) { - // 数据权限由 @EfcodeDataFilter 拦截器自动处理 + return loadAndSortAll(bo); + } + + /** + * 加载全量数据并按字典顺序排序(与旧系统一致) + * 旧系统:加载全部 → 按区域字典顺序遍历 → 按街道字典顺序收集 → 前端分页 + */ + private List loadAndSortAll(EnforcementRegistrationBo bo) { Page page = new Page<>(1, Integer.MAX_VALUE, false); IPage result = registrationMapper.selectReportPage(page, bo, null); - return result.getRecords(); + List records = result.getRecords(); + // 从企业地址中解析区域/街道并按字典顺序排序 + return enrichAndSortByDictOrder(records); + } + + /** + * 从 enterprise_address 中解析区域和街道,并按字典顺序排序(与旧系统逻辑完全一致) + * 旧系统排序:按区域字典dict_sort顺序 → 每个区域内按街道dict_sort顺序 → 同街道内按enforcement_time倒序 + */ + private List enrichAndSortByDictOrder(List list) { + if (list == null || list.isEmpty()) { + return Collections.emptyList(); + } + // 加载区域字典(address_type)——按dict_sort顺序 + List areaList = dictTypeService.selectDictDataByType("address_type"); + if (areaList == null || areaList.isEmpty()) { + return list; + } + // 加载每个区域下的街道字典(按dict_sort顺序) + Map> areaStreetMap = new LinkedHashMap<>(); + for (SysDictDataVo area : areaList) { + List streets = dictTypeService.selectDictDataByType(area.getDictValue()); + areaStreetMap.put(area.getDictLabel(), streets != null ? streets : Collections.emptyList()); + } + + // 构建区域排序索引(dictLabel → 顺序号) + Map areaSortMap = new HashMap<>(); + int areaIdx = 0; + for (SysDictDataVo area : areaList) { + areaSortMap.put(area.getDictLabel(), areaIdx++); + } + // 构建街道排序索引(dictLabel → 顺序号) + Map streetSortMap = new HashMap<>(); + for (List streets : areaStreetMap.values()) { + int streetIdx = 0; + for (SysDictDataVo street : streets) { + streetSortMap.put(street.getDictLabel(), streetIdx++); + } + } + + // 填充区域/街道 + list.forEach(vo -> { + String address = vo.getEnterpriseAddress(); + if (StringUtils.isBlank(address)) { + return; + } + String matchedArea = null; + String matchedStreet = null; + + for (Map.Entry> entry : areaStreetMap.entrySet()) { + String areaLabel = entry.getKey(); + int quIdx = areaLabel.indexOf("区"); + if (quIdx <= 0) { + continue; + } + String prefix = areaLabel.substring(0, quIdx); + String prefixQu = "深圳市" + prefix + "区"; + String prefixXinQu = "深圳市" + prefix + "新区"; + if (address.startsWith(prefixQu) || address.startsWith(prefixXinQu)) { + matchedArea = areaLabel; + for (SysDictDataVo street : entry.getValue()) { + String streetLabel = street.getDictLabel(); + if (address.startsWith(prefixQu + streetLabel) || address.startsWith(prefixXinQu + streetLabel)) { + matchedStreet = streetLabel; + break; + } + } + break; + } + } + + vo.setDistrict(matchedArea != null ? matchedArea : ""); + vo.setStreet(matchedStreet != null ? matchedStreet : ""); + }); + + // 按字典顺序排序:区域字典序 → 街道字典序 → 执法时间倒序 + int maxAreaIdx = areaList.size(); + int maxStreetIdx = streetSortMap.size() + 1; + list.sort((a, b) -> { + int aAreaSort = areaSortMap.getOrDefault(a.getDistrict(), maxAreaIdx); + int bAreaSort = areaSortMap.getOrDefault(b.getDistrict(), maxAreaIdx); + if (aAreaSort != bAreaSort) { + return Integer.compare(aAreaSort, bAreaSort); + } + int aStreetSort = streetSortMap.getOrDefault(a.getStreet(), maxStreetIdx); + int bStreetSort = streetSortMap.getOrDefault(b.getStreet(), maxStreetIdx); + if (aStreetSort != bStreetSort) { + return Integer.compare(aStreetSort, bStreetSort); + } + // 同区域同街道,按执法时间倒序 + if (a.getEnforcementTime() == null && b.getEnforcementTime() == null) return 0; + if (a.getEnforcementTime() == null) return 1; + if (b.getEnforcementTime() == null) return -1; + return b.getEnforcementTime().compareTo(a.getEnforcementTime()); + }); + + return list; } @Override - public List exportList(EnforcementRegistrationBo bo) { + public List exportListV1(EnforcementRegistrationBo bo) { List dataList = listAll(bo); // 字典翻译:执法类别 @@ -115,6 +235,60 @@ public class EnforcementRegistrationReportImpl implements IEnforcementRegistrati }).collect(Collectors.toList()); } + @Override + public List exportListV2(EnforcementRegistrationBo bo) { + // 使用V2排序:Sql JOIN字典表排序,全量加载 + Page page = new Page<>(1, Integer.MAX_VALUE, false); + IPage result = registrationMapper.selectReportPageV2(page, bo, null); + List dataList = result.getRecords(); + + // 字典翻译 + Map categoryDictMap2 = dictTypeService.selectDictDataByType("law_enforce_category").stream() + .collect(Collectors.toMap(SysDictDataVo::getDictValue, SysDictDataVo::getDictLabel, (a, b) -> a)); + Map checkCategoryDictMap = dictTypeService.selectDictDataByType("check_category").stream() + .collect(Collectors.toMap(SysDictDataVo::getDictValue, SysDictDataVo::getDictLabel, (a, b) -> a)); + Map noScanReasonDictMap = dictTypeService.selectDictDataByType("no-scan-reason").stream() + .collect(Collectors.toMap(SysDictDataVo::getDictValue, SysDictDataVo::getDictLabel, (a, b) -> a)); + + java.text.SimpleDateFormat sdf2 = new java.text.SimpleDateFormat("yyyy-MM-dd"); + + return dataList.stream().map(vo -> { + RegistrationExportV2Vo export = new RegistrationExportV2Vo(); + export.setBureauDeptName(vo.getBureauDeptName()); + export.setEnterpriseName(vo.getEnterpriseName()); + export.setEnterpriseNumber(vo.getEnterpriseNumber()); + export.setDistrict(vo.getDistrict()); + export.setStreet(vo.getStreet()); + // 执法人员 + String enforcer = vo.getLawEnforcer() != null ? vo.getLawEnforcer() : ""; + if (StringUtils.isNotBlank(vo.getLawEnforcerTwo())) { + enforcer = enforcer + "," + vo.getLawEnforcerTwo(); + } + export.setLawEnforcer(enforcer); + export.setLawEnforcementItemText(vo.getLawEnforcementItemText()); + // 执法时间 + export.setEnforcementTime(vo.getEnforcementTime() != null ? sdf2.format(vo.getEnforcementTime()) : ""); + // 联合执法 + export.setHasUnion(vo.getHasUnion() != null && vo.getHasUnion() == 1 && StringUtils.isNotBlank(vo.getUnionNo()) ? "是" : "否"); + // 受委托 + export.setHasAuto(vo.getHasAuto() != null && vo.getHasAuto() == 1 ? "是" : "否"); + // 委托单位 + export.setEntrustDeptName(vo.getEntrustDeptName()); + // 行政执法类别 + export.setLawEnforceCategory(categoryDictMap2.getOrDefault( + vo.getLawEnforceCategory() != null ? vo.getLawEnforceCategory() : "", "")); + // 任务来源 + export.setCheckCategory(checkCategoryDictMap.getOrDefault( + vo.getCheckCategory() != null ? vo.getCheckCategory() : "", "")); + // 未扫码原因 + export.setNoScanReason(noScanReasonDictMap.getOrDefault( + vo.getCheckCss() != null ? vo.getCheckCss() : "", "")); + // 是否投诉 + export.setIsComplaint(vo.getIsComplaint() != null && vo.getIsComplaint() == 1 ? "是" : "否"); + return export; + }).collect(Collectors.toList()); + } + @Override public List categoryChart(EnforcementRegistrationBo bo) { // 数据权限由 @EfcodeDataFilter 拦截器自动处理 diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/resources/mapper/enforcementcode/EnforcementRegistrationReportMapper.xml b/zdxt-modules/zdxt-enforcement-code/src/main/resources/mapper/enforcementcode/EnforcementRegistrationReportMapper.xml index ebd34c90..568062b1 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/resources/mapper/enforcementcode/EnforcementRegistrationReportMapper.xml +++ b/zdxt-modules/zdxt-enforcement-code/src/main/resources/mapper/enforcementcode/EnforcementRegistrationReportMapper.xml @@ -132,6 +132,124 @@ ORDER BY enforcement_time DESC + + +