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
204 lines
7.2 KiB
Markdown
204 lines
7.2 KiB
Markdown
# 账务日志功能按钮 + 呆坏账恢复 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` 匹配
|