docs: add ETC-only vehicle recharge design/plan and refresh graphify
Persist the approved cutover spec and implementation plan; sync graphs after the ETC-only changes. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
9a8dd691d8
commit
9968fc72a3
7 files changed
+38936
-38407
No files matched your search
@@ -0,0 +1,397 @@
|
||||
# 车辆充值模块收窄为仅 ETC 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:** 将「ETC加油申请 / ETC加油发放登记」收窄为仅 ETC:菜单改名、UI 只留 ETC、列表/选项/导出强制只出 etc,历史 fuel 留库不删。
|
||||
|
||||
**Architecture:** Schema 写路径只允许 `etc`;Service 读路径(列表/看板/导出/pending/按 id)统一 `recharge_type == 'etc'`;SQL migration 改菜单名并软停用字典「加油」;前端去掉加油选项并同步路由标题。
|
||||
|
||||
**Tech Stack:** FastAPI + Pydantic v2、SQLAlchemy、Vue 3 + Element Plus、MySQL migration
|
||||
|
||||
**Spec:** `docs/superpowers/specs/2026-09-12-pl-vehicle-recharge-etc-only-design.md`
|
||||
|
||||
---
|
||||
|
||||
## File map
|
||||
|
||||
| File | Responsibility |
|
||||
|------|----------------|
|
||||
| `docs/sql/migrations/2026-09-12-pl-vehicle-recharge-etc-only.sql` | 菜单改名 + 字典 fuel 软停用 |
|
||||
| `backend/app/schemas/pl/vehicle_recharge.py` | `RECHARGE_TYPES = {"etc"}` |
|
||||
| `backend/app/services/pl_vehicle_recharge_service.py` | 读强制 etc;get 对 fuel 等同不存在 |
|
||||
| `backend/tests/test_vehicle_recharge_etc_only.py` | Schema + 常量断言单测 |
|
||||
| `web-admin/src/router/modules/pl.ts` | `meta.title` |
|
||||
| `web-admin/src/views/pl/vehicle-recharge-apply/index.vue` | 文案 + 下拉 |
|
||||
| `web-admin/src/views/pl/vehicle-recharge-record/index.vue` | 文案 + 下拉 |
|
||||
| `web-admin/src/views/pl/vehicle-recharge-apply/columnFilterDefs.ts` | 列头枚举只留 ETC |
|
||||
|
||||
**Do not change:** API path、perms、表结构、`getPlRechargeTypeLabel` 对 `fuel` 的映射(历史标签仍可解析,列表已不可见)。
|
||||
|
||||
---
|
||||
|
||||
### Task 1: SQL migration(菜单 + 字典)
|
||||
|
||||
**Files:**
|
||||
- Create: `docs/sql/migrations/2026-09-12-pl-vehicle-recharge-etc-only.sql`
|
||||
|
||||
- [ ] **Step 1: 写 migration**
|
||||
|
||||
```sql
|
||||
-- 车辆充值模块收窄为仅 ETC:菜单改名 + 加油字典软停用(不删业务数据)
|
||||
-- Spec: docs/superpowers/specs/2026-09-12-pl-vehicle-recharge-etc-only-design.md
|
||||
|
||||
UPDATE sys_menu
|
||||
SET menu_name = 'ETC充值申请',
|
||||
update_time = NOW()
|
||||
WHERE id = 'PL_VEH_RECHARGE_APPLY'
|
||||
AND del_flag = 0;
|
||||
|
||||
UPDATE sys_menu
|
||||
SET menu_name = 'ETC充值发放登记',
|
||||
update_time = NOW()
|
||||
WHERE id = 'PL_VEH_RECHARGE_RECORD'
|
||||
AND del_flag = 0;
|
||||
|
||||
UPDATE sys_dict_data
|
||||
SET del_flag = 1,
|
||||
remark = 'ETC模块收窄:加油选项停用,业务数据保留待新加油模块',
|
||||
update_time = NOW()
|
||||
WHERE id = 'PL_RECHARGE_TYPE_FUEL'
|
||||
AND del_flag = 0;
|
||||
|
||||
-- 可选知情统计(只读,不写入变更):
|
||||
-- SELECT COUNT(*) FROM pl_vehicle_recharge_apply
|
||||
-- WHERE del_flag = 0 AND recharge_type = 'fuel' AND status = 'pending';
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Commit**
|
||||
|
||||
```bash
|
||||
git add docs/sql/migrations/2026-09-12-pl-vehicle-recharge-etc-only.sql
|
||||
git commit -m "$(cat <<'EOF'
|
||||
docs(sql): narrow vehicle recharge menus to ETC-only labels
|
||||
|
||||
Rename ETC/fuel menus and soft-disable fuel dict for the ETC-only cutover.
|
||||
EOF
|
||||
)"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 2: Schema 只允许 etc + 单测
|
||||
|
||||
**Files:**
|
||||
- Modify: `backend/app/schemas/pl/vehicle_recharge.py`
|
||||
- Create: `backend/tests/test_vehicle_recharge_etc_only.py`
|
||||
|
||||
- [ ] **Step 1: 写失败单测(当前仍接受 fuel)**
|
||||
|
||||
```python
|
||||
"""车辆充值模块收窄为仅 ETC。"""
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
from pydantic import ValidationError
|
||||
|
||||
from app.schemas.pl.vehicle_recharge import (
|
||||
RECHARGE_TYPES,
|
||||
VehicleRechargeApplyCreate,
|
||||
VehicleRechargeRecordCreate,
|
||||
)
|
||||
|
||||
|
||||
def test_recharge_types_only_etc():
|
||||
assert RECHARGE_TYPES == {"etc"}
|
||||
|
||||
|
||||
def test_apply_create_rejects_fuel():
|
||||
with pytest.raises(ValidationError):
|
||||
VehicleRechargeApplyCreate.model_validate(
|
||||
{
|
||||
"licensePlate": "鄂A12345",
|
||||
"rechargeType": "fuel",
|
||||
"applyDate": "2026-09-12",
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def test_apply_create_accepts_etc():
|
||||
obj = VehicleRechargeApplyCreate.model_validate(
|
||||
{
|
||||
"licensePlate": "鄂A12345",
|
||||
"rechargeType": "etc",
|
||||
"applyDate": "2026-09-12",
|
||||
}
|
||||
)
|
||||
assert obj.recharge_type == "etc"
|
||||
|
||||
|
||||
def test_record_create_rejects_fuel():
|
||||
with pytest.raises(ValidationError):
|
||||
VehicleRechargeRecordCreate.model_validate(
|
||||
{
|
||||
"rechargeDate": "2026-09-12",
|
||||
"rechargeType": "fuel",
|
||||
"amount": "100.00",
|
||||
"licensePlate": "鄂A12345",
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 跑测确认失败**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
cd backend && source venv/bin/activate && pytest tests/test_vehicle_recharge_etc_only.py -v
|
||||
```
|
||||
|
||||
Expected: `test_recharge_types_only_etc` FAIL(当前 `RECHARGE_TYPES == {"etc", "fuel"}`)。
|
||||
|
||||
- [ ] **Step 3: 改 Schema**
|
||||
|
||||
In `backend/app/schemas/pl/vehicle_recharge.py`:
|
||||
|
||||
```python
|
||||
RECHARGE_TYPES = {"etc"}
|
||||
```
|
||||
|
||||
Update both validators' error message to:
|
||||
|
||||
```python
|
||||
if v not in RECHARGE_TYPES:
|
||||
raise ValueError("本期仅支持 ETC")
|
||||
return v
|
||||
```
|
||||
|
||||
(`VehicleRechargeApplyCreate.validate_recharge_type` 与 `VehicleRechargeRecordCreate.validate_recharge_type` 两处。)
|
||||
|
||||
- [ ] **Step 4: 跑测确认通过**
|
||||
|
||||
```bash
|
||||
cd backend && source venv/bin/activate && pytest tests/test_vehicle_recharge_etc_only.py -v
|
||||
```
|
||||
|
||||
Expected: 全部 PASS。
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add backend/app/schemas/pl/vehicle_recharge.py backend/tests/test_vehicle_recharge_etc_only.py
|
||||
git commit -m "$(cat <<'EOF'
|
||||
fix(pl): allow only etc recharge type in vehicle recharge schemas
|
||||
|
||||
Reject fuel writes so the shared module can be narrowed to ETC-only.
|
||||
EOF
|
||||
)"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 3: Service 读路径强制 etc + fuel 按 id 不可见
|
||||
|
||||
**Files:**
|
||||
- Modify: `backend/app/services/pl_vehicle_recharge_service.py`
|
||||
|
||||
- [ ] **Step 1: 在 service 顶部增加模块常量**
|
||||
|
||||
```python
|
||||
# 本期本模块仅服务 ETC;历史 fuel 行保留但不暴露
|
||||
MODULE_RECHARGE_TYPE = "etc"
|
||||
```
|
||||
|
||||
- [ ] **Step 2: `_get_apply_row` / `_get_record_row` 增加类型条件**
|
||||
|
||||
In `_get_apply_row` filter add:
|
||||
|
||||
```python
|
||||
PlVehicleRechargeApply.recharge_type == MODULE_RECHARGE_TYPE,
|
||||
```
|
||||
|
||||
In `_get_record_row` filter add:
|
||||
|
||||
```python
|
||||
PlVehicleRechargeRecord.recharge_type == MODULE_RECHARGE_TYPE,
|
||||
```
|
||||
|
||||
保留原有 404 文案「申请单不存在」/「发放登记不存在」(与 spec:等同不存在)。
|
||||
|
||||
- [ ] **Step 3: `list_applies` 基查询强制 etc**
|
||||
|
||||
在初始 `.filter(tenant_no, del_flag == 0)` 中增加:
|
||||
|
||||
```python
|
||||
PlVehicleRechargeApply.recharge_type == MODULE_RECHARGE_TYPE,
|
||||
```
|
||||
|
||||
(与列头 `recharge_type` / `recharge_type_in` AND 叠加:客户端传 fuel 时结果为空。)
|
||||
|
||||
- [ ] **Step 4: `list_pending_apply_options` 强制 etc**
|
||||
|
||||
在其 `.filter(...)` 增加:
|
||||
|
||||
```python
|
||||
PlVehicleRechargeApply.recharge_type == MODULE_RECHARGE_TYPE,
|
||||
```
|
||||
|
||||
- [ ] **Step 5: `list_records` 强制 etc**
|
||||
|
||||
将可选:
|
||||
|
||||
```python
|
||||
if recharge_type:
|
||||
query = query.filter(PlVehicleRechargeRecord.recharge_type == recharge_type)
|
||||
```
|
||||
|
||||
改为始终:
|
||||
|
||||
```python
|
||||
query = query.filter(PlVehicleRechargeRecord.recharge_type == MODULE_RECHARGE_TYPE)
|
||||
```
|
||||
|
||||
(忽略请求里的 `recharge_type` 参数,避免绕过。)
|
||||
|
||||
- [ ] **Step 6: `list_disburse_board` 强制 etc**
|
||||
|
||||
在申请基查询 `.filter(...)` 增加:
|
||||
|
||||
```python
|
||||
PlVehicleRechargeApply.recharge_type == MODULE_RECHARGE_TYPE,
|
||||
```
|
||||
|
||||
- [ ] **Step 7: 跑既有 + 新单测**
|
||||
|
||||
```bash
|
||||
cd backend && source venv/bin/activate && pytest tests/test_vehicle_recharge_etc_only.py tests/test_pl_vehicle_ops_list_filters.py -v
|
||||
```
|
||||
|
||||
Expected: PASS。
|
||||
|
||||
- [ ] **Step 8: Commit**
|
||||
|
||||
```bash
|
||||
git add backend/app/services/pl_vehicle_recharge_service.py
|
||||
git commit -m "$(cat <<'EOF'
|
||||
fix(pl): hide non-ETC vehicle recharge rows in list and get APIs
|
||||
|
||||
Force etc on reads so historical fuel data stays in DB but out of this module.
|
||||
EOF
|
||||
)"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 4: 前端菜单标题 + 只留 ETC 选项
|
||||
|
||||
**Files:**
|
||||
- Modify: `web-admin/src/router/modules/pl.ts`
|
||||
- Modify: `web-admin/src/views/pl/vehicle-recharge-apply/columnFilterDefs.ts`
|
||||
- Modify: `web-admin/src/views/pl/vehicle-recharge-apply/index.vue`
|
||||
- Modify: `web-admin/src/views/pl/vehicle-recharge-record/index.vue`
|
||||
|
||||
- [ ] **Step 1: 路由标题**
|
||||
|
||||
In `web-admin/src/router/modules/pl.ts`,四处替换:
|
||||
|
||||
- `'ETC加油申请'` → `'ETC充值申请'`
|
||||
- `'ETC加油发放登记'` → `'ETC充值发放登记'`
|
||||
|
||||
- [ ] **Step 2: 列头枚举**
|
||||
|
||||
In `columnFilterDefs.ts`:
|
||||
|
||||
```typescript
|
||||
const RECHARGE_TYPE_OPTIONS = [{ value: 'etc', label: 'ETC' }]
|
||||
```
|
||||
|
||||
- [ ] **Step 3: 申请页**
|
||||
|
||||
1. File comment: `<!-- ETC充值申请 -->`
|
||||
2. Form select — 删除加油 option,只保留:
|
||||
|
||||
```vue
|
||||
<el-option label="ETC" value="etc" />
|
||||
```
|
||||
|
||||
3. 类型收窄:`rechargeType: 'etc' as 'etc'`(去掉 `| 'fuel'`)
|
||||
|
||||
- [ ] **Step 4: 发放页**
|
||||
|
||||
1. File comment: `<!-- ETC充值发放登记 -->`
|
||||
2. 同样删除 `<el-option label="加油" value="fuel" />`
|
||||
3. 收窄 `rechargeType` 类型同上
|
||||
4. Optional:placeholder「ETC卡号/油卡号」→「ETC卡号」
|
||||
|
||||
- [ ] **Step 5: 本地目视 / 类型检查**
|
||||
|
||||
```bash
|
||||
cd web-admin && pnpm exec vue-tsc --noEmit --pretty false 2>&1 | head -n 40
|
||||
```
|
||||
|
||||
浏览器:侧栏标题、新建下拉、列头漏斗仅 ETC。
|
||||
|
||||
- [ ] **Step 6: Commit**
|
||||
|
||||
```bash
|
||||
git add web-admin/src/router/modules/pl.ts \
|
||||
web-admin/src/views/pl/vehicle-recharge-apply/columnFilterDefs.ts \
|
||||
web-admin/src/views/pl/vehicle-recharge-apply/index.vue \
|
||||
web-admin/src/views/pl/vehicle-recharge-record/index.vue
|
||||
git commit -m "$(cat <<'EOF'
|
||||
fix(web-admin): rename ETC recharge menus and drop fuel type option
|
||||
|
||||
Align UI with ETC-only scope; list filtering is enforced by the backend.
|
||||
EOF
|
||||
)"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 5: 图谱更新 + 手工验收清单
|
||||
|
||||
- [ ] **Step 1: 更新知识图谱**
|
||||
|
||||
```bash
|
||||
./scripts/update-graph.sh all
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 手工验收(对照 spec)**
|
||||
|
||||
| # | 检查项 | 期望 |
|
||||
|---|--------|------|
|
||||
| 1 | 执行 migration 后侧栏 | ETC充值申请 / ETC充值发放登记 |
|
||||
| 2 | 新建申请/补录发放 | 只能选 ETC,落库 etc |
|
||||
| 3 | POST/PUT `rechargeType=fuel` | 422 / 校验失败 |
|
||||
| 4 | 库中已有 fuel 行 | 列表、看板、导出、pending-options 均不可见 |
|
||||
| 5 | GET fuel 的 id | 与「不存在」相同 |
|
||||
| 6 | etc 全流程 | 申请→待发放→发放正常 |
|
||||
| 7 | 字典管理 | 「加油」不再出现在有效选项 |
|
||||
|
||||
- [ ] **Step 3: Commit 图谱(若有 diff)**
|
||||
|
||||
```bash
|
||||
git add graphify-out backend/graphify-out web-admin/graphify-out
|
||||
git commit -m "$(cat <<'EOF'
|
||||
chore: update graphify after ETC-only vehicle recharge cutover
|
||||
EOF
|
||||
)"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Spec coverage self-check
|
||||
|
||||
| Spec 项 | Task |
|
||||
|---------|------|
|
||||
| D1 列表只出 etc | Task 3 |
|
||||
| D2 菜单名 | Task 1 + Task 4 |
|
||||
| D3 待发放加油可隐去 | Task 3(pending + board) |
|
||||
| D4 UI 只留 ETC | Task 4 |
|
||||
| D5 不删数据 / 不改 path·perms | 全任务均未 DELETE 业务行、未改 path |
|
||||
| D6 写拒 fuel + 字典软停用 | Task 1 + Task 2 |
|
||||
| get fuel ≡ 不存在 | Task 3 Step 2 |
|
||||
| 导出只出 etc | Task 3(list/board 被 export 复用) |
|
||||
|
||||
## Out of scope(勿做)
|
||||
|
||||
- 新加油模块、数据迁移、改 API path、改权限码、删 `fuel` 历史行
|
||||
@@ -0,0 +1,157 @@
|
||||
# 车辆充值模块收窄为仅 ETC — 设计文档
|
||||
|
||||
> **日期**: 2026-09-12
|
||||
> **状态**: 已批准
|
||||
> **前置**: `docs/superpowers/specs/2026-06-29-pl-vehicle-recharge-design.md`(原 ETC/加油共用模块)
|
||||
> **界面模式**: 沿用既有 P01 + 发放看板;本期仅文案与类型收窄,不换模式
|
||||
|
||||
## 背景与目标
|
||||
|
||||
现有「运输管理 → 车辆管理」下两个菜单同时支持 **ETC** 与 **加油**(`recharge_type`: `etc` | `fuel`):
|
||||
|
||||
| 当前菜单名 | 组件 | 表 |
|
||||
|---|---|---|
|
||||
| ETC加油申请 | `web-admin/src/views/pl/vehicle-recharge-apply/index.vue` | `pl_vehicle_recharge_apply` |
|
||||
| ETC加油发放登记 | `web-admin/src/views/pl/vehicle-recharge-record/index.vue` | `pl_vehicle_recharge_record` |
|
||||
|
||||
客户希望将**加油申请**后续独立成模块;本期先把上述两菜单收窄为 **仅 ETC 充值**。生产环境历史数据**不可删除**。
|
||||
|
||||
## 已确认业务规则
|
||||
|
||||
| # | 规则 | 决策 |
|
||||
|---|------|------|
|
||||
| D1 | 列表范围 | 本模块只展示 `recharge_type = etc`;历史 `fuel` 留库、本模块不出现,等新加油模块再管 |
|
||||
| D2 | 菜单名称 | `ETC充值申请` / `ETC充值发放登记` |
|
||||
| D3 | 待发放加油单 | 可隐去;客户已知晓;本期不迁移、不另开临时入口 |
|
||||
| D4 | 充值类型 UI | 仍显示「充值类型」字段,下拉**只保留 ETC** |
|
||||
| D5 | 数据安全 | 不物理删表/行;不改 path、component、权限码 |
|
||||
| D6 | 实现深度 | 前端约束 + 后端读强制 ETC + 写拒绝 `fuel` + 字典软停用「加油」 |
|
||||
|
||||
## 非目标(本期不做)
|
||||
|
||||
- 独立「加油申请 / 加油发放」模块与菜单
|
||||
- 迁移、清洗或改写历史 `fuel` 行
|
||||
- 变更表结构、API 路径、权限编码、单号规则、附件目录
|
||||
- 审批流、小程序、报表统计等新能力
|
||||
- 页面布局重构或更换界面模式
|
||||
|
||||
## 方案选型
|
||||
|
||||
| 方案 | 说明 | 结论 |
|
||||
|---|---|---|
|
||||
| 1 仅前端改名 + 下拉 | 列表仍出加油;API 仍可写 `fuel` | 否:不满足 D1/D6 |
|
||||
| **2 前后端收窄 + 字典软停用** | 菜单改名;列表/选项/导出只出 ETC;写只允许 etc;`fuel` 字典软停用 | **采用** |
|
||||
| 3 拆表迁数据 | 新建加油模块并迁 `fuel` | 否:超出本期;加油后续再做 |
|
||||
|
||||
---
|
||||
|
||||
## 后端设计
|
||||
|
||||
### 读路径(强制只出 ETC)
|
||||
|
||||
在 service 层对下列能力统一限定 `recharge_type = 'etc'`(**即使请求参数未传、传 `fuel` 或伪造查询,也不返回加油数据**):
|
||||
|
||||
- 申请列表与导出
|
||||
- 发放看板(`disburse-board`)与导出
|
||||
- 发放记录列表(若仍有入口)
|
||||
- 待发放下拉 `pending-options`
|
||||
|
||||
列头「充值类型」漏斗:枚举仅 ETC。若客户端传入非法/`fuel` 过滤值,服务端**强制按 etc 过滤**(不扩大为加油数据)。
|
||||
|
||||
按 id 详情 / 编辑 / 作废 / 删除:若目标行为历史 `fuel`,本模块 **与「记录不存在」相同处理**(沿用现有 get 失败语义),**不删库数据**。
|
||||
|
||||
### 写路径(只允许 etc)
|
||||
|
||||
- Schema:`RECHARGE_TYPES` 本期改为仅 `{"etc"}`;create/update 校验失败时明确提示「本期仅支持 ETC」
|
||||
- 申请 create/update、发放 create/update:拒绝 `fuel`
|
||||
- 发放关联申请:若 `apply_id` 指向 `fuel` 申请 → 拒绝(正常 UI 已选不到)
|
||||
|
||||
### 不变项
|
||||
|
||||
- 表名、字段、软删除语义、申请↔发放 1:0~1 关系、无申请补录、车牌范围、附件规则、单号规则均沿用原设计
|
||||
|
||||
---
|
||||
|
||||
## 前端设计
|
||||
|
||||
### 菜单与标题
|
||||
|
||||
| 位置 | 改动 |
|
||||
|---|---|
|
||||
| SQL migration `sys_menu` | `PL_VEH_RECHARGE_APPLY` → `ETC充值申请`;`PL_VEH_RECHARGE_RECORD` → `ETC充值发放登记` |
|
||||
| `web-admin/src/router/modules/pl.ts` | 正式路由 + redirect 隐藏路由共四处 `meta.title` 同步 |
|
||||
| 两页 Vue 注释 / 页内标题文案 | 与菜单名一致 |
|
||||
|
||||
**不动:** `path`、`component`、`perms` / `menuCode`、菜单图标、badge 编码。
|
||||
|
||||
### 充值类型控件
|
||||
|
||||
| 位置 | 改动 |
|
||||
|---|---|
|
||||
| 申请页、发放页表单 `el-select` | 去掉「加油」选项,只留 ETC |
|
||||
| `columnFilterDefs.ts` 中 `RECHARGE_TYPE_OPTIONS` | 只保留 `{ value: 'etc', label: 'ETC' }` |
|
||||
| 新建默认值 | `rechargeType: 'etc'`(字段仍展示) |
|
||||
|
||||
列表请求不必额外依赖前端传 `rechargeType=etc`(后端已强制);传了也不冲突。
|
||||
|
||||
当前页面选项为 Vue 硬编码,不依赖字典;字典停用仍做,避免系统字典管理或其他调用方再拉出「加油」。
|
||||
|
||||
---
|
||||
|
||||
## 数据与 Migration
|
||||
|
||||
新建:`docs/sql/migrations/2026-09-12-pl-vehicle-recharge-etc-only.sql`(名称可微调),内容至少包括:
|
||||
|
||||
1. **菜单改名**(仅 `menu_name`)
|
||||
2. **字典软停用**:`PL_RECHARGE_TYPE_FUEL` 置 `del_flag = 1`,`remark` 注明「ETC 模块收窄停用,数据保留待新加油模块」
|
||||
|
||||
**禁止:** `DELETE` 业务表行;禁止改 `recharge_type` 历史值;禁止 drop/alter 业务表结构。
|
||||
|
||||
上线前可选(运维/告知用,不阻塞发版):
|
||||
|
||||
```sql
|
||||
-- 待发放加油申请笔数(知情统计)
|
||||
SELECT COUNT(*) FROM pl_vehicle_recharge_apply
|
||||
WHERE del_flag = 0 AND recharge_type = 'fuel' AND status = 'pending';
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 影响文件(实现清单)
|
||||
|
||||
| 层 | 文件(预期) |
|
||||
|---|---|
|
||||
| SQL | `docs/sql/migrations/2026-09-12-pl-vehicle-recharge-etc-only.sql`;基线快照按仓库惯例择机同步 |
|
||||
| Backend schema | `backend/app/schemas/pl/vehicle_recharge.py`(`RECHARGE_TYPES`) |
|
||||
| Backend service | `backend/app/services/pl_vehicle_recharge_service.py`;必要时 `vehicle_recharge_list_filters.py` |
|
||||
| Backend API | `backend/app/api/pl/vehicle_recharge.py`(若 get-by-id 需在路由/服务层拦截 fuel) |
|
||||
| Frontend | `vehicle-recharge-apply/index.vue`、`vehicle-recharge-record/index.vue`、`columnFilterDefs.ts`、`router/modules/pl.ts` |
|
||||
|
||||
---
|
||||
|
||||
## 测试要点
|
||||
|
||||
1. 侧栏与 Tab 标题为「ETC充值申请」「ETC充值发放登记」
|
||||
2. 新建申请/发放:只能选 ETC;默认 ETC;提交成功且落库 `etc`
|
||||
3. API 传 `rechargeType=fuel` 创建/更新 → 失败
|
||||
4. 库中已有 `fuel` 申请/发放:两菜单列表、看板、导出、pending-options **均不可见**
|
||||
5. 用已知 `fuel` 的 id 调详情/编辑 → 与记录不存在相同失败语义
|
||||
6. `etc` 单据全流程(申请 → 待发放 → 发放登记)回归正常
|
||||
7. 字典管理中「加油」不再作为有效选项出现(软删后)
|
||||
8. 回滚演练思路:恢复菜单名 + 恢复 `RECHARGE_TYPES`/`fuel` 读过滤与字典 `del_flag`;业务数据无需恢复
|
||||
|
||||
---
|
||||
|
||||
## 后续(不在本期)
|
||||
|
||||
独立「加油申请 / 加油发放」模块时,可:
|
||||
|
||||
- 复用或迁出 `recharge_type = fuel` 历史行,或新建业务表
|
||||
- 恢复/新建加油相关菜单与字典项
|
||||
- 本 ETC 模块保持仅 etc 不变
|
||||
|
||||
---
|
||||
|
||||
## 与原设计文档关系
|
||||
|
||||
本变更是对 `2026-06-29-pl-vehicle-recharge-design.md` 的**产品收窄补丁**:原 D2 菜单名、充值类型双值语义在本期被 D1–D6 覆盖;其余申请/发放规则仍有效。
|
||||
Reference in new issue
Block a user