docs: add recharge 发放中 status design and plan
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
553c1ef316
commit
7ebbaa2784
2 files changed
+622
No files matched your search
@@ -0,0 +1,498 @@
|
||||
# 充值申请「发放中」状态 Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** 末级审批通过进入发放节点后,申请状态变为 `pending`,Web 展示为「发放中」;待办/徽章/发放登记与撤销回退一并兼容。
|
||||
|
||||
**Architecture:** 油卡/ETC 共用后端状态机。`approve_apply` 在下一节点为 `disburse` 时写入 `pending`;`_current_node` / `list_pending` / 菜单徽章同时接受 `in_approval` 与 `pending`;撤销发放有流程时回退 `pending`。前端仅改充值申请文案与筛选项(尿素等其它业务不动)。
|
||||
|
||||
**Tech Stack:** FastAPI / SQLAlchemy、pytest、Vue 3 + Element Plus(web-admin)
|
||||
|
||||
**Spec:** `docs/superpowers/specs/2026-11-12-pl-recharge-pending-disburse-status-design.md`
|
||||
|
||||
---
|
||||
|
||||
## File map
|
||||
|
||||
| 文件 | 职责 |
|
||||
| --- | --- |
|
||||
| `backend/app/schemas/pl/vehicle_recharge.py` | `APPLY_STATUSES` 纳入 `pending` |
|
||||
| `backend/app/services/pl_vehicle_recharge_approval_service.py` | 审批推进切 `pending`;待办/当前节点准入 |
|
||||
| `backend/app/services/pl_vehicle_recharge_service.py` | 撤销/换绑回退;关联提示文案 |
|
||||
| `backend/app/services/pl_menu_badge_service.py` | 徽章计数含 `pending` |
|
||||
| `backend/app/api/pl/vehicle_recharge.py` | 导出状态标签「发放中」 |
|
||||
| `backend/tests/test_pl_vehicle_recharge_workflow.py` | 状态机单测 |
|
||||
| `backend/tests/test_pl_menu_badge_recharge_approval.py` | 徽章含 pending |
|
||||
| `web-admin/src/utils/pl-display.ts` | 充值申请 `pending` → 发放中 |
|
||||
| `web-admin/src/views/pl/vehicle-recharge-apply/columnFilterDefs.ts` | 筛选项 |
|
||||
| `web-admin/src/views/pl/etc-vehicle-recharge-apply/columnFilterDefs.ts` | 筛选项 |
|
||||
| `web-admin/src/views/pl/vehicle-recharge-record/index.vue` | 撤销确认文案 |
|
||||
| `web-admin/src/views/pl/etc-vehicle-recharge-record/index.vue` | 撤销确认文案 |
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Schema + 审批推进写 pending(TDD)
|
||||
|
||||
**Files:**
|
||||
- Modify: `backend/app/schemas/pl/vehicle_recharge.py`
|
||||
- Modify: `backend/app/services/pl_vehicle_recharge_approval_service.py`
|
||||
- Modify: `backend/tests/test_pl_vehicle_recharge_workflow.py`
|
||||
|
||||
- [ ] **Step 1: 改现有断言并加失败用例**
|
||||
|
||||
在 `test_apply_statuses_include_workflow_states` 中让集合包含 `pending`:
|
||||
|
||||
```python
|
||||
assert {"draft", "in_approval", "pending", "rejected", "disbursed", "cancelled"} <= APPLY_STATUSES
|
||||
```
|
||||
|
||||
将 `test_approve_advances_to_next_node` 中通过后断言改为(默认种子流程下一节点是发放):
|
||||
|
||||
```python
|
||||
assert result.status == "pending"
|
||||
assert result.current_node == node_fin
|
||||
```
|
||||
|
||||
新增三级流程用例(一级通过仍审批中,二级通过变发放中):
|
||||
|
||||
```python
|
||||
def _seed_three_node_workflow(db) -> tuple[str, str, str, str]:
|
||||
wf_id = "wf-3"
|
||||
n1, n2, n3 = "node-a1", "node-a2", "node-dis"
|
||||
db.add(
|
||||
BxWorkflowDef(
|
||||
id=wf_id,
|
||||
biz_type="vehicle_recharge",
|
||||
wf_name="三级充值流程",
|
||||
status=1,
|
||||
tenant_no="t1",
|
||||
create_dept_id="d1",
|
||||
)
|
||||
)
|
||||
for nid, name, order, uid, uname, action in (
|
||||
(n1, "一审", 1, "u-a1", "一审", "approve"),
|
||||
(n2, "二审", 2, "u-a2", "二审", "approve"),
|
||||
(n3, "发放", 3, "u-fin", "财务", "disburse"),
|
||||
):
|
||||
db.add(
|
||||
BxWorkflowNode(
|
||||
id=nid,
|
||||
wf_id=wf_id,
|
||||
node_name=name,
|
||||
node_order=order,
|
||||
approver_id=uid,
|
||||
approver_name=uname,
|
||||
action_type=action,
|
||||
tenant_no="t1",
|
||||
create_dept_id="d1",
|
||||
)
|
||||
)
|
||||
return wf_id, n1, n2, n3
|
||||
|
||||
|
||||
def test_mid_approve_stays_in_approval_final_approve_sets_pending(monkeypatch):
|
||||
from app.services import pl_vehicle_recharge_approval_service as approval_svc
|
||||
from app.services import pl_vehicle_recharge_service as svc
|
||||
|
||||
db = _make_session()
|
||||
_seed_vehicle(db)
|
||||
wf_id, n1, n2, n3 = _seed_three_node_workflow(db)
|
||||
db.add(
|
||||
PlVehicleRechargeApply(
|
||||
id="apply-1",
|
||||
apply_no="YK2026092601",
|
||||
license_plate="鄂A00001",
|
||||
recharge_type="fuel",
|
||||
apply_date=date(2026, 9, 26),
|
||||
applicant_id="u-applicant",
|
||||
status="in_approval",
|
||||
wf_id=wf_id,
|
||||
current_node=n1,
|
||||
approval_round=1,
|
||||
tenant_no="t1",
|
||||
create_dept_id="d1",
|
||||
)
|
||||
)
|
||||
db.commit()
|
||||
_patch_scope(monkeypatch, svc)
|
||||
|
||||
mid = approval_svc.approve_apply(db, "t1", _user("u-a1", "一审"), "apply-1", opinion="ok")
|
||||
assert mid.status == "in_approval"
|
||||
assert mid.current_node == n2
|
||||
|
||||
final = approval_svc.approve_apply(db, "t1", _user("u-a2", "二审"), "apply-1", opinion="ok")
|
||||
assert final.status == "pending"
|
||||
assert final.current_node == n3
|
||||
```
|
||||
|
||||
新增:`pending` 状态下可发放:
|
||||
|
||||
```python
|
||||
def test_disburse_accepts_pending_status(monkeypatch):
|
||||
from app.services import pl_vehicle_recharge_approval_service as approval_svc
|
||||
from app.services import pl_vehicle_recharge_service as svc
|
||||
from app.schemas.pl.vehicle_recharge import VehicleRechargeRecordCreate
|
||||
|
||||
db = _make_session()
|
||||
_seed_vehicle(db)
|
||||
wf_id, _gm, node_fin = _seed_workflow(db)
|
||||
db.add(
|
||||
PlVehicleRechargeApply(
|
||||
id="apply-1",
|
||||
apply_no="ETC2026092601",
|
||||
license_plate="鄂A00001",
|
||||
recharge_type="etc",
|
||||
apply_date=date(2026, 9, 26),
|
||||
applicant_id="u-applicant",
|
||||
status="pending",
|
||||
wf_id=wf_id,
|
||||
current_node=node_fin,
|
||||
approval_round=1,
|
||||
tenant_no="t1",
|
||||
create_dept_id="d1",
|
||||
)
|
||||
)
|
||||
db.commit()
|
||||
_patch_scope(monkeypatch, svc)
|
||||
payload = VehicleRechargeRecordCreate(
|
||||
rechargeDate=date(2026, 9, 26),
|
||||
rechargeType="etc",
|
||||
amount=Decimal("50.00"),
|
||||
applyId="apply-1",
|
||||
)
|
||||
result = approval_svc.disburse_apply(
|
||||
db, "t1", _user("u-fin", "财务"), "apply-1", payload
|
||||
)
|
||||
assert result.status == "disbursed"
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 跑测确认失败**
|
||||
|
||||
Run(在 `backend/`,已激活项目 venv):
|
||||
|
||||
```bash
|
||||
pytest tests/test_pl_vehicle_recharge_workflow.py::test_apply_statuses_include_workflow_states \
|
||||
tests/test_pl_vehicle_recharge_workflow.py::test_approve_advances_to_next_node \
|
||||
tests/test_pl_vehicle_recharge_workflow.py::test_mid_approve_stays_in_approval_final_approve_sets_pending \
|
||||
tests/test_pl_vehicle_recharge_workflow.py::test_disburse_accepts_pending_status -v
|
||||
```
|
||||
|
||||
Expected: FAIL(`pending` 不在集合 / 状态仍为 `in_approval` / `申请单不在审批中`)
|
||||
|
||||
- [ ] **Step 3: 最小实现**
|
||||
|
||||
`vehicle_recharge.py` schema:
|
||||
|
||||
```python
|
||||
APPLY_STATUSES = {"draft", "in_approval", "pending", "rejected", "disbursed", "cancelled"}
|
||||
```
|
||||
|
||||
`pl_vehicle_recharge_approval_service.py` 中 `_current_node`:
|
||||
|
||||
```python
|
||||
if apply.status not in ("in_approval", "pending") or not apply.current_node:
|
||||
raise HTTPException(status_code=400, detail="申请单不在可审批/发放状态")
|
||||
```
|
||||
|
||||
`list_pending` 过滤:
|
||||
|
||||
```python
|
||||
PlVehicleRechargeApply.status.in_(("in_approval", "pending")),
|
||||
```
|
||||
|
||||
`approve_apply` 在推进节点后:
|
||||
|
||||
```python
|
||||
next_node = nodes[idx + 1]
|
||||
apply.current_node = next_node.id
|
||||
next_action = (next_node.action_type or "approve").strip() or "approve"
|
||||
if next_action == "disburse":
|
||||
apply.status = "pending"
|
||||
```
|
||||
|
||||
(勿改中间 approve 的 status。)
|
||||
|
||||
- [ ] **Step 4: 再跑 Step 2 命令**
|
||||
|
||||
Expected: PASS
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add backend/app/schemas/pl/vehicle_recharge.py \
|
||||
backend/app/services/pl_vehicle_recharge_approval_service.py \
|
||||
backend/tests/test_pl_vehicle_recharge_workflow.py
|
||||
git commit -m "$(cat <<'EOF'
|
||||
feat(pl): set recharge apply to pending when entering disburse node
|
||||
|
||||
EOF
|
||||
)"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 2: 徽章计数含 pending
|
||||
|
||||
**Files:**
|
||||
- Modify: `backend/app/services/pl_menu_badge_service.py`
|
||||
- Modify: `backend/tests/test_pl_menu_badge_recharge_approval.py`
|
||||
|
||||
- [ ] **Step 1: 扩展徽章测试**
|
||||
|
||||
在现有 `add_apply` 种子后增加:
|
||||
|
||||
```python
|
||||
add_apply("a6", status="pending", current_node="node-me")
|
||||
```
|
||||
|
||||
并将断言改为:
|
||||
|
||||
```python
|
||||
assert counts[MENU_CODE_RECHARGE_APPROVAL] == 3
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 跑测确认失败**
|
||||
|
||||
```bash
|
||||
pytest tests/test_pl_menu_badge_recharge_approval.py -v
|
||||
```
|
||||
|
||||
Expected: FAIL(仍为 2)
|
||||
|
||||
- [ ] **Step 3: 实现**
|
||||
|
||||
`count_recharge_approval_pending` 中:
|
||||
|
||||
```python
|
||||
PlVehicleRechargeApply.status.in_(("in_approval", "pending")),
|
||||
```
|
||||
|
||||
- [ ] **Step 4: 再跑测**
|
||||
|
||||
Expected: PASS
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add backend/app/services/pl_menu_badge_service.py \
|
||||
backend/tests/test_pl_menu_badge_recharge_approval.py
|
||||
git commit -m "$(cat <<'EOF'
|
||||
fix(pl): include pending recharge applies in approval menu badge
|
||||
|
||||
EOF
|
||||
)"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 3: 撤销发放回退为 pending + 文案「发放中」
|
||||
|
||||
**Files:**
|
||||
- Modify: `backend/app/services/pl_vehicle_recharge_service.py`(`delete_records` / 换绑旧申请回退两处:约 1136、1205 行,有 `wf_id` 时现为 `in_approval`)
|
||||
- Modify: `backend/app/api/pl/vehicle_recharge.py`(`RECHARGE_APPLY_STATUS_LABELS`)
|
||||
- Modify: `backend/app/services/pl_vehicle_recharge_service.py`(`仅待发放申请可关联` → `仅发放中申请可关联`)
|
||||
|
||||
- [ ] **Step 1: 写回退单测(可放在 workflow 测试文件)**
|
||||
|
||||
```python
|
||||
def test_delete_record_with_workflow_reverts_to_pending(monkeypatch):
|
||||
from app.services import pl_vehicle_recharge_service as svc
|
||||
|
||||
db = _make_session()
|
||||
_seed_vehicle(db)
|
||||
wf_id, _gm, node_fin = _seed_workflow(db)
|
||||
db.add(
|
||||
PlVehicleRechargeApply(
|
||||
id="apply-1",
|
||||
apply_no="ETC2026092601",
|
||||
license_plate="鄂A00001",
|
||||
recharge_type="etc",
|
||||
apply_date=date(2026, 9, 26),
|
||||
applicant_id="u-applicant",
|
||||
status="disbursed",
|
||||
wf_id=wf_id,
|
||||
current_node=None,
|
||||
approval_round=1,
|
||||
tenant_no="t1",
|
||||
create_by="u-applicant",
|
||||
create_dept_id="d1",
|
||||
)
|
||||
)
|
||||
db.add(
|
||||
PlVehicleRechargeRecord(
|
||||
id="rec-1",
|
||||
recharge_order_no="RO1",
|
||||
recharge_date=date(2026, 9, 26),
|
||||
recharge_type="etc",
|
||||
amount=Decimal("10.00"),
|
||||
apply_id="apply-1",
|
||||
license_plate="鄂A00001",
|
||||
tenant_no="t1",
|
||||
create_by="u-fin",
|
||||
create_dept_id="d1",
|
||||
del_flag=0,
|
||||
)
|
||||
)
|
||||
db.commit()
|
||||
_patch_scope(monkeypatch, svc)
|
||||
svc.delete_records(db, "t1", _user("u-fin", "财务"), ["rec-1"])
|
||||
apply = db.query(PlVehicleRechargeApply).filter_by(id="apply-1").one()
|
||||
assert apply.status == "pending"
|
||||
assert apply.current_node == node_fin
|
||||
```
|
||||
|
||||
若 `PlVehicleRechargeRecord` 构造缺必填字段,按模型补齐后保持断言不变。
|
||||
|
||||
- [ ] **Step 2: 跑测确认失败**
|
||||
|
||||
```bash
|
||||
pytest tests/test_pl_vehicle_recharge_workflow.py::test_delete_record_with_workflow_reverts_to_pending -v
|
||||
```
|
||||
|
||||
Expected: FAIL(仍为 `in_approval`)
|
||||
|
||||
- [ ] **Step 3: 实现回退与文案**
|
||||
|
||||
两处有 wf 回退改为:
|
||||
|
||||
```python
|
||||
old_apply.status = "pending" # 或 apply.status = "pending"
|
||||
```
|
||||
|
||||
API 标签:
|
||||
|
||||
```python
|
||||
"pending": "发放中",
|
||||
```
|
||||
|
||||
服务提示:
|
||||
|
||||
```python
|
||||
detail="仅发放中申请可关联",
|
||||
```
|
||||
|
||||
- [ ] **Step 4: 跑回退测 + 相关 workflow 测**
|
||||
|
||||
```bash
|
||||
pytest tests/test_pl_vehicle_recharge_workflow.py -v
|
||||
```
|
||||
|
||||
Expected: PASS
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add backend/app/services/pl_vehicle_recharge_service.py \
|
||||
backend/app/api/pl/vehicle_recharge.py \
|
||||
backend/tests/test_pl_vehicle_recharge_workflow.py
|
||||
git commit -m "$(cat <<'EOF'
|
||||
fix(pl): revert disbursed recharge apply to pending and rename label
|
||||
|
||||
EOF
|
||||
)"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 4: Web 文案与筛选项
|
||||
|
||||
**Files:**
|
||||
- Modify: `web-admin/src/utils/pl-display.ts`(仅 `getPlRechargeApplyStatusLabel`,**不要**改 `getPlUreaApplyStatusLabel`)
|
||||
- Modify: `web-admin/src/views/pl/vehicle-recharge-apply/columnFilterDefs.ts`
|
||||
- Modify: `web-admin/src/views/pl/etc-vehicle-recharge-apply/columnFilterDefs.ts`
|
||||
- Modify: `web-admin/src/views/pl/vehicle-recharge-record/index.vue`
|
||||
- Modify: `web-admin/src/views/pl/etc-vehicle-recharge-record/index.vue`
|
||||
|
||||
- [ ] **Step 1: 改充值状态文案**
|
||||
|
||||
```typescript
|
||||
pending: '发放中',
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 筛选项插入 pending(建议放在审批中之后)**
|
||||
|
||||
油卡与 ETC 的 `RECHARGE_STATUS_OPTIONS`:
|
||||
|
||||
```typescript
|
||||
{ value: 'draft', label: '草稿' },
|
||||
{ value: 'in_approval', label: '审批中' },
|
||||
{ value: 'pending', label: '发放中' },
|
||||
{ value: 'rejected', label: '已驳回' },
|
||||
{ value: 'disbursed', label: '已发放' },
|
||||
{ value: 'cancelled', label: '已作废' }
|
||||
```
|
||||
|
||||
- [ ] **Step 3: 撤销确认文案**
|
||||
|
||||
两处 record 页:
|
||||
|
||||
```typescript
|
||||
'确定撤销该发放登记吗?关联申请将回退为发放中。'
|
||||
```
|
||||
|
||||
全文检索 `web-admin` 内充值相关「待发放」字样,仅改充值申请/发放语境;跳过尿素、运费、备用金。
|
||||
|
||||
- [ ] **Step 4: 静态核对**
|
||||
|
||||
```bash
|
||||
# 在 web-admin/
|
||||
rg "待发放" src/utils/pl-display.ts src/views/pl/vehicle-recharge-apply src/views/pl/etc-vehicle-recharge-apply src/views/pl/vehicle-recharge-record src/views/pl/etc-vehicle-recharge-record
|
||||
```
|
||||
|
||||
Expected: 上述路径无残留「待发放」(尿素等其它目录可仍有)
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add web-admin/src/utils/pl-display.ts \
|
||||
web-admin/src/views/pl/vehicle-recharge-apply/columnFilterDefs.ts \
|
||||
web-admin/src/views/pl/etc-vehicle-recharge-apply/columnFilterDefs.ts \
|
||||
web-admin/src/views/pl/vehicle-recharge-record/index.vue \
|
||||
web-admin/src/views/pl/etc-vehicle-recharge-record/index.vue
|
||||
git commit -m "$(cat <<'EOF'
|
||||
feat(web-admin): show recharge pending status as 发放中
|
||||
|
||||
EOF
|
||||
)"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 5: 回归验证
|
||||
|
||||
**Files:** 无新文件
|
||||
|
||||
- [ ] **Step 1: 后端相关测试全跑**
|
||||
|
||||
```bash
|
||||
pytest tests/test_pl_vehicle_recharge_workflow.py \
|
||||
tests/test_pl_menu_badge_recharge_approval.py \
|
||||
tests/test_pl_vehicle_recharge_summary.py -v
|
||||
```
|
||||
|
||||
Expected: PASS
|
||||
|
||||
- [ ] **Step 2: 手工冒烟清单(记结果,未跑勿称通过)**
|
||||
|
||||
1. 两级审批 + 发放节点:一审后「审批中」;二审后「发放中」;发放后「已发放」
|
||||
2. 发放节点人审批待办仍可见并发放成功
|
||||
3. 申请列表可用「发放中」筛选
|
||||
4. 油卡、ETC 各至少一单(或同后端断言后单侧冒烟 + 说明)
|
||||
|
||||
- [ ] **Step 3: 若用户要求再 push;默认本任务不 push**
|
||||
|
||||
---
|
||||
|
||||
## Spec coverage check
|
||||
|
||||
| Spec 项 | Task |
|
||||
| --- | --- |
|
||||
| 末级 approve → pending | Task 1 |
|
||||
| 中间仍 in_approval | Task 1 |
|
||||
| 待办/准入认 pending | Task 1 |
|
||||
| 徽章含 pending | Task 2 |
|
||||
| 撤销回退 pending | Task 3 |
|
||||
| 文案「发放中」 | Task 3–4 |
|
||||
| 筛选项 | Task 4 |
|
||||
| 不做历史刷库 / 不改尿素文案 | 明确不做 |
|
||||
| 回归 | Task 5 |
|
||||
@@ -0,0 +1,124 @@
|
||||
# 充值申请「发放中」状态(审批通过后)
|
||||
|
||||
## 背景与问题
|
||||
|
||||
车辆充值(油卡 / ETC 共用后端)走审批流程时,单据从提交起一直是 `in_approval`(审批中),直到发放登记才变为 `disbursed`(已发放)。
|
||||
|
||||
用户配置多级审批人后,期望:
|
||||
|
||||
- 中间审批级等待处理:仍显示「审批中」
|
||||
- **末级审批人通过、进入发放节点后**:显示「发放中」
|
||||
- 发放登记完成后:显示「已发放」
|
||||
|
||||
系统里已有 `pending` 枚举(原前端文案「待发放」),但有工作流时主路径几乎不会写入该状态;发放撤销在有流程时还会回退为 `in_approval`。申请列表筛选项也未暴露该状态。
|
||||
|
||||
**文案约定(已确认)**:充值申请 `pending` 的对外名称统一为 **「发放中」**(不再用「待发放」)。状态码仍为 `pending`,不改库字段。尿素 / 运费等其它业务的「待发放」文案不在本期范围。
|
||||
|
||||
## 已确认决策
|
||||
|
||||
| 项 | 结论 |
|
||||
| --- | --- |
|
||||
| 切换时机 | 末级 `approve` 节点通过后,若下一节点为 `disburse`(发放登记),将 `status` 设为 `pending` |
|
||||
| 展示文案 | `pending` → **发放中**(Web `getPlRechargeApplyStatusLabel`、导出/后端 `RECHARGE_APPLY_STATUS_LABELS`、筛选项、相关提示语) |
|
||||
| 中间审批 | 仍保持 `in_approval` |
|
||||
| 发放完成 | 仍为 `disbursed` |
|
||||
| 撤销发放 | 有工作流时回退为 `pending`(停在发放节点),不再回退为 `in_approval`;提示改为「回退为发放中」 |
|
||||
| 无工作流路径 | 维持现有 `pending` 语义不变,仅文案改为「发放中」 |
|
||||
| 历史数据 | 本期**不做**批量刷库;已停在发放节点但仍为 `in_approval` 的单据继续可在审批待办发放,列表可能仍显示「审批中」直至被处理 |
|
||||
| 范围 | 油卡 + ETC 共用后端一并生效;Web 列表文案/筛选项同步;小程序不单独改(若共用展示映射则自然带上) |
|
||||
| 不另拆 | 不新建独立「发放中」菜单;发放仍在现有「充值审批」待办中对发放节点操作 |
|
||||
|
||||
## 目标状态机(有工作流)
|
||||
|
||||
```text
|
||||
draft / rejected
|
||||
└─提交─► in_approval # 当前节点为 approve*
|
||||
│
|
||||
├─中间 approve 通过──► in_approval(推进 current_node)
|
||||
│
|
||||
└─末级 approve 通过且下一节点为 disburse
|
||||
─► pending # 发放中;current_node = 发放节点
|
||||
│
|
||||
└─发放登记─► disbursed
|
||||
|
||||
任意审批节点驳回 ─► rejected
|
||||
撤回(规则不变)─► draft
|
||||
撤销发放登记 ─► pending(有 wf)或 pending(无 wf,保持现状)
|
||||
```
|
||||
|
||||
\* 流程末节点必须仍是 `disburse`(现有约束:`approve_apply` 不得收尾)。
|
||||
|
||||
## 后端改动要点
|
||||
|
||||
### 1. 状态常量与文案
|
||||
|
||||
- `APPLY_STATUSES` 正式纳入 `pending`(schema / 单测断言同步)
|
||||
- `RECHARGE_APPLY_STATUS_LABELS["pending"]`:`待发放` → `发放中`
|
||||
- 关联申请错误提示等用户可见「待发放」字样同步改为「发放中」
|
||||
|
||||
### 2. `approve_apply`
|
||||
|
||||
通过当前 `approve` 节点后:
|
||||
|
||||
- `apply.current_node = nodes[idx + 1].id`(不变)
|
||||
- 若下一节点 `action_type == "disburse"`:`apply.status = "pending"`
|
||||
- 否则:保持 `in_approval`
|
||||
|
||||
### 3. 待办与发放登记准入
|
||||
|
||||
当前 `_current_node` / `list_pending` / 菜单徽章只认 `status == "in_approval"`。改为认:
|
||||
|
||||
`status in ("in_approval", "pending")`
|
||||
|
||||
且仍要求 `current_node` 存在、当前用户为该节点审批人。这样「发放中」单据继续出现在审批待办,发放人可完成登记。
|
||||
|
||||
错误文案可区分「不在可处理状态」,但行为上两者同等可办。
|
||||
|
||||
### 4. 撤销 / 换绑发放记录回退
|
||||
|
||||
`delete_records` / 换绑旧申请回退时:有 `wf_id` 时改为 `status = "pending"` + `current_node = 发放节点`(与文案「回退为发放中」一致);无流程仍 `pending`。
|
||||
|
||||
### 5. 发放登记页关联申请
|
||||
|
||||
现有 `_resolve_apply_for_record`:拒绝 `in_approval`、仅允许 `pending`。与新状态机一致——走审批发放应走审批菜单的 `disburse_apply`;记录页手动关联仍只认 `pending` 单。无需为发放节点旁路放开记录页。
|
||||
|
||||
### 6. 看板 / 汇总
|
||||
|
||||
`pl_vehicle_recharge_summary_service` 已将 `pending` 与 `in_approval` 计入 pending 类统计,保持即可;回归确认油卡看板数字仍合理。
|
||||
|
||||
## 前端改动要点
|
||||
|
||||
- `getPlRechargeApplyStatusLabel`:`pending` → `发放中`(仅充值申请映射;尿素等其它模块不动)
|
||||
- 油卡 / ETC 申请列表列头筛选项:增加 `{ value: 'pending', label: '发放中' }`
|
||||
- 发放页撤销确认等「回退为待发放」→「回退为发放中」
|
||||
- 发放页提示「审批中请到审批菜单发放」逻辑可保留(`in_approval`);`pending` 仍可按现有关联逻辑处理
|
||||
- 审批页「待我审批」Tab 不改名(含审批 + 发放节点待办)
|
||||
|
||||
## 测试与验收
|
||||
|
||||
**后端单测(优先)**
|
||||
|
||||
- 两级 approve + 末节点 disburse:一级通过后仍 `in_approval`;二级通过后 `pending` 且 `current_node` 为发放节点
|
||||
- `list_pending` / 徽章计数包含 `pending` 且当前节点审批人匹配的单据
|
||||
- `disburse_apply` 在 `pending` 状态下成功 → `disbursed`
|
||||
- 撤销发放回退为 `pending`(有流程)
|
||||
- 导出/标签映射:`pending` 文案为「发放中」
|
||||
|
||||
**手工验收**
|
||||
|
||||
- 申请列表:二级通过后状态显示「发放中」,可按「发放中」筛选
|
||||
- 发放节点处理人在审批待办仍能看到并完成发放 →「已发放」
|
||||
- 油卡与 ETC 模块各走一单冒烟
|
||||
|
||||
## 明确不做
|
||||
|
||||
- 历史 `in_approval` + 已在发放节点的数据迁移脚本
|
||||
- 拆分发放独立菜单 / 独立待办 API
|
||||
- 修改流程配置 UI(仍要求末节点为发放登记)
|
||||
- 小程序专项改造
|
||||
- 尿素 / 运费 / 备用金等其它业务「待发放」文案改名
|
||||
|
||||
## 风险
|
||||
|
||||
- 若漏改徽章或 `list_pending` 状态条件,会出现「列表已是发放中但待办/角标消失」;实现时与 `approve_apply` 同批改、同批测。
|
||||
- 历史停在发放节点的 `in_approval` 单据列表文案仍为「审批中」,验收时需知悉;若后续需要可另开刷数任务。
|
||||
Reference in new issue
Block a user