feat(export): 导出与交付(M6)—— 前置检查、目录树预览、分卷打包与 7 天过期清理

客户最关心的那条链:precheck(不通过就没有 force 分支,铁律 10)→ 目录树预览
(与真正打包共用同一份构建代码,预览不会说谎)→ 异步分卷(每卷都是完整可解的 ZIP)
→ 产物落表按行判可下载(过期回「已被清理、请重新导出」)。

契约没有但界面必需的 GET /exports/precheck 一并补上(否则按钮要点一次才知道能不能导)。

顺带修 F-11:severity 口径统一为 INFO=1/WARN=2/ERROR=3(三处注释曾互相矛盾,
按直觉写会把「提示」当阻断,正常数据也导不出来)。

验证:scripts/e2e-m6-export.py 60/60、e2e-m6-export-split.py 33/33;
ZIP 的 UTF-8 标志位(general purpose bit 11)与 sha256 都有断言。
This commit is contained in:
2026-09-30 09:02:50 +08:00
parent 3195dc4d7b
commit 6cca97efe6
18 changed files with 3406 additions and 1 deletions
+15
View File
@@ -89,6 +89,21 @@
<artifactId>easyexcel</artifactId>
</dependency>
<!--
ZIP 打包(导出交付物)。
⚠️ 用它而不是 JDK 的 `ZipOutputStream`,唯一原因是**中文文件名的编码**:
JDK 的 ZipOutputStream 永远写 UTF-8 并置 EFS 标志位,而 Windows 自带的
「解压缩文件夹」对没有 EFS 标志的历史做法是按本地代码页解 —— 于是中文名
变成乱码,而**这个 bug 只在客户机器上出现**(服务器上怎么看都是对的)。
commons-compress 允许显式指定 `entryNameEncoding`,把这件事变成可控的。
版本由 POI 传递引入,这里只把它抬成直接依赖,避免"哪天 POI 换版本就编不过"。
-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.27.1</version>
</dependency>
<!-- 对象存储(材料原图与规范件)—— provider=qiniu 时用,本地开发可退回磁盘 -->
<dependency>
<groupId>com.qiniu</groupId>