3.0 KiB
Context
山峡化工 web-admin 运输管理(PL)已有 ETC/加油充值申请与发放(pl_vehicle_recharge_apply / pl_vehicle_recharge_record),采用双菜单、无审批、1:0~1 关联、发放看板 UX。客户新增 车辆维保 需求,业务形态相似但申请字段更丰富,且需在选车时提醒未过预计取车日的待处理维保。
工程约束:租户隔离、数据权限、软删除、Fresh Mint UI、静态路由(VITE_ACCESS_MODE=frontend)。
Goals / Non-Goals
Goals:
- 交付维保申请页 + 处理登记页,业务规则与客户确认一致
- 复用 ETC 模块架构,降低回归与工期
- 选车维保提醒 API + 前端弹窗
Non-Goals:
- 审批流、车辆状态自动联动、报表、小程序
Decisions
D1 双菜单平行模块(非抽象框架)
决策:新建 pl_vehicle_maintenance_* 表与独立 Service/API/页面,复制 ETC 模式。
理由:仅第二个类似场景,抽象成本高;独立模块便于维保特有规则(提醒、日期校验)演进。
备选:通用 ApplyDisburse 基类 — 拒绝(过度设计)。
D2 处理完成 = 申请 status processed
决策:不设 is_processed 字段;创建/更新处理记录且关联申请时,申请置 processed。
理由:客户选 A,与 ETC「发放即完成」一致。
备选:独立布尔 — 拒绝。
D3 金额可选
决策:amount NULL 允许;非 NULL 时 > 0。
理由:客户选 B,可先登记处理人与时间。
D4 维保类型 varchar + UI allow-create
决策:库存自由文本;字典仅作下拉预设(保养/维修/年检)。
理由:客户要求可手填;避免每次自定义类型写 dict 表。
D5 选车提醒
决策:查询 pending 且 (expected_pickup_date IS NULL OR today <= expected_pickup_date) 的申请;today > expected_pickup_date 不提醒;取车时间为空仍提醒。
理由:客户明确规则;不依赖 vehicle_status。
D6 单号前缀
决策:申请 SXWB,处理 SXWC。
理由:与 SXSQ/SXCL 命名风格一致,WB=维保,WC=维保处理。
D7 处理看板 API
决策:GET .../process-board,申请 LEFT JOIN 处理(同 ETC disburse-board)。
理由:UX 已验证;行内处理/编辑。
Risks / Trade-offs
| 风险 | 缓解 |
|---|---|
| 与 ETC 代码重复 | 接受;后续若第三模块再抽公共层 |
| 多条 pending 提醒信息过多 | 弹窗列表展示全部待提醒项 |
| 预计取车日为空长期 pending 持续提醒 | 符合客户确认;业务侧应填取车日或作废 |
| 静态路由遗漏导致菜单不可见 | 同步 pl.ts + DB 菜单 |
Migration Plan
- 执行
docs/sql/migrations/2026-06-29-pl-vehicle-maintenance.sql - 部署后端 + 前端
- 为相关角色授权菜单(脚本含 super_admin + 拥有 PL_VEHICLE 的角色)
- 回滚:隐藏菜单;表保留(软删即可)
Open Questions
- (无 — 客户已确认 V1 范围)