Jelajahi Sumber

docs: extend cert batch ZIP design to self-vehicle and personnel lists.

Reuse the frontend JSZip approach with personnel name folders and shared toolbar entry.

Co-authored-by: Cursor <cursoragent@cursor.com>
wuzilong 1 bulan lalu
induk
melakukan
b84eec3c90

+ 83 - 0
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`