Files
uniprop-manual/prop-acc/scenarios/deposit/deposit-additional-topup.md

148 lines
5.7 KiB
Markdown
Raw Permalink Normal View History

2026-05-25 22:22:37 +08:00
---
title: prop-acc · deposit · 场景 - 已有账户追加缴款
aliases:
- 追加缴款
- 押金账户追加
- deposit-additional-topup
- 场景-押金追加缴款
tags:
- 场景
- prop-acc
- 保证金
- 缴纳
audience:
- 业户
- 业务人员
status: 已发布
sub_feature: deposit
last_review: 2026-05-25
code_version: 2026-05-22
---
# 场景:已有账户后续追加缴款
业户**已经有一个 Active 状态的押金账户**,现在要追加缴款(扩大装修范围 / 押金标准提升 / 分期补齐)。比首次开户简单 —— 不重建账户,只加流水。
## 典型情境
> [!example] 真实情境
> 张阿姨家原来交了 ¥3,000 装修保证金。装修过程中她决定多动一面承重墙,物业要求她**补 ¥2,000 押金**(高风险装修加押)。第二天她到前台补缴。
## 业户视角
### 第 1 步:到前台 / 小程序
带身份证(部分物业要求)到前台,告诉职员:
> "我要给装修押金账户补 ¥2,000。"
### 第 2 步:付款
同 [[deposit-first-time-renovation|首次缴款]]:现金 / 微信 / POS / 银行转账。
### 第 3 步:拿收据
新收据"装修保证金缴纳 ¥2,000"。
> [!info] 您账户里现在有多少?
> 旧 ¥3,000 + 新 ¥2,000 = **¥5,000**。下次退押时按这个总数算。
## 业务人员视角
> [!info] 与首次缴款的关键差异
> **不开新账户,在既有账户上加缴款流水**。如果误开新账户,会出现两个并行账户,退款时一笔退不清,业户会困惑。
### 第 1 步:找到既有账户
后台 → 保证金 → 账户列表 → 按业户姓名 / 房号 / 缴款人姓名搜索 → 找到 Active 账户。
### 第 2 步:进入账户详情(`ViewDepositAccount`)
详情页右上角的状态管理组里点 **`DepositAction`** 按钮(标签"追加缴款")。
> [!warning] 按钮可能灰化
> 仅当账户 `status=Active` 时可点。Frozen / Closed 状态下灰化。详见 [[account-state-machine]] 的 `canDeposit()` 守护。
### 第 3 步:Modal 表单
| 字段 | 填什么 |
|---|---|
| 缴款金额 | ¥2,000 |
| 支付方式 | 现金 / 微信 / POS / 银行转账 |
| 收款银行账户 | 微信/POS/转账选对应银行 |
| 备注 | 选填,如 "动承重墙加押" |
### 第 4 步:提交
系统调用业务层 `DepositIntoAccountAction`,在事务内:
1. 校验账户 `canDeposit()`(Active only)
2.`CollectionOrder`(`actual_amount=+2000`,`status=Completed`)
3. 在既有账户上加 `DepositTransaction`(`type=deposit`,`amount=2000`,`balance_before=3000`,`balance_after=5000`,关联 CO)
4. 更新 `DepositAccount.balance` = 5000
5. 触发 `CollectionOrderCompleted` → Listener 自动建 Receipt
### 第 5 步:给收据
后台找到新生成的 Receipt(只对应这一笔追加),交给业户。
## 系统流程
```mermaid
sequenceDiagram
participant 业户
participant 前台
participant Filament
participant DepositIntoAccountAction
participant 数据库
participant 监听器
业户->>前台: 给押金账户加 2000
前台->>Filament: ViewDepositAccount → DepositAction(modal)
Filament->>DepositIntoAccountAction: handle(account, 2000, paymentChannel)
DepositIntoAccountAction->>DepositIntoAccountAction: canDeposit() ? (Active=true)
DepositIntoAccountAction->>数据库: 开启事务
DepositIntoAccountAction->>数据库: 1. 建 CollectionOrder (+2000, Completed)
DepositIntoAccountAction->>数据库: 2. 建 DepositTransaction (deposit, 3000→5000)
DepositIntoAccountAction->>数据库: 3. 更新 DepositAccount.balance=5000
DepositIntoAccountAction->>监听器: 4. 触发 CollectionOrderCompleted
监听器->>数据库: 5. 建 Receipt (装修保证金缴纳 ¥2,000)
DepositIntoAccountAction->>数据库: 提交事务
Filament-->>前台: 成功通知 + 刷新余额显示
前台->>业户: 给新收据
```
> [!info] 一处代码,两处入口
> `DepositIntoAccountAction` 是**两处调用方共用**的业务 Action:
> - 本场景(追加缴款):从 `ViewDepositAccount` → `DepositAction` 触发
> - [[deposit-first-time-renovation|首次开户]]:从 `CreateDepositAccount` 表单触发
>
> 未来若小程序在线缴款,也复用同一份。逻辑只写一遍。
## 常见问题
> [!question] Frozen 账户能追加缴款吗?
> **不能**。`canDeposit()` 只允许 `Active`。Frozen 状态下按钮灰化,直接调 Action 会抛 `RuntimeException`。
>
> 这条规则比直觉更严:看上去"多存钱不亏",但实际风险是纠纷期间装修公司继续往受冻结账户灌钱,资金被困、责任更复杂。详见 [[account-state-machine]] "关键守护" 段。
> [!question] Closed 账户呢?
> 同样**不能**。Closed 是永久终态,新业务请[[deposit-first-time-renovation|开新账户]]。
> [!question] 多次追加缴款,余额怎么算?
> 每笔 `DepositTransaction` 都有 `balance_before` 和 `balance_after`,账户 `balance` 字段也实时更新。任何时刻业户问"我现在有多少押金",看 `DepositAccount.balance` 即可。审计可重算 `SUM(deposit) - SUM(refund) - SUM(forfeiture)` 校验自洽。
> [!question] 追加缴款的收据是单独一张还是合并到原收据?
> **单独一张**。每笔 `DepositTransaction` 对应一张独立的 `Receipt`。这与"原单上挂退款标记"的反模式相反,详见 [[red-receipt-design]] "为什么不在原 CollectionOrder 上挂退款标记" 段。
> [!question] 业户能在小程序自助追加缴款吗?
> 待补。当前 Action 假设手工操作(前台触发)。未来加小程序在线支付时,前端调同一个 `DepositIntoAccountAction`,只需多加一个支付回调入口。
## 相关文档
- [[deposit-first-time-renovation]]
- [[account-state-machine]]
- [[deposit-account-vs-transaction]]
- [[transaction-types]]
- [[exception-deposit-on-frozen]]