# 功能测试报告 — 投资明细表取数修复(软件生成 vs 人工版 差异收敛) > 测试日期:2026-09-22 > 被测对象:报表生成 → 投资《客运站投资明细表》《物流站场投资明细》导出 + 投资月报(市州单表)导入 > 背景:《数据比对报告_投资明细表软件生成与人工版_2026-09-22.md》定位出 156 格差异与 3 类"会静默出数"的取数缺陷,本报告为第一轮修复与回归验证。 ## 一、功能说明(本次改了什么) ### 1. 导出:`traffic-audit-server/src/main/java/com/trafficaudit/reportexport/service/ReportExportService.java` | # | 改动 | 说明 | | --- | --- | --- | | 1-1 | `normInvestName()` 归一化补标点 | 增加半/全角句点、顿号、逗号、分号、冒号等(原只去 `·•—-_-`)。库内项目名「中国供销**.**公安商贸物流园」与明细表行名「中国供销公安商贸物流园(公安县域集采集配中心)」归一化后前缀一致 → 可匹配 | | 1-2 | 新增 `preferMonthlyCandidate()` | 匹配到的档在**当月无数据**时,改选「归一化同名且当月有数据」的档(取 id 最大者)。修复十堰「快递物流产业园二期」取到旧档 id=154(月度只到 7 月)的问题 | | 1-3 | 新增 `logSkippedRows()` + 客运/物流导出留痕 | 未按当月数据覆盖的行**逐行 WARN**:`[未覆盖] 第N行 市州 项目名 → 原因`,并给出按市州统计。彻底消除"静默结转上期值" | ### 2. 导入:`traffic-audit-server/src/main/java/com/trafficaudit/dataimport/service/DataImportService.java` | # | 改动 | 说明 | | --- | --- | --- | | 2-1 | `investHeaderKey()` 先去空白再判定 | 表头单元格常含换行/全角空格(天门「自开始建\n设累计完\n成投资\n(万元)」),原逻辑 `v.contains("自开始建设")` 匹配不上 → H/J/K 三列映射落到 -1 被写成 0。改为 `replaceAll("[\\s\\u3000]+","")` 后再判定 | | 2-2 | 新增 `investSheetPeriodCellHit()` + 评分加权 | 多 sheet 历史文件按 sheet 名匹配月份会把 2018 年的「潜江(8月)」当成 2026-08。新增"表内报表期"命中(sheet 前 8 行的 `2026.08.24` / `2026年8月` / 日期单元格),权重 2000000 高于 sheet 名匹配(1000000) | ## 二、测试环境 - 后端:`mvn spring-boot:run`(8090),重启后日志出现 `Started TrafficAuditApplication`;前端 8080 在运行 - 数据库:`localhost:3308/traffic_audit`(本机开发库);登录 `admin/123456` 取 JWT - 人工版基准:`D:\05_数据分类\投资\8月\8月客运站投资明细表.xlsx`、`8月物流站场投资明细.xls` - 修复前软件版:`D:\桌面\生成数据\生成_所选报表_2026-08 (1)\…` - 修复后软件版:`_tmp/gen_new_0922/…`(本次重跑导出) - 比对脚本:`_tmp_diff_invest_0922.py`(修复前)、`_tmp_diff_after_fix_0922.py`(修复后) > **2026-09-23 续接核实**:本报告记录的验证库 `localhost:3308` 不是当前应用实际连接库;当前 `application.yml` 与运行中后端均使用 `localhost:3305`。在 `3305` 上复核时,潜江 2026-08 仍是旧项目错值,说明本报告当时的 08 月重导结果未落到当前运行库。已在 2026-09-23 重导潜江 2026-06/07/08 并完成库内/导出验证,详见 `docs/功能测试报告/功能测试报告_潜江投资物流月报重导_2026-09-23.md`。 ## 三、测试用例与结果 | # | 用例 | 输入 | 预期 | 实际 | 结论 | | --- | --- | --- | --- | --- | --- | | 1 | 导出-项目名带标点 | 2026-08 物流明细导出 | 第119/120行「中国供销公安商贸物流园」按库内当月写入 | 修复前:未覆盖,保留底稿 7758.5/7758.5/1600.1;修复后:写入 **15986/15986/8227.5** 与源表一致;日志不再列该行 | ✅ | | 2 | 导出-同名双档 | 同上 | 取「当月有数据」的档(id=181) | 修复前:20081/2900/214、竣工 2026;修复后:**20377/3196/296、竣工 2029**(= 十堰源表 R71) | ✅ | | 3 | 导出-未覆盖留痕(物流) | 同上 | 未覆盖行列出行号+市州+项目名+原因 | 日志:`物流站场投资明细 2026-08:写入 93 行,结转母版原值 6 行` + 6 条 `[未覆盖] 第12行 武汉市 航发智慧物流园 → 库内无 2026-08 月度数据`(按市州统计 `{武汉市=6}`) | ✅ | | 4 | 导出-未覆盖留痕(客运) | 同上 | 同上 | `写入 37 行,结转母版原值 12 行(其中库内有项目但当月无数据 9 行)` + 12 条明细(黄石 1 / 黄冈 9 / 恩施 1 / 仙桃 1) | ✅ | | 5 | 导入-表头含换行(天门) | `8月份物流园中心建设项目(天门).xlsx`,period=2026-08,type=investmentLogistics | 入库 16677.7 / 16677.7 / 500 | 修复前库内 0/0/0;修复后 `investment_monthly` = **16677.7 / 16677.7 / 500**,接口返回 success=1 | ✅ | | 6 | 导入-历史页签(潜江) | `潜江2026.08.xlsx`(含 20 个历史 sheet) | 选当期 sheet(表内报表期 2026.08.24) | 修复前:入库 **2018 年**「潜江市公路项目」5173/5173/1440(错);修复后:入库「**中国虾谷冷链仓储物流园**」11947.9/1135/0(= 源表当期 sheet),旧错行被同市州同期间清理 | ✅ | | 7 | 回归-逐格比对 | 修复后导出 vs 人工版 | 差异数下降且无新增差异 | 156 格 → **129 格**(降 27),剩余差异与修复前逐条对应,无新增 | ✅ | | 8 | 负向-未匹配行不写错值 | 武汉 6 行(库内无 2026-08 数据) | 保持底稿原值且必须有日志告警 | 6 行保持原值,日志逐行告警(不静默) | ✅ | ### 修复前后逐页签对照 | 文件 / 页签 | 修复前 | 修复后 | 说明 | | --- | --- | --- | --- | | 客运-明细 | 12 | 12 | 本次未动客运匹配逻辑(差异属取整/文本口径) | | 客运-汇总 | 4 | 4 | 同上 | | 物流-月2 | 0 | 0 | — | | 物流-分项目投资完成情况 | 108 | **91** | 荆州 −10、十堰 −5、天门 −2 | | 物流-分市州规划内外项目完成情况 | 15 | **11** | 荆州、天门随明细页归位 | | 物流-市州汇总 | 17 | **11** | 同上 | | **合计** | **156** | **129** | 收敛 27 格 | ## 四、剩余差异(129 格)分类与责任 | 类别 | 格数 | 原因 | 责任方 / 下一步 | | --- | --- | --- | --- | | 武汉整段(明细 24 + 合计 3) | 27 | 库内**无武汉物流当月数据**(8 月武汉无单表),导出只能结转底稿 7 月值 | 业务补武汉单表;或明确"武汉由人工填"(现已有告警) | | 十堰枢纽 2 万元差异 | 3 | 人工版用旧值 11047/589/0,源表与库内是 11049/591/2 | **软件对**,人工版需更新(已列入差异清单) | | L 列(建设阶段)未覆盖 | 3 | 导出按 2026-09-18 口径不写 L,沿用底稿 | 需《建设阶段归一表》后放开(见第五节) | | D 列(建设性质)未覆盖 | 3 | 同上(I/L/G/D/E/F 不写) | 同上 | | 工期 E/F 写法(日期 vs 年份) | 4 | 人工版是日期序列号,软件写年份/文本 | 格式口径,建议以源表原样为准 | | 分组小计行(6 个市州) | 25 | 软件按渠道求和不填=市州合计,人工版留空 | 口径差异,建议人工版补齐(软件规则与武汉 R11/R16 完全一致) | | 0 与空白 | 11 | 写法不同 | 统一规则:源表空→空、源表 0→0 | | 客运取整 + 文本 | 16 | 人工版手写取整(203/2531/43225.9);M26/M85 人工版空、L91 底稿旧值 | 人工版对齐;L91 需归一表 | | 未覆盖行(数据缺口清单) | 18 行 | 物流:武汉 6;客运:黄石 1、黄冈 9、恩施 1、仙桃 1 | 补源文件/项目主档后重导(日志已逐行列出) | ## 五、遗留问题与处置 1. **【新发现,已修+重导】潜江导入选错历史页签**:2026-08 曾导入 2018 年「潜江市公路项目」的数据;已修复选页签逻辑并重导 2026-08。 - **仍遗留**:潜江 **2026-06 / 2026-07** 两个月的月度数据仍是历史 sheet 错值,需用 6/7 月源表重导(不要用 8 月文件重导,会把 8 月数写成 7 月)。 2. **【需口径拍板】"全量覆盖"未实施**:现行口径(2026-09-18 确认)是只写 H/J/K/M,I/L/G 不动。若要与人工版完全一致,需确认 L/D/E/F/I 是否也按当月写,且 L 需要《源表用词→输出用词》归一表(源表有 主体施工/竣工收尾/未开工/本年正式施工/暂停施工/前期 等,人工版写 在建/完工/前期/暂停施工)。 3. **【数据缺口】黄冈客运 8 月无源文件**(9 行)、黄石/恩施/仙桃 3 行库内无对应项目主档、武汉物流无单表 —— 导出已能自动告警,但数据本身需要业务提供。 4. **【对比工具化】** 目前"未覆盖行"只进后端日志;建议按 P1-9 约定,在导出结果旁生成《校验报错_<年月>.xlsx》或前端弹窗提示(用户要求"失败要显示行号",本次已做到日志留痕,页面提示待做)。 ## 六、结论 - 本次修复后,**逐格差异由 156 格降至 129 格**;三处"会影响数字"的取数缺陷(荆州项目名匹配失败、十堰同名双档取旧值、天门导入丢 H/J/K)全部闭环并逐条回溯源文件验证。 - 同时端到端暴露并修复了一个更严重的问题:**潜江导入选到 2018 年历史页签**(属"把旧年份数据当当期数据入库");未覆盖行现已在日志中逐行列出(行号+市州+项目名+原因),不再静默。 - 剩余 129 格差异中,**只有武汉 27 格属"缺数据"、L/D 列 6 格属"待放开口径"**,其余为填表习惯(分组行/0 与空白/取整)与人工版自身旧值,均已在《数据比对报告》中逐条标注"以谁为准"。 - 建议下一步:① 业务确认 L/D/E/F 覆盖口径并出《建设阶段归一表》;② 补武汉物流、黄冈客运源数据;③ 按 P1-9 把未覆盖清单输出成校验文件/页面提示。 ## 七、本次数据变更说明(未删除任何项目主档) | 表 | 变更 | 修复前 | 修复后 | | --- | --- | --- | --- | | `investment_monthly`(天门市物流中心建设项目 2026-08) | 重导修正 | start_cum/year_cum/month_done = 0/0/0 | **16677.7 / 16677.7 / 500** | | `investment_monthly`(潜江市 2026-08) | 重导修正(旧错行删除、新行写入) | 潜江市公路项目 5173/5173/1440 | **中国虾谷冷链仓储物流园 11947.9/1135/0** | - 未删除任何 `investment_project` 项目主档;未改动其他市州、其他期间数据。 - 复现命令:`POST /api/import/batch?type=investmentLogistics&period=2026-08`(multipart,字段名 `files`)+ `GET /api/report/export/investLogisticsDetail?period=2026-08`;均需 `Authorization: Bearer `。