diff --git a/docs/superpowers/specs/2026-09-08-cert-batch-zip-personnel-self-vehicle-design.md b/docs/superpowers/specs/2026-09-08-cert-batch-zip-personnel-self-vehicle-design.md new file mode 100644 index 000000000..dd3e3ccf7 --- /dev/null +++ b/docs/superpowers/specs/2026-09-08-cert-batch-zip-personnel-self-vehicle-design.md @@ -0,0 +1,83 @@ +# 证书附件批量 ZIP 下载 — 扩展至自有车辆与驾押人员 + +**日期:** 2026-09-08 +**状态:** 已确认设计,待写实现计划 +**范围:** `web-admin` +- 山峡自有车辆(`/#/pl/...` → `views/pl/self-vehicle/index.vue`) +- 三方驾押人员 / 山峡驾押人员(同一 `views/pl/personnel/index.vue` 分册) +**基线:** `docs/superpowers/specs/2026-09-08-vehicle-cert-batch-zip-design.md`(三方车辆已落地) + +## 背景 + +三方车辆列表已支持勾选后「批量下载证书 ZIP」。用户要求在 **山峡自有车辆**、**三方驾押人员**、**山峡驾押人员** 三个界面提供同等能力。 + +三页均已有「证书附件」列(`PlCertListAttachmentCell` + 行内 `certList`),可复用前端 JSZip 方案。 + +## 已确认决策 + +| 项 | 决策 | +|----|------| +| 实现路径 | 方案 1:抽出通用证书 ZIP 核心,车辆/人员薄封装 | +| 入口 | 工具栏「批量下载证书 ZIP」(与三方车辆一致) | +| 附件范围 | 仅「证书附件」列;不含照片等 | +| 无附件 | 跳过;全部无附件 →「无可下载附件」 | +| 人员 ZIP 命名 | 单人 `人员证书_{姓名}.zip`;多人 `人员证书批量_{N}人_{yyyyMMdd}.zip` + 姓名子目录;同名目录 `_2`/`_3` | +| 自有车辆 | 与三方车辆同一套车牌命名与主·/挂·规则 | + +## UI 与交互 + +三页均在 `ListExportDropdown` 与 `ListToolbarEndActions` 之间增加描边按钮: + +- 文案「批量下载证书 ZIP」+ `Download` 图标(`btn-ghost`) +- 未勾选禁用;勾选 ≥1 可点;点击后 `loading` +- Message 分支与三方车辆页一致(无可下载 / 全失败 / 部分失败 / 全成功) +- 列内单个 ↓ 下载不变 + +## ZIP 规则 + +### 车辆(三方已有 + 自有新增) + +- 文件夹/文件名:车牌展示名(`formatPlVehiclePlateDisplay`) +- 有挂车证书时文件名加 `主·`/`挂·`(对齐列组件) +- 单车:`车辆证书_{车牌}.zip` 平铺;多车:`车辆证书批量_{N}辆_{yyyyMMdd}.zip` + 车牌子目录 + +### 人员(三方 / 山峡分册) + +- 无 `vehiclePart` 前缀(列组件亦无 `show-vehicle-part`) +- 文件夹名:`sanitize(姓名)`;空姓名回退 `id` +- 单人:`人员证书_{姓名}.zip` 平铺 +- 多人:`人员证书批量_{N}人_{yyyyMMdd}.zip`,每人一子目录;**同名用 `_2`、`_3`**(不用手机号) +- 包内文件名:`{证书名}.{ext}`;同目录重名同样 `_2`/`_3` + +## 架构 + +| 位置 | 职责 | +|------|------| +| 通用核心(从现有 `pl-vehicle-cert-zip.ts` 抽出或扩展) | 并发拉取、失败跳过、`uniqueZipPath`、JSZip 生成与保存 | +| 车辆适配 | `collectVehicleCertZipEntries` + `车辆证书_*` 文件名(现有逻辑) | +| 人员适配(新建函数) | 从 `personnelName` + `certList` 收集;`人员证书_*` 文件名;同名 folder 去重 | +| `self-vehicle/index.vue` | 调用车辆打包(同三方车辆) | +| `personnel/index.vue` | 两分册共用同一 handler,调用人员打包 | + +**约束:** 仍只用列表行已有 `certList`;不新增后端接口;默认并发约 4。 + +## 异常与验收 + +继承基线 spec 的异常表。额外验收: + +1. 自有车辆:勾选 1 / 多辆行为与三方车辆一致 +2. 三方驾押人员、山峡驾押人员:单人/多人 ZIP 命名符合上文;同名两人产生 `张三` 与 `张三_2` 子目录 +3. 三页均「无可下载附件」与部分失败提示正确 +4. 既有三方车辆行为与单测不回归 + +## 非目标 + +- 照片、关联车辆/人员交叉附件 +- 后端 ZIP +- 进度百分比 UI + +## 参考 + +- 基线设计:`docs/superpowers/specs/2026-09-08-vehicle-cert-batch-zip-design.md` +- 基线实现:`web-admin/src/utils/pl-vehicle-cert-zip.ts`、`views/pl/vehicle/index.vue` +- Demo:`docs/superpowers/demos/2026-09-08-vehicle-cert-batch-zip-demo.html`