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

164 lines
5.3 KiB
Markdown
Raw Permalink Normal View History

2026-05-25 23:22:55 +08:00
---
title: prop-acc · prepaid · 场景 - 已有账户追加充值
aliases:
- 追加充值预存款
- 预存款续充
- deposit-additional-topup
- 场景-预存款追加充值
tags:
- 场景
- prop-acc
- 预存款
- 充值
audience:
- 业户
- 业务人员
status: 已发布
sub_feature: prepaid
last_review: 2026-05-25
code_version: 2026-05-22
---
# 场景:已有账户追加充值
业户**已有 Active 预存款账户**,余额不够 / 想多存,继续充值。比首次开户简单 —— 不建账户,只加流水。
## 典型情境
> [!example] 真实情境
> 张阿姨 3 个月前充了 ¥5,000 预存款,期间扣了 ¥2,400(物业费 800 × 3),余额 ¥2,600。下个月还要扣 ¥800 + ¥600 水电费,觉得余额勉强够,**再充 ¥3,000** 凑个整。
## 业户视角
### 第 1 步:到前台 / 小程序
跟物业管家说"我预存账户加 ¥3,000"。
### 第 2 步:付款
支付方式同首次充值。
### 第 3 步:拿收据
"预付款充值 ¥3,000"。
### 第 4 步:余额查看
后台 / 小程序看到:
- 上次余额 ¥2,600 + 本次 ¥3,000 = **当前余额 ¥5,600**
- 后续账单自动从这扣
## 业务人员视角
> [!info] 与首次充值的差异
> **不开新账户**,在既有账户上 `DepositAction` 加流水。
### 第 1 步:找到既有账户
后台 → 预存款 → 账户列表 → 按业户姓名 / 房号搜索 → 找到 Active 账户。
### 第 2 步:进 `ViewPrepaidAccount`
详情页右上角点 **`DepositAction`**(标签"充值")。
> [!warning] 按钮可见性
> `DepositAction` 守护:`canOperate()`(Active only)+ Policy `->authorize('deposit')`。Frozen / Closed 灰化。
### 第 3 步:Modal 表单
| 字段 | 填什么 |
|---|---|
| **充值金额** | ¥3,000 |
| **支付方式** | 现金 / 微信 / POS / 银行转账 |
| **收款银行账户** | 微信/POS/转账选对应银行 |
| **备注** | 选填 |
### 第 4 步:提交
系统调 `PrepaidAccount::deposit($amount, ...)`,事务内:
1. 模型层校验 `canOperate()`(Active only)
2.`CollectionOrder`(`type=Prepaid`,`actual=+3000`,`Completed`)
3.`PrepaidTransaction`(`type=deposit`,`amount=3000`,`balance_before=2600`,`balance_after=5600`,关联 CO)
4. 更新 `PrepaidAccount.balance=5600`
5. 触发 `CollectionOrderCompleted` → Listener 建 Receipt"预付款充值 ¥3,000"
### 第 5 步:给收据
打印 / 发微信。
## 系统流程
```mermaid
sequenceDiagram
participant 业户
participant 前台
participant Filament
participant PrepaidAccount
participant 数据库
业户->>前台: 给预存账户加 3000
前台->>Filament: ViewPrepaidAccount → DepositAction(modal)
Filament->>PrepaidAccount: deposit(3000, ...)
PrepaidAccount->>PrepaidAccount: canOperate()? Active=true
PrepaidAccount->>数据库: 开启事务
PrepaidAccount->>数据库: 1. 建 CO (Prepaid, +3000, Completed)
PrepaidAccount->>数据库: 2. 建 PrepaidTransaction (deposit, 2600→5600)
PrepaidAccount->>数据库: 3. 更新 balance=5600
PrepaidAccount->>监听器: 触发 CollectionOrderCompleted
监听器->>数据库: 建 Receipt (预付款充值 ¥3,000)
PrepaidAccount->>数据库: 提交
Filament-->>前台: 成功
前台->>业户: 收据
```
## 流水台账(本场景在累计流水中的位置)
| 流水 | type | amount | balance_before | balance_after | 备注 |
|---|---|---|---|---|---|
| 1 | deposit | 5000 | 0 | 5000 | 3 个月前首次充值 |
| 2 | consume | 800 | 5000 | 4200 | 第 1 月物业费 |
| 3 | consume | 800 | 4200 | 3400 | 第 2 月物业费 |
| 4 | consume | 800 | 3400 | 2600 | 第 3 月物业费 |
| **5** | **deposit** | **3000** | **2600** | **5600** | **本次追加** |
## 常见问题
> [!question] Frozen 账户能追加充值吗?
> **不能**。`canOperate()` 只允许 Active。详见 [[exception-refund-on-frozen|三层守护]](deposit / consume / refund 都一样)。
>
> 如果业户硬要充:
> - 系统层无法绕过(模型层兜底)
> - **业务层** 需先 [[unfreeze-after-verification|解冻]] → 再充
> - 不可"暂存钱等解冻后录入" —— 不合规
> [!question] Closed 账户能追加充值吗?
> **不能**(同上)。需要开新账户,但**一户一账约束阻塞**(详见 [[one-account-per-resident]] "已知设计 gap")。
> [!question] 同时多笔追加(一天充两次)可以吗?
> 可以。每次独立 Action,各自一笔 Transaction + CO + Receipt。账户 balance 累加。
> [!question] 充值过多担心退不出来?
> 任何时候可走 [[refund-partial-after-consume]] 或 [[refund-full-resident-moveout]] 退余。预存款不像押金有"装修结束才能退"的业务节点,**随时可退**。
> [!question] 业户问"我能用别人的微信付吗?"
> 系统不限制实际支付来源(微信扫码用谁付都行)。**业务上**:
> - 账面缴款人是业户本人(`PrepaidAccount.community_user_profile_id` 不变)
> - 实际付钱的是谁是业户自己的事
> - 退款时**只退给账面缴款人**(业户本人),不是实际付钱的微信号
## 异常分支
- 业户从未充过 → 走 [[deposit-first-time]] 开户
- 充错金额 → [[refund-partial-after-consume]]
- 账户冻结 → 先 [[unfreeze-after-verification]] 解冻
## 相关文档
- [[deposit-first-time]]
- [[account-state-machine]]
- [[consume-monthly-property-bill]]
- [[refund-partial-after-consume]]
- [[exception-refund-on-frozen]]