docs: add ETC vehicle recharge apply withdraw design
Capture approved rules for in_approval → draft withdraw on web-admin and miniprogram, aligned with reimbursement withdraw. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
4f364bc9a0
commit
134c541ebc
1 file changed
+159
@@ -0,0 +1,159 @@
|
||||
# ETC/加油充值申请 · 撤回 — 设计文档
|
||||
|
||||
> **日期**: 2026-09-29
|
||||
> **状态**: 已确认待实现
|
||||
> **仓库**: shanxia2.0(`backend/` + `web-admin/` + `miniprogram/`)
|
||||
> **对齐**: 报销申请撤回(`ReimburseService.withdraw`:审批中 → 草稿,记录保留)
|
||||
> **前置**:
|
||||
> - `docs/superpowers/specs/2026-06-29-pl-vehicle-recharge-design.md`
|
||||
> - `docs/superpowers/specs/2026-09-26-pl-vehicle-recharge-workflow-design.md`
|
||||
> - `docs/superpowers/specs/2026-09-27-mini-pl-vehicle-recharge-apply-design.md`
|
||||
|
||||
## 背景与问题
|
||||
|
||||
【报销申请】在审批中支持申请人**撤回** → 变为待提交/草稿,可修改后再提交。
|
||||
|
||||
【ETC/加油充值申请】现状:
|
||||
|
||||
| 能力 | 状态 |
|
||||
|------|------|
|
||||
| 草稿 / 已驳回:编辑、提交、作废 | 已有 |
|
||||
| 审批中 `in_approval`:编辑 | 无 |
|
||||
| 审批中:撤回 → 草稿 | **缺失** |
|
||||
| 作废 `cancel` | 仅草稿/已驳回 → `cancelled`(与撤回不同) |
|
||||
|
||||
申请人发现写错内容时,只能等驳回或让审批人处理,无法主动撤回修改。
|
||||
|
||||
## 已确认决策
|
||||
|
||||
| # | 决策 | 说明 |
|
||||
|---|------|------|
|
||||
| D1 | 撤回结果 | 审批中 → **草稿 `draft`**,可再编辑后重新提交(与报销一致) |
|
||||
| D2 | 端范围 | **Web 管理端 + 小程序** |
|
||||
| D3 | 审批记录 | **保留**,不强制切轮次、不写「撤回」分界(与报销撤回现状对齐) |
|
||||
| D4 | 可撤回状态 | 仅 **`in_approval`(审批中)**;不含待发放 `pending`、已发放、已作废、草稿、已驳回 |
|
||||
| D5 | 操作人 | 仅 **申请人本人**(`applicant_id === 当前用户`) |
|
||||
| D6 | 实现方案 | 新增独立 `withdraw` API,与 `cancel`(作废)分离 |
|
||||
|
||||
## 1. 目标与范围
|
||||
|
||||
### 目标
|
||||
|
||||
1. 申请人可在审批中撤回充值申请,单据回到草稿。
|
||||
2. Web 与小程序均可操作,规则一致。
|
||||
3. 撤回后沿用现有草稿编辑 / 提交能力。
|
||||
|
||||
### 范围内
|
||||
|
||||
- 后端:`withdraw_apply` + `POST /transport/vehicle-recharge-apply/{id}/withdraw`
|
||||
- Web:`views/pl/vehicle-recharge-apply/index.vue` 列表工具栏 + 查看弹窗
|
||||
- 小程序:`pages/pl/vehicle-recharge-apply/list.vue`(及详情/表单页若有操作区则对齐)
|
||||
- API 封装:`web-admin/src/api/pl/index.ts`、`miniprogram/api/pl.js`
|
||||
|
||||
### 范围外(明确不做)
|
||||
|
||||
- 审批轮次过滤改造、写入 `withdrawn` 审批记录
|
||||
- 待发放 `pending` 撤回
|
||||
- 改作废语义或合并 cancel/withdraw
|
||||
- 备用金、维修、尿素等其它业务的撤回
|
||||
- 同步改造报销撤回的轮次逻辑
|
||||
|
||||
---
|
||||
|
||||
## 2. 后端行为
|
||||
|
||||
### 2.1 接口
|
||||
|
||||
`POST /api/transport/vehicle-recharge-apply/{id}/withdraw`
|
||||
|
||||
Query(与现有 apply 写接口一致):
|
||||
|
||||
- `mineVehicles`(可选,小程序列表作用域时传 `true`)
|
||||
|
||||
成功:返回更新后的 `VehicleRechargeApplyRead`。
|
||||
|
||||
### 2.2 前置校验
|
||||
|
||||
1. 申请存在且未删除、租户匹配、数据权限可读。
|
||||
2. `applicant_id` 必须等于当前用户,否则 403。
|
||||
3. `status == "in_approval"`,否则 400(文案如:仅审批中的申请可撤回)。
|
||||
4. `mineVehicles=true` 时继续沿用现有本人车辆/本人写校验。
|
||||
|
||||
### 2.3 成功副作用
|
||||
|
||||
| 字段 | 处理 |
|
||||
|------|------|
|
||||
| `status` | → `draft` |
|
||||
| `current_node` | → `null` / 清空 |
|
||||
| `approval_round` | **保持不变**(下次 `submit` 仍会 `+1`,当前进度按新轮展示) |
|
||||
| `wf_id` | 保持不变 |
|
||||
| `pl_vehicle_recharge_approval` 行 | **不删、不改** |
|
||||
| 其它业务字段 | 不变 |
|
||||
|
||||
无发票额度等资源需退回(与报销不同)。
|
||||
|
||||
### 2.4 与重新提交的关系
|
||||
|
||||
现有 `submit_apply` 已执行 `approval_round = (approval_round or 0) + 1` 并重置 `current_node` 为首节点。
|
||||
因此:撤回 → 改稿 → 再提交后,**当前审批进度**自然只看新轮;旧轮记录仍可通过既有 **审批历史** 接口/UI 查看。
|
||||
这与「不强制切轮次」决策兼容:不新增撤回分界记录,依赖已有 `approval_round`。
|
||||
|
||||
### 2.5 错误语义(建议)
|
||||
|
||||
| 情况 | HTTP | detail |
|
||||
|------|------|--------|
|
||||
| 非申请人 | 403 | 仅申请人可撤回 |
|
||||
| 非审批中 | 400 | 仅审批中的申请可撤回 |
|
||||
| 不存在 | 404 | 申请单不存在 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 前端行为
|
||||
|
||||
### 3.1 公共规则
|
||||
|
||||
`canWithdraw(row)`:
|
||||
|
||||
- `row.status === 'in_approval'`
|
||||
- `String(row.applicantId) === 当前用户 id`
|
||||
|
||||
确认文案建议:
|
||||
|
||||
> 确定撤回该充值申请?撤回后变为草稿,可修改后再提交。
|
||||
|
||||
成功 Toast:`已撤回`。
|
||||
|
||||
### 3.2 Web 管理端
|
||||
|
||||
对齐报销申请页交互:
|
||||
|
||||
- 列表工具栏:在「作废」附近增加「撤回」按钮;单选且 `canWithdraw` 时可用。
|
||||
- 查看弹窗 `#hero-actions`:审批中且本人时展示「撤回」(替代或并列于仅查看态;**不**开放编辑/作废)。
|
||||
- 图标:与报销一致优先 `RefreshLeft`(或项目已有等价图标)。
|
||||
|
||||
编辑 / 提交 / 作废条件不变:仍仅 `draft` / `rejected`。
|
||||
|
||||
### 3.3 小程序
|
||||
|
||||
- 列表卡片:当 `canWithdraw(item)` 时展示「撤回」;审批中他人单据仅「查看」+「复制发群」等现有能力。
|
||||
- 若表单页以只读打开审批中本人单,可在底部增加「撤回」(可选,与列表能力二选一即可;**至少列表具备**)。
|
||||
- 调用 `vehicleRechargeApplyApi.withdraw(id)`,小程序请求带现有 `mineVehicles` 约定。
|
||||
|
||||
---
|
||||
|
||||
## 4. 验收要点
|
||||
|
||||
1. 本人 + 审批中:两端均可撤回 → 状态变草稿 → 可编辑 → 可再提交进入新一轮审批。
|
||||
2. 非本人 / 非审批中:无撤回入口;直调 API 被拒绝。
|
||||
3. 作废仍仅草稿/已驳回;撤回不会变成 `cancelled`。
|
||||
4. 撤回后审批历史中仍可见撤回前已产生的审批动作;再提交后当前进度为新轮。
|
||||
5. 待发放、已发放、已作废不可撤回。
|
||||
|
||||
---
|
||||
|
||||
## 5. 实现备注
|
||||
|
||||
- Service 放在 `pl_vehicle_recharge_service.py`(与 `submit_apply` / `cancel_apply` 同层)。
|
||||
- 路由挂在 `vehicle_recharge.py` 的 `apply_router`,放在 `submit` / `cancel` 附近。
|
||||
- 无需改表结构 / SQL。
|
||||
- 建议补一条后端单测:`in_approval` 本人撤回成功;非本人 / 错误状态失败。
|
||||
Reference in new issue
Block a user