From 3a70c445081d8a8cb8d0713e43c2a5803ac9e1ff Mon Sep 17 00:00:00 2001 From: wuzilong <704541015@qq.com> Date: Sun, 13 Sep 2026 10:23:34 +0800 Subject: [PATCH] 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 --- .../2026-09-13-mini-pl-driver-plan-design.md | 285 ++++++++++++++++++ 1 file changed, 285 insertions(+) create mode 100644 docs/superpowers/specs/2026-09-13-mini-pl-driver-plan-design.md diff --git a/docs/superpowers/specs/2026-09-13-mini-pl-driver-plan-design.md b/docs/superpowers/specs/2026-09-13-mini-pl-driver-plan-design.md new file mode 100644 index 000000000..30084f847 --- /dev/null +++ b/docs/superpowers/specs/2026-09-13-mini-pl-driver-plan-design.md @@ -0,0 +1,285 @@ +# 小程序 · 司机运输计划单(运输记录 / 司机回执)— 设计文档 + +> **日期**: 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. 架构 + +```text +【账号绑定】 +驾押人员 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` |