2026-09-02-pl-plan-draft-save-design.md 7.6 KB

运输计划「暂存 / 草稿中」设计

日期: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 增加(缺省兼容现网):

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,文档与代码注释需标明「含草稿」以免后续误改回单状态过滤