Files
shanxia2.0/docs/superpowers/specs/2026-09-13-mini-pl-driver-plan-design.md
T
wuzilongandCursor 3a70c44508 docs: add mini driver transport plan design spec
Capture approved decisions for miniprogram driver/escort plan list,
escort selection on arrange, and personnel-user linking.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 10:23:34 +08:00

13 KiB
Raw Blame History

小程序 · 司机运输计划单(运输记录 / 司机回执)— 设计文档

日期: 2026-09-13
状态: 待实现
方案: 方案 1 — 小程序原生页 + 登录态 API(复用现有司机公开页业务逻辑)
对齐: H5 司机链接「运输记录 / 司机回执」;顶栏对齐小程序「备用金申请」;实现路径对齐「运输计划单」(现场)

1. 目标

司机 / 押运员此前通过管理端「复制司机链接」在微信中打开 H5 免登录页完成查看与回执。现已有微信小程序,需在小程序内提供同等能力:

  • 工作台 运输管理 → 司机运输计划单
  • 默认打开等同 H5 运输记录 的列表(日历按日)
  • 点击记录进入等同 H5 司机链接回执 的详情
  • 正文样式与现网司机链接页一致;仅顶栏改为与备用金申请等同款
  • 列表过滤改为:当前登录用户关联驾押人员作为该计划当前司机或当前押运的记录(可跨多车/多计划)
  • Web 公开司机链接能力继续保留

2. 已确认决策

# 项 决策
D1 实现路径 原生列表 + 原生回执 + 登录态 API;不复用公开 token 混调;不 web-view
D2 列表对齐 H5「运输记录」:日历按日;正文样式一致;顶栏对齐备用金
D3 详情对齐 H5「司机回执」功能/正文一致;顶栏对齐备用金
D4 可见性 登录用户关联的驾押人员 = 计划当前司机或当前押运;改安排后旧人立刻不可见
D5 押运字段 安排运输增加「选择押运员」(可选、可模糊检索;车辆已绑定则自动带出)
D6 押运选项 优先该车已绑定押运;可从驾押人员库选押运(filterable + remote)
D7 账号关联 【驾押人员】增加「关联用户账号」(本需求一并做)
D8 菜单权限 仅系统角色「司机」「押运员」(测试库若无则创建;生产已有则复用并绑菜单)
D9 公开链接 Web 司机链接 H5 / 公开 API 全部保留;公开「运输记录」仍按单车牌过滤
D10 列表标题 司机运输计划单(与菜单名一致)
D11 详情标题 司机回执

3. 非目标

  • 不按 pl_vehicle_personnel 车辆任职单独过滤(不以「挂在车上」为准)
  • 不强制必填押运员
  • 不改现场「运输计划单」逻辑与菜单授权
  • 不修改或下线 /api/public/pl/transport/{token}/...
  • 不给「司机 / 押运员」自动授权加油登记、现场运输计划单等其他菜单
  • 不输出独立 HTML demo

4. 架构

【账号绑定】
驾押人员 pl_personnel.sys_user_id  ←→  sys_user
        ↓
【安排运输】
选车 → 自动带出司机 / 押运(可改、可空)
  → pl_transport.driver_id + escort_id(新增)
  → resource_snapshot.selectedDriverId / selectedEscortId
  → 公开司机链接仍生成 driver_access_token(不变)

【小程序】
登录 JWT
  → 工作台 perms: mini:pl:driverPlan:list
  → 列表 pages/pl/driver-plan/list
       GET /api/transport/driver-plan/history?date=YYYY-MM-DD
       过滤:tenant + arranged + 日匹配
             AND (driver_id OR escort_id) ∈ 当前用户关联的 personnel_id
  → 详情 pages/pl/driver-plan/detail?planId=
       GET/POST /api/transport/driver-plan/{planId}/...
       (复用公开司机回执同一套 service)

【公开 H5 保留】
/#/public/pl/transport/{token}[/history]
  → /api/public/pl/transport/{token}/...

登录态与公开 API 共用 回执页构建 / 反馈保存 / 附件等 service 逻辑:
公开链路为 token → transport → tenant/plan;登录态为 current_user → personnel → 校验 plan 当前司机/押运命中。

列表过滤与公开 history 不同:公开 history 按 token 解析出的单车牌;登录态按当前用户命中的司机/押运(可多计划、多车牌)。日期 OR 逻辑(取货日或送货日)保持一致。

5. 数据模型

5.1 pl_personnel

字段 类型 说明
sys_user_id VARCHAR(64) NULL 关联系统用户 ID
  • 同租户下同一 sys_user_id 最多绑一条未删除人员(应用层校验)
  • 山峡 / 三方分册均可维护;无账号可不绑

5.2 pl_transport / pl_plan(与司机字段对称)

字段 类型 说明
escort_id VARCHAR(64) NULL 当前选中押运员人员 ID
escort_name VARCHAR(100) NULL 押运员姓名冗余
escort_phone VARCHAR(32) NULL 押运员电话冗余

resource_snapshot JSON 增加 selectedEscortId(与现有 selectedDriverId 对称)。

5.3 可见性规则(规范性)

设当前用户关联人员 ID 为 P:

  • 可见:transport_status = arranged 且(driver_id = P 或 escort_id = P)且命中所选日
  • 改安排:司机由张三改为李四后,张三立即不可见、不可写;李四可见
  • 押运为空:仅司机可命中该单;押运员账号看不到该单(非必填的自然结果)
  • 历史无 escort_id 的旧单:仅能按司机命中;需重新安排并选押运后押运员才可见

日期匹配与公开运输记录一致:

  • date(pickup_time) = day 或 date(delivery_time) = day
  • 不使用 plan_date 作为登录态司机列表日条件(与公开 driver history 对齐)

6. 菜单与权限

6.1 菜单树

移动端根 (id=1)
└─ 运输管理 (MINI_PL_ROOT)                 ← 已存在则复用
   ├─ 加油登记 (MINI_PL_FUEL_REG)          ← 不动
   ├─ 运输计划单 (MINI_PL_TRANSPORT_PLAN)  ← 不动(现场人员)
   └─ 司机运输计划单 (MINI_PL_DRIVER_PLAN) ← 新建
字段 值
id MINI_PL_DRIVER_PLAN
menu_name 司机运输计划单
parent_id MINI_PL_ROOT
menu_type C
path driver-plan
perms mini:pl:driverPlan:list
order_num 3(在运输计划单之后;若冲突以迁移 SQL 为准)

6.2 角色

  • 按 sys_role.role_name IN ('司机', '押运员') AND del_flag = 0 匹配(不写死 role id)
  • 测试库:若不存在则幂等创建这两个角色,再绑菜单
  • 生产库:角色已存在则只做菜单 + sys_role_menu 绑定
  • 绑定菜单:移动端根 1、MINI_PL_ROOT、MINI_PL_DRIVER_PLAN

6.3 交付 SQL

  • 文件:docs/sql/migrations/2026-09-13-mini-pl-driver-plan-menus.sql(菜单 + 角色补齐 + 授权)
  • 另需 schema 迁移:pl_personnel.sys_user_id、pl_transport/pl_plan 押运字段
  • 在测试环境库、生产环境库各执行相应迁移

6.4 前端菜单配置

  • miniprogram/config/workbench-menus.js:运输管理下增加菜单项
  • miniprogram/config/api.js:PAGE_PATHS + WORKBENCH_ROUTE_MAP(code:pl-driver-plan)
  • miniprogram/pages.json:分包注册 list / detail

7. Web 管理端改造

7.1 驾押人员

  • 列表 / 新增 / 编辑:增加「关联用户账号」(可清空、模糊选择用户)
  • 一人一账号;若用户已被其他人员绑定则提示并拒绝保存
  • 查看弹窗展示已关联用户(若有)

7.2 安排运输

  • 在「选择司机」旁增加「选择押运员」
  • 控件:el-select,filterable + remote + clearable,未选车时禁用(与司机一致)
  • 选车后:从该车 personnelList 中 role=escort 自动带出(多个取默认或第一个);可改选人员库押运
  • 提交:写入 escort_id/name/phone,快照写入 selectedEscortId
  • 重新安排更新押运后,旧押运失去小程序可见性

7.3 公开司机链接

  • 复制入口、token 生成、H5 回执 / 运输记录行为不改
  • 公开运输记录仍按当前 token 运输单车牌过滤

8. 后端 API

前缀:/api/transport/driver-plan(挂入现有 pl_router,JWT + 租户隔离)。

方法 路径 说明
GET /history?date=YYYY-MM-DD 我的运输记录列表
GET /{planId} 司机回执详情
POST /{planId}/feedback 对齐公开 POST /public/pl/transport/{token}/feedback
POST /{planId}/driver-feedback 对齐公开 POST /public/pl/transport/{token}/driver-feedback
POST /{planId}/attachments 对齐公开附件上传

8.1 规则

  • Depends(get_current_user);读写强制当前用户 tenant_no
  • 解析 pl_personnel:sys_user_id = current_user.id 且同租户、未删除;无关联则 history 返回空列表,详情 403/404
  • 列表:本租户、arranged、日期 OR 逻辑同公开 driver history,且 driver_id 或 escort_id 等于关联人员
  • 详情 / 保存:计划属本租户,且当前用户仍是该单司机或押运;否则拒绝
  • 作废 / 已归档:只读,禁止保存与上传
  • 菜单权限主要用于入口显隐;后端以登录 + 租户 + 司机/押运命中为准
  • 附件上传遵循小程序拍照凭证基线;若网关加密,路径加入 API_ENCRYPT_EXCLUDE_PATHS

8.2 实现约束

  • 抽出与 token 无关的 service 能力,公开 API 与登录态 API 共用,避免两套业务规则
  • 列表出参对齐公开 history 卡片字段(planId、车牌、stops、statusLabel 等);小程序用 planId 跳详情,不依赖 URL token
  • 参考实现:backend/app/api/pl/site_plan.py + pl_site_plan_service.py 与 public_transport_site 的关系

9. 小程序页面

页面 路径 顶栏标题
列表 miniprogram/pages/pl/driver-plan/list.vue 司机运输计划单
详情 miniprogram/pages/pl/driver-plan/detail.vue 司机回执

9.1 顶栏

与备用金申请 / 运输计划单相同结构:

  • 根节点 class="bx-page"(复用 bx-theme 顶栏样式)
  • topbar + safeAreaStyle
  • topbar-back(←)+ topbar-title
  • 白底、底边、左对齐标题;禁止绿色渐变顶栏 / H5 van-nav-bar 绿顶栏

9.2 列表

  • 月历选日(默认今日)
  • 不提供车牌/产品搜索框(范围已是「我作为司机或押运的计划」)
  • 卡片字段与交互对齐 H5 transport/history.vue
  • 点击 → detail?planId=...
  • 返回:回工作台

9.3 详情

  • 能力对齐公开司机回执页(计划摘要、人员、停靠、反馈、附件等现有能力)
  • 底栏:回列表 + 保存(文案对齐产品;可用「运输记录」「保存回执」等与 H5 语义一致的文案)
  • 附件:uni.chooseImage + uni.uploadFile(Bearer + folder)
  • 作废 / 归档只读,与 H5 一致
  • 保存成功 toast,留在详情并刷新

9.4 视觉 Token

正文使用小程序三墙体系(如 #0a9f6d / #059669),不混用 web-admin Fresh Mint #10b981 作为主色。

10. 错误处理

场景 行为
未登录 既有登录拦截
无「司机/押运员」菜单权限 工作台不展示入口
用户未关联驾押人员 列表空态「暂无运输记录」;详情拒绝
当日无命中计划 空态「暂无运输记录」
planId 无效 / 跨租户 / 已不是当前司机或押运 详情错误空态或提示后回列表
作废 / 归档写操作 业务错误 toast
网络失败 toast,不静默失败

11. 验收

  1. 角色「司机」「押运员」可见运输管理 → 司机运输计划单;其他角色不可见该菜单
  2. 列表默认今日;日历切日、卡片与 H5 运输记录一致;可进司机回执
  3. 张三改为李四后:张三立刻看不到该单,李四能看;押运同理
  4. 安排运输可选押运、可模糊搜、有绑定自动带出、非必填
  5. 驾押人员可关联/解绑系统用户;一人一账号
  6. 回执保存与公开司机链接写同一套数据
  7. 顶栏对齐备用金申请;正文对齐现网司机链接页
  8. 复制司机链接与公开 H5 仍可用;公开运输记录仍按单车牌
  9. 测试库补角色(若缺)+ 菜单/schema SQL;生产复用已有角色并绑菜单

12. 风险

风险 缓解
公开与登录态逻辑分叉 共用 service
生产角色名不一致 SQL 按 role_name 匹配,执行前核对
历史单无 escort_id 仅司机可见;补安排后再给押运
用户未绑人员 空态 + 管理端引导关联
小程序日历与 Vant 月历差异 交互对齐验收对照 H5;可复用运输计划单日历组件
附件加密网关 上传路径按约定排除加解密

13. 参考实现

用途 路径
H5 运输记录 web-admin/src/views/public/pl/transport/history.vue
H5 司机回执 web-admin/src/views/public/pl/transport/index.vue
公开司机 API backend/app/api/pl/public_transport.py
现场小程序先例 miniprogram/pages/pl/transport-plan/*、backend/app/api/pl/site_plan.py
现场设计文档 docs/superpowers/specs/2026-09-13-mini-pl-transport-plan-site-design.md
顶栏参考 miniprogram/pages/bx/advance/list.vue
安排运输司机选择 web-admin/src/components/business/pl-plan-form-dialog/index.vue
驾押人员页 web-admin/src/views/pl/personnel/index.vue
菜单 SQL 参考 docs/sql/migrations/2026-09-13-mini-pl-transport-plan-menus.sql