2026-07-19-pl-inbound-outbound-order-design.md 9.7 KB

运输计划 · 入库单 / 出库单设计

日期: 2026-07-19
状态: 已确认并实现中
范围: web-admin 运输管理 + backend PL API + 免登录现场公共页
界面模式: 列表对齐标准列表(P01 / system/unit);编辑弹窗对齐 Fresh Mint dialog-form-layout


1. 背景与问题

现状为双轨:

  • 安排运输后按产品生成 pl_transport_site_link(现场仅备注+附件,数量只读)
  • 可选勾选生成地磅 db_inbound_outbound(合一列表 /#/db/inventory)

客户需要运输计划域下独立入库单 / 出库单界面:安排后落单、现场按产品填实际数量、整单附件备注、归档可见;并覆盖取消与「只能作废重建」的约束。


2. 已确认决策

# 决策 选择
D1 单据域 新建 PL 主从表:入库一套 + 出库一套(对称),不复用地磅表作主单据
D2 地磅关系 有关联地磅单时,用其数量预填 actual_qty,仍可改;不做双向自动覆盖
D3 现场链接 免登录公共页;一单一链(多产品同页)
D4 多产品 明细各自填实际数量;附件+备注在主表整单共用
D5 状态 in_progress / completed / voided;新建默认进行中;现场首次提交 → 自动已完成;管理端可手动选择进行中/已完成;已作废主要由计划作废写入(管理端也可手动置作废,作废后禁止现场提交)(现场自动完成规则已被 2026-07-19-pl-site-io-order-status-select-design.md 覆盖:现场提交须显式传 status)
D6 已完成可改 已完成仍可继续完善数量/附件/备注
D7 归档 以入库/出库单为权威,归档只读展示;可选同步到 pl_plan_product
D8 快照 最小快照(兼容作废单历史展示)+ 保留 plan_id / transport_id
D9 计划冻结 安排后完全冻结:不可编辑计划、不提供调整运输;只可作废 → 新建计划再安排
D10 菜单 一级「运输管理」→ 二级「库存管理」→「入库单」「出库单」
D11 直销单 不生成入库/出库单

3. 菜单与路由

运输管理(PL_MENU_ROOT,既有)
└── 库存管理(新建 M,建议 id: PL_GROUP_STOCK)
    ├── 入库单(C,perms: pl:inbound:list)
    └── 出库单(C,perms: pl:outbound:list)
菜单 建议 path component 路由 Hash(示意)
库存管理 stock-module — /#/pl/stock-module/...
入库单 inbound pl/inbound/index /#/pl/stock-module/inbound
出库单 outbound pl/outbound/index /#/pl/stock-module/outbound

说明:

  • 与既有「地磅出入库」/#/db/inventory、证件提醒路径 pl/inventory/... 分离,故二级目录用 stock-module,避免与 pl_inventory 库存台账语义混淆。
  • 权限按钮:列表查看、编辑、改状态、复制现场链接(细项实现阶段落库 sys_menu)。
  • 角色授权:实现时挂到既有运输相关角色;super_admin 默认可见。

4. 数据模型

4.1 入库主表 pl_inbound_order

字段 说明
id VARCHAR(64) UUID
order_no 业务单号(如 RK + 日期序号)
plan_id → pl_plan
transport_id → pl_transport
status in_progress | completed | voided
partner_company 最小快照:往来单位
vehicle_no 最小快照:车牌
plan_no 最小快照:计划号
plan_date 最小快照:计划日期
site_access_token 一单一链,唯一
site_feedback_remark 整单现场备注
site_feedback_images 回执图(逗号分隔 URL 或 JSON,与现现场链路一致)
site_feedback_time 最近提交时间
site_first_submitted_at 首次提交时间;用于自动置 completed
公共字段 tenant_no, order_num, remark, create_by, create_dept_id, create_time, update_by, update_time, del_flag

4.2 入库明细 pl_inbound_order_item

字段 说明
id UUID
order_id → pl_inbound_order
plan_product_id → pl_plan_product
product_id / product_name / specification / unit 产品快照
plan_qty 安排时计划数量
actual_qty 实际数量(可改)
qty_source plan | dibang | manual
公共字段 同规范

4.3 出库

pl_outbound_order / pl_outbound_order_item 与上表字段对称(单号前缀 CK)。

4.4 索引建议

  • (tenant_no, plan_id)、(tenant_no, transport_id)、(tenant_no, status)、site_access_token UNIQUE
  • 明细 (order_id)、(plan_product_id)

4.5 与旧对象

对象 关系
pl_transport_site_link 新安排不再生成;历史数据只读兼容或后续迁移脚本(实现计划中单列任务)
db_inbound_outbound 仍可选「生成地磅」;有关联时预填 actual_qty,不互相覆盖写死
pl_plan / pl_transport 关联键 + 最小快照;列表可跳转计划

5. 生命周期

安排运输(入库/出库计划)
    → 创建 1 主表 + N 明细,status=in_progress,生成 token
    → actual_qty 默认 = plan_qty
    → 若有地磅关联产品行 → 预填 actual_qty,qty_source=dibang

现场首次成功提交
    → 写明细 actual_qty + 主表备注/附件
    → site_first_submitted_at 有值则 status → completed(若仍为 in_progress)

管理端
    → 可手动改 status(含 completed ↔ in_progress)
    → 已完成仍可改数量/附件/备注

计划作废
    → 关联未作废的入库/出库单 → voided
    → token 失效(公共页只读提示已作废,禁止提交)

已安排后
    → 禁止编辑计划正文
    → 禁止「调整运输」
    → 纠错路径:作废计划 → 新建计划 → 再安排(新单 + 新链接)

直销单:安排运输不创建入库/出库单(可继续仅司机链接,若现网有)。


6. 接口(示意)

6.1 管理端

  • GET /api/.../pl/inbound 列表
  • GET /api/.../pl/inbound/{id} 详情(含 items)
  • PATCH /api/.../pl/inbound/{id} 编辑(数量、备注、附件、status)
  • GET /api/.../pl/inbound/{id}/site-url 复制现场链接
  • 出库对称:/pl/outbound/...

安排运输成功响应中返回:inboundOrder / outboundOrder(含 siteUrl),供安排成功弹窗复制。

作废计划:在现有 cancel 流程中追加作废关联入库/出库单。

6.2 公共页

  • GET /api/public/pl/inbound/{token} 摘要 + 明细
  • POST /api/public/pl/inbound/{token}/feedback 提交实际数量(按 item)+ 备注 + 附件
  • 出库对称

URL 形态:{PUBLIC_WEB_ORIGIN}/#/public/pl/inbound/{token}(出库 /public/pl/outbound/{token})。


7. 前端界面

7.1 列表

  • 筛选:单号、计划号、状态、日期、往来单位、车牌等
  • 列:单号(主标识链接打开查看/编辑)、状态 Tag、计划号、往来单位、车牌、产品摘要、实际量合计、首次/最近提交时间
  • 工具栏:复制现场链接(选中一行)等
  • 状态 Tag:进行中=warning,已完成=success,已作废=info(或 danger,实现时对齐 UI 规范枚举)

7.2 编辑弹窗

  • 主表:状态(可选手动改)、快照信息只读、整单备注与附件
  • 明细表:计划数量只读、实际数量可编辑
  • label-position="top",无背景模糊

7.3 现场公共页

  • 免登录;布局对齐「一张单编辑」:产品行实际数量 + 底部备注/附件 + 提交
  • voided:不可提交;completed:仍可再次提交完善

7.4 归档

  • PlPlanViewTabs / 归档弹窗:以关联入库/出库单只读展示实际数量、附件、备注
  • 可选:归档保存时同步 pl_plan_product.actual_qty(及 inbound/outbound 数量字段)

7.5 运输计划

  • arranged 后:隐藏/禁用编辑与「调整运输」;作废入口保留
  • 安排成功:复制现场链接改为入库/出库单单链(替代按产品多条旧现场 link)

8. 非目标(本期不做)

  • 入库/出库与地磅单双向自动覆盖
  • 拼车多计划共用一张出入库单
  • 强制迁移全部历史 pl_transport_site_link(可后续脚本)
  • 小程序端入库/出库列表(若未单列需求)

9. 验收要点

ID 场景
V1 入库计划安排 → 库存管理-入库单可见,状态进行中,有现场链接
V2 多产品:一链打开,各产品实际数量独立,备注附件整单
V3 有地磅时 actual 预填地磅量,可改
V4 现场首次提交 → 已完成;管理端可改回进行中/再改完成
V5 已完成后仍可改数量与附件
V6 作废计划 → 单作废,链接不可再提交
V7 已安排计划不可编辑、无调整运输;须作废重建
V8 归档只读看到单上实际数据
V9 菜单:运输管理 → 库存管理 → 入库单/出库单
V10 直销单不产生入库/出库单

10. 实现备注

  • DDL 同步 docs/sql/;遵守 database-conventions 公共字段与软删
  • 租户隔离、数据权限与现有 PL API 一致
  • 字段一致性:_row_to_dict / CreateUpdateBody / 前端 form 对齐
  • 替代旧现场 link 时,安排运输 API 与前端复制链接 UX 一并切换

11. 决策记录(brainstorm)

  • 可视化会话:.superpowers/brainstorm/ 下 HTML 选项页
  • 方案选型:主从表分离 A;现场公共页 A;一单一链 A;归档权威 A;最小快照 A;计划完全冻结 B