fujian_water_biz_doc/docs/superpowers/plans/2026-06-14-account-log-baddebt-recovery.md
tangweijie 3eccab2cf9 docs: 文档治理统一 — AGENTS.md 生命周期规则 + 模块归档 + DDL 修正
1. AGENTS.md 更新
   - water-docs: 新增 specs/ 与 docs/design/ 生命周期规则章节
   - water-backend: 更新协作引用(建设期/建成后、evidence 模块化)

2. specs/ 重复合并
   - 006-reminder-event-design 合并入 003-rev006-reminder-event-design
   - 001-rev004-accounting 删除冗余 data-model.md + contracts/
   - 002-rev005-invoice-flow 删除冗余 data-model.md + contracts/

3. evidence 按模块归档
   - 35 个 REV-004 文件归入 evidence/rev004-accounting/
   - 7 个通用 bugfix 文件归入 evidence/bugfix/ 和 bugfix/frontend/
   - 新建 rev005-invoice/、rev006-reminder/、rev007-statistics/ 目录

4. guides/ 清理
   - 14 个 REV004_*.md 移入 evidence/rev004-accounting/

5. 遗留文件处理
   - docs/research/ 归档到 Archive/06_Migration_Plans/
   - backend-check detached worktrees 清理

6. 交叉引用修复
   - 006-reminder-event-design → 003-rev006-reminder-event-design
   - docs/guides/REV004_ → docs/evidence/rev004-accounting/REV004_

7. DB 设计文档修正(01_Database_Design.md)
   - biz_invoice 明确为开票配置表,非发票记录表
   - 新增 biz_invoice_record 为发票申请/结果主表
   - 新增 biz_charge_invoice_rel 账单-发票关联说明
   - REV-005 承接口径表名全部修正

8. 发票审计证据
   - 新增 evidence/rev005-invoice/2026-06-16-invoice-document-audit.md
2026-06-16 11:47:16 +08:00

204 lines
7.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 账务日志功能按钮 + 呆坏账恢复 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:** 修复账务日志页功能按钮(撤销/退转款/预转存/呆坏账恢复)根据数据状态正确显示,不再硬编码 `false`;新增呆坏账恢复入口。
**Architecture:** 后端 `toPageResp()` 当前将 `canRevoke`/`canRefund`/`canPrestore` 硬编码为 `false``canRecoverBadDebt` 字段不存在。修复后根据 `LegacyLogRecord``objectType` + `resultStatus` + `approvalStatus` 动态判定;前端补 API 调用和按钮。
**Tech Stack:** Java 17 + Spring Boot (backend), Vue 3 + TypeScript (frontend)
---
## canXxx 判定规则
`toPageResp(LegacyLogRecord record)` 中按以下规则赋值:
| 字段 | 条件 | 说明 |
|---|---|---|
| `canRevoke` | `approvalStatus == "PENDING_APPROVAL"` | 待审批状态可撤销 |
| `canRefund` | `objectType == "PREPAID_REFUND" && resultStatus == "SUCCESS"` | 退转款成功后允许二次退款 |
| `canPrestore` | `objectType == "PREPAID_REFUND" && resultStatus == "SUCCESS"` | 退转款成功后允许转预存 |
| `canRecoverBadDebt` | `objectType == "BAD_DEBT_RECORD" && resultStatus == "SUCCESS"` | 坏账已执行可恢复为欠费 |
---
### Task 1: 后端 VO 加 canRecoverBadDebt
**Files:**
- Modify: `sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/controller/admin/accountingadjust/accountProcess/vo/AccountingAdjustLogPageRespVO.java`
- [ ] **Step 1: 在 VO 末尾 canPrestore 后添加字段**
```java
@Schema(description = "是否可恢复呆坏账")
private Boolean canRecoverBadDebt;
```
添加位置:紧跟 `private Boolean canPrestore;` 之后。
---
### Task 2: 后端 Service 修正 canXxx 赋值
**Files:**
- Modify: `sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/service/accountingadjust/accountProcess/AccountingAdjustLogProcessServiceImpl.java:520-522`
- [ ] **Step 1: 替换硬编码 false 为动态判定**
`toPageResp()` 中的三行:
```java
respVO.setCanRevoke(false);
respVO.setCanRefund(false);
respVO.setCanPrestore(false);
```
替换为:
```java
// 动态判定功能按钮可见性
respVO.setCanRevoke("PENDING_APPROVAL".equals(record.approvalStatus));
boolean refundEnabled = "PREPAID_REFUND".equals(record.objectType) && "SUCCESS".equals(record.resultStatus);
respVO.setCanRefund(refundEnabled);
respVO.setCanPrestore(refundEnabled);
respVO.setCanRecoverBadDebt("BAD_DEBT_RECORD".equals(record.objectType) && "SUCCESS".equals(record.resultStatus));
```
**同时需要更新 `AccountingAdjustLogPageReqVO` 的 `copyReq` 方法:** 无需改动canXxx 是响应字段。
---
### Task 3: 前端 API 加 recoverBadDebt
**Files:**
- Modify: `src/api/accountProcess/accountLog/index.ts`
- [ ] **Step 1: 添加接口类型和 API 方法**
`AccountingAdjustPageRespVO` 接口中添加 `canRecoverBadDebt` 字段,并在 `AccountLogApi` 对象中添加 `recoverBadDebt` 方法:
```typescript
// 在 AccountingAdjustPageRespVO 接口中添加
canRecoverBadDebt?: boolean
```
```typescript
// 在 AccountLogApi 对象中添加(放在 revokeAccountLog 之前)
// 账务日志呆坏账恢复
recoverBadDebt: async (data: { adjustmentNo: string }) => {
return await request.post<AccountingAdjustRespVO>({
url: '/business/accounting-adjust/log-recover-bad-debt',
data
})
},
```
---
### Task 4: 前端页面加呆坏账恢复按钮
**Files:**
- Modify: `src/views/accountProcess/accountLog/index.vue`
- [ ] **Step 1: 在 function 模板中添加按钮**
在现有三个按钮之后、`</div>` 之前添加:
```html
<el-button
v-if="scope.row.canRecoverBadDebt"
link
type="primary"
@click="handleRecoverBadDebt(scope.row)"
>
<el-tooltip effect="dark" content="恢复呆坏账" placement="top">
<Icon icon="ep:refresh-left" :size="18" />
</el-tooltip>
</el-button>
```
- [ ] **Step 2: 在 script 中添加处理函数**
`handlePrestore` 之后添加:
```typescript
const handleRecoverBadDebt = async (row: any) => {
const adjustmentNo = row?.adjustmentNo
if (!adjustmentNo) {
message.warning('缺少调整单号,无法恢复')
return
}
try {
await message.confirm(`确认要将呆坏账调整单「${adjustmentNo}」恢复为欠费状态吗?`)
await AccountLogApi.recoverBadDebt({ adjustmentNo })
message.success('呆坏账已恢复为欠费')
await getList()
} catch (e: any) {
if (e !== 'cancel' && e !== 'close') {
message.error('恢复失败,请稍后重试')
}
}
}
```
---
### Task 5: 编译验证 + 提交
- [ ] **Step 1: 后端编译 + 测试**
```bash
cd /Volumes/Dpan/github/water-workspace/water-backend
mvn test -pl sw-business/sw-business-server -Dtest=AccountingAdjustLogProcessServiceImplTest -DfailIfNoTests=false 2>&1 | grep -E "Tests run|BUILD"
```
预期Tests run: 4, Failures: 0, BUILD SUCCESS
- [ ] **Step 2: 前端 TypeScript 编译**
```bash
cd /Volumes/Dpan/github/water-workspace/water-frontend
npx vue-tsc --noEmit 2>&1 | grep -i "error\|accountLog" | head -10
```
预期:无类型错误。
- [ ] **Step 3: 提交**
```bash
# 后端
cd /Volumes/Dpan/github/water-workspace/water-backend
git add sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/controller/admin/accountingadjust/accountProcess/vo/AccountingAdjustLogPageRespVO.java
git add sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/service/accountingadjust/accountProcess/AccountingAdjustLogProcessServiceImpl.java
git commit -m "feat: add canRecoverBadDebt and fix canRevoke/canRefund/canPrestore logic
- Add canRecoverBadDebt field to AccountingAdjustLogPageRespVO
- Replace hardcoded false with dynamic logic in toPageResp():
canRevoke = approvalStatus is PENDING_APPROVAL
canRefund/canPrestore = PREPAID_REFUND + SUCCESS
canRecoverBadDebt = BAD_DEBT_RECORD + SUCCESS"
# 前端
cd /Volumes/Dpan/github/water-workspace/water-frontend
git add src/api/accountProcess/accountLog/index.ts src/views/accountProcess/accountLog/index.vue
git commit -m "feat: add bad debt recovery button and API to account log page
- Add recoverBadDebt API method calling POST log-recover-bad-debt
- Add canRecoverBadDebt field to AccountingAdjustPageRespVO
- Add recovery button with confirm dialog in function column"
```
---
## Self-Review
**1. Spec coverage:** 4 个功能按钮全部覆盖canRevoke/canRefund/canPrestore 修正 + canRecoverBadDebt 新增。
**2. Placeholder scan:** 无占位符,所有步骤含具体代码。
**3. Type consistency:**
- `record.approvalStatus``record.resultStatus``record.objectType` 均为 `LegacyLogRecord` 内部类字段,已存在于 ServiceImpl
- 前端 `canRecoverBadDebt` 字段同时加入 `AccountingAdjustPageRespVO` 接口和 API 调用
- 后端 `recoverBadDebt` API 接收 `{ adjustmentNo: string }`,与 `AdjustExecuteReqDTO` 匹配