| docs/功能测试报告/功能测试报告_汇总大表预览删除中口径后明细表_2026-09-16.md | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| docs/功能测试报告/功能测试报告_货运量周转量多年度导入_2026-09-16.md | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| docs/工作日结/工作日结_2026-09-16.md | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| traffic-audit-server/src/main/java/com/trafficaudit/dataimport/service/DataImportService.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| traffic-audit-web/src/views/ReportExport.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
docs/¹¦ÄܲâÊÔ±¨¸æ/¹¦ÄܲâÊÔ±¨¸æ_»ã×Ü´ó±íÔ¤ÀÀɾ³ýÖпھ¶ºóÃ÷ϸ±í_2026-09-16.md
New file @@ -0,0 +1,47 @@ # åè½æµè¯æ¥åï¼æ¥è¡¨çæ-æ±æ»å¤§è¡¨é¢è§å¼¹çªå é¤ãä¸å£å¾ãä¹åçæç»è¡¨ 2026-09-16 ## åè½è¯´æ - ä½ç½®ï¼æ¥è¡¨çæé¡µ â æ¥è¡¨ç±»åãæ±æ»å¤§è¡¨ãâ éæä»½ â å表è¡ãé¢è§ãâ å¼¹çªãé¢è§æ°æ® - æ±æ»å¤§è¡¨ï¼YYYY-MMï¼ãã - ç°è±¡ï¼æ¹å¨åï¼ï¼å¼¹çªéåºç°**ä¸¤å¼ è¡¨**ââ第ä¸å¼ æ¯ãææ / æ°æ® / 忝ãä¸åçæ±æ»è¡¨ï¼å«é路货è¿ãåå¸å®¢è¿ãä¸å£å¾ä¸æ®µï¼ï¼ç¬¬äºå¼ æ¯ä¸å£å¾ä¹åé夿¸²æçä¸å¼ æç»è¡¨ï¼ä¿¡æ¯åä½ã - éæ±ï¼ææ±æ»å¤§è¡¨é¢è§é**ä¸å£å¾åé¢çè¡¨æ ¼å ¨é¨å æ**ï¼åªä¿çä¸é¢é£å¼ æ±æ»è¡¨ã - æ¹å¨åï¼å¼¹çªå åªå©ç¬¬ä¸å¼ 表ï¼`class="preview-summary wb-table"`ï¼ï¼è¡¨æ ¼ä¸æ¹æ¯ä¸¤æ¡åæ¯ç¼ºå¤±æç¤ºä¸ãå ³éãæé®ã ## æ¶åæ¹å¨ - å端 `traffic-audit-web/src/views/ReportExport.vue`ï¼**åè¡æ¹å¨**ï¼ç¬¬ 133 è¡ï¼ï¼ - åï¼`<table class="preview-summary" v-else-if="it.summary && it.summary.length">` - ç°ï¼`<table class="preview-summary" v-if="it.key !== 'summaryWorkbook' && it.summary && it.summary.length">` - åå 说æï¼`previewItems` é `summaryWorkbook` è¿ä¸é¡¹åæ¶å¸¦æ `summary` æ°æ®ï¼èä¸é¢çæ±æ»è¡¨ï¼ç¬¬ 115 è¡ `v-if="it.key === 'summaryWorkbook' && it.summary && it.summary.length"`ï¼å·²ç»æ¯ `v-if`ï¼åæ¥ç第äºç§è¡¨ç¨çæ¯ `v-else-if`ï¼ä¼è·å¨åä¸ä¸ª `v-if` ä¹åï¼äºæ¯å¯¹ `summaryWorkbook` ä¹ç §æ ·æ¸²æåºç¬¬äºå¼ è¡¨ãæ¹æå¸¦ `it.key !== 'summaryWorkbook'` æ¡ä»¶çç¬ç« `v-if` åï¼æ±æ»å¤§è¡¨ä¸å渲æç¬¬äºå¼ 表ï¼èå ¶å®æ¥è¡¨ç±»åï¼å¦æ `summary` çï¼è¡ä¸ºä¿æä¸åã - 第 115â132 è¡çæ±æ»è¡¨ï¼å«ãé¨åææ ç¼ºå°ä¸å¹´åæâ¦ãæç¤ºï¼**æªæ¹å¨**ã - æªæ¹åç«¯ãæªæ¹æ¥å£ãæªæ¹å¯¼åºã ## æµè¯ç¯å¢ - å端ï¼traffic-audit-web 8080 devï¼æ¹å¨å `Compiled successfully`ï¼ã - å端ï¼traffic-audit-server 8090ï¼æ¬æ¬¡ä¸æ¶åå端ï¼ã - æµè§å¨ï¼Codex åºç¨å æµè§å¨ï¼`admin` ç»å½ï¼å°å `http://localhost:8080/#/report`ã - è¢«æµæ°æ®ï¼æ¥è¡¨ç±»åãæ±æ»å¤§è¡¨ããæä»½ `2026å¹´8æ`ï¼æºæ°æ®å·²ç±æ¬æ¬¡å¤å¹´åº¦å¯¼å ¥ä¿è¯ï¼ã ## æµè¯æ¹æ³ï¼éè¦è¯´æï¼ - **ä¸ä¸è½®çæªå¾ä¸è½ä½ä¸ºè¯æ®**ï¼æ©ææªå¾ `_qa_out/preview_summaryWorkbook_2026-08_after_fix.png` æ¯å¨å¼¹çªå°æªæ¸²æ/忝ä¸å½æ¶æçï¼ç»é¢é没æå¼¹çªå 容ï¼å±äºæ æè¯æ®ï¼åæ¶ä¾èµå¯è®¿é®æ§æ ï¼AXï¼è¯»åä¹ä¸å¯é ï¼æ¬æº `getAXState()` è¿åç¼åï¼ä¼è¯»å°è¿æå 容ï¼ã - æ¬è½®æ¹ç¨**ç´æ¥è¯» DOM**ä½ä¸ºå¯ä¸å¤æ®ï¼`tab.playwright.evaluate(() => {...})` ç»è®¡å¼¹çªå `table` å ç´ çæ°éãç±»åä¸è¡æ°ã - å ³é®æä½åï¼å·²é¿å¼ï¼ï¼`el-select` 䏿项 `isVisible()` æä¸º falseï¼æ æ³ç¨ææ¬ç¹å»éæä»½ï¼æ¹ç¨é®ç `ArrowDown`/`Enter`ï¼è¡å ãé¢è§ãæé®å¿ é¡»ç¨ `locator('.el-table__row button').nth(1)`ï¼`has-text` ä¼å½ä¸ç¦ç¨çãæ¹éé¢è§ãï¼ï¼é¡µé¢ä¸å¸¸é©» 3 个 `.el-dialog__wrapper`ï¼éæ `getComputedStyle(w).display !== 'none'` æ¾å½åæå¼çé£ä¸ªï¼æ¹ `.vue` åå¿ é¡» `tab.reload()` æè½æ¿å°ææ°é¡µé¢ã - æææªå¾ï¼`_qa_out/preview_summaryWorkbook_2026-08_verified_20260916.png`ï¼54006 åèï¼ä¸ `_qa_out/preview_summaryWorkbook_2026-08_verified2_20260916.png`ï¼54006 åèï¼æ¬è½®å¤æ ¸æ¶éæï¼ã ## ç¨ä¾è¡¨ | # | ç¨ä¾ | è¾å ¥ | 颿 | å®é | ç»è®º | |---|---|---|---|---|---| | 1 | æ£å-å¼¹çªå¯æå¼ | æ±æ»å¤§è¡¨ / 2026å¹´8æ / ç¹è¡å ãé¢è§ã | å¼¹åºãé¢è§æ°æ® - æ±æ»å¤§è¡¨ï¼2026-08ï¼ã | å¼¹çªæ£å¸¸æå¼ï¼æ é¢ä¸é¢æä¸è´ | éè¿ | | 2 | æ£å-è¡¨æ ¼æ°é | DOM ç»è®¡å½åå¯è§å¼¹çªå `table` æ°é | åªå© 1 å¼ ï¼ä¸å£å¾ä¹åç表已å é¤ï¼ | `visible` å¼¹çªä» 1 个ï¼å ¶ä¸ `body.querySelectorAll('table').length === 1` | éè¿ | | 3 | æ£å-è¡¨æ ¼æ è¯ | 读å该表 class ä¸è¡æ° | ä¸ºæ±æ»è¡¨ï¼`preview-summary wb-table`ï¼ï¼12 è¡ææ | `cls="preview-summary wb-table"`ï¼`tbody tr` 计 12 è¡ | éè¿ | | 4 | æ£å-å 容宿´ | 读å 12 è¡ææ¬ | é路货è¿/åå¸å®¢è¿/ä¸å£å¾å 4 é¡¹ï¼æ°å¼ä¸åæ¯é½å ¨ | é路货è¿ï¼å½æè´§è¿é 16888.76ãå½æè´§ç©å¨è½¬é 2270010.6ï¼åæ¯ 4.8%ï¼ã累计货è¿é 130311.89ã累计货ç©å¨è½¬é 17492129.05ï¼åæ¯ 0%ï¼ï¼åå¸å®¢è¿ï¼29575.09 / 212391.4 / 254440.17 / 1806719.08ï¼ä¸å£å¾ï¼1628.65 / 115847.35 / 12691.45 / 900177.92 | éè¿ | | 5 | æ£å-è¡¨æ ¼ä¸æ¹å 容 | 读åè¡¨æ ¼ä¹åçèç¹ | åªå©æç¤ºä¸å ³éæé®ï¼æ 第äºå¼ 表 | 便¬¡ä¸ºã· 2025-08 åæåå¸å®¢è¿æ°æ®æªå¯¼å ¥åºï¼åå¸å®¢è¿åæ¯æä¸æ¾ç¤ºâ¦ãã· 2025-08 åæå ¬è·¯æ å®¢æ°æ®æªå¯¼å ¥åºï¼ä¸å£å¾åæ¯æä¸æ¾ç¤ºâ¦ãä¸ãå ³éãæé® | éè¿ | | 6 | åå½-å ¶å®æ¡ä»¶ä¸åå½ | æ£æ¥ç¬¬ 115â132 è¡æ±æ»è¡¨ä¸ `wbMissing` æç¤º | æªè¢«æ¹å¨ | 䏿¹å¨åä¸è´ï¼`git diff` ä» ç¬¬ 133 è¡ 1 è¡åæ´ï¼ | éè¿ | | 7 | åå½-å ¶å®æ¥è¡¨ç±»å | æ£æ¥ `v-if` æ¡ä»¶å¯¹é `summaryWorkbook` 项 | è¡ä¸ºä¸åï¼ä»æ `summary` 渲æï¼ | æ¡ä»¶ä¸º `it.key !== 'summaryWorkbook' && it.summary && it.summary.length`ï¼éæ±æ»å¤§è¡¨é¡¹è¡ä¸ºä¸å | éè¿ | ## åç°çé®é¢ä¸å¤ç½® 1. **ä¸ä¸è½®åè¯æ æï¼å·²ä¿®æ£ï¼**ï¼æ©ææªå¾æªæå°å¼¹çªãAX æ 为ç¼åï¼å·²å¨æ¬æ¥åä¸ä½åºï¼æ¬è½®ä»¥ DOM 宿µ + æææªå¾éæ°åè¯ã 2. **å¼¹çªå ãå ± 0 è¡ãä¸ä¸æ¹ãæåº¦è¦çï¼1~8æåææ°æ®ãå£å¾ä¸å**ï¼`rowCount` è¡¨ç¤ºçæ¯æç»è¡æ°ï¼æ±æ»å¤§è¡¨ä¸å«æç»è¡ï¼æ 为 0ï¼ï¼è¿æ¯æ¢æå±ç¤ºå£å¾ï¼éæ¬æ¬¡æ¹å¨å¼å ¥ï¼æ¬æ¬¡æªæ¹ï¼å¦ç¨æ·è§å¾æè¯¯è§£ï¼å¯å¦è¡è°æ´ææ¡ã 3. 两æ¡åæ¯ç¼ºå¤±æç¤ºï¼2025-08 åå¸å®¢è¿ / å ¬è·¯æ 客忿°æ®æªå ¥åºï¼ä¸ºæ°æ®ä¾§ç°ç¶ï¼éæ¬æ¬¡æ¹å¨å¼èµ·ï¼å¾ 2025 å¹´å®ç¨¿æ°æ®å¯¼å ¥åèªå¨æ¶å¤±ã ## ç»è®º - éè¿ãæ±æ»å¤§è¡¨é¢è§å¼¹çªä¸ãä¸å£å¾ãä¹åçé£å¼ 表已彻åºç§»é¤ï¼DOM 宿µå¼¹çªå æä¸ä» æ 1 å¼ è¡¨ï¼`preview-summary wb-table`ï¼12 è¡æ±æ»ææ ï¼ï¼è¡¨æ ¼å 容䏿¹å¨åä¸è´ãæ ä¿¡æ¯ä¸¢å¤±ï¼å ¶å®æ¥è¡¨ç±»åçé¢è§è¡ä¸ºä¸åå½±åã - å¾ ç¨æ·å¨èªå·±çæµè§å¨ä¸æå¼ãæ¥è¡¨çæ â æ±æ»å¤§è¡¨ â 2026å¹´8æ â é¢è§ãå䏿¬¡ç®è§éªæ¶ã docs/¹¦ÄܲâÊÔ±¨¸æ/¹¦ÄܲâÊÔ±¨¸æ_»õÔËÁ¿ÖÜתÁ¿¶àÄê¶Èµ¼Èë_2026-09-16.md
New file @@ -0,0 +1,50 @@ # åè½æµè¯æ¥åï¼è´§è¿éå¨è½¬é表å¤å¹´åº¦å·¥ä½ç°¿ï¼2021â2026ï¼ä¸æ¬¡æ§å ¥åº 2026-09-16 ## åè½è¯´æ - éæ±ï¼8 æå¯¼å ¥çãå®ç¨¿-æ¹åçåå¸å·è¿è¾éæ°æ®ï¼2026å¹´1-8æï¼.xlsxãä¸ä¸ªå·¥ä½ç°¿å å« 21â26 å¹´ï¼æºæä»¶ç¼º 2023 å¹´ï¼å ¨é¨å¹´åº¦æ°æ®ï¼è¦æ±æè¿äºæ°æ®å ¨é¨è¯»å ¥æ°æ®åºã - æ§è¡ä¸ºï¼`importFreightTurnover` åªè¯»ç¬¬ 1 个 Sheetï¼å¹¶æã模æ¿_è´§è¿éå¨è½¬é.xlsxãçå·¦å³ä¸¤åï¼å·¦åä»å¹´ 1âN æãå³åå»å¹´ 1â12 æï¼è§£æï¼å¯¼è´å ¶ä½å¹´åº¦ Sheet çæ°æ®è¢«ç´æ¥ä¸¢å¼ã - æ°è¡ä¸ºï¼å¯¼å ¥æ¶å 夿æ¯å¦ä¸ºãå¤å¹´åº¦å·¥ä½ç°¿ãï¼Sheet æ° â¥ 2ãæ¯ä¸ª Sheet åå½¢å¦ `2021å¹´`ãä¸é¦è¡ A åå«ãè´§è¿éããB åå«ãæãï¼ã - å½ä¸ï¼é Sheet è§£ææ´å¹´ 1â12 æçè´§è¿éåä¸å¨è½¬éåï¼**æ¯ä¸ªå¹´åº¦è½ä¸ä¸ªæ¥è¡¨æ**ï¼æ¥è¡¨æ = 该年æåä¸ä¸ªæè´§è¿éæ°æ®çæä»½ï¼æ¬æ¬¡ä¸º `YYYY-12`ï¼ï¼ä¸å¹´åæåä¸ä¸å¹´åº¦ Sheetã - æªå½ä¸ï¼å®å ¨åéåææåº¦è§£æè·¯å¾ï¼è¡ä¸ºä¸æ¹å¨åä¸è´ã - å¹çï¼ä»ææ¥è¡¨æãå å åæãï¼æ¯ä¸ªå¹´åº¦åå䏿¡ `import_batch` è®°å½ã ## æ¶åæ¹å¨ - å端 `traffic-audit-server/src/main/java/com/trafficaudit/dataimport/service/DataImportService.java`ï¼+153 / â19ï¼ï¼ - `importFreightTurnover` æ¹ä¸ºåæµå ¥å£ï¼åé»è¾æ´ä½æ½ä¸º `importFreightTurnoverByMonth`ï¼é»è¾ä¸æ¹å¨åéè¡ä¸è´ï¼ã - æ°å¢ `detectYearSheets`ï¼å¤å¹´åº¦è¯å«ï¼ã`importFreightTurnoverByYear`ï¼æå¹´è§£æ + ä¸å¹´åæï¼ã`parseWholeYearSheet`ï¼æ´å¹´ Sheet è§£æï¼ã`persistFreightTurnover`ï¼ææ¥è¡¨æå å åæ + è®°æ¹æ¬¡ï¼ã - 顶鍿°å¢ `import java.util.TreeMap;`ã - æªæ¹æ°æ®åºç»æãæªæ¹åç«¯ãæªæ¹å¯¼å ¥æ¥å£ç¾åï¼ä»ä¸º `POST /api/import/freightTurnover?period=yyyy-MM`ï¼ã ## æµè¯ç¯å¢ - å端ï¼traffic-audit-server 8090ï¼å«æ¬æ¬¡æ¹å¨ï¼`start-dev.ps1` å¯å¨æåï¼backend.log åºç° `Tomcat started on port(s): 8090` / `Started TrafficAuditApplication`ï¼ã - å端ï¼traffic-audit-web 8080ï¼æ¬æ¬¡ä¸æ¶åå端ï¼ã - æ°æ®åºï¼æ¬æº MySQL `127.0.0.1:3308/traffic_audit`ï¼ç¨ mysql CLI ç´æ¥æ ¸å¯¹ã - æºæä»¶ï¼`D:\05_æ°æ®åç±»\é«é\å®ç¨¿-æ¹åçåå¸å·è¿è¾éæ°æ®ï¼2026å¹´1-8æï¼.xlsx`ï¼Sheet 为 `['2026å¹´','2025å¹´','2024å¹´','2022å¹´','2021å¹´']`ï¼2026/2025 å 38 è¡Ã15 åï¼2024 48 è¡Ã13 åï¼2022 40 è¡Ã15 åï¼2021 41 è¡Ã14 åï¼ã - è´å/è¾¹çç¨ä¾ä¸å¾å¨ä¸æ¬¡æ§æµè¯æ `2099-01` ~ `2099-04` å è¿è¡ï¼å ¨ç¨ä¸è§¦ç¢°çå®æä»½ï¼æµè¯åå·²éä¸ªæ¸ ç©ºã ## ç¨ä¾è¡¨ | # | ç¨ä¾ | è¾å ¥ | 颿 | å®é | ç»è®º | |---|---|---|---|---|---| | 1 | æ£å-å¤å¹´åº¦å¯¼å ¥ | ä¸ä¼ æºæä»¶ï¼`period=2026-08` | 21/22/24/25/26 äºä¸ªå¹´åº¦å ¨é¨å ¥åº | è¿åãå ± 90 æ¡è®°å½ãï¼5 个æ¥è¡¨æ à 18 è¡ï¼ï¼åºå æ°å¢/è¦ç `2021-12`ã`2022-12`ã`2024-12`ã`2025-12`ã`2026-08` | éè¿ | | 2 | æ£å-å ¥åºæ½æ¥ï¼é项对é½ï¼ | æºæä»¶éå¹´éå¸å·éæä¸åºå é项æ¯å¯¹ï¼ä»å¹´è´§è¿é/ä»å¹´å¨è½¬é/ä¸å¹´è´§è¿é/ä¸å¹´å¨è½¬éï¼ | å®å ¨ä¸è´ | æ¯å¯¹ **1080 个åå æ ¼ï¼å·®å¼ 0**ï¼èæ¬ `_verify_ft_multi.py`ï¼ | éè¿ | | 3 | æ£å-æ¥è¡¨æè¯ä¹ | æ¥çåæ `report_period` | æ¯å¹´åº¦ä¸ä¸ªæ¥è¡¨æ | `2021-12 / 2022-12 / 2024-12 / 2025-12 / 2026-08`ï¼æºæä»¶æ 2023 å¹´ï¼æ æªçæ `2023-12` | éè¿ | | 4 | æ£å-ä¸å¹´åæ | åæ `last_*` æ¯å¦åä¸ä¸å¹´åº¦ Sheet | æä¸ä¸å¹´åº¦çæå¼ãæ ç为空 | `2022-12`ã`2025-12`ã`2026-08` å 18 è¡ `last_*` å ¨é¨æå¼ï¼`2021-12`ï¼æ ä¸å¹´ï¼ã`2024-12`ï¼ç¼º 2023ï¼ä¸ºç©º | éè¿ | | 5 | æ£å-å¯¼å ¥æ¹æ¬¡ | æ¥è¯¢ `import_batch` | æ¯ä¸ªæ¥è¡¨æä¸æ¡è®°å½ | 馿¬¡å¯¼å ¥åå ¥ id 324â328ï¼2021-12/2022-12/2024-12/2025-12/2026-08ï¼ï¼5 æ¡å total=success=18ãfail=0ï¼file_name ä¸ºæºæä»¶å | éè¿ | | 6 | è´å-å Sheet æåº¦æ¨¡æ¿åé | å Sheet æåº¦æ¨¡æ¿æä»¶ + `period=2099-01` | è¯å«ä¸å½ä¸ï¼åéæåº¦è·¯å¾ | è¿åãå ± 18 æ¡è®°å½ãï¼ä¸æ¹å¨åä¸è´ | éè¿ | | 7 | è´å-é年度å½åå¤ Sheet åé | 两个é年度å½å Sheetï¼Sheet1/Sheet2ï¼+ `period=2099-02` | è¯å«ä¸å½ä¸ï¼åéæåº¦è·¯å¾ | `code=200`ï¼18 æ¡ | éè¿ | | 8 | è´å-æ··åå½ååé | 年度å + éå¹´åº¦åæ··åï¼2021å¹´/2022å¹´/夿³¨è¯´æï¼+ `period=2099-03` | è¯å«ä¸å½ä¸ï¼åéæåº¦è·¯å¾ | `code=200`ï¼18 æ¡ | éè¿ | | 9 | è´å-é Excel æä»¶ | ææ¬æä»¶å½ xlsx ä¸ä¼ + `period=2099-04` | æ¥éä¸ä¸è½åº | `{"code":500,"message":"å¯¼å ¥å¤±è´¥: Can't open workbook - unsupported file type: UNKNOWN"}` | éè¿ | | 10 | å¹ç-éå¤å¯¼å ¥ | å䏿ºæä»¶å坼䏿¬¡ | ä¸äº§çéå¤è¡ãå¼ä¸å | ä»è¿åãå ± 90 æ¡è®°å½ãï¼å¯¼å ¥ååå id 332â336ï¼**å ¨è¡¨ 216 è¡åå md5 ä¸è´**ï¼`a2a733b2c5321a9d5efa9be2e0c5dacb`ï¼ | éè¿ | | 11 | åå½-æµè¯ææ¸ ç | é个 `POST /api/import/clear?period=2099-0x` | æµè¯ææ°æ®ä¸æ¹æ¬¡å ¨é¨å é¤ | åæ dataRows=18ãbatchRows=1 å 餿åï¼å½ååº **0 æ¡ 2099 æ°æ®ã0 æ¡ 2099 æ¹æ¬¡** | éè¿ | | 12 | åå½-ç宿份æ»é | ç»è®¡ `freight_turnover_import` | ä¸å¯¼å ¥åå£å¾ä¸è´ | 12 个æ¥è¡¨æ à 18 è¡ = **216 è¡**ï¼2021-12 / 2022-12 / 2024-12 / 2025-12 / 2026-01â¦2026-08ï¼ | éè¿ | ## åç°çé®é¢ä¸å¤ç½® 1. **æºæä»¶ç¼º 2023 å¹´ Sheet**ï¼å¯¼è´ä¸çæ `2023-12` æ¥è¡¨æï¼`2024-12` æ ä¸å¹´åæï¼`last_*` 为空ï¼ã屿ºæ°æ®ç¼ºå£ï¼é代ç 缺é·ï¼å·²å¦å®åæ å¨åºå ã 2. **æ¥è¡¨æè¯ä¹ä¸ºãæ´å¹´ã**ï¼`2021-12` çæå®é æ¿è½½è¯¥å¹´ 1â12 æçå ¨å¹´æ°æ®ï¼èé 12 æåæï¼ãè¥åç»æ¥è¡¨/å®¡æ ¸æãåæãå£å¾åè¿äºæï¼éè¦ç¨æ·ç¡®è®¤å£å¾ï¼æ¬æ¬¡æªåæ¹å¨ã 3. **éå¤å¯¼å ¥ä¼è¦çåæ¥è¡¨æ**ï¼æ°é»è¾å»¶ç»ãå å åæãçå¹ççç¥ï¼é导 `2026-08` ä¼è¦ç该æåæå¼ãæ¬æ¬¡å·²éé¡¹æ ¸å¯¹æºæä»¶ä¸åºå ä¸è´ï¼å·®å¼ 0ï¼ï¼æ æ°æ®æå¤±ã 4. **å¤ä»½ä¸å®æ´ï¼å·²è®°å½ï¼**ï¼æ¹å¨åçå¤ä»½ `_backup_freight_turnover_before_multiyear_20260916.sql` åªæ 59642 åèä¸ä» è§£æåº `2026-04` ä¸å¤ INSERTï¼ä¸è½ä½ä¸ºå®æ´åæ»ä¾æ®ã**ä¸è¦æè¯¥æä»¶å½ä½å®æ´å¤ä»½ä½¿ç¨ã** 5. **2026-01â¦2026-07 ç `last_*` 为空**ï¼ç»æ ¸å¯¹å¤ä»½ï¼`2026-04`ï¼ç¡®è®¤è¿å æå¨æ¬æ¬¡æ¹å¨å `last_*` å³ä¸ºç©ºï¼ä¸æ¬æ¬¡å¯¼å ¥æªè§¦ç¢°è¿äºæ¥è¡¨æï¼æ¹æ¬¡è®°å½åªè¦ç 5 个æï¼ï¼æ éæ¬æ¬¡æ¹å¨å¼å ¥ã ## ç»è®º - éè¿ãå¤å¹´åº¦å·¥ä½ç°¿ï¼21â26 å¹´ï¼å·²å ¨é¨å ¥åºï¼éå¹´ä¸ä¸ªæ¥è¡¨æãéå¹´ä¸å¹´åæï¼1080 个åå æ ¼é项æ¯å¯¹é¶å·®å¼ï¼éå¤å¹´åº¦æä»¶èªå¨åéåææåº¦è·¯å¾ï¼è´åä¸è¾¹çç¨ä¾å符å颿ï¼éå¤å¯¼å ¥å¹çï¼æµè¯æå·²æ¸ çå¹²åï¼çå®æä»½æ°æ®ä¸æ¹å¨åå£å¾ä¸è´ï¼216 è¡ / 12 æï¼ã - å¾ ç¨æ·ç¡®è®¤ï¼`2021-12` çãæ´å¹´ãæ¥è¡¨æçä¸å¡å£å¾æ¯å¦ç¬¦ååç»æ¥è¡¨/å®¡æ ¸åæ°è¦æ±ï¼å¦éãéææ¥è¡¨æãï¼éè¦å¦è¡æ¹é ï¼æ¬æ¬¡æªåï¼ã docs/¹¤×÷ÈÕ½á/¹¤×÷ÈÕ½á_2026-09-16.md
@@ -43,3 +43,38 @@ 2. æäº¤ `0d2a5fc`ï¼`fix(cors): æ¾è¡å ç½ç½æ®µæ¥æºï¼ä¿®å¤å±åç½ IP è®¿é®æ¶ç»å½ 403`ï¼ 3. æ¨ä¸ªäººä»åº `origin`ï¼`git push origin main:master` æåï¼`82100d6..0d2a5fc`ï¼ï¼ 4. æ¨å ¬å¸ `gitea`ï¼`git fetch gitea`ã`git push gitea main:main` åå HTTP æ ååºèæèµ·ï¼æªæ¨éæåï¼è¯¦è§éçé®é¢ 5ï¼ï¼æ¬æ¬¡ä¸ºå¿«è¿æ¨éï¼ä¸æ¶å强æ¨ã --- ## å ãä¸å追å ï¼ä¸¤æ¡ç¨æ·éæ±ï¼2026-09-16ï¼ ### 1. æ 8 æå¯¼å ¥çãè´§è¿éå¨è½¬é表ãä¸ç 21â26 å¹´æ°æ®å ¨é¨è¯»å ¥æ°æ®åº - **èæ¯**ï¼ç¨æ· 8 æå¯¼å ¥ç `å®ç¨¿-æ¹åçåå¸å·è¿è¾éæ°æ®ï¼2026å¹´1-8æï¼.xlsx` ä¸ä¸ªå·¥ä½ç°¿å å« 5 个年度 Sheetï¼`2026å¹´ / 2025å¹´ / 2024å¹´ / 2022å¹´ / 2021å¹´`ï¼æºæä»¶æ 2023 å¹´ï¼ï¼èèé»è¾åªè¯»ç¬¬ 1 个 Sheet å¹¶æãå·¦åä»å¹´ 1âN æ / å³åå»å¹´ 1â12 æãçæåº¦æ¨¡æ¿è§£æï¼å ¶ä½å¹´åº¦æ°æ®è¢«ä¸¢å¼ã - **æ¹å¨ï¼å端 1 æä»¶ï¼+153/â19ï¼**ï¼`DataImportService.java` ä¸ `importFreightTurnover` æ¹ä¸ºåæµå ¥å£ï¼åé»è¾æ½ä¸º `importFreightTurnoverByMonth`ï¼éè¡ä¸åï¼ï¼æ°å¢ `detectYearSheets`ï¼è¯å«å¤å¹´åº¦å·¥ä½ç°¿ï¼ã`importFreightTurnoverByYear`ï¼æå¹´å ¥åº + ä¸å¹´åæåèªä¸ä¸å¹´åº¦ Sheetï¼ã`parseWholeYearSheet`ï¼æ´å¹´ Sheet çè´§è¿éå/å¨è½¬éåè§£æï¼ã`persistFreightTurnover`ï¼ææ¥è¡¨æå å åæå¹¶è®°æ¹æ¬¡ï¼ã - **ç»æ**ï¼æºæä»¶ 5 ä¸ªå¹´åº¦å ¨é¨å ¥åºï¼è¿åãå ± 90 æ¡è®°å½ãï¼æ¥è¡¨æä¸º `2021-12 / 2022-12 / 2024-12 / 2025-12 / 2026-08`ï¼æ¯æ 18 è¡ï¼ä¸æºæä»¶é项æ¯å¯¹ **1080 个åå æ ¼é¶å·®å¼**ï¼éå¤å¯¼å ¥å¹çï¼å ¨è¡¨ 216 è¡ md5 ååä¸è´ï¼ï¼éå¤å¹´åº¦æä»¶èªå¨åéåæåº¦è·¯å¾ã - 详è§ãåè½æµè¯æ¥å_è´§è¿éå¨è½¬éå¤å¹´åº¦å¯¼å ¥_2026-09-16.mdãã ### 2. æ¥è¡¨çæ-æ±æ»å¤§è¡¨é¢è§ï¼å æãä¸å£å¾ãä¹åçè¡¨æ ¼ - **æ¹å¨ï¼å端 1 æä»¶ï¼åè¡ï¼**ï¼`ReportExport.vue` 第 133 è¡ç± `v-else-if="it.summary && it.summary.length"` æ¹ä¸º `v-if="it.key !== 'summaryWorkbook' && it.summary && it.summary.length"`ãæ ¹å æ¯ä¸é¢çæ±æ»è¡¨ç¨ `v-if`ã第äºå¼ è¡¨ç¨ `v-else-if`ï¼å¯¹ `summaryWorkbook` ä¹ç §æ ·æ¸²æã - **éªè¯ï¼æ¨ç¿»ä¸ä¸è½®çæ æåè¯ï¼**ï¼æ©ææªå¾æ²¡æå°å¼¹çªãAX æ 读å°çæ¯ç¼åï¼åä¸ºæ æè¯æ®ï¼æ¬è½®æ¹ç¨ `tab.playwright.evaluate` ç´æ¥è¯» DOM ââ å¼¹çªå æä¸ä» æ 1 å¼ è¡¨ï¼`preview-summary wb-table`ï¼12 è¡ææ ï¼ï¼è¡¨æ ¼ä¸æ¹åªæä¸¤æ¡åæ¯ç¼ºå¤±æç¤ºä¸ãå ³éãæé®ï¼**第äºå¼ è¡¨å·²å½»åºæ¶å¤±**ãæææªå¾ï¼`_qa_out/preview_summaryWorkbook_2026-08_verified_20260916.png`ï¼æ¬è½®å¤æ ¸éæ `..._verified2_20260916.png`ï¼å 54006 åèï¼ã - 详è§ãåè½æµè¯æ¥å_æ±æ»å¤§è¡¨é¢è§å é¤ä¸å£å¾åæç»è¡¨_2026-09-16.mdãã ## ä¸ãæµè¯ç»ææè¦ï¼ä¸å追å é¨åï¼ - å¤å¹´åº¦å¯¼å ¥ï¼12 æ¡ç¨ä¾å ¨éè¿ââæ£åï¼å¤å¹´åº¦å ¥åºã1080 åå æ ¼éé¡¹æ½æ¥é¶å·®å¼ãæ¥è¡¨æè¯ä¹ãä¸å¹´åæãæ¹æ¬¡è®°å½ï¼ãè´åï¼å Sheet æåº¦æ¨¡æ¿åéãé年度å½åå Sheet åéãæ··åå½ååéãé Excel æä»¶æ¥éï¼ãå¹çï¼éå¤å¯¼å ¥å ¨è¡¨ md5 ä¸è´ï¼ãåå½ï¼æµè¯ææ¸ çå¹²åãç宿份 216 è¡ / 12 æå£å¾ä¸åï¼ã - é¢è§å¼¹çªï¼7 æ¡ç¨ä¾å ¨éè¿ââDOM 宿µå¼¹çªå `table` æ°é为 1ãç±»åä¸è¡æ°æ£ç¡®ã12 è¡æ°å¼ä¸åæ¯å®æ´ãè¡¨æ ¼ä¸æ¹æ 第äºå¼ 表ã`git diff` ä» 1 è¡æ¹å¨ä¸åå½ã - æµè¯ææ¸ çï¼`2099-01` ~ `2099-04` å ¨é¨ç¨ `POST /api/import/clear?period=â¦` æ¸ ç©ºï¼å dataRows=18ãbatchRows=1ï¼ï¼å½ååº **0 æ¡ 2099 æ®ç**ã`freight_turnover_import` 216 è¡ / 12 个æ¥è¡¨æã ## å «ãéçé®é¢ä¸å¾ åï¼æ´æ°ï¼ 1. **`2021-12` çæ¥è¡¨ææ¯ãæ´å¹´ãè¯ä¹**ï¼è¿äºææ¿è½½è¯¥å¹´ 1â12 æå ¨å¹´æ°æ®ï¼èé 12 æåæï¼åç»æ¥è¡¨/å®¡æ ¸è¥æåæå£å¾åæ°éç¨æ·ç¡®è®¤å£å¾ï¼å¿ è¦æ¶åæ¹é ã 2. **æºæä»¶ç¼º 2023 å¹´ Sheet**ï¼å¯¼è´ä¸çæ `2023-12`ï¼`2024-12` æ ä¸å¹´åæã屿ºæ°æ®ç¼ºå£ã 3. **`2026-01` ~ `2026-07` ç `last_*` 为空**ï¼ç»æ¯å¯¹æ¹å¨åå¤ä»½ï¼`2026-04` ç INSERTï¼ç¡®è®¤è¿å ææ¹å¨åå³ä¸ºç©ºï¼ä¸æ¬æ¬¡å¯¼å ¥æªè§¦ç¢°è¿äºæ¥è¡¨æï¼æ¹æ¬¡åªè¦ç 5 个æï¼ï¼**éæ¬æ¬¡æ¹å¨å¼å ¥**ï¼å¦éè¡¥ä¸å¹´åæééæ°å¯¼å ¥å¯¹åºå¹´åº¦æ°æ®ã 4. **æ¹å¨åçå¤ä»½ä¸å®æ´**ï¼`_backup_freight_turnover_before_multiyear_20260916.sql` ä» 59642 åèãåªè§£æåº `2026-04` ä¸å¤ INSERTï¼**ä¸è½ä½ä¸ºå®æ´åæ»ä¾æ®**ã 5. å¼¹çªå ãå ± 0 è¡ãä¸ãæåº¦è¦çï¼1~8æåææ°æ®ãå£å¾ä¸åï¼åè æ¯æç»è¡æ°ï¼ï¼æè¯¯è§£ï¼å¯èèæ¹ææ¡ï¼æªåï¼çç¨æ·ç¡®è®¤ï¼ã 6. ä¸åéçç»§ç»æè´¦ï¼åå/å ¬ç½è®¿é®çç½ååè¡¥å ã`Login.vue` é误æç¤ºç»åãAI å¤åè±æè¡¥é½ã4 å¼ æç»æ¥è¡¨æ¨¡æ¿æ©åãå®¡æ ¸æ¯å¯¹åºåç¼ºå¤±ä¿æ¤ã`sys_role` æéè½å°ã3D éªè¯ç ç产å¼å¯ã`backend.log` åå²æææ¸ çãä»åºæ ¹ç®å½ä¸´æ¶æä»¶æ¸ çã 7. **å ¬å¸ gitea ä»å¾ è¡¥æ¨**ï¼ç½ç»é®é¢ï¼éåæ®ï¼ï¼è¡¥æ¨åå `git fetch gitea` ä¸è¿ç«¯ `main` 对æ¯åå¹¶ï¼ç¦å¼ºæ¨ã ## ä¹ãæå¤©è®¡å 1. ä¸ç¨æ·ç¡®è®¤ `2021-12` / `2022-12` çãæ´å¹´æ¥è¡¨æãçä¸å¡å£å¾ï¼ä»¥åæ¯å¦éè¦æå¹´åº¦æ°æ®ææéææ¥è¡¨æã 2. 确认æ¯å¦éè¦è¡¥ 2023 å¹´æ°æ®ã以å `2026-01`~`2026-07` çä¸å¹´åææ¯å¦éè¦è¡¥é½ã 3. è§ç¨æ·æè§å¤çé¢è§å¼¹çªãå ± 0 è¡ãææ¡ã 4. ç½ç»æ¢å¤åè¡¥æ¨å ¬å¸ giteaã traffic-audit-server/src/main/java/com/trafficaudit/dataimport/service/DataImportService.java
@@ -85,6 +85,7 @@ import java.util.Arrays; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.TreeMap; import java.util.stream.Collectors; import java.text.SimpleDateFormat; @@ -1054,11 +1055,22 @@ // ========== è´§è¿éå¨è½¬éï¼æ¨¡æ¿_è´§è¿éå¨è½¬é.xlsxï¼æ¯æå¯¼å ¥ï¼ ========== public int importFreightTurnover(MultipartFile file, String period) throws Exception { try (Workbook wb = WorkbookFactory.create(file.getInputStream())) { // å¤å¹´åº¦å·¥ä½ç°¿ï¼ä¸å¹´ä¸ä¸ª Sheetï¼æ´å¹´ 1-12 æï¼å¦ 21-26 å¹´å®ç¨¿æä»¶ï¼â å ¨é¨å¹´ä»½å ¥åº List<String> yearSheets = detectYearSheets(wb); if (!yearSheets.isEmpty()) { return importFreightTurnoverByYear(wb, file, yearSheets); } return importFreightTurnoverByMonth(wb, file, period); } } /** æ¯æå¯¼å ¥ï¼æ¨¡æ¿_è´§è¿éå¨è½¬é.xlsxï¼ï¼å·¦åä»å¹´ 1-N æï¼å³åå»å¹´ 1-12 æ */ private int importFreightTurnoverByMonth(Workbook wb, MultipartFile file, String period) throws Exception { List<FreightTurnoverImport> list = new ArrayList<>(); int failRows = 0; // æ¥è¡¨æ N æï¼å·¦å为ä»å¹´ 1-N æï¼åæ°ä¸åºå®ï¼ï¼å³ååºå®ä¸ºå»å¹´ 1-12 æï¼ç®åæ¯ç¨ï¼ int monthCount = Integer.parseInt(period.split("-")[1]); try (Workbook wb = WorkbookFactory.create(file.getInputStream())) { { Sheet sheet = wb.getSheetAt(0); Row header = sheet.getRow(0); String h0 = header == null ? null : getString(header, 0); @@ -1123,27 +1135,149 @@ } list.add(entity); } } catch (Exception e) { throw e; } Map<String, List<FreightTurnoverImport>> byPeriod = new LinkedHashMap<>(); byPeriod.put(period, list); return persistFreightTurnover(byPeriod, file.getOriginalFilename()); } // å¹çï¼åæ¥è¡¨æå å é¤ freightTurnoverMapper.delete(new LambdaQueryWrapper<FreightTurnoverImport>() .eq(FreightTurnoverImport::getReportPeriod, period)); /** è¯å«ãå¤å¹´åº¦å·¥ä½ç°¿ãï¼æ¯ä¸ª Sheet ä¸å¹´ï¼Sheet å 2021å¹´/2022å¹´â¦ï¼ï¼ä¸è¡¨å¤´ä¸ºãè´§è¿é/1æâ¦12æãï¼å¦åè¿å空å表 */ private List<String> detectYearSheets(Workbook wb) { List<String> names = new ArrayList<>(); if (wb.getNumberOfSheets() < 2) return names; for (int i = 0; i < wb.getNumberOfSheets(); i++) { Sheet sheet = wb.getSheetAt(i); String nm = sheet.getSheetName() == null ? "" : sheet.getSheetName().trim(); if (!nm.matches("\\d{4}\\s*å¹´?")) { names.clear(); return names; } Row header = sheet.getRow(0); String h0 = header == null ? null : getString(header, 0); String h1 = header == null ? null : getString(header, 1); if (h0 == null || !h0.contains("è´§è¿é") || h1 == null || !h1.contains("æ")) { names.clear(); return names; } names.add(nm); } return names; } int success = 0; for (FreightTurnoverImport entity : list) { try { freightTurnoverMapper.insert(entity); success++; } catch (Exception e) { log.error("freight turnover insert error: {}", entity.getRegionName(), e); failRows++; /** å¤å¹´åº¦å·¥ä½ç°¿å¯¼å ¥ï¼é年䏿¡æ¥è¡¨æï¼æ¥è¡¨æ=该年æåææ°æ®çæä»½ï¼ï¼ä¸å¹´åæåä¸ä¸å¹´åº¦ Sheet */ private int importFreightTurnoverByYear(Workbook wb, MultipartFile file, List<String> yearSheets) { Map<Integer, String> sheetByYear = new TreeMap<>(); for (String sheetName : yearSheets) { sheetByYear.put(Integer.parseInt(sheetName.replace("å¹´", "").trim()), sheetName); } Map<Integer, Map<String, FreightTurnoverImport>> byYear = new TreeMap<>(); Map<Integer, Integer> maxMonthByYear = new HashMap<>(); for (Map.Entry<Integer, String> entry : sheetByYear.entrySet()) { Map<String, FreightTurnoverImport> parsed = new LinkedHashMap<>(); int maxMonth = parseWholeYearSheet(wb.getSheet(entry.getValue()), parsed); if (parsed.isEmpty()) continue; byYear.put(entry.getKey(), parsed); maxMonthByYear.put(entry.getKey(), Math.max(1, Math.min(12, maxMonth))); } Map<String, List<FreightTurnoverImport>> byPeriod = new LinkedHashMap<>(); for (Map.Entry<Integer, Map<String, FreightTurnoverImport>> entry : byYear.entrySet()) { int year = entry.getKey(); String yearPeriod = year + "-" + String.format("%02d", maxMonthByYear.get(year)); Map<String, FreightTurnoverImport> lastYear = byYear.get(year - 1); List<FreightTurnoverImport> rows = new ArrayList<>(); for (Map.Entry<String, FreightTurnoverImport> regionEntry : entry.getValue().entrySet()) { FreightTurnoverImport entity = regionEntry.getValue(); entity.setReportPeriod(yearPeriod); // ä¸å¹´åæ = ä¸ä¸å¹´åº¦ Sheetï¼å¤å¹´åº¦æä»¶æ²¡æå³åãå»å¹´1-12æãåºåï¼ FreightTurnoverImport last = lastYear == null ? null : lastYear.get(regionEntry.getKey()); if (last != null) { for (int m = 1; m <= 12; m++) { setLastFreight(entity, m, getFreight(last, m)); setLastTurnover(entity, m, getTurnover(last, m)); } } rows.add(entity); } byPeriod.put(yearPeriod, rows); } return persistFreightTurnover(byPeriod, file.getOriginalFilename()); } /** è§£ææ´å¹´ Sheetï¼1-12 æåï¼ï¼è´§è¿éå + å¨è½¬éåï¼è¿åæåä¸ä¸ªæè´§è¿éæ°æ®çæä»½ */ private int parseWholeYearSheet(Sheet sheet, Map<String, FreightTurnoverImport> out) { Map<String, FreightTurnoverImport> freightMap = new LinkedHashMap<>(); Map<String, FreightTurnoverImport> turnoverMap = new LinkedHashMap<>(); Set<String> seen = new HashSet<>(); int maxMonth = 0; for (int r = 1; r <= sheet.getLastRowNum(); r++) { Row row = sheet.getRow(r); if (row == null) continue; String name = getString(row, 0); if (name == null || name.trim().isEmpty()) continue; String region = RegionUtil.normalizeCityName(name); boolean isCity = RegionUtil.cityList().contains(region); if (!isCity && !"æ¹åç".equals(region)) continue; // 表头/说æè¡ if (seen.contains(region)) { // 该åç§°å·²åºç°è¿ -> å¨è½¬éåºå FreightTurnoverImport entity = turnoverMap.get(region); if (entity == null) { entity = new FreightTurnoverImport(); entity.setRegionName(name.trim()); turnoverMap.put(region, entity); } for (int m = 1; m <= 12; m++) { setTurnover(entity, m, getDecimalOrNull(row, m)); } } else { seen.add(region); FreightTurnoverImport entity = freightMap.get(region); if (entity == null) { entity = new FreightTurnoverImport(); entity.setRegionName(name.trim()); freightMap.put(region, entity); } for (int m = 1; m <= 12; m++) { Double v = getDecimalOrNull(row, m); setFreight(entity, m, v); if (v != null && m > maxMonth) maxMonth = m; } } } recordBatch(file.getOriginalFilename(), "FREIGHT_TURNOVER", period, list.size(), success, failRows, null); log.info("Freight turnover imported: {} rows for {}", success, period); return success; // åå¹¶ï¼ä¸ä¸ªå¸å·ä¸è¡ï¼è´§è¿é + å¨è½¬éï¼ for (Map.Entry<String, FreightTurnoverImport> entry : freightMap.entrySet()) { FreightTurnoverImport entity = entry.getValue(); FreightTurnoverImport turnover = turnoverMap.get(entry.getKey()); if (turnover != null) { for (int m = 1; m <= 12; m++) { setTurnover(entity, m, getTurnover(turnover, m)); } } out.put(entry.getKey(), entity); } return maxMonth; } /** è½åºï¼ææ¥è¡¨æå å åæï¼å¹çï¼ï¼æ¯ä¸ªæ¥è¡¨æä¸æ¡å¯¼å ¥æ¹æ¬¡è®°å½ï¼è¿åæåæ¡æ° */ private int persistFreightTurnover(Map<String, List<FreightTurnoverImport>> byPeriod, String fileName) { int total = 0; for (Map.Entry<String, List<FreightTurnoverImport>> entry : byPeriod.entrySet()) { String p = entry.getKey(); List<FreightTurnoverImport> rows = entry.getValue(); freightTurnoverMapper.delete(new LambdaQueryWrapper<FreightTurnoverImport>() .eq(FreightTurnoverImport::getReportPeriod, p)); int failRows = 0; int success = 0; for (FreightTurnoverImport entity : rows) { try { freightTurnoverMapper.insert(entity); success++; } catch (Exception e) { log.error("freight turnover insert error: {}", entity.getRegionName(), e); failRows++; } } recordBatch(fileName, "FREIGHT_TURNOVER", p, rows.size(), success, failRows, null); log.info("Freight turnover imported: {} rows for {}", success, p); total += success; } return total; } /** è§£æè´§è¿éåºåè¡ï¼å·¦å B èµ· N å为ä»å¹´ 1-N æï¼å³å为å»å¹´ 1-12 æ */ traffic-audit-web/src/views/ReportExport.vue
@@ -130,7 +130,7 @@ <div v-if="it.key === 'summaryWorkbook' && wbMissing(it.summary)" class="wb-note"> é¨åææ ç¼ºå°ä¸å¹´åæï¼{{ wbPrevYear() }}ï¼åºææ°æ®ï¼åæ¯ææªè®¡ç® </div> <table class="preview-summary" v-else-if="it.summary && it.summary.length"> <table class="preview-summary" v-if="it.key !== 'summaryWorkbook' && it.summary && it.summary.length"> <tbody> <tr v-for="(s, i) in it.summary" :key="i"> <td>{{ s.label }}</td>