From 7a17662bdadf36c4e30bd53b896571612d48abbb Mon Sep 17 00:00:00 2001
From: zhizhijie <zhizhijie@users.noreply.gitee.com>
Date: 星期三, 09 九月 2026 11:17:38 +0800
Subject: [PATCH] fix: 4项整改——审核结果按模板双Sheet导出(仅核实型+状态筛选)/明细表格化、数据查看分组选择与隐藏三列、报表页隐藏货运旅客城市客运小表、整本预览展示货运城市客运中口径当月累计同比 + 测试报告与工作日结
---
traffic-audit-server/src/main/java/com/trafficaudit/auditengine/service/AuditEngineService.java | 222 ++++++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 203 insertions(+), 19 deletions(-)
diff --git a/traffic-audit-server/src/main/java/com/trafficaudit/auditengine/service/AuditEngineService.java b/traffic-audit-server/src/main/java/com/trafficaudit/auditengine/service/AuditEngineService.java
index 5d343bb..75c05b2 100644
--- a/traffic-audit-server/src/main/java/com/trafficaudit/auditengine/service/AuditEngineService.java
+++ b/traffic-audit-server/src/main/java/com/trafficaudit/auditengine/service/AuditEngineService.java
@@ -1403,24 +1403,29 @@
return a;
}
- /** 瀹℃牳缁撴灉瀵煎嚭 Excel锛堝惈浼佷笟鍚�/瑙勫垯鍚�/鐘舵��/瀹℃牳鎰忚锛� */
+ /** 瀹℃牳缁撴灉瀵煎嚭 Excel锛堜袱 Sheet锛屾寜涓氬姟妯℃澘锛夛細Sheet1 瀹℃牳缁撴灉锛堥�愭潯鏄庣粏锛夛紱Sheet2 浼佷笟鍚堝苟锛堟寜浼佷笟姹囨�� + 闂鍒楋級 */
public byte[] exportResults(String reportPeriod, String reportType) throws Exception {
+ return exportResults(reportPeriod, reportType, true, "all");
+ }
+
+ /** onlyVerify=true 鏃跺墧闄も�滄彁閱掑瀷鈥濊鍒欙紙濡� RULE_004 鐜瘮鎻愰啋锛夛紝鍙繚鐣欐牳瀹炲瀷闂锛泂tatus=all/pending/handled 涓庣晫闈⑩�滅姸鎬佲�濈瓫閫変竴鑷� */
+ public byte[] exportResults(String reportPeriod, String reportType, boolean onlyVerify, String status) throws Exception {
List<AuditResult> results = queryResults(reportPeriod, reportType);
+ java.util.List<AuditResult> filtered = new java.util.ArrayList<>();
+ String st = status == null ? "all" : status.trim();
+ for (AuditResult res : results) {
+ if (onlyVerify && isReminderRule(res.getRuleCode())) continue;
+ if ("pending".equals(st) && !"PENDING".equals(res.getStatus())) continue;
+ if ("handled".equals(st) && (res.getStatus() == null || "PENDING".equals(res.getStatus()))) continue;
+ filtered.add(res);
+ }
try (XSSFWorkbook wb = new XSSFWorkbook()) {
+ // ---------- Sheet1 瀹℃牳缁撴灉锛堥�愭潯锛屽垪涓庝笟鍔℃ā鏉夸竴鑷达級 ----------
Sheet sheet = wb.createSheet("瀹℃牳缁撴灉");
String[] headers = {"鎶ヨ〃鏈�", "浼佷笟/甯傚窞", "瑙勫垯缂栫爜", "瀹℃牳瑙勫垯", "绛夌骇", "瀹為檯鍊�", "闃堝��/鍩哄噯", "鍋忓樊璇存槑", "鐘舵��", "瀹℃牳鎰忚"};
- Row head = sheet.createRow(0);
- for (int i = 0; i < headers.length; i++) {
- Cell cell = head.createCell(i);
- cell.setCellValue(headers[i]);
- org.apache.poi.ss.usermodel.CellStyle style = wb.createCellStyle();
- org.apache.poi.ss.usermodel.Font font = wb.createFont();
- font.setBold(true);
- style.setFont(font);
- cell.setCellStyle(style);
- }
+ writeAuditHeader(sheet, headers);
int r = 1;
- for (AuditResult res : results) {
+ for (AuditResult res : filtered) {
Row row = sheet.createRow(r++);
row.createCell(0).setCellValue(valueOf(res.getReportPeriod()));
row.createCell(1).setCellValue(valueOf(res.getEnterpriseName()));
@@ -1437,10 +1442,95 @@
for (int i = 0; i < widths.length; i++) {
sheet.setColumnWidth(i, widths[i] * 256);
}
+
+ // ---------- Sheet2 浼佷笟鍚堝苟锛堝悓涓�浼佷笟澶氭潯瑙勫垯骞舵帓鍒楀嚭 + 闂姹囨�诲垪锛� ----------
+ Sheet ms = wb.createSheet("浼佷笟鍚堝苟");
+ String[] h2 = {"鎶ヨ〃鏈�", "浼佷笟/甯傚窞", "瀹℃牳瑙勫垯", "瀹為檯鍊�", "闃堝��/鍩哄噯", "鍋忓樊璇存槑", "闂"};
+ writeAuditHeader(ms, h2);
+ java.util.LinkedHashMap<String, java.util.List<AuditResult>> groups = new java.util.LinkedHashMap<>();
+ for (AuditResult res : filtered) {
+ String key = valueOf(res.getEnterpriseName());
+ if (key.isEmpty()) key = valueOf(res.getReportPeriod()) + "#" + valueOf(res.getActualValue());
+ groups.computeIfAbsent(key, k -> new java.util.ArrayList<>()).add(res);
+ }
+ int rowCursor = 1;
+ for (java.util.Map.Entry<String, java.util.List<AuditResult>> e : groups.entrySet()) {
+ java.util.List<AuditResult> items = e.getValue();
+ int groupStart = rowCursor;
+ StringBuilder problems = new StringBuilder();
+ int seq = 0;
+ for (AuditResult it : items) {
+ Row row = ms.createRow(rowCursor++);
+ if (seq == 0) {
+ row.createCell(0).setCellValue(valueOf(it.getReportPeriod()));
+ row.createCell(1).setCellValue(valueOf(it.getEnterpriseName()).isEmpty() ? e.getKey() : valueOf(it.getEnterpriseName()));
+ }
+ row.createCell(2).setCellValue(valueOf(it.getRuleName()));
+ row.createCell(3).setCellValue(valueOf(it.getActualValue()));
+ row.createCell(4).setCellValue(valueOf(it.getThresholdValue()));
+ row.createCell(5).setCellValue(valueOf(it.getDeviation()));
+ seq++;
+ if (problems.length() > 0) problems.append("\n");
+ problems.append(seq).append("銆�").append(issueSentence(it));
+ }
+ if (rowCursor - groupStart > 1) {
+ ms.addMergedRegion(new org.apache.poi.ss.util.CellRangeAddress(groupStart, rowCursor - 1, 1, 1));
+ ms.addMergedRegion(new org.apache.poi.ss.util.CellRangeAddress(groupStart, rowCursor - 1, 6, 6));
+ }
+ Row first = ms.getRow(groupStart);
+ if (first.getCell(6) == null) first.createCell(6);
+ first.getCell(6).setCellValue(problems.toString());
+ }
+ int[] widths2 = {12, 30, 22, 34, 22, 34, 60};
+ for (int i = 0; i < widths2.length; i++) {
+ ms.setColumnWidth(i, widths2[i] * 256);
+ }
ByteArrayOutputStream out = new ByteArrayOutputStream();
wb.write(out);
return out.toByteArray();
}
+ }
+
+ private void writeAuditHeader(Sheet sheet, String[] headers) {
+ Row head = sheet.createRow(0);
+ for (int i = 0; i < headers.length; i++) {
+ Cell cell = head.createCell(i);
+ cell.setCellValue(headers[i]);
+ org.apache.poi.ss.usermodel.CellStyle style = sheet.getWorkbook().createCellStyle();
+ org.apache.poi.ss.usermodel.Font font = sheet.getWorkbook().createFont();
+ font.setBold(true);
+ style.setFont(font);
+ cell.setCellStyle(style);
+ }
+ }
+
+ /** 鎻愰啋鍨嬭鍒欙細浠呮彁绀哄彉鍖栥�佷笉闇�浜哄伐鏍稿疄锛堝 RULE_004 璐ц繍绫诲瀷鐜瘮鎻愰啋锛� */
+ private boolean isReminderRule(String ruleCode) {
+ return "RULE_004".equals(ruleCode);
+ }
+
+ /** 浼佷笟鍚堝苟鈥滈棶棰樷�濆垪璇濇湳锛氭寜瑙勫垯绫诲瀷鐢熸垚鍙鐨勬牳瀹炴剰瑙� */
+ private String issueSentence(AuditResult res) {
+ String code = res.getRuleCode();
+ String dev = valueOf(res.getDeviation());
+ String act = valueOf(res.getActualValue());
+ String thr = valueOf(res.getThresholdValue());
+ if ("RULE_001".equals(code) || "RULE_002".equals(code)) {
+ return "浼佷笟涓婃姤杞﹁締/鍚ㄤ綅涓庤繍鏀挎暟鎹姣斿瓨鍦ㄥ樊寮傦紙" + dev + "锛夛紝璇锋牳瀹�";
+ }
+ if ("RULE_003".equals(code)) {
+ return "涓婃姤鍛ㄨ浆閲忎笌杞ㄨ抗娴嬬畻鍛ㄨ浆閲忓樊寮傛槑鏄撅紙" + dev + "锛夛紝璇峰弬鑰冭建杩规牳瀹炰紒涓氬懆杞噺";
+ }
+ if ("RULE_004".equals(code)) {
+ return "璐ц繍绫诲瀷鐜瘮鍙戠敓鍙樺寲锛岃鏍稿疄";
+ }
+ if ("RULE_005".equals(code)) {
+ return "鏃犻泦瑁呯杞︿絾瀛樺湪闆嗚绠辫揣杩愰噺锛岃鏍稿疄杞﹁締绫诲瀷涓庤揣杩愰噺濉姤";
+ }
+ if ("RULE_006".equals(code)) {
+ return "鏁磋溅鍚ㄤ綅瓒呭嚭 4~40 鍚ㄥ悎鐞嗚寖鍥达紝璇锋牳瀹炲钩鍧囧惃浣嶅~鎶�";
+ }
+ return valueOf(res.getRuleName()) + "寮傚父锛堝疄闄咃細" + act + "锛涘熀鍑嗭細" + thr + "锛�" + dev + "锛夛紝璇锋牳瀹�";
}
private String auditStatusCn(String status) {
@@ -1569,6 +1659,8 @@
switch (rule.getCompareType()) {
case "DIFF":
return checkDiff(rule, report, authMap);
+ case "DIFF_FIELDS":
+ return checkDiffFields(rule, report, authMap);
case "RATIO":
return checkRatio(rule, report, authMap, trackMap);
case "MOM":
@@ -1611,6 +1703,86 @@
return null;
}
+ /** RULE_001 鍒嗛」杩愭斂瀵规瘮锛氱壍寮曡溅/鎸傝溅/鏁磋溅杞﹁締鏁颁笌鎸傝溅鍚ㄤ綅/鏁磋溅鍚ㄤ綅/鎬诲惃浣嶅垎鍒笌杩愭斂瀵规瘮锛屼换涓�鍒嗛」瓒呴檺鍗虫彁閱� */
+ private AuditResult checkDiffFields(AuditRule rule, H2032EnterpriseMonthly report,
+ Map<String, TransportAuthVehicle> authMap) {
+ TransportAuthVehicle auth = findAuth(authMap, report.getEnterpriseName());
+ if (auth == null) return null;
+ String[] fields = rule.getCheckField() == null ? new String[0] : rule.getCheckField().split(",");
+ String[] limits = rule.getThreshold() == null ? new String[0] : rule.getThreshold().split("[,;|]");
+ if (fields.length == 0 || limits.length != fields.length) return null;
+ java.util.List<String> hits = new java.util.ArrayList<>();
+ double maxAbs = 0;
+ for (int i = 0; i < fields.length; i++) {
+ String field = fields[i].trim();
+ double limit;
+ try {
+ limit = Double.parseDouble(limits[i].trim());
+ } catch (Exception e) {
+ return null;
+ }
+ double actual;
+ double reference;
+ String unit;
+ switch (field) {
+ case "vehicleTractor":
+ actual = num(report.getVehicleTractor());
+ reference = num(auth.getTractorCount());
+ unit = "鍙�";
+ break;
+ case "vehicleTrailer":
+ actual = num(report.getVehicleTrailer());
+ reference = num(auth.getTrailerCount());
+ unit = "鍙�";
+ break;
+ case "tonsTrailer":
+ actual = nvl(report.getTonsTrailer());
+ reference = nvl(auth.getTrailerTons());
+ unit = "鍚�";
+ break;
+ case "vehicleWhole":
+ actual = num(report.getVehicleWhole());
+ reference = num(auth.getOtherCount());
+ unit = "鍙�";
+ break;
+ case "tonsWhole":
+ actual = nvl(report.getTonsWhole());
+ reference = nvl(auth.getOtherTons());
+ unit = "鍚�";
+ break;
+ case "tonsTotal":
+ actual = nvl(report.getTonsTotal());
+ reference = nvl(auth.getTrailerTons()) + nvl(auth.getOtherTons());
+ unit = "鍚�";
+ break;
+ default:
+ return null;
+ }
+ double diff = Math.abs(actual - reference);
+ maxAbs = Math.max(maxAbs, diff);
+ if (diff > limit) {
+ hits.add(h2032FieldLabel(field) + "锛氫笂鎶�=" + fmt(actual) + " " + unit + "锛岃繍鏀�=" + fmt(reference) + " " + unit
+ + "锛屽樊" + fmt(diff) + " " + unit + "锛堥檺" + fmt(limit) + " " + unit + "锛�");
+ }
+ }
+ if (hits.isEmpty()) return null;
+ StringBuilder detail = new StringBuilder();
+ for (int i = 0; i < hits.size(); i++) {
+ String one = hits.get(i);
+ if (detail.length() == 0) {
+ detail.append(one);
+ } else if (detail.length() + one.length() + 1 <= 180) {
+ detail.append("锛�").append(one);
+ } else {
+ detail.append("锛涚瓑").append(hits.size() - i).append("椤硅秴闄�");
+ break;
+ }
+ }
+ return buildResult(rule, report, detail.toString(),
+ "鐗靛紩杞�/鎸傝溅/鏁磋溅杞﹁締宸墹5鍙帮紱鎸傝溅鍚ㄤ綅/鏁磋溅鍚ㄤ綅宸墹50鍚紱鎬诲惃浣嶅樊鈮�50鍚�",
+ "瓒呭嚭椤规暟=" + hits.size() + "锛屾渶澶у樊=" + fmt(maxAbs));
+ }
+
/** 涓婃姤鍛ㄨ浆閲忎笌杞ㄨ抗娴嬬畻鍛ㄨ浆閲忓姣旓紝楂樺嚭闃堝�兼瘮渚嬫牳瀹� */
private AuditResult checkRatio(AuditRule rule, H2032EnterpriseMonthly report,
Map<String, TransportAuthVehicle> authMap,
@@ -1645,26 +1817,34 @@
return null;
}
- /** 璐ц繍绫诲瀷鐜瘮锛氭湰鏈堟柊澧烇紙涓婃湀涓�0銆佹湰鏈�>0锛夐渶鏍稿疄锛屽皯鐨勪笉绠� */
+ /** 璐ц繍绫诲瀷鐜瘮锛圧ULE_004锛夛細涓婃湀鏃犫啋鏈湀鏂板 鎴� 涓婃湀鏈夆啋鏈湀鏃狅紝鍧囨彁閱掓牳瀹� */
private AuditResult checkMom(AuditRule rule, H2032EnterpriseMonthly report,
Map<String, H2032EnterpriseMonthly> lastMonthMap) {
H2032EnterpriseMonthly lastMonth = lastMonthMap.get(key(report.getEnterpriseCode()));
if (lastMonth == null) return null;
- List<String> hits = new ArrayList<>();
+ List<String> addHits = new ArrayList<>();
+ List<String> delHits = new ArrayList<>();
for (String field : rule.getCheckField().split(",")) {
double current = getH2032FieldValue(report, field);
double last = getH2032FieldValue(lastMonth, field);
if (current > 0 && last == 0) {
- hits.add(h2032FieldLabel(field) + "=" + fmt(current));
+ addHits.add(h2032FieldLabel(field) + "=" + fmt(current));
+ } else if (last > 0 && current == 0) {
+ delHits.add(h2032FieldLabel(field) + "锛堜笂鏈�=" + fmt(last) + "锛屾湰鏈堟棤锛�");
}
}
- if (!hits.isEmpty()) {
- return buildResult(rule, report, "鏈湀鏂板: " + String.join("銆�", hits),
- "涓婃湀璇ョ被鍨嬩负0", "鏈湀鏂板璐ц繍绫诲瀷锛堜笂鏈堟棤锛�");
+ if (!addHits.isEmpty() || !delHits.isEmpty()) {
+ StringBuilder msg = new StringBuilder();
+ if (!addHits.isEmpty()) msg.append("鏈湀鏂板: ").append(String.join("銆�", addHits));
+ if (!delHits.isEmpty()) {
+ if (msg.length() > 0) msg.append("锛�");
+ msg.append("鏈湀娑堝け: ").append(String.join("銆�", delHits));
+ }
+ return buildResult(rule, report, msg.toString(),
+ "涓婃湀鏃犫啋鏈湀鏂板 鎴� 涓婃湀鏈夆啋鏈湀鏃�", "璐ц繍绫诲瀷鐜瘮鏂板/娑堝け闇�鏍稿疄");
}
return null;
}
-
/** 鏈夎揣杩愰噺浣嗗搴旇溅杈嗕负0 闇�鏍稿疄锛堝 鏈夐泦瑁呯璐ц繍閲忔棤闆嗚绠辫溅杈嗭級 */
private AuditResult checkNull(AuditRule rule, H2032EnterpriseMonthly report) {
String[] fields = rule.getCheckField().split(",");
@@ -1796,6 +1976,10 @@
labels.put("tonsWhole", "鏁磋溅鍚ㄤ綅");
labels.put("turnoverTotal", "鍛ㄨ浆閲�");
labels.put("vehicleWhole", "鏁磋溅杞﹁締鏁�");
+ labels.put("vehicleTractor", "鐗靛紩杞︽暟");
+ labels.put("vehicleTrailer", "鎸傝溅鏁�");
+ labels.put("tonsTrailer", "鎸傝溅鍚ㄤ綅");
+ labels.put("tonsWhole", "鏁磋溅鍚ㄤ綅");
String v = labels.get(field);
return v == null ? field : v;
}
--
Gitblit v1.9.1