应付款终版导入:支持 20 万行(流式读取 + 分片导入 + 进度显示) #360

Closed
renshen wants to merge 2 commits from feature/sumu-import-memory-fix into main
Collaborator

背景

上一版把「大文件导致 500」修掉了,但 20 万行仍然跑不动:整表解析一次要 25-30 秒、峰值 430MB(sharedStrings),分块读完整表要 9 分钟;单次 HTTP 请求也扛不住。

改动

  • 新增流式工作簿读取器 PayablesWorkbookStreamReader:xlsx 用 ZipArchive + XMLReader 逐行解析,共享字符串用「拼接串 + 偏移索引」紧凑存放(内存从几百兆降到几十兆);支持日期样式单元格(转 Y-m-d)、GBK 编码 CSV、分隔符自动识别;xls 回退 PhpSpreadsheet。
  • 新增 PayablesFinalImportRunner:上传时把工作簿转成行缓存(jsonl.gz),之后前端按片调用;每片 20000 行 / 25 秒预算,落库改为批量 upsert + 批量审计事件;单次导入上限 200,000 行,完成后自动清理缓存。
  • 新接口:import-upload(上传建缓存)/ import-chunk(按片处理),只挂在终版目录的按表路由上;导入弹窗改为 AJAX 分片流程,带进度条与"新增/更新"计数,完成后自动刷新。
  • 上传限制:校验放宽到 50MB,php.ini upload_max_filesize 10M→64M(nginx 已是 64m / 120s)。

验证

  • 新增 PayablesFinalImportRunnerTest 5 个用例:xlsx 流式读取(含日期转换)、GBK CSV、分片续跑与完成清理、上传/分片接口、页面接线;全部通过。
  • 相关回归 40 个用例全部通过(终版页面、快递终版、导入导出、基础页)。
  • 部署后会在生产容器内用真实 20 万行 xlsx 复测(prepare + 分片处理的时间与内存)。

说明

  • 不涉及数据库结构变更;旧的同步导入接口保留(兼容既有调用与测试)。
## 背景 上一版把「大文件导致 500」修掉了,但 20 万行仍然跑不动:整表解析一次要 25-30 秒、峰值 430MB(sharedStrings),分块读完整表要 9 分钟;单次 HTTP 请求也扛不住。 ## 改动 - 新增流式工作簿读取器 `PayablesWorkbookStreamReader`:xlsx 用 ZipArchive + XMLReader 逐行解析,共享字符串用「拼接串 + 偏移索引」紧凑存放(内存从几百兆降到几十兆);支持日期样式单元格(转 Y-m-d)、GBK 编码 CSV、分隔符自动识别;xls 回退 PhpSpreadsheet。 - 新增 `PayablesFinalImportRunner`:上传时把工作簿转成行缓存(jsonl.gz),之后前端按片调用;每片 20000 行 / 25 秒预算,落库改为批量 upsert + 批量审计事件;单次导入上限 200,000 行,完成后自动清理缓存。 - 新接口:`import-upload`(上传建缓存)/ `import-chunk`(按片处理),只挂在终版目录的按表路由上;导入弹窗改为 AJAX 分片流程,带进度条与"新增/更新"计数,完成后自动刷新。 - 上传限制:校验放宽到 50MB,php.ini `upload_max_filesize` 10M→64M(nginx 已是 64m / 120s)。 ## 验证 - 新增 `PayablesFinalImportRunnerTest` 5 个用例:xlsx 流式读取(含日期转换)、GBK CSV、分片续跑与完成清理、上传/分片接口、页面接线;全部通过。 - 相关回归 40 个用例全部通过(终版页面、快递终版、导入导出、基础页)。 - 部署后会在生产容器内用真实 20 万行 xlsx 复测(prepare + 分片处理的时间与内存)。 ## 说明 - 不涉及数据库结构变更;旧的同步导入接口保留(兼容既有调用与测试)。
renshen added 2 commits 2026-10-16 23:50:43 +08:00
以前整表载入内存(大文件/带幽灵区域的工作簿会让 PHP 进程涨到 GB 级并被系统杀掉,页面只显示一个 500 且没有任何日志);现在按 2000 行分块读取,读满 1 万行立即给出「请拆分文件」提示。部署 php.ini 补上 display_errors=Off / log_errors=On / error_log,避免以后再出现看不到原因的 500。
同步导入在 20 万行规模下必然超时/爆内存:新增 xlsx/csv 流式读取器(共享字符串紧凑存放、支持日期单元格、GBK CSV),上传时把工作簿转成行缓存,之后按片处理(每片 2 万行/25 秒预算),前端显示进度并自动续跑;落库改为批量 upsert + 批量审计事件;上限提升到 20 万行,上传限制放宽到 50MB。
Author
Collaborator

该 PR 因复用了已合并的旧分支名被 Gitea 判定冲突,已改为 #361 重新提交并合并,此 PR 关闭。

该 PR 因复用了已合并的旧分支名被 Gitea 判定冲突,已改为 #361 重新提交并合并,此 PR 关闭。
renshen closed this pull request 2026-10-16 23:54:25 +08:00

Pull request closed

Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: WuYongJie/CaiWuXiTong#360
No description provided.