Capture approved decisions for miniprogram driver/escort plan list, escort selection on arrange, and personnel-user linking. Co-authored-by: Cursor <cursoragent@cursor.com>
13 KiB
13 KiB
小程序 · 司机运输计划单(运输记录 / 司机回执)— 设计文档
日期: 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+safeAreaStyletopbar-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. 验收
- 角色「司机」「押运员」可见运输管理 → 司机运输计划单;其他角色不可见该菜单
- 列表默认今日;日历切日、卡片与 H5 运输记录一致;可进司机回执
- 张三改为李四后:张三立刻看不到该单,李四能看;押运同理
- 安排运输可选押运、可模糊搜、有绑定自动带出、非必填
- 驾押人员可关联/解绑系统用户;一人一账号
- 回执保存与公开司机链接写同一套数据
- 顶栏对齐备用金申请;正文对齐现网司机链接页
- 复制司机链接与公开 H5 仍可用;公开运输记录仍按单车牌
- 测试库补角色(若缺)+ 菜单/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 |