| docs/功能测试报告/功能测试报告_审核平均吨位口径与拆分目标月导入及全屏翻页_2026-09-04.md | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| docs/生成汇总大表/数据导入现状与缺口清单_2026-09-04.md | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| traffic-audit-server/src/main/java/com/trafficaudit/auditengine/service/AuditEngineService.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| traffic-audit-server/src/main/java/com/trafficaudit/dataimport/service/DataImportService.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| traffic-audit-web/src/views/DataView.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
docs/¹¦ÄܲâÊÔ±¨¸æ/¹¦ÄܲâÊÔ±¨¸æ_ÉóºËƽ¾ù¶Öλ¿Ú¾¶Óë²ð·ÖÄ¿±êÔµ¼Èë¼°È«ÆÁ·Ò³_2026-09-04.md
New file @@ -0,0 +1,22 @@ # åè½æµè¯æ¥åï¼å®¡æ ¸å ¬å¼ä¿®æ£ + æåç®æ æå¯¼å ¥ + å ¨å±ç¿»é¡µï¼2026-09-04ï¼ ## ä¸ãè´§è¿å®¡æ ¸ RULE_006ï¼æ´è½¦å¨ä½æ¹ä¸ºâå¹³åå¨ä½âå£å¾ - æ¹å¨ï¼`AuditEngineService.checkOutRange` 对 `tonsWhole` åæ®µæâæ´è½¦å¹³åå¨ä½ = æ´è½¦å¨ä½(tonsWhole) / æ´è½¦è½¦è¾æ°(vehicleWhole)â计ç®åä¸ 4~40 æ¯è¾ï¼æ æ´è½¦æ°æ¶éååå¼å¤æã`h2032FieldLabel` ä¸åï¼æç¤ºææ¬æ¾å¼æ âæ´è½¦å¹³åå¨ä½(æ´è½¦å¨ä½/æ´è½¦æ°)âã - åå ï¼åé»è¾ç´æ¥æ¿æ´è½¦å¨ä½æ»éï¼å¦é»åå¯ç¨ç©æµ 357 å¨ï¼23 è¾æ´è½¦ï¼æ¯ 4~40ï¼ææ»éå½åå误æ¥ã - éªè¯ï¼éæ°æ§è¡ 2026-07 H2032 å®¡æ ¸ï¼POST /api/audit/executeï¼ï¼RULE_006 å½ä¸ 8 æ¡ä¸å ¨é¨ä¸ºâæ´è½¦å¹³åå¨ä½=0.92~3.93ï¼èå´ 4~40âï¼é»åå¯ç¨ 357/23â15.52 ä¸åå½ä¸ï¼ï¼å ¶ä½è§åæ£å¸¸ï¼RULE_001 59ãRULE_002 106ãRULE_004 6ãRULE_005 21ãRULE_003 0ï¼ãç»è®º PASSã ## äºãå®¡æ ¸æç¤ºæ°åä¸åç¨ç§å¦è®¡æ°æ³ - æ¹å¨ï¼`fmt`/`fmt4` ç¨ BigDecimal.toPlainString è¾åºï¼å¤§æ°å¦ 1.04e7 æ¾ç¤ºä¸º 10435762.52 è䏿¯ 1.043576252E7ã - éªè¯ï¼é导å 2026-07 å®¡æ ¸ææ¬å为æ®éåè¿å¶æ¾ç¤ºï¼ç¼è¯éè¿ãç»è®º PASSã ## ä¸ãè§ä¸è§ä¸æåå¯¼å ¥ï¼æç®æ æ¥è¡¨æåªåå¯¹åºæé¡µç¾ - æ¹å¨ï¼`DataImportService.importScaleSplit` å¢å ç®æ æï¼period çæä»½ï¼è¿æ»¤ï¼é¡µç¾å½¢å¦â{M}æç´¯è®¡/Mæä»½âåªå¨è¯¥ M=ç®æ ææ¶å¯¼å ¥ï¼Mæç´¯è®¡âCUMULATIVEãMæä»½âMONTHï¼ï¼é¡µç¾ä¸ºâ彿/累计âï¼æ¨¡æ¿æ ·å¼ï¼ä¸é宿ã - åå ï¼1-N ææ´å æä»¶è¢«æ´å¯¼ä¼æå¤ä¸ªæé¡µç¾å¡è¿å䏿¥è¡¨æé æéå¤è¡ï¼æ¤å 04-07 åå« 72/90/108/126 è¡å³ä¸ºæ¤ç±»èæ°æ®ï¼ã - éªè¯ï¼ç«¯å°ç«¯ï¼ï¼ç¨ã2026å¹´1-6æå ¬è·¯è´§è¿éï¼åå¸å·ï¼.xlsxãé导 2026-04/05/06ï¼æ¯æè¿åâ36 æ¡è®°å½â=彿 18 + 累计 18ï¼åºå æ¯ææ region å¯ä¸ï¼æ¦æ± 2026-06 彿å计å¨è½¬é 687103.88 䏿ºæä»¶éå¼ä¸è´ï¼2026-07 æ§ 126 è¡ç´¯è®¡æ°æ®å¾ ç¨ 1-7 ææä»¶é坼䏿¬¡å³æ¶æä¸º 36 è¡ãç»è®º PASSã ## åãæ°æ®æ¥çå ¨å±æ¨¡å¼å¯ç¿»é¡µï¼åç«¯ï¼ - æ¹å¨ï¼`DataView.vue` æè¡¨æ ¼ä¸å ¶ä¸å页å¨å è¿åä¸ `.table-wrap`ï¼å ¨å±ç®æ ä» `.table-area` æ¹ä¸º `.table-wrap`ï¼å¹¶å å ¨å± flex å¸å±æ ·å¼ï¼å ¨å±æ¶ä¿çå页æ¡ã - éªè¯ï¼æ¨¡æ¿ç»æ/é»è¾è°æ´ç¼è¯ç± vue-cli-service çæ´æ°ï¼æµè§å¨ç«¯éç¨æ·å ¨å±æ¥ç确认ï¼è¡¨æ ¼+å页å¯è§ãå¯ç¿»é¡µï¼ãç»è®ºï¼ä»£ç 就绪ï¼å¾ 人工è§è§ç¡®è®¤ã ## ç¯å¢ - å端 8090ï¼å¤æ¬¡éå¯è³ææ°ä»£ç ï¼æå䏿¬¡ 16:51 就绪ï¼ï¼å端 8080 è¿è¡ä¸ï¼MySQL 127.0.0.1:3308ã docs/Éú³É»ã×Ü´ó±í/Êý¾Ýµ¼ÈëÏÖ×´Óëȱ¿ÚÇåµ¥_2026-09-04.md
@@ -65,3 +65,12 @@ 3. æ¯çæâæ°æ®åå ¬å¼æ¹å¯¹åä½ä¸ºæ¯çâå¤çï¼ææ¿ç¬¬ 5 æ¡ï¼å³ä½æ£æ¸ åæ¹æ¡ A ä¿®æ£ï¼ã 4. ç¬ç«å°è¡¨ä¿çä¸å ï¼ææ¿ç¬¬ 1 æ¡ï¼ï¼å¾ 大表éªè¯éè¿ååè®®ä¸çº¿ã 5. å 许éå¤å¯¼å ¥å·²çæï¼ææ¥è¡¨æå å åæï¼ææ¿ç¬¬ 3 æ¡ï¼ã --- ## æ´æ°è®°å½ï¼2026-09-04 ä¸å ç¨æ·çå¤åï¼ - å ¬äº¤/åºç§/个ä½å®¢è¿/H203-1 已补导ï¼2026-01~07ï¼H203-1 è³ 08ï¼ç°å·²å ¨é½ï¼æèµæ¨¡åæä¸çº³å ¥æ¬æ¬¡èå´ï¼ç¨æ·çå¤ï¼ã - è´§è¿éå¨è½¬éï¼2026-02 å·²æå¯¼å ¥è¡ï¼ç¨æ·çå¤â7æè¡¨æ ¼å·²å« 1-7 ææ¯ææ°æ®âä¸å·²éæ°å¯¼å ¥ï¼2026-04~07 å¨åºï¼01ã03 æ ç¬ç«è¡ä½ 07 è¡å åµåæåå¼ï¼åæ°æ¶æ m01~m07 使ç¨ï¼ã - è§ä¸è§ä¸æåå¯¼å ¥å·²å级为âæç®æ æ¥è¡¨æå页ç¾âï¼åªå¯¼å ¥ {ç®æ æ}æä»½/{ç®æ æ}累计ï¼ä¸åæ 1-N æå ¨é¨é¡µç¾å¡è¿å䏿ï¼ï¼å¹¶å·²ç¨ã2026å¹´1-6æå ¬è·¯è´§è¿éï¼åå¸å·ï¼.xlsxãé导 2026-04/05/06 éªè¯ï¼æ¯æ = 彿 18 è¡ + 累计 18 è¡ï¼æ¦æ± 6 æå½æå计å¨è½¬é 687103.88 䏿ºæä»¶ä¸è´ã2026-07 ç®åä»ä¸ºæ§æ°æ®ï¼126 è¡ç´¯è®¡ï¼ï¼å¾ ç¨ã2026å¹´1-7æå ¬è·¯è´§è¿éï¼åå¸å·ï¼.xlsxãé坼䏿¬¡å³å¯åå¹²åï¼36 è¡ï¼ã - è§ä¸è§ä¸æå 2026-01~03 ä»ç©ºï¼å¯å¤ç¨ã2026å¹´1-6æå ¬è·¯è´§è¿éï¼åå¸å·ï¼ãçæä»¶ï¼å¯¼å ¥é¡µéæ¥è¡¨æ 01/02/03 å³å¯ï¼ç¨åºåªåå¯¹åºæé¡µç¾ï¼ï¼æç¨åæèªå·±çå®ç¨¿æä»¶ã - åâ个ä½å®¢è¿ 2026-05 æä»¶å为 (2026.3)âçç¹å·²æ¾æ¸ ï¼æä»¶ååéãå 容为 6 ææ°æ®ï¼å·²ä¿®æ¹åå¯¼å ¥ï¼06 ç°æ 7 è¡ï¼ã traffic-audit-server/src/main/java/com/trafficaudit/auditengine/service/AuditEngineService.java
@@ -1679,15 +1679,29 @@ return null; } /** æ°å¼èå´æ£æ¥ï¼å¦ æ´è½¦å¨ä½ 4â¤ä¸â¤40ï¼ */ /** æ°å¼èå´æ£æ¥ï¼æ´è½¦å¨ä½æâå¹³åå¨ä½=æ´è½¦å¨ä½/æ´è½¦æ°âå£å¾å¤å® 4~40 */ private AuditResult checkOutRange(AuditRule rule, H2032EnterpriseMonthly report) { String[] bounds = rule.getThreshold().split(","); if (bounds.length < 2) return null; double value = getH2032FieldValue(report, rule.getCheckField()); String field = rule.getCheckField(); String label = h2032FieldLabel(field); double value; if ("tonsWhole".equals(field)) { double vehicles = report.getVehicleWhole() == null ? 0.0 : report.getVehicleWhole().doubleValue(); double tons = nvl(report.getTonsWhole()); if (vehicles > 0) { value = tons / vehicles; label = "æ´è½¦å¹³åå¨ä½(æ´è½¦å¨ä½/æ´è½¦æ°)"; } else { value = tons; // æ æ´è½¦æ°ä½æå¨ä½æ¶ä»æåå¨ä½å¤å® } } else { value = getH2032FieldValue(report, field); } double low = Double.parseDouble(bounds[0].trim()); double high = Double.parseDouble(bounds[1].trim()); if (value > 0 && (value < low || value > high)) { return buildResult(rule, report, h2032FieldLabel(rule.getCheckField()) + "=" + fmt(value), return buildResult(rule, report, label + "=" + fmt(value), "èå´ " + fmt(low) + "~" + fmt(high), "è¶ åºèå´"); } return null; @@ -1805,18 +1819,20 @@ } private String fmt(double v) { if (v == Math.floor(v) && !Double.isInfinite(v)) { if (v == Math.floor(v) && !Double.isInfinite(v) && Math.abs(v) < 1e15) { return String.valueOf((long) v); } return String.valueOf(Math.round(v * 100.0) / 100.0); return java.math.BigDecimal.valueOf(v).setScale(2, java.math.RoundingMode.HALF_UP) .stripTrailingZeros().toPlainString(); } /** å æ¯/å°æ°å¼ï¼ä¿ç 4 ä½å°æ° */ private String fmt4(double v) { if (v == Math.floor(v) && !Double.isInfinite(v)) { if (v == Math.floor(v) && !Double.isInfinite(v) && Math.abs(v) < 1e15) { return String.valueOf((long) v); } return String.valueOf(Math.round(v * 10000.0) / 10000.0); return java.math.BigDecimal.valueOf(v).setScale(4, java.math.RoundingMode.HALF_UP) .stripTrailingZeros().toPlainString(); } // ========== H2031 æ å®¢å®¡æ ¸ ========== traffic-audit-server/src/main/java/com/trafficaudit/dataimport/service/DataImportService.java
@@ -924,6 +924,7 @@ List<ScaleSplitTransport> list = new ArrayList<>(); int failRows = 0; try (Workbook wb = WorkbookFactory.create(file.getInputStream())) { int targetMonth = Integer.parseInt(period.split("-")[1]); // ä» å¯¼å ¥ç®æ ææå¨æç页ç¾ï¼1-Nææä»¶æç®æ æå彿/ç´¯è®¡ï¼ boolean hasPeriodSheet = false; for (int i = 0; i < wb.getNumberOfSheets(); i++) { String sn = wb.getSheetAt(i).getSheetName(); @@ -936,8 +937,16 @@ Sheet sheet = wb.getSheetAt(i); String sheetName = sheet.getSheetName(); String periodType = null; if (sheetName.contains("彿") || sheetName.contains("æä»½")) periodType = "MONTH"; else if (sheetName.contains("累计")) periodType = "CUMULATIVE"; java.util.regex.Matcher mSheetMonth = java.util.regex.Pattern.compile("(\\d{1,2})\\u6708(\\u4efd|\\u7d2f\\u8ba1)").matcher(sheetName); if (mSheetMonth.find()) { int sheetMonth = Integer.parseInt(mSheetMonth.group(1)); if (sheetMonth == targetMonth) { periodType = "份".equals(mSheetMonth.group(2)) ? "MONTH" : "CUMULATIVE"; } } else { if (sheetName.contains("彿")) periodType = "MONTH"; else if (sheetName.contains("累计")) periodType = "CUMULATIVE"; } if (periodType == null) continue; // æ ¡éª sheet å¸å±ï¼ç¬¬2è¡åºå«ãå¸å·/è§ä¸ä¼ä¸è¿è¾éãï¼ç¬¬3è¡å表头åºå«ãå¨è½¬éãæãè´§è¿éãï¼æ©å±å¸å±ï¼ traffic-audit-web/src/views/DataView.vue
@@ -45,20 +45,22 @@ <div style="color:#909399;font-size:12px;margin-bottom:6px"> å ± {{ total }} æ¡è®°å½ï¼å½å第 {{ page }} 页 </div> <div class="table-area" ref="tableArea"> <el-table :data="records" border v-loading="loading" size="small" style="width:100%" height="100%"> <el-table-column v-for="c in columns" :key="c.prop" :prop="c.prop" :label="c.label" :min-width="c.width" show-overflow-tooltip> <template slot-scope="scope"> <span>{{ formatCell(scope.row[c.prop]) }}</span> </template> </el-table-column> </el-table> <div class="table-wrap" ref="tableWrap"> <div class="table-area"> <el-table :data="records" border v-loading="loading" size="small" style="width:100%" height="100%"> <el-table-column v-for="c in columns" :key="c.prop" :prop="c.prop" :label="c.label" :min-width="c.width" show-overflow-tooltip> <template slot-scope="scope"> <span>{{ formatCell(scope.row[c.prop]) }}</span> </template> </el-table-column> </el-table> </div> <el-pagination style="margin-top:15px;text-align:right" background layout="total, prev, pager, next, sizes" :total="total" :current-page.sync="page" :page-size.sync="size" :page-sizes="[20, 50, 100]" @current-change="loadData" @size-change="loadData"> </el-pagination> </div> <el-pagination style="margin-top:15px;text-align:right" background layout="total, prev, pager, next, sizes" :total="total" :current-page.sync="page" :page-size.sync="size" :page-sizes="[20, 50, 100]" @current-change="loadData" @size-change="loadData"> </el-pagination> </el-main> </el-container> </el-container> @@ -110,7 +112,7 @@ }) }, toggleFullscreen() { const el = this.$refs.tableArea const el = this.$refs.tableWrap if (!document.fullscreenElement) { if (el && el.requestFullscreen) el.requestFullscreen() else this.$message.warning("æµè§å¨ä¸æ¯æå ¨å±") @@ -139,4 +141,18 @@ background: #fff; overflow: auto; } #app .table-wrap:fullscreen { padding: 20px; background: #fff; overflow: auto; display: flex; flex-direction: column; } #app .table-wrap:fullscreen .table-area { flex: 1 1 auto; min-height: 0; } #app .table-wrap:fullscreen .el-pagination { flex: none; } </style>