用户诉求:「我已经下载过了为什么还要重新生成呢?可以弄一个记忆功能吗——我下载过某个数据,第二次下载期间没有新导入数据,就直接沿用上次算好的结果。不然每次下载都要等很久。」
改造前:已有「10 分钟内 + 期间无新导入」的内存缓存,但①窗口只有 10 分钟;②存在内存里,进程一重启就没了 → 正常场景下第二次下载仍要重算 13~17 秒。
改造后:
1. 结果**落盘**保存到 docs/生成汇总大表/_cache/(已加入 .gitignore),文件名 <key>_v<数据版本>.xlsx;
2. 提交导出时(未点「重新生成」):**内存缓存 → 落盘缓存 → 真算**;落盘命中要求「同一报表期 + 同一数据版本」;
3. 数据版本 = MAX(import_batch.id):只要期间有任何一次数据导入,版本就变,旧缓存自动失效;
4. 复用上限 7 天(防陈年结果被当新表发出),超期文件在下次提交时自动清理;同一 key 只保留最新版本文件;
5. 前端命中缓存时显示「本次直接沿用 <生成时间> 生成的结果(期间没有新的数据导入)。如需按最新数据重算,请点「重新生成」。」,并把一行元信息改成「报表期 2026-08 上次生成于 …」(不再显示「上次生成用时 0.0 秒」);
6. 修掉落盘命中时 elapsedMs 为负数的问题(以生成时间作为任务起点)。
改动文件:ReportExportTaskService.java(核心)、ReportExportController.java(注释)、ReportExport.vue(文案)、.gitignore。
npm run serve 8080(Compiled successfully)traffic_audit;报表期 2026-08(月报)docs/生成汇总大表/_cache/;命中判据 MAX(import_batch.id)(测试时为 541)| # | 用例 | 操作 | 预期 | 实际 | 结论 |
|---|---|---|---|---|---|
| T01 | 首次提交(无缓存,正向) | GET /api/report/exportTask/summaryWorkbook?period=2026-08 |
真算,完成后写落盘缓存 | RUNNING → DONE(12.4 s);生成 summaryWorkbook_2026-08_month__v541.xlsx(1,204,461 B) |
通过 |
| T02 | 再次提交(内存命中) | 同上报 | 立即 DONE、fromCache=true | 提交耗时 164 ms,fromCache=true;下载 1,204,461 B 与缓存文件一致 |
通过 |
| T03 | 重启后端后再提交(落盘命中,核心) | 停/起前后端后提交 | 仍立即 DONE(不再重算) | 提交 1,194 ms,fromCache=true,日志「命中落盘缓存…」,下载字节一致 |
通过 |
| T04 | 有新导入(负向) | 临时插入一条 import_batch(id 变 542)后提交 |
缓存失效、重新生成 | fromCache=false、status=RUNNING |
通过 |
| T05 | 同 key 只留最新版本 | 重算完成后看缓存目录 | 旧版本文件被删除 | 目录只剩 …_v542.xlsx(v541 已删) |
通过 |
| T06 | 版本回落后 | 删掉临时导入行(版本回到 541)后再提交 | 不命中 v542,重算并写回 v541 | fromCache=false → 重算完成;目录只剩 …_v541.xlsx |
通过 |
| T07 | 时长显示(回归修复) | 落盘命中时看 elapsedMs / 前端元信息 |
不为负数 | 修复前 elapsedMs=-72937;修复后 elapsedMs=0,前端显示「报表期 2026-08 上次生成于 2026-09-22 11:27:32」 |
通过 |
| T08 | 浏览器端到端(正向) | admin/123456 → 报表生成 → 汇总大表 → 2026-08 → 导出 | 秒出并自动下载,文案正确 | 点击后**立即**「汇总大表已生成」100%;显示「本次直接沿用 2026-09-22 11:27:32 生成的结果(期间没有新的数据导入)」、「已自动下载:生成_道路运输量汇总表_2026-08.xlsx (1.15 MB)…」;按钮仅「重新生成 / 关闭」;控制台 0 报错 | 通过 |
| T09 | 缓存不串期(静态) | —— | 不同报表期/模式互不命中 | key(type|period|mode|toMonth)同时进入内存键与落盘文件名前缀 | 通过(静态) |
| T10 | 自动清理 | —— | 超期文件被删除 | 每次提交调用 cleanupExpired():内存条目与磁盘文件超过 7 天即清 |
通过(静态) |
| # | 问题 | 处置 |
|---|---|---|
| P1 | 落盘命中时前端「用时」为负数(elapsedMs=-72937,因为任务起点是现在、结束时间是历史生成时间) |
已修:落盘命中时把任务起点设为生成时间;前端缓存命中不再显示用时,改显示「上次生成于 …」 |
| P2 | 测试用的临时 import_batch 行 |
已删除(MAX(id) 回到 541、批次 419 条),仅用于验证「导入即失效」 |
| P3 | 数据版本是**全局**的:任何一次导入(含与汇总大表无关的投资/能耗导入)都会让汇总缓存失效 | 属保守设计(宁可重算不可出错)。若希望「只有相关数据导入才失效」,需要按 import_type 细分依赖,待用户确认后排期 |
| P4 | 落盘目录 | 新增 docs/生成汇总大表/_cache/ 并加入 .gitignore(结果文件不入库) |
MAX(import_batch.id))+ 7 天上限」双重把关:有新导入必定重算,测试已覆盖;测试人:Codex(AI) 测试日期:2026-09-22