191 lines
7.3 KiB
Markdown
191 lines
7.3 KiB
Markdown
|
|
---
|
||
|
|
title: prop-acc · prepaid · 场景 - 业户搬走全额退余
|
||
|
|
aliases:
|
||
|
|
- 业户搬走退预存款
|
||
|
|
- 全额退预存款
|
||
|
|
- refund-full-resident-moveout
|
||
|
|
- 场景-业户搬走退预存款
|
||
|
|
tags:
|
||
|
|
- 场景
|
||
|
|
- prop-acc
|
||
|
|
- 预存款
|
||
|
|
- 退款
|
||
|
|
audience:
|
||
|
|
- 业户
|
||
|
|
- 业务人员
|
||
|
|
status: 已发布
|
||
|
|
sub_feature: prepaid
|
||
|
|
last_review: 2026-05-25
|
||
|
|
code_version: 2026-05-22
|
||
|
|
---
|
||
|
|
|
||
|
|
# 场景:业户搬走全额退余
|
||
|
|
|
||
|
|
业户**搬离社区**(卖房 / 退租 / 不再使用本物业),要把预存款账户余额全额退回。退款后**不自动关账**(prepaid 特性),业务人员**主动**走 [[close-resident-moveout|关账]] 流程。
|
||
|
|
|
||
|
|
## 典型情境
|
||
|
|
|
||
|
|
> [!example] 真实情境
|
||
|
|
> 刘先生把 12-3-501 房子卖了,下周搬走。他在预存款账户里还有 ¥3,200(本月物业费扣完之后的余),要全额退回。
|
||
|
|
|
||
|
|
## 业户视角
|
||
|
|
|
||
|
|
### 第 1 步:告知物业搬走
|
||
|
|
|
||
|
|
- 跟物业管家说"我下周搬走,把预存款里的钱退给我"
|
||
|
|
- 提供退款渠道(银行卡 / 微信 / 支付宝)
|
||
|
|
|
||
|
|
### 第 2 步:等退款
|
||
|
|
|
||
|
|
- 业务人员核对账户余额
|
||
|
|
- 操作退款(走线下 + 系统)
|
||
|
|
|
||
|
|
### 第 3 步:收到红字收据 + 退款到账
|
||
|
|
|
||
|
|
- 红字收据"预付款退款 ¥-3,200"
|
||
|
|
- 银行 / 微信收到 ¥3,200
|
||
|
|
|
||
|
|
### 第 4 步:账户被关
|
||
|
|
|
||
|
|
- 后续物业再发账单(若有)→ 不会自动从这个账户扣(已 Closed)
|
||
|
|
- 业户在小程序"我的预存款" 显示 "🔒 已关闭"
|
||
|
|
|
||
|
|
## 业务人员视角
|
||
|
|
|
||
|
|
### 第 1 步:核实业户搬走情况
|
||
|
|
|
||
|
|
- 房屋已过户(看 community_user_profile 状态)
|
||
|
|
- 业户已结清其他费用(无未付账单)
|
||
|
|
- 业户提供退款渠道
|
||
|
|
|
||
|
|
> [!warning] 注意未付账单
|
||
|
|
> 如果业户还有未付账单(物业费 / 水电费等),**先抵扣再退余**:
|
||
|
|
> - 业户余额 ¥3,200,有未付账单 ¥800 → 先 [[consume-monthly-property-bill|抵 800]],余 ¥2,400 → 再退 ¥2,400
|
||
|
|
> - 不要直接退全部 → 否则未付账单仍挂业户身上,变成"搬走后还欠物业钱",催收困难
|
||
|
|
|
||
|
|
### 第 2 步:打开账户做退款
|
||
|
|
|
||
|
|
后台 → 预存款 → 找到刘先生账户(Active,balance=3200)→ 进 `ViewPrepaidAccount` → 点 `RefundAction`(标签"退款")。
|
||
|
|
|
||
|
|
> [!warning] 按钮可见性
|
||
|
|
> `RefundAction` 守护:`canOperate() && balance > 0` + Policy `->authorize('refund')`。Frozen / Closed / 零余额账户灰化。
|
||
|
|
|
||
|
|
Modal 表单:
|
||
|
|
|
||
|
|
| 字段 | 填什么 |
|
||
|
|
|---|---|
|
||
|
|
| **退款金额** | ¥3,200(默认带入当前余额)|
|
||
|
|
| **退款渠道(PaymentChannel)** | 选业户指定回款方式 |
|
||
|
|
| **退款备注** | 必填,如 "业户搬离,12-3-501 已过户,退预存款全额" |
|
||
|
|
|
||
|
|
### 第 3 步:提交
|
||
|
|
|
||
|
|
系统调 `RefundFromPrepaidAccountAction`,事务内:
|
||
|
|
|
||
|
|
1. 校验 `canOperate()`(Active only)
|
||
|
|
2. 校验金额 ≤ 当前余额
|
||
|
|
3. 建 `CollectionOrder`(`type=Prepaid`,`actual_amount=-3200` 红字,`Completed`)
|
||
|
|
4. 调 `PrepaidAccount::refund(3200, ...)`:
|
||
|
|
- 模型层再校验 `canOperate()`(三层防御之模型层兜底)
|
||
|
|
- 加 `PrepaidTransaction`(`type=refund`,`amount=3200`,`balance_before=3200`,`balance_after=0`,关联红字 CO)
|
||
|
|
- 更新 `balance=0`
|
||
|
|
5. **不自动关账**(prepaid 特性,与 deposit 不同 —— 见 [[account-state-machine]] "零余额不自动关账" 段)
|
||
|
|
6. 触发 `CollectionOrderCompleted` → Listener 建红字 Receipt"预付款退款 ¥-3,200"
|
||
|
|
|
||
|
|
### 第 4 步:走线下退款
|
||
|
|
|
||
|
|
- 银行转账:导出回款指令 → 银行办理
|
||
|
|
- 微信:在物业微信号上做退款
|
||
|
|
- 支付宝:同上
|
||
|
|
|
||
|
|
### 第 5 步:主动关账([[close-resident-moveout]])
|
||
|
|
|
||
|
|
退完余额后**账户仍是 Active 状态**,需手动走 `CloseAccountAction` 关掉。这是 prepaid 与 deposit 的关键差异。
|
||
|
|
|
||
|
|
详见 [[close-resident-moveout]]。
|
||
|
|
|
||
|
|
### 第 6 步:把红字收据给业户
|
||
|
|
|
||
|
|
后台找 Receipt → 微信 / 邮件发刘先生。
|
||
|
|
|
||
|
|
## 系统流程
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
sequenceDiagram
|
||
|
|
participant 业户
|
||
|
|
participant 财务
|
||
|
|
participant Filament
|
||
|
|
participant RefundFromPrepaidAccountAction
|
||
|
|
participant 数据库
|
||
|
|
participant 监听器
|
||
|
|
|
||
|
|
Note over 业户,财务: 业户搬走,余额 3200
|
||
|
|
|
||
|
|
财务->>财务: 核实无未付账单(若有,先 consume)
|
||
|
|
财务->>Filament: ViewPrepaidAccount → RefundAction(3200)
|
||
|
|
Filament->>RefundFromPrepaidAccountAction: handle(account, 3200, channel)
|
||
|
|
RefundFromPrepaidAccountAction->>RefundFromPrepaidAccountAction: canOperate()? Active=true
|
||
|
|
RefundFromPrepaidAccountAction->>RefundFromPrepaidAccountAction: 3200 ≤ 3200 yes
|
||
|
|
RefundFromPrepaidAccountAction->>数据库: 开启事务
|
||
|
|
RefundFromPrepaidAccountAction->>数据库: 1. 建 CO(Prepaid, -3200 红字, Completed)
|
||
|
|
RefundFromPrepaidAccountAction->>数据库: 2. account.refund(3200) → balance 3200→0
|
||
|
|
RefundFromPrepaidAccountAction->>数据库: 3. balance=0, **status 仍 Active**
|
||
|
|
RefundFromPrepaidAccountAction->>监听器: 4. 触发 CollectionOrderCompleted
|
||
|
|
监听器->>数据库: 5. 建 Receipt("预付款退款 ¥-3,200")
|
||
|
|
RefundFromPrepaidAccountAction->>数据库: 提交事务
|
||
|
|
Filament-->>财务: 成功(注:account 仍 Active,需手动关账)
|
||
|
|
|
||
|
|
Note over 财务: 接着走关账
|
||
|
|
财务->>Filament: CloseAccountAction → status=Closed
|
||
|
|
财务-->>业户: 银行/微信退 3200 + 红字收据
|
||
|
|
```
|
||
|
|
|
||
|
|
## 与 deposit 退款的关键差异
|
||
|
|
|
||
|
|
| 维度 | deposit 退款(refund-full-no-damage) | prepaid 退款(本场景) |
|
||
|
|
|---|---|---|
|
||
|
|
| 余额清零后状态 | **自动 Closed** | **仍 Active**(可继续充值)|
|
||
|
|
| 关账操作 | 不需要 | **需手动 CloseAccountAction** |
|
||
|
|
| 业务背景 | 装修结束等业务节点 | 业户搬走等长期事件 |
|
||
|
|
| 是否常见 | 高频(每户装修都做) | 低频(业户搬走才做)|
|
||
|
|
|
||
|
|
## 常见问题
|
||
|
|
|
||
|
|
> [!question] 为什么 prepaid 不自动关账?
|
||
|
|
> 详见 [[account-state-machine]] "零余额不自动关账" 段。简言之:预存款账户**一户一账**,频繁开关无意义,业户随时可能继续充值。
|
||
|
|
|
||
|
|
> [!question] 退完不关账户有什么风险?
|
||
|
|
> 几乎无风险:
|
||
|
|
> - 业户搬走后再无消费/充值动作 → 账户保持 0 余额 Active
|
||
|
|
> - 但**长期闲置 Active 账户**会出现在审计扫描里([[audit-low-balance-and-overdue]] 类似),业务上不专业
|
||
|
|
> - 推荐**退完立即关**(走 [[close-resident-moveout]]),清爽
|
||
|
|
|
||
|
|
> [!question] 业户搬走后又租回来或买回来,关了账户怎么办?
|
||
|
|
> 当前**一户一账约束阻塞**(unique 不允许重开)。详见 [[one-account-per-resident]] "已知设计 gap"。业务上目前用:
|
||
|
|
> - 业户重新现金 / 微信付账单(不用预存款)
|
||
|
|
> - 联系运维特殊处理(罕见)
|
||
|
|
|
||
|
|
> [!question] 退款渠道与充值渠道不同可以吗?
|
||
|
|
> 可以,看 [[../deposit/refund-with-payment-channel-switch]] 介绍的换渠道逻辑(deposit 模块,逻辑相同)。
|
||
|
|
|
||
|
|
> [!question] 业户失联但要退预存款怎么办?
|
||
|
|
> 几个选项:
|
||
|
|
> - **暂留 Active**:不操作,等业户出现(余额对业户仍可用)
|
||
|
|
> - **freeze 账户**:走 [[freeze-suspected-fraud|风控冻结]] 流程(reason 改"业户失联待联系")
|
||
|
|
> - **不可走 ForceClose retain**(prepaid 没有 ForceClose,与 deposit 不同)
|
||
|
|
> - 长期失联(>2 年)走业务流程(类似 deposit 的 retain,但 prepaid 当前没有内建机制,需运维介入)
|
||
|
|
|
||
|
|
## 异常分支
|
||
|
|
|
||
|
|
- 退一部分余下继续用 → [[refund-partial-after-consume]]
|
||
|
|
- 账户 Frozen 想退 → 先 [[unfreeze-after-verification|解冻]] 再退(prepaid 没有 ForceClose)
|
||
|
|
- 关账步骤 → [[close-resident-moveout]]
|
||
|
|
|
||
|
|
## 相关文档
|
||
|
|
|
||
|
|
- [[refund-partial-after-consume]]
|
||
|
|
- [[close-resident-moveout]]
|
||
|
|
- [[account-state-machine]]
|
||
|
|
- [[transaction-types]]
|
||
|
|
- [[consume-monthly-property-bill]]
|