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>
This commit is contained in:
1 parent
1c631ccd50
commit
3a70c44508
1 file changed
+285
@@ -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` |
|
||||
Reference in new issue
Block a user