docs(pl): add blank slip print design for transport plans

Document toolbar blank inbound/delivery/subpack print via openBlank(),
including empty fields, no seal on delivery blanks, and no selection required.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
zlwuandCursor committed 2026-08-22 11:18:31 +08:00
1 parent 16be6fa22d
commit ed939097f0
1 file changed
+120
@@ -0,0 +1,120 @@
# 运输计划 · 空白单据打印 — 设计文档
> **日期**: 2026-08-22
> **状态**: 待实施
> **前置**: `docs/superpowers/specs/2026-07-26-pl-print-slip-dropdown-design.md`;`docs/superpowers/specs/2026-07-27-pl-plan-batch-print-merge-design.md`;现网入库单 / 送(提)货单 / 分装单模版与打印弹窗
## 目标
运输计划列表支持打印 **空白** 入库单、送(提)货单、分装单:保留版式骨架,不填业务数据,供现场手写。与「按勾选计划填数打印」并存。
## 已确认决策
| # | 决策 | 说明 |
|---|------|------|
| D1 | **方案 A:`openBlank()`** | 三个打印弹窗各增空白打开路径;与填数打印隔离,不伪造业务态混入现有 `open(planIds)` |
| D2 | **入口仅列表工具栏** | 「打印单据」下拉增加三项空白;查看弹窗、安排成功底栏不加空白项 |
| D3 | **未勾选也可点** | 「打印单据」按钮始终可点;未勾选时原三项灰掉,仅三个空白项可用 |
| D4 | **勾选时两项并存** | 原三项仍按 `planType` / 合打规则启用;空白三项始终可点(忽略所选计划数据) |
| D5 | **空白入库单** | 业务字段全空(含单据编号等);版式骨架保留;印章随默认模板(不特意关闭) |
| D6 | **空白送(提)货单** | 业务字段全空;**默认不显示印章** |
| D7 | **空白分装单** | 业务字段全空;**分装单号也不填**;不调用 `ensureSubpackSlipNo` |
| D8 | **产品区** | 使用若干空行便于手写;**不得**展示「暂无产品信息」 |
| D9 | **不读计划模板 / 不占号** | 空白模式使用内置默认模板生成;不拉计划详情;不读写计划上已存模板内容;不占分装单号 |
| D10 | **保存模板** | 空白模式下隐藏或禁用「保存模板」,避免误写到计划 |
---
## 非目标(本期不做)
- 后端空白单专用 API
- 独立空白打印页面 / 路由
- 空白单合打、按计划覆盖空白字段
- 修改富文本模版列结构或条款文案
- 查看弹窗、安排运输成功栏的空白打印入口
---
## 交互(列表工具栏)
```
打印单据 ▾ ← 始终可点(不依赖勾选)
├─ 入库单 ← 需勾选且 canBatchPrintSlip(..., 'inbound')
├─ 送(提)货单 ← 需勾选且 canBatchPrintSlip(..., 'delivery')
├─ 分装单 ← 需勾选且 canBatchPrintSlip(..., 'subpack')
├─ 空白入库单 ← 始终可点 → inboundSlipPrintRef.openBlank()
├─ 空白送(提)货单 ← 始终可点 → deliverySlipPrintRef.openBlank()
└─ 空白分装单 ← 始终可点 → subpackSlipPrintRef.openBlank()
```
- 未勾选:原三项 `disabled`,空白三项可点。
- 已勾选:原三项按现网规则;空白三项仍可点,且 **不使用** 勾选行数据。
---
## 空白内容规则
### 保留(版式骨架)
- Logo、公司名称、单据标题(入库单 / 送(提)货单 / 分装单)
- 信息区标签与下划线框、物料表表头、空行网格
- 条款、签字栏等固定版式(各模板现有结构)
### 清空(业务数据)
- 客户/单位、日期、人员、车辆、备注、联系方式等占位字段 → 空
- 物料单元格 → 空
- 单据编号 / 计划号 / 分装单号 → 空
- 送(提)货单:`showRedSeal = false`,打开时不注入印章图
### 产品空行
| 单据 | 空行策略 |
|------|----------|
| 入库单 / 送(提)货单 | 空白模式生成固定数量空网格行(建议与分装单最小行数对齐,或不少于 5 行);禁止「暂无产品信息」合并单元格文案 |
| 分装单 | 复用现有 `SUBPACK_SLIP_PRODUCT_MIN_ROWS` 空行填充逻辑,产品数组为空即可 |
---
## 技术要点
### 前端改动面
| 文件 | 改动 |
|------|------|
| `web-admin/src/views/pl/plan/index.vue` | 工具栏:按钮去掉「未选禁用」;下拉增加三个空白 command;handler 调 `openBlank()` |
| `pl-inbound-slip-print-dialog/index.vue` | `openBlank()`;空白态禁用保存模板;产品空行 |
| `pl-delivery-slip-print-dialog/index.vue` | 同上;打开时默认关章 |
| `pl-subpack-slip-print-dialog/index.vue` | 同上;不请求分装单号 |
| `pl-*-slip-template.ts`(按需) | 支持「空 Plan + 空 ctx」替换;入库/送提货 `buildProductRows` 增加空白模式空行(或由弹窗传入空行 HTML) |
### `openBlank()` 行为
1. 不调用 `planApi.get` / `get*SlipTemplate` / `ensureSubpackSlipNo`
2. `htmlContent = generate*SlipTemplate()`(默认模板)
3. 用空业务数据做 `replace*SlipPlaceholders`(或等价全空替换)
4. 送(提)货:`showRedSeal = false`,并确保内容无印章 img
5. 打开弹窗;标题可区分如「预览空白入库单」或沿用现标题(实现时择一,保持三类一致)
### 后端
本期 **无** 后端变更。
---
## 验收标准
1. 未勾选任何计划时,「打印单据」可点;原三项灰;三个空白项可打开对应弹窗。
2. 空白入库单:无业务数据、无「暂无产品信息」、有空行;可打印/PDF。
3. 空白送(提)货单:无业务数据、无印章、有空行;可打印/PDF。
4. 空白分装单:无业务数据、分装单号为空、有空行;不产生新分装单号;可打印/PDF。
5. 勾选计划后,原三项填数打印行为与现网一致;空白三项仍出空白单且不带入勾选数据。
6. 空白模式下无法「保存模板」到计划。
---
## 风险与注意
- 入库/送提货现网空产品会渲染「暂无产品信息」,空白模式必须绕开该分支。
- 已保存的计划模板可能含历史数据;空白路径 **禁止** 读取计划模板,避免脏数据。
- 公司名等常量来自模板 defaults,属版式而非业务填写,保留。