From 70c9de36182d57d1ea772298759f7a4876df41c9 Mon Sep 17 00:00:00 2001 From: zlwu <704541015@qq.com> Date: Wed, 2 Sep 2026 11:33:05 +0800 Subject: [PATCH] docs: add transport plan draft/save design for drafting follow status MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Capture approved decisions for 暂存 button, drafting status, list tab, and saveMode API so implementation can follow a single spec. Co-authored-by: Cursor --- .../2026-09-02-pl-plan-draft-save-design.md | 179 ++++++++++++++++++ 1 file changed, 179 insertions(+) create mode 100644 docs/superpowers/specs/2026-09-02-pl-plan-draft-save-design.md diff --git a/docs/superpowers/specs/2026-09-02-pl-plan-draft-save-design.md b/docs/superpowers/specs/2026-09-02-pl-plan-draft-save-design.md new file mode 100644 index 000000000..84715abcf --- /dev/null +++ b/docs/superpowers/specs/2026-09-02-pl-plan-draft-save-design.md @@ -0,0 +1,179 @@ +# 运输计划「暂存 / 草稿中」设计 + +日期:2026-09-02 +范围:`web-admin` 运输计划列表与新增/编辑弹窗;`backend` 计划 create-full / update 及跟进状态相关门禁 +状态:已评审(待实现) + +## 1. 背景与目标 + +业务希望在【运输计划】新增/编辑弹窗增加【暂存】:跳过合同、装送货段、产品等业务校验,以跟进状态「草稿中」落库,便于稍后补全。 + +正式【创建/保存】仍走全量校验;若原状态为草稿,正式保存后自动升为「待安排」。 + +## 2. 已确认决策 + +| 项 | 决策 | +|---|---| +| 列表默认可见 | 「草稿中」进入默认筛选(与待安排等同类) | +| 首个 Tab | 文案改为「待安排/草稿」;默认同时查 `pending_arrange` + `drafting` | +| 跟进状态筛选 | 保持多选;该 Tab 下不再禁用,可继续增删勾选 | +| 暂存校验 | 仅要求归属公司 + 创建日期;跳过业务校验 | +| 正式保存 | 草稿 → 自动变为待安排 | +| 【暂存】可见性 | 新建、草稿中、待安排可暂存;等通知/已安排/已完成/已取消不可 | +| 列表操作 | 草稿与待安排完全相同(安排运输、等通知等;动作内仍全量校验) | +| 实现路径 | 新增状态值 `drafting` + create/update 增加 `saveMode`(方案 1) | + +## 3. 状态与数据模型 + +### 3.1 跟进状态枚举(6) + +| value | 文案 | Tag 建议 | +|---|---|---| +| `drafting` | 草稿中 | `info` | +| `wait_notice` | 等通知 | `warning` | +| `pending_arrange` | 待安排 | `danger` | +| `arranged` | 已安排 | `success` | +| `completed` | 已完成 | `success` | +| `cancelled` | 已取消 | `info` | + +- **不复用** 旧兼容值 `draft`(展示层曾映射为「待安排」)。 +- **不动** `archive_status = draft`(归档暂存,另一概念)。 +- `pl_plan.follow_status` 为字符串字段,**无需 DDL**;更新 schema 注释、前端选项与强制改状态白名单即可。 + +### 3.2 状态流转 + +``` +新建【暂存】 ──────────────────▶ drafting +drafting / pending_arrange + 【暂存】 ──────────────────▶ drafting +drafting + 【创建/保存】formal ────────▶ pending_arrange +drafting / pending_arrange + 【安排运输】全量校验 ───────▶ arranged +drafting / pending_arrange + 【等通知】全量校验 ─────────▶ wait_notice + +wait_notice / arranged / completed / cancelled + ✕ 不允许【暂存】降级 +``` + +### 3.3 与「待安排」对齐的门禁 + +凡业务上写死「仅 `pending_arrange`」且应对草稿开放的能力,同步允许 `drafting`: + +- 前端:`canWaitNotice`、删除按钮可见性等 +- 后端:`wait-notice`、`delete`、`ALLOWED_FORCE_FOLLOW_STATUSES`(纳入 `drafting`) +- 安排运输:全量校验通过后可从 `drafting` 直接进入 `arranged` + +## 4. 接口与校验 + +### 4.1 请求约定 + +在现有接口 body 增加(缺省兼容现网): + +```ts +saveMode?: 'draft' | 'formal' // 默认 'formal' +``` + +涉及: + +- `POST /transport/plan/create-full` +- `PUT /transport/plan/{id}` + +不新增独立草稿 URL。 + +### 4.2 服务端行为 + +| saveMode | 校验 | follow_status 写入 | +|---|---|---| +| `draft` | 仅强制 `belongsCompany`、`createDate`(缺省则服务端用当天);跳过 `validate_create_full`、装送货合同/产品等业务校验;不完整装送货结构宽松落库或按空段处理 | 固定 `drafting` | +| `formal` | 保持现有全量校验 | 新建 → `pending_arrange`;若原为 `drafting` → 升为 `pending_arrange`;其它正式状态按现有更新逻辑 | + +`draft` 更新门禁:仅当当前 `follow_status ∈ {drafting, pending_arrange}`,否则 400「当前状态不可暂存」。 + +### 4.3 列表动作接口 + +| 接口 | 调整 | +|---|---| +| `wait-notice` | 源状态允许 `drafting` \| `pending_arrange` | +| `delete` | 允许 `drafting`(仍要求未安排运输、未归档) | +| `force-follow-status` | 白名单加入 `drafting` | +| 安排运输链路 | 全量校验后 → `arranged`(可自 `drafting`) | + +## 5. 前端 UI + +### 5.1 列表 Tab / 筛选 + +文件主要:`web-admin/src/utils/pl-display.ts`、`web-admin/src/views/pl/plan/index.vue` + +- `PL_PLAN_LIST_TABS` 首项 label:`待安排/草稿`(`name` 仍为 `pending_arrange`) +- `plPlanListTabToFilters('pending_arrange')` → `followStatus: 'pending_arrange,drafting'` +- 切入该 Tab:`searchForm.followStatus = ['pending_arrange', 'drafting']` +- 离开该 Tab:恢复扩展后的 `PL_PLAN_DEFAULT_FOLLOW_STATUSES`(含 `drafting`,不含 `cancelled`) +- 跟进状态:`el-select` `multiple`;**去掉**该 Tab 下的 `:disabled` +- `PL_PLAN_FOLLOW_STATUS_OPTIONS` 增加「草稿中」/`drafting` +- `getPlPlanFollowStatusLabel` / `TagType` 支持 `drafting` + +### 5.2 弹窗底栏(`PlPlanFormDialog`) + +顺序:`取消` → **`暂存`**(条件)→ `创建|保存` → `创建并安排|保存并安排` / `调整运输` + +【暂存】显示: + +- 新建:显示 +- 编辑:仅 `followStatus ∈ {drafting, pending_arrange}` + +样式:中性描边(非 primary);与保存共用/互斥 loading。 + +`handleSubmit` 增加 mode:`'draft' | 'save' | 'saveAndArrange' | 'rearrange'` + +- `draft`:只校验归属公司 + 创建日期;`saveMode: 'draft'`;成功「暂存成功」 +- `save`:全量校验;`saveMode: 'formal'` +- 安排类:全量校验 + 现有安排链路(不传 draft) + +### 5.3 错误与成功提示 + +| 场景 | 行为 | +|---|---| +| 暂存缺归属公司/创建日期 | 高亮两项 + Message;不跑其它校验 | +| 非法状态暂存 | 后端 400 | +| 正式保存/安排失败 | 与现网一致,状态不变 | +| 暂存成功 | 关弹窗、刷新列表 | + +## 6. 主要改动面 + +| 层 | 路径 | +|---|---| +| 展示常量 | `web-admin/src/utils/pl-display.ts` | +| 列表页 | `web-admin/src/views/pl/plan/index.vue` | +| 表单弹窗 | `web-admin/src/components/business/pl-plan-form-dialog/index.vue` | +| API 类型 | `web-admin/src/api/pl/index.ts`(`saveMode`) | +| Schema | `backend/app/schemas/pl/plan.py` | +| 创建/更新 | `backend/app/api/pl/plan.py` | +| 校验辅助 | `backend/app/services/pl_plan_service.py`(按需拆 `validate_draft_min_fields`) | +| 强制改状态等 | 同 `plan.py` 白名单与 wait-notice / delete | + +危化品证等其它列表若复用 `PL_PLAN_FOLLOW_STATUS_OPTIONS` / 默认筛选,一并带上 `drafting`(与「默认可见」决策一致)。 + +## 7. 验收用例 + +1. 新建仅填归属公司 + 创建日期 → 暂存 → 列表「草稿中」,出现在「待安排/草稿」Tab +2. 编辑草稿 → 正式保存 → 「待安排」 +3. 编辑待安排 → 暂存 → 「草稿中」 +4. 已安排打开编辑 → 无【暂存】 +5. 「待安排/草稿」Tab 默认同时看到两类;多选可再筛 +6. 草稿可点等通知/安排:失败提示校验;成功离开草稿态 +7. 草稿可删除(未安排、未归档) + +## 8. 非目标 + +- 不改归档暂存(`archive_status`)语义与「归档草稿」接口 +- 不做本地未落库草稿(必须写库) +- 不为此单独做新页面/新菜单 +- 不强制迁移历史数据中的旧 `draft` 跟进值(若存在,展示兼容可保留,与新 `drafting` 并存) + +## 9. 风险 + +- create-full / update 的 draft 分支若跳过装送货校验过松,需保证 DB 可空字段与前端再次打开不崩 +- 列表「与待安排相同」会扩大草稿可触发的下游动作,依赖动作内全量校验守门 +- Tab `name` 仍为 `pending_arrange`,文档与代码注释需标明「含草稿」以免后续误改回单状态过滤