vault backup: 2026-05-25 23:32:57
This commit is contained in:
163
prop-acc/scenarios/prepaid/close-resident-moveout.md
Normal file
163
prop-acc/scenarios/prepaid/close-resident-moveout.md
Normal file
@@ -0,0 +1,163 @@
|
||||
---
|
||||
title: prop-acc · prepaid · 场景 - 业户搬走主动关账
|
||||
aliases:
|
||||
- 关预存款账户
|
||||
- 业户搬走关账
|
||||
- close-resident-moveout
|
||||
- 场景-预存款搬走关账
|
||||
tags:
|
||||
- 场景
|
||||
- prop-acc
|
||||
- 预存款
|
||||
- 结清
|
||||
audience:
|
||||
- 业务人员
|
||||
status: 已发布
|
||||
sub_feature: prepaid
|
||||
last_review: 2026-05-25
|
||||
code_version: 2026-05-22
|
||||
---
|
||||
|
||||
# 场景:业户搬走主动关账
|
||||
|
||||
业户搬走、走完 [[refund-full-resident-moveout|全额退余]] 后,**业务人员手动**关账户。**与 deposit 不同,prepaid 不会自动关账**(零余额仍 Active),所以这步必须手动做。
|
||||
|
||||
## 典型情境
|
||||
|
||||
> [!example] 真实情境
|
||||
> 刘先生卖了房子,昨天走 [[refund-full-resident-moveout|全额退余]] 流程退完了 ¥3,200。账户余额 0,状态仍 Active(因为 prepaid 设计如此)。物业财务今天清理时主动关掉这个账户。
|
||||
|
||||
## 业务人员视角(本场景**业户无感**)
|
||||
|
||||
> [!info] 业户视角
|
||||
> 业户已经搬走,通常**不感知**关账动作。小程序登录(若仍登)会看到账户从 ✅ Active 变 🔒 Closed,但流水照常可看。
|
||||
|
||||
### 第 1 步:确认前提
|
||||
|
||||
- 业户已搬走(房屋已过户 / 退租)
|
||||
- 余额已退完(balance = 0)
|
||||
- 无未付账单
|
||||
|
||||
### 第 2 步:打开账户
|
||||
|
||||
后台 → 预存款 → 找到刘先生账户(Active,balance=0)→ 进 `ViewPrepaidAccount`。
|
||||
|
||||
### 第 3 步:点击 `CloseAccountAction`(标签"关账")
|
||||
|
||||
> [!warning] 按钮可见性
|
||||
> 守护:`canOperate()`(Active only)+ `balance == 0` + Policy `->authorize('close')`。Frozen / 有余额账户灰化。
|
||||
|
||||
Modal 表单:
|
||||
|
||||
| 字段 | 填什么 |
|
||||
|---|---|
|
||||
| **关账事由(memo)** | 必填,如 "业户搬走,12-3-501 已过户,余额已退完" |
|
||||
|
||||
### 第 4 步:提交
|
||||
|
||||
系统调 `PrepaidAccount::close($memo)`:
|
||||
|
||||
1. 校验 `canOperate() && balance == 0`
|
||||
2. 更新 `status=Closed`
|
||||
3. 在 `meta.close_memo` 记关账事由
|
||||
4. 在 `meta.closed_at` 记关账时间
|
||||
|
||||
**不产生** PrepaidTransaction / CollectionOrder / Receipt(状态变更)。
|
||||
|
||||
### 第 5 步:无需通知业户
|
||||
|
||||
业户已搬走,通知意义不大。后台档案有完整记录(开户 → 历次充值 / 消费 → 退款 → 关账)。
|
||||
|
||||
## 系统流程
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant 财务
|
||||
participant Filament
|
||||
participant PrepaidAccount
|
||||
participant 数据库
|
||||
|
||||
Note over 财务: 业户搬走,退余已完成,balance=0
|
||||
|
||||
财务->>Filament: ViewPrepaidAccount → CloseAccountAction(memo)
|
||||
Filament->>PrepaidAccount: close(memo)
|
||||
PrepaidAccount->>PrepaidAccount: canOperate() && balance==0? yes
|
||||
PrepaidAccount->>数据库: 更新 status=Closed, meta.close_memo, meta.closed_at
|
||||
数据库-->>Filament: ok
|
||||
Filament-->>财务: 成功
|
||||
|
||||
Note over 数据库: 无 Transaction / CO / Receipt
|
||||
```
|
||||
|
||||
## 完整流程(退余 + 关账)
|
||||
|
||||
业户搬走的**完整两步**:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant 业户
|
||||
participant 财务
|
||||
participant Filament
|
||||
participant Account
|
||||
|
||||
业户->>财务: 我要搬走,退预存款
|
||||
财务->>Filament: RefundAction (全额)
|
||||
Filament->>Account: refund() → balance 0, status 仍 Active
|
||||
|
||||
Note over Filament: prepaid 不自动关账,需手动
|
||||
|
||||
财务->>Filament: CloseAccountAction
|
||||
Filament->>Account: close() → status=Closed
|
||||
财务-->>业户: 退款 + 关账完成
|
||||
```
|
||||
|
||||
## 与 deposit 关账的差异
|
||||
|
||||
| 维度 | deposit close-after-zero-balance(自动)| prepaid close(本场景,手动)|
|
||||
|---|---|---|
|
||||
| 触发 | 最后一笔 refund/forfeit 使 balance=0 时自动 | 业务人员手动点 CloseAccountAction |
|
||||
| 是否需 CloseAction | 不需要(自动)| **需要** |
|
||||
| 业务背景 | 押金业务完结 | 业户搬走、长期不用 |
|
||||
| 业务人员介入度 | 0 | 1 次操作 |
|
||||
|
||||
## 常见问题
|
||||
|
||||
> [!question] 业户没搬走但想关账户?
|
||||
> 看具体情况:
|
||||
> - **业户主动要求关**:不推荐(以后想用还得开新户,**一户一账约束阻塞**)。建议劝业户留 Active 账户,余额 0 不影响什么
|
||||
> - **业户彻底不想用预存款**:走 [[refund-full-resident-moveout|全额退]] → 本场景关账
|
||||
>
|
||||
> 关闭账户是**业务终态**,反悔代价大。
|
||||
|
||||
> [!question] 没退完余额能关账吗?
|
||||
> **不能**。`CloseAccountAction` 守护 `balance == 0`。要关必须先退完。这与 deposit 一致。
|
||||
|
||||
> [!question] 关账后能反悔重开吗?
|
||||
> 不能(`canBeReopened` 永远 false)。新业务**开新账户**,但**一户一账阻塞**(详见 [[one-account-per-resident]] "已知设计 gap")。
|
||||
|
||||
> [!question] 业务上批量关账(例如批量清理多年未用的零余额账户)有功能吗?
|
||||
> 当前没有。如果要清理 100+ 账户,需要 List 页加批量操作,或运维 tinker。**优先级不高** —— 零余额 Active 账户对业务影响小,不主动清理也可。
|
||||
|
||||
> [!question] 关账后流水台账还能看吗?
|
||||
> 能。Closed 账户**只读模式**保留全部历史,流水台账 / Receipt 都可查询。
|
||||
|
||||
> [!question] 关账时业户还有未付账单怎么办?
|
||||
> 不会触发系统校验(系统不主动联动 Bill 模块),但**业务上是大问题**:
|
||||
> - 业户搬走 + 余额已退 + 关账户 → 未付账单挂业户身上
|
||||
> - 业户搬走后催收困难
|
||||
>
|
||||
> **预防** = 关账前业务人员**手动核对** 该业户是否有未付账单,有 → 先 [[consume-monthly-property-bill|抵清]] 再关账。
|
||||
|
||||
## 异常分支
|
||||
|
||||
- 余额非 0 想关 → 先退完([[refund-full-resident-moveout]] / [[refund-partial-after-consume]])
|
||||
- Frozen 账户想关 → 先 [[unfreeze-after-verification|解冻]] 再退再关
|
||||
- 余额 0 但不想关(业户可能还用)→ [[close-with-zero-balance-decision]]
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [[refund-full-resident-moveout]]
|
||||
- [[close-with-zero-balance-decision]]
|
||||
- [[account-state-machine]]
|
||||
- [[one-account-per-resident]]
|
||||
- [[../deposit/close-after-zero-balance]](deposit 自动关账对比)
|
||||
199
prop-acc/scenarios/prepaid/close-with-zero-balance-decision.md
Normal file
199
prop-acc/scenarios/prepaid/close-with-zero-balance-decision.md
Normal file
@@ -0,0 +1,199 @@
|
||||
---
|
||||
title: prop-acc · prepaid · 场景 - 余额清零后不自动关,业户决定
|
||||
aliases:
|
||||
- 零余额不自动关账
|
||||
- 余额 0 决策
|
||||
- close-with-zero-balance-decision
|
||||
- 场景-预存款零余额决策
|
||||
tags:
|
||||
- 场景
|
||||
- prop-acc
|
||||
- 预存款
|
||||
- 结清
|
||||
audience:
|
||||
- 业户
|
||||
- 业务人员
|
||||
status: 已发布
|
||||
sub_feature: prepaid
|
||||
last_review: 2026-05-25
|
||||
code_version: 2026-05-22
|
||||
---
|
||||
|
||||
# 场景:余额清零后不自动关,业户决定
|
||||
|
||||
业户预存款账户**余额自然变为 0**(消费抵扣完 / 退款完),账户**保持 Active**,等业户决定继续充值复用,还是主动 [[close-resident-moveout|关账]]。突出 prepaid 与 deposit 在零余额行为上的关键差异。
|
||||
|
||||
## 典型情境
|
||||
|
||||
> [!example] 真实情境
|
||||
> 张阿姨预存款账户余额 ¥800,5 月物业费账单 ¥800,业务人员抵扣后**余额 = 0**。
|
||||
>
|
||||
> 账户**仍 Active** —— 系统没自动关。张阿姨有 3 个选择:
|
||||
>
|
||||
> 1. **继续用**:下月再充值,账户复用,啥都不操作
|
||||
> 2. **主动关账**:不想用预存款了,联系物业关账
|
||||
> 3. **不管**:留 Active 零余额账户,以后想用再充
|
||||
|
||||
## 业户视角
|
||||
|
||||
### 您会感受到什么
|
||||
|
||||
- 推送通知:"5 月物业费 ¥800 已抵扣,**余额 ¥0**"
|
||||
- 小程序"我的预存款"显示 "✅ Active,余额 ¥0"
|
||||
- **账户没关**,仍可用(若有钱)
|
||||
|
||||
### 您要做什么(三选一)
|
||||
|
||||
#### 选项 1:继续用(默认,推荐)
|
||||
|
||||
什么都不用做。下次想用预存款付账单,先充值:
|
||||
|
||||
- 走 [[deposit-additional-topup|追加充值]]
|
||||
- 充值后余额非 0,继续抵账单
|
||||
|
||||
适合:**长期居住业户**,预存款是日常工具。
|
||||
|
||||
#### 选项 2:主动关账
|
||||
|
||||
如果决定**不再使用预存款**(例如转用现金 / 微信付每月账单):
|
||||
|
||||
- 联系物业(电话 / 微信 / 前台)
|
||||
- 业务人员走 [[close-resident-moveout|关账]] 流程
|
||||
|
||||
适合:**业户偏好不变**(决定不再用预存款服务)、**搬走**等长期事件。
|
||||
|
||||
> [!warning] 关账后想反悔?
|
||||
> 关账永久不可逆。如果以后又想用,**理论上**重开,但**一户一账约束阻塞**(详见 [[one-account-per-resident]] "已知设计 gap")。保险起见:不确定就**不要关**。
|
||||
|
||||
#### 选项 3:留 Active 不管
|
||||
|
||||
什么都不做。账户保持 Active + 余额 0:
|
||||
|
||||
- 不影响业户
|
||||
- 占用一条数据库记录(微不足道)
|
||||
- 后续可能在 [[audit-low-balance-and-overdue|审计]] 里被标记"长期零余额",业务人员可能主动联系您确认
|
||||
|
||||
适合:**犹豫**(可能以后会用)、**短期没决定**。
|
||||
|
||||
## 业务人员视角
|
||||
|
||||
### 通常无需操作
|
||||
|
||||
零余额 Active 账户**默认保留**,不主动清理。理由:
|
||||
|
||||
| 理由 | 说明 |
|
||||
|---|---|
|
||||
| 业户随时可能继续充值 | 关了再开成本大(一户一账约束)|
|
||||
| 业务上无伤害 | 账户余额 0,不挂账、不欠款、不占资金 |
|
||||
| 清理意义低 | 数据量不大,清理工时 > 收益 |
|
||||
| 自动关风险大 | "自动关账后业户充值要重新开,体验差" |
|
||||
|
||||
### 何时主动关
|
||||
|
||||
只在以下情况业务人员主动关:
|
||||
|
||||
| 情况 | 关账理由 |
|
||||
|---|---|
|
||||
| 业户搬走 | 业务终结,清爽 |
|
||||
| 业户明确说"不再用预存款" | 用户决定 |
|
||||
| 账户长期闲置(>2 年)且业户长期失联 | 清账类似 [[audit-low-balance-and-overdue]] 处理 |
|
||||
|
||||
### 操作
|
||||
|
||||
走 [[close-resident-moveout|主动关账]] 流程,Modal 表单 memo 填具体原因。
|
||||
|
||||
## 与 deposit 的关键差异(再次强调)
|
||||
|
||||
| 维度 | deposit 零余额 | **prepaid 零余额(本场景)** |
|
||||
|---|---|---|
|
||||
| 自动关账 | ✅ 是,最后一笔 refund/forfeit 触发 | ❌ **保持 Active** |
|
||||
| 业户感知 | 收到最后一张红字收据 + 自动关账通知 | **无感**(余额 0 但账户 Active)|
|
||||
| 业务人员介入 | 不需要 | 视需求决定 |
|
||||
| 设计哲学 | 押金 = 业务节点性,完结即关 | 预存款 = 长期工具,清零不等于终结 |
|
||||
|
||||
## 系统流程(消费导致清零)
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant 业户
|
||||
participant 业务
|
||||
participant Filament
|
||||
participant Account
|
||||
participant 数据库
|
||||
|
||||
Note over Account: balance=800,有 800 物业费账单
|
||||
|
||||
业务->>Filament: ConsumeAction(800)
|
||||
Filament->>Account: consume(bill, 800)
|
||||
Account->>数据库: 建 CO(type=Bill, +800) + PrepaidTransaction(consume, 800→0)
|
||||
Account->>数据库: **balance=0, status=Active(不变)**
|
||||
Account->>监听器: 触发 CollectionOrderCompleted
|
||||
监听器->>数据库: 建 Receipt("物业费 ¥800")
|
||||
Account->>数据库: 提交
|
||||
|
||||
Note over Account: balance=0 但 Active
|
||||
|
||||
Filament-->>业务: 完成
|
||||
业务-->>业户: 推送"5 月物业费已抵扣,余额 ¥0"
|
||||
|
||||
Note over 业户: 业户选择:继续用 / 关账 / 不管
|
||||
```
|
||||
|
||||
## 流水台账(本场景)
|
||||
|
||||
| 流水 | type | amount | balance_before | balance_after | 备注 |
|
||||
|---|---|---|---|---|---|
|
||||
| ... | (前面省略)| | | | |
|
||||
| N | consume | 800 | 800 | 0 | 5 月物业费抵扣 |
|
||||
|
||||
账户 `status` 保持 Active,无关账动作。
|
||||
|
||||
## 常见问题
|
||||
|
||||
> [!question] 为什么 prepaid 设计成不自动关账?
|
||||
> 详见 [[account-state-machine]] "零余额不自动关账" 段。简言之:
|
||||
>
|
||||
> - 一户一账,关了重开成本大(unique 约束)
|
||||
> - 业户长期可能复用
|
||||
> - 业务高频,频繁开关无意义
|
||||
|
||||
> [!question] 系统层面有"零余额超 N 个月自动关账" job 吗?
|
||||
> 没有,也**不推荐加**。零余额 Active 账户无害,自动关账反而引发业户"为什么我账户被关了"的客服压力。
|
||||
|
||||
> [!question] 业户登录小程序看到余额 0,会困惑吗?
|
||||
> 不会(理论上)。小程序界面应清楚显示:
|
||||
> - 余额:¥0
|
||||
> - 状态:Active
|
||||
> - 行动按钮:"立即充值"(显眼)
|
||||
> - 流水:可看历史
|
||||
>
|
||||
> 业户清楚看到"我可以充值继续用"。
|
||||
|
||||
> [!question] 业户问"我账户还在用吗?"
|
||||
> 看状态:
|
||||
> - Active + 余额 > 0:正常用
|
||||
> - Active + 余额 = 0:**仍在用,但需要充值才能抵账单**
|
||||
> - Frozen:暂停中,联系物业了解
|
||||
> - Closed:已关闭,不再使用
|
||||
|
||||
> [!question] 退到 0 的退款流程跟消费到 0 的流程一样吗?
|
||||
> 状态机层面**完全一样** —— 都保持 Active。不同点:
|
||||
> - 消费到 0:走 [[consume-monthly-property-bill]] 等抵扣场景
|
||||
> - 退款到 0:走 [[refund-full-resident-moveout]] 或 [[refund-partial-after-consume]] 之类的退款场景
|
||||
>
|
||||
> 两种动作都**不触发**自动关账。
|
||||
|
||||
## 异常分支
|
||||
|
||||
- 业户决定关账 → [[close-resident-moveout]]
|
||||
- 业户决定继续用 → [[deposit-additional-topup|追加充值]]
|
||||
- 长期零余额累积成审计问题 → [[audit-low-balance-and-overdue]]
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [[account-state-machine]]
|
||||
- [[close-resident-moveout]]
|
||||
- [[deposit-additional-topup]]
|
||||
- [[refund-full-resident-moveout]]
|
||||
- [[../deposit/close-after-zero-balance]](deposit 自动关账对比)
|
||||
- [[../deposit/close-manual-with-zero-balance]](deposit 主动关空账户对比)
|
||||
196
prop-acc/scenarios/prepaid/freeze-suspected-fraud.md
Normal file
196
prop-acc/scenarios/prepaid/freeze-suspected-fraud.md
Normal file
@@ -0,0 +1,196 @@
|
||||
---
|
||||
title: prop-acc · prepaid · 场景 - 疑似欺诈风控冻结
|
||||
aliases:
|
||||
- 冻结预存款账户
|
||||
- 风控冻结
|
||||
- freeze-suspected-fraud
|
||||
- 场景-预存款风控冻结
|
||||
tags:
|
||||
- 场景
|
||||
- prop-acc
|
||||
- 预存款
|
||||
- 冻结
|
||||
audience:
|
||||
- 业务人员
|
||||
- 风控
|
||||
status: 已发布
|
||||
sub_feature: prepaid
|
||||
last_review: 2026-05-25
|
||||
code_version: 2026-05-22
|
||||
---
|
||||
|
||||
# 场景:疑似欺诈风控冻结
|
||||
|
||||
物业财务 / 风控发现某预存款账户**有可疑迹象**(短时间大额充值、与其他账户关联异常、业户身份疑问等),先冻结账户,禁止任何资金动作,核实后再决定解冻或关账。
|
||||
|
||||
## 典型情境
|
||||
|
||||
> [!example] 真实情境
|
||||
> 平台风控系统发现:
|
||||
>
|
||||
> - **王女士**(15-7-203)预存款账户**昨天充了 ¥50,000**(往常月充值 < ¥3,000)
|
||||
> - 同时,该业户绑定的微信号**昨天给 3 个不同预存款账户**各转了 ¥10,000-¥20,000(不像本人正常操作)
|
||||
> - 业户报备的手机号**昨天突然变更**
|
||||
>
|
||||
> 风控团队判断:**疑似账户被盗 / 洗钱嫌疑**。先**冻结**所有相关账户,联系业户核实。
|
||||
|
||||
## 业务人员视角(风控 + 财务)
|
||||
|
||||
### 第 1 步:风控触发
|
||||
|
||||
风控团队识别异常 → 通知物业财务 → 财务在系统层立即冻结。
|
||||
|
||||
### 第 2 步:打开账户
|
||||
|
||||
后台 → 预存款 → 找到王女士账户(Active,balance=50000+原余额)→ 进 `ViewPrepaidAccount`。
|
||||
|
||||
### 第 3 步:点击 `FreezeAccountAction`(标签"冻结")
|
||||
|
||||
> [!warning] 按钮可见性
|
||||
> 守护:`canBeFreezed()`(等价 Active)+ Policy `->authorize('freeze')`。Frozen / Closed 灰化。
|
||||
|
||||
Modal 表单:
|
||||
|
||||
| 字段 | 填什么 |
|
||||
|---|---|
|
||||
| **冻结事由(reason)** | **必填且详细**,如 "风控:24h 内大额异常充值 + 微信关联多账户 + 手机号变更,疑似账户被盗" |
|
||||
|
||||
### 第 4 步:提交
|
||||
|
||||
系统调 `PrepaidAccount::freeze($reason)`:
|
||||
|
||||
1. 校验 `canBeFreezed()`(Active only)
|
||||
2. 更新 `status=Frozen`
|
||||
3. 在 `meta.freeze_reason` 记冻结事由
|
||||
4. 在 `meta.frozen_at` 记冻结时间
|
||||
|
||||
**不产生** `PrepaidTransaction`、**不产生** `CollectionOrder`、**不产生** `Receipt`(纯状态变更)。
|
||||
|
||||
### 第 5 步:通知 + 调查
|
||||
|
||||
- 通知业户:"您的预存款账户已冻结,事由 XXX,请联系物业核实身份"
|
||||
- 联系业户本人(已知手机号 + 业户备用联系方式),核实近期操作是否本人
|
||||
- 如果是本人 → 解释 + 解冻;如果不是本人 → 走风控 / 法务流程
|
||||
|
||||
## 业户视角
|
||||
|
||||
### 您会感受到什么
|
||||
|
||||
- 收到通知:"您的预存款账户已冻结,事由:风控异常,请联系物业核实"
|
||||
- 小程序"我的预存款"显示 "🧊 冻结"
|
||||
- 想充值 → 失败,提示"账户冻结"
|
||||
- 想抵账单 → 失败,提示"账户冻结"
|
||||
- 想退款 → 失败,提示"账户冻结"
|
||||
- 余额仍可见(只读)
|
||||
|
||||
### 您要做什么
|
||||
|
||||
立即联系物业(电话 / 微信 / 上门),核实:
|
||||
|
||||
- 近期充值 / 退款是不是您本人操作
|
||||
- 手机号变更是不是您本人申请
|
||||
- 提供身份证 / 房产证等核实身份
|
||||
|
||||
| 核实结果 | 后续 |
|
||||
|---|---|
|
||||
| 是本人,正常操作 | 物业解冻,详见 [[unfreeze-after-verification]] |
|
||||
| 不是本人(账户被盗 / 微信号被盗)| 走风控流程,可能 retain 账户等司法处理 |
|
||||
| 不是本人(他人冒充)| 走法务流程,资金可能扣留待裁决 |
|
||||
|
||||
## 系统流程
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant 风控
|
||||
participant 财务
|
||||
participant Filament
|
||||
participant PrepaidAccount
|
||||
participant 数据库
|
||||
participant 业户
|
||||
|
||||
Note over 风控: 检测异常充值 + 关联微信号
|
||||
|
||||
风控->>财务: 告警,要求冻结王女士账户
|
||||
财务->>Filament: ViewPrepaidAccount → FreezeAccountAction(reason)
|
||||
Filament->>PrepaidAccount: freeze(reason)
|
||||
PrepaidAccount->>PrepaidAccount: canBeFreezed()? Active=true
|
||||
PrepaidAccount->>数据库: 更新 status=Frozen, meta.freeze_reason, meta.frozen_at
|
||||
数据库-->>财务: ok
|
||||
Filament-->>财务: 成功
|
||||
|
||||
Note over 数据库: 冻结期间所有 deposit/consume/refund 调用都拦截
|
||||
|
||||
财务->>业户: 通知冻结 + 要求核实
|
||||
```
|
||||
|
||||
## 冻结期间的能力对照
|
||||
|
||||
| 操作 | Active | Frozen |
|
||||
|---|---|---|
|
||||
| `DepositAction`(充值)| ✅ | ❌(`canOperate=false`)|
|
||||
| `ConsumeAction`(消费抵扣)| ✅ | ❌ |
|
||||
| `RefundAction`(退款)| ✅ | ❌ |
|
||||
| `FreezeAccountAction`(冻结)| ✅ | ❌(已是 Frozen)|
|
||||
| `ReactivateAccountAction`(解冻)| ❌(已是 Active)| ✅ |
|
||||
| `CloseAccountAction`(关账)| ✅(balance=0)| ❌(必须先解冻)|
|
||||
| 看账户 / 看流水 | ✅ | ✅(只读)|
|
||||
|
||||
> [!info] 与 deposit 关键差异:**没有 ForceClose**
|
||||
> deposit 在 Frozen + 有余额困境时可以走 ForceClose(refund/forfeit/retain 三种 disposition)直接关账。**prepaid 没有这条路径** —— 一户一账 + 业户基本是本人,纠纷场景罕见,设计上简化。
|
||||
>
|
||||
> 真要"关 Frozen 账户":
|
||||
> 1. 先 [[unfreeze-after-verification|解冻]] 回 Active
|
||||
> 2. 再退余 + 关账
|
||||
> 3. 如果完全不能解冻(业户被司法冻结之类),账户**一直留 Frozen**,运维介入
|
||||
|
||||
## 真实情境(二):月初批量自动抵扣误冻
|
||||
|
||||
> [!example] 反例:误冻结
|
||||
> 风控系统某次误报,把正常业户王女士的账户冻结了。月初自动抵扣 job 跑到她账户时,因 Frozen 跳过,她的物业费没扣。
|
||||
>
|
||||
> 业户次月发现欠费,投诉。物业核实是误冻,立即 [[unfreeze-after-verification|解冻]],手动 ConsumeAction 补抵账单。
|
||||
|
||||
误冻的代价比 deposit 大,因为 prepaid 是**业户日常用的钱包**,误冻一天就让业户感觉服务出问题。**冻结前务必充分判断**。
|
||||
|
||||
## 常见问题
|
||||
|
||||
> [!question] 冻结期间业户能查询余额吗?
|
||||
> 能。只读。可以看到余额、流水、状态(Frozen)、冻结事由。
|
||||
|
||||
> [!question] 冻结后业务人员可以做什么?
|
||||
> - 看账户和流水(只读)
|
||||
> - 走 `ReactivateAccountAction` 解冻
|
||||
> - 不能充值 / 消费 / 退款(全部按钮灰)
|
||||
> - 不能关账(必须先解冻)
|
||||
> - **不能 ForceClose**(prepaid 没这功能)
|
||||
|
||||
> [!question] 风控应该多严?误报代价大不大?
|
||||
> 误报代价:
|
||||
> - 业户感知 = 服务异常 = 投诉
|
||||
> - 业务人员介入解释 + 解冻 = 工作量
|
||||
> - 严重影响信任
|
||||
>
|
||||
> 漏报代价:
|
||||
> - 真欺诈未拦截 = 资金损失 / 法律风险
|
||||
>
|
||||
> **建议**:风控规则宽严平衡,人工审核 + 紧急冻结。冻结前优先**主动联系业户核实**,确认异常再冻。
|
||||
|
||||
> [!question] 业户失联或不配合核实怎么办?
|
||||
> 长期 Frozen 状态保留。资金留在账户(`balance`),业户出现可解冻。**prepaid 没有 retain 机制**,长期失联走业务流程(类似 deposit retain,运维 / 法务介入)。
|
||||
|
||||
> [!question] 冻结期间业户能在小程序看到原因吗?
|
||||
> 看 UI 设计。**推荐** 在小程序的"账户状态"页显示 `meta.freeze_reason` 的对外友好版本(去掉技术细节,如"账户冻结中,请联系物业了解详情")。
|
||||
|
||||
## 异常分支
|
||||
|
||||
- 误冻 → 立即 [[unfreeze-after-verification|解冻]]
|
||||
- 核实后正常 → [[unfreeze-after-verification|解冻]] → 继续用
|
||||
- 核实后确认被盗 / 欺诈 → 走法务流程,资金可能 retain 等司法
|
||||
- 业户已失联 → 留 Frozen,等业户出现
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [[account-state-machine]]
|
||||
- [[unfreeze-after-verification]]
|
||||
- [[exception-refund-on-frozen]]
|
||||
- [[../deposit/freeze-during-dispute]](deposit 冻结场景对比)
|
||||
168
prop-acc/scenarios/prepaid/refund-partial-after-consume.md
Normal file
168
prop-acc/scenarios/prepaid/refund-partial-after-consume.md
Normal file
@@ -0,0 +1,168 @@
|
||||
---
|
||||
title: prop-acc · prepaid · 场景 - 部分消费后退余(不自动关账)
|
||||
aliases:
|
||||
- 部分退预存款
|
||||
- 退一部分留账户
|
||||
- refund-partial-after-consume
|
||||
- 场景-预存款部分退余
|
||||
tags:
|
||||
- 场景
|
||||
- prop-acc
|
||||
- 预存款
|
||||
- 退款
|
||||
audience:
|
||||
- 业户
|
||||
- 业务人员
|
||||
status: 已发布
|
||||
sub_feature: prepaid
|
||||
last_review: 2026-05-25
|
||||
code_version: 2026-05-22
|
||||
---
|
||||
|
||||
# 场景:部分消费后退余(不自动关账)
|
||||
|
||||
业户**部分使用**预存款后,想**退余下一部分**(不全退,继续保留账户)。退完仍 Active,业户可后续继续充值复用。本场景突出 prepaid 与 deposit 的**关键差异**:零余额不自动关账,部分余额更不会。
|
||||
|
||||
## 典型情境
|
||||
|
||||
> [!example] 真实情境
|
||||
> 陈先生 3 个月前充了 ¥5,000 预存款,期间扣了 ¥2,400(3 个月物业费),余额 ¥2,600。他最近现金流紧张,想**先退 ¥1,500 应急**,留 ¥1,100 在账户继续扣物业费。
|
||||
|
||||
## 业户视角
|
||||
|
||||
### 第 1 步:跟物业说要退一部分
|
||||
|
||||
- "我想从预存款退 ¥1,500,留点继续用"
|
||||
- 提供退款渠道
|
||||
|
||||
### 第 2 步:等退款
|
||||
|
||||
- 业务人员核实余额、操作
|
||||
|
||||
### 第 3 步:收到红字收据 + 退款
|
||||
|
||||
- 红字收据"预付款退款 ¥-1,500"
|
||||
- 银行 / 微信收到 ¥1,500
|
||||
|
||||
### 第 4 步:账户保持 Active
|
||||
|
||||
- 小程序"我的预存款"显示余额 ¥1,100
|
||||
- 仍可继续抵账单
|
||||
- 后续可继续充值
|
||||
|
||||
> [!info] 与 deposit 的核心差异
|
||||
> deposit 退完余额到 0 会自动 Closed。prepaid **退完无论余额多少都不自动关**,业户随时可继续用。
|
||||
|
||||
## 业务人员视角
|
||||
|
||||
### 第 1 步:打开账户
|
||||
|
||||
后台 → 预存款 → 陈先生账户(Active,balance=2600)→ 进 `ViewPrepaidAccount`。
|
||||
|
||||
### 第 2 步:`RefundAction` Modal
|
||||
|
||||
| 字段 | 填什么 |
|
||||
|---|---|
|
||||
| **退款金额** | **¥1,500**(不是全额,**手动改**)|
|
||||
| 退款渠道 | 微信 / 银行 |
|
||||
| 备注 | 选填,如 "业户申请部分退款" |
|
||||
|
||||
> [!warning] 易错点
|
||||
> Modal 默认带入**当前余额全额**(¥2,600)。**必须手动改为 ¥1,500**,否则就成了全退。
|
||||
|
||||
### 第 3 步:提交
|
||||
|
||||
系统调 `RefundFromPrepaidAccountAction`,事务内:
|
||||
|
||||
1. 校验 `canOperate()`
|
||||
2. 校验金额 ≤ 余额(1500 ≤ 2600 ✓)
|
||||
3. 建 `CollectionOrder`(`type=Prepaid`,`actual=-1500` 红字,`Completed`)
|
||||
4. 调 `account.refund(1500)`:
|
||||
- 加 `PrepaidTransaction`(type=refund, 2600→1100,关联 CO)
|
||||
- 更新 balance=1100
|
||||
5. **不关账**(余额非 0)
|
||||
6. 触发监听器 → Receipt"预付款退款 ¥-1,500"
|
||||
|
||||
### 第 4 步:走线下退款 + 给收据
|
||||
|
||||
银行 / 微信退 ¥1,500;红字收据交业户。**账户保持 Active,余额 ¥1,100**。
|
||||
|
||||
### 第 5 步:告知业户
|
||||
|
||||
"已退 ¥1,500,账户还有 ¥1,100 可继续抵账单"。
|
||||
|
||||
## 系统流程
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant 业户
|
||||
participant 财务
|
||||
participant Filament
|
||||
participant 数据库
|
||||
|
||||
Note over 业户: 余额 2600,要退 1500
|
||||
|
||||
业户->>财务: 退 1500
|
||||
财务->>Filament: ViewPrepaidAccount → RefundAction(modal, **改成 1500**)
|
||||
Filament->>数据库: RefundFromPrepaidAccountAction
|
||||
数据库->>数据库: 建 CO(-1500 红字) + PrepaidTransaction(refund, 2600→1100)
|
||||
数据库->>数据库: balance=1100(**不关账**)
|
||||
数据库->>监听器: 触发监听器 → Receipt("预付款退款 ¥-1,500")
|
||||
财务-->>业户: 微信退 1500 + 红字收据 + 告知余额 1100
|
||||
```
|
||||
|
||||
## 流水台账(累计)
|
||||
|
||||
| 流水 | 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** | **refund** | **1500** | **2600** | **1100** | **本场景** |
|
||||
|
||||
账户余额 ¥1,100,**仍 Active**,后续可继续抵账单或充值。
|
||||
|
||||
## 与 deposit 退款的差异
|
||||
|
||||
| 维度 | deposit 部分退款(refund-partial-after-forfeit) | prepaid 部分退款(本场景) |
|
||||
|---|---|---|
|
||||
| 退款产生的 CO 类型 | type=Deposit, -N 红字 | type=Prepaid, -N 红字 |
|
||||
| 退完余额 0 | **自动 Closed** | **仍 Active** |
|
||||
| 退完余额非 0 | 仍 Active(deposit 也允许部分退后继续动)| 仍 Active |
|
||||
| 业务背景 | 押金扣罚 + 退余 | 业户应急需现金,部分提取 |
|
||||
|
||||
## 常见问题
|
||||
|
||||
> [!question] 退完余额变 0,会自动关账吗?
|
||||
> **不会**。即使全退到 0,prepaid 仍保持 Active。详见 [[account-state-machine]]"零余额不自动关账"段 + [[close-with-zero-balance-decision]]。
|
||||
|
||||
> [!question] 业务人员退多了(改余额时手抖)?
|
||||
> 系统会校验 `amount ≤ balance` 守护拦截。例如余额 2600,改成 3000 提交 → 抛错 "amount exceeds balance"。**预防**:Modal 提交前再三确认数字。
|
||||
|
||||
> [!question] 业户想退完了又改主意,要充回去?
|
||||
> 当然可以。直接走 [[deposit-additional-topup|追加充值]] 把钱充回账户即可。账户一直 Active 没动过。
|
||||
|
||||
> [!question] 业户拿到红字收据后困惑"我没买东西啊为什么收据是负数"?
|
||||
> 解释:
|
||||
> - 红字 = 钱从物业流出 / 回到您手里
|
||||
> - 这不是消费收据,是退款收据
|
||||
> - 详见 [[../deposit/red-receipt-design]](deposit 模块的概念,prepaid 复用相同设计)
|
||||
|
||||
> [!question] 业户问"我现在余额 1100,还能扣账单吗?"
|
||||
> 当然能。账户 Active,余额 > 0,正常用。物业费下月扣完后余额会变 ¥300(假设 ¥800 月费)。
|
||||
|
||||
## 异常分支
|
||||
|
||||
- 全额退 → [[refund-full-resident-moveout]]
|
||||
- Frozen 状态退 → 先 [[unfreeze-after-verification]] 再退
|
||||
- 退完想关账 → 走 [[close-with-zero-balance-decision]]
|
||||
- 业户搬走全退 + 关账 → [[refund-full-resident-moveout]] + [[close-resident-moveout]]
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [[refund-full-resident-moveout]]
|
||||
- [[account-state-machine]]
|
||||
- [[close-with-zero-balance-decision]]
|
||||
- [[transaction-types]]
|
||||
- [[../deposit/red-receipt-design]]
|
||||
180
prop-acc/scenarios/prepaid/unfreeze-after-verification.md
Normal file
180
prop-acc/scenarios/prepaid/unfreeze-after-verification.md
Normal file
@@ -0,0 +1,180 @@
|
||||
---
|
||||
title: prop-acc · prepaid · 场景 - 核实后解冻
|
||||
aliases:
|
||||
- 解冻预存款账户
|
||||
- 风控核实后解冻
|
||||
- unfreeze-after-verification
|
||||
- 场景-预存款解冻
|
||||
tags:
|
||||
- 场景
|
||||
- prop-acc
|
||||
- 预存款
|
||||
- 冻结
|
||||
audience:
|
||||
- 业务人员
|
||||
- 风控
|
||||
status: 已发布
|
||||
sub_feature: prepaid
|
||||
last_review: 2026-05-25
|
||||
code_version: 2026-05-22
|
||||
---
|
||||
|
||||
# 场景:核实后解冻
|
||||
|
||||
[[freeze-suspected-fraud|冻结]] 后,物业核实业户身份和操作合法性,**解冻账户**回到 Active,业户继续正常使用。是冻结的对称操作。
|
||||
|
||||
> [!info] Action 名称的历史
|
||||
> 解冻的 Action 在代码里叫 **`ReactivateAccountAction`**(字面"重新激活"),但**实际行为只允许 Frozen → Active**(等价解冻)。UI 文案已统一为"解冻",图标 `lock-open`,与 deposit 模块对齐。详见 [[account-state-machine]]"ReactivateAccountAction = 解冻"段。
|
||||
|
||||
## 典型情境
|
||||
|
||||
> [!example] 真实情境
|
||||
> 王女士的预存款账户因风控异常被冻结(详见 [[freeze-suspected-fraud]])。物业联系她核实:
|
||||
>
|
||||
> - 确认昨天大额充值是**本人操作**(她准备一次性存够全年物业费)
|
||||
> - 微信号给其他账户转钱是给亲戚朋友转账,与预存款无关(只是该微信刚好绑了多个预存款账户在风控规则下触发了关联)
|
||||
> - 手机号变更是因为旧号停用,她已到运营商办手续
|
||||
>
|
||||
> 物业核实后:王女士身份属实、所有操作合法。**立即解冻**。
|
||||
|
||||
## 业务人员视角
|
||||
|
||||
### 第 1 步:核实业户身份与操作
|
||||
|
||||
- 业户当面 / 视频 / 公证 提供身份证 + 房产证 / 租赁合同
|
||||
- 核对近期操作是否本人(看充值时间、IP、设备)
|
||||
- 核对手机号变更证明(运营商凭证)
|
||||
- 核对资金来源说明(若大额异常)
|
||||
|
||||
> [!warning] 核实必须留书面凭证
|
||||
> - 业户签字声明
|
||||
> - 微信 / 邮件确认截图
|
||||
> - 任何后续争议时的依据
|
||||
|
||||
### 第 2 步:打开账户
|
||||
|
||||
后台 → 预存款 → 找到王女士账户(Frozen)→ 进 `ViewPrepaidAccount`。
|
||||
|
||||
状态显示 "🧊 Frozen",右上角只有 `ReactivateAccountAction`(标签"解冻")可点,其他写入按钮全灰。
|
||||
|
||||
### 第 3 步:点击解冻
|
||||
|
||||
> [!warning] 按钮可见性
|
||||
> 守护:`status === Frozen` + Policy `->authorize('unfreeze')`。
|
||||
>
|
||||
> **修过的语义**:历史代码允许 `!= Active` 都可见(等于"既能撤销 Frozen 也能撤销 Closed"),issue.md Q4 改为**只允许 Frozen → Active**,等价解冻,**禁止从 Closed 撤销关账**。
|
||||
|
||||
Modal 表单:
|
||||
|
||||
| 字段 | 填什么 |
|
||||
|---|---|
|
||||
| **解冻事由(reason)** | 必填,如 "风控核实:大额充值与微信转账均为本人操作,手机号变更已凭运营商证明确认" |
|
||||
|
||||
### 第 4 步:提交
|
||||
|
||||
系统调 `PrepaidAccount::unfreeze($reason)`(或同名方法):
|
||||
|
||||
1. 校验 status === Frozen
|
||||
2. 更新 `status=Active`
|
||||
3. 在 `meta.unfreeze_reason` 记解冻事由
|
||||
4. 在 `meta.unfrozen_at` 记解冻时间
|
||||
5. (可选)`meta.freeze_history[]` 追加这次冻结-解冻的完整记录
|
||||
|
||||
**不产生** PrepaidTransaction(状态变更,无资金动作)。
|
||||
|
||||
### 第 5 步:通知业户
|
||||
|
||||
- "您的预存款账户已解冻,现可正常使用"
|
||||
- 业务人员 / 运维监督看后续是否有异常
|
||||
|
||||
## 业户视角
|
||||
|
||||
### 您会感受到什么
|
||||
|
||||
- 收到通知:"您的预存款账户已解冻,事由:经核实身份与操作合法"
|
||||
- 小程序"我的预存款"显示 "✅ Active"
|
||||
- 充值 / 消费 / 退款 重新可用
|
||||
- 余额未变(冻结期间不动)
|
||||
|
||||
### 您要做什么
|
||||
|
||||
继续正常用账户。建议:
|
||||
|
||||
- 留意自己账户的异常操作
|
||||
- 重要变更(手机号、绑定微信)及时告知物业
|
||||
- 大额充值(>10000)建议提前告知物业,避免风控误报
|
||||
|
||||
## 系统流程
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant 业户
|
||||
participant 物业
|
||||
participant Filament
|
||||
participant PrepaidAccount
|
||||
participant 数据库
|
||||
|
||||
Note over 业户,物业: 核实业户身份和操作合法
|
||||
|
||||
业户->>物业: 提供身份证 / 房产证 / 操作说明
|
||||
物业->>物业: 核实通过
|
||||
物业->>Filament: ViewPrepaidAccount → ReactivateAccountAction(reason)
|
||||
Filament->>PrepaidAccount: unfreeze(reason)
|
||||
PrepaidAccount->>PrepaidAccount: status === Frozen? yes
|
||||
PrepaidAccount->>数据库: 更新 status=Active, meta.unfreeze_reason
|
||||
数据库-->>Filament: ok
|
||||
Filament-->>物业: 成功
|
||||
物业->>业户: 通知解冻
|
||||
|
||||
Note over 业户: 后续正常充值 / 消费 / 退款
|
||||
```
|
||||
|
||||
## 流水台账(本场景不动)
|
||||
|
||||
| 流水 | 说明 |
|
||||
|---|---|
|
||||
| (无)| 解冻是状态变更,无资金动作 |
|
||||
|
||||
只有 `PrepaidAccount.status` 字段从 Frozen → Active,`meta` 多几个审计字段。
|
||||
|
||||
## 与 deposit 解冻的差异
|
||||
|
||||
| 维度 | deposit unfreeze-after-mediation | prepaid 解冻(本场景) |
|
||||
|---|---|---|
|
||||
| 业务上下文 | 押金纠纷调解 | 风控核实 / 误冻撤销 |
|
||||
| Action 名 | `UnfreezeAction` | `ReactivateAccountAction`(字面历史包袱) |
|
||||
| 后续操作 | 调解结果决定 refund / forfeit | 直接恢复使用 |
|
||||
| 通常频率 | 中(押金纠纷有时间区) | 罕见(风控误报)|
|
||||
|
||||
## 常见问题
|
||||
|
||||
> [!question] 误冻立即解冻可以吗?
|
||||
> 可以,且**推荐立即**。误冻每多挂一分钟,业户体验越差。
|
||||
|
||||
> [!question] 解冻后业户能立即充值 / 消费吗?
|
||||
> 能。解冻是同步事务,提交后立即生效。
|
||||
|
||||
> [!question] 多次冻结-解冻同一账户会有问题吗?
|
||||
> 不会。账户可以在 `Active ↔ Frozen` 之间多次切换。如果业务上常见,`meta.freeze_history[]` 数组(若已实现)记历次完整记录。
|
||||
|
||||
> [!question] 解冻后业户再次触发风控怎么办?
|
||||
> 重复 [[freeze-suspected-fraud|冻结]] 流程 → 这次更严格核实。多次触发风控的业户可能是真的高风险,需法务介入。
|
||||
|
||||
> [!question] 解冻必须要书面凭证吗?
|
||||
> 系统层面不强制(`reason` 字段非空即可)。**业务层面强烈推荐**,留书面凭证防纠纷。
|
||||
|
||||
> [!question] 解冻能从 Closed 状态做吗?
|
||||
> **不能**。`ReactivateAccountAction` 只允许 Frozen → Active。Closed 永久(`canBeReopened` 永远 false)。这是 issue.md Q4 第二轮明确修的语义。
|
||||
|
||||
## 异常分支
|
||||
|
||||
- 核实不通过(确认欺诈)→ 留 Frozen,法务介入
|
||||
- 业户长期不出现 → 留 Frozen,等业户出现或法律时效
|
||||
- 解冻后再次异常 → 重新 [[freeze-suspected-fraud|冻结]]
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [[freeze-suspected-fraud]]
|
||||
- [[account-state-machine]]
|
||||
- [[exception-refund-on-frozen]]
|
||||
- [[../deposit/unfreeze-after-mediation]](deposit 解冻场景对比)
|
||||
Reference in New Issue
Block a user