vault backup: 2026-05-25 22:32:40

This commit is contained in:
Willie
2026-05-25 22:32:40 +08:00
parent 963d432d62
commit 68ea6dfbe9
6 changed files with 833 additions and 5 deletions

View File

@@ -0,0 +1,163 @@
---
title: prop-acc · deposit · 场景 - 业户纠纷期间冻结账户
aliases:
- 冻结押金账户
- 纠纷冻结
- freeze-during-dispute
- 场景-押金账户冻结
tags:
- 场景
- prop-acc
- 保证金
- 冻结
audience:
- 业户
- 业务人员
status: 已发布
sub_feature: deposit
last_review: 2026-05-25
code_version: 2026-05-22
---
# 场景:业户纠纷期间冻结账户
业户和物业**就扣罚 / 退款 / 损坏归责发生纠纷**,沟通陷入僵局。物业先把账户**冻结**(任何资金动作禁止),等调解结果。
## 典型情境
> [!example] 真实情境
> 陈先生家装修完了,物业验收发现公共走道墙面损坏要扣 ¥800。陈先生坚持"墙是装修前就坏的,跟我没关系,拒绝扣罚"。物业找施工方核实暂无定论,**预计要 1-2 周走调解**。这段时间不能让账户继续动 —— 不能让陈先生提退款,也不能强行扣罚。物业先冻结账户。
## 业户视角
### 您会感受到什么
- 想申请退押金 → 物业说"账户冻结中,等纠纷处理完才能退"
- 微信小程序"我的押金账户"显示"⏸ 冻结"
- 不会被强行扣钱(冻结期间扣罚也不允许)
- 不会丢钱(余额冻结,只是不让动)
- 收到通知:"您的押金账户已冻结,事由:XXX"
> [!info] 冻结不等于扣钱
> 冻结只是**暂停所有资金动作**,余额仍是您的钱,等纠纷处理完会做正确处置(退 / 扣 / 部分扣余下退)。
### 您要做什么
- 配合物业调解(提供装修前后照片、施工合同等证据)
- 不要单方面追讨(系统层面已挡住,纠纷不在系统层面解决)
- 调解有结果后通知物业操作(走 [[unfreeze-after-mediation|解冻]] 或 [[force-close-refund|强制关账]] 等)
## 业务人员视角(物业财务 + 物业管理)
### 第 1 步:决定冻结
触发场景:
- 业户对扣罚归责有异议
- 装修方与业户之间纠纷,押金归属不明
- 涉及司法 / 仲裁,资金需保留待裁决
- 业户失联但有未决业务(暂留 Active 不合适)
### 第 2 步:打开账户
后台 → 保证金 → 账户列表 → 找到陈先生账户(Active,balance=5000)→ 进入 `ViewDepositAccount`
### 第 3 步:点击 `FreezeAction`(标签"冻结")
右上角状态管理组。Modal 表单:
| 字段 | 填什么 |
|---|---|
| **冻结事由(reason)** | 必填,如 "业户对墙面损坏归责有异议,等待第三方核查" |
| **预计冻结时长** | 选填,如 "2 周" |
> [!warning] Policy 守护
> `FreezeAction` 调 `DepositAccount::canBeFreezed()`:仅 Active 状态可冻。Frozen / Closed 状态下按钮灰化。
### 第 4 步:提交
系统调 `DepositAccount::freeze(reason)`,事务内:
1. 校验 `canBeFreezed()`(Active only)
2. 更新 `status=Frozen`
3.`meta.freeze_reason` 记冻结事由(可选)
4.`meta.frozen_at` 记冻结时间
**注意:不产生 DepositTransaction**(冻结不是资金动作,只是状态变更)。
### 第 5 步:通知业户
后台 → 短信 / 微信通知陈先生"账户已冻结,事由 XXX,预计解冻时间 XXX"。
## 系统流程
```mermaid
sequenceDiagram
participant 业户
participant 财务
participant Filament
participant 数据库
Note over 业户,财务: 业户与物业就 800 扣罚分歧,调解中
财务->>Filament: ViewDepositAccount → FreezeAction(modal, reason)
Filament->>数据库: 校验 canBeFreezed() (Active=true, ok)
Filament->>数据库: 更新 status=Frozen + meta.freeze_reason
数据库-->>Filament: ok
Filament-->>财务: 成功通知
Note over 数据库: 冻结期间所有 deposit/refund/forfeit 调用都会被守护拦截
```
## 冻结状态下的能力对照
| 操作 | Active 状态 | Frozen 状态 |
|---|---|---|
| `DepositAction`(缴款)| ✅ | ❌(`canDeposit=false`)|
| `RefundAction`(退款)| ✅ | ❌(`canWithdraw=false`)|
| `ForfeitureAction`(扣罚)| ✅ | ❌(`canWithdraw=false`)|
| `FreezeAction`(冻结)| ✅ | ❌(已是 Frozen)|
| `UnfreezeAction`(解冻)| ❌(已是 Active)| ✅ |
| `CloseAction`(关账)| ✅(余额 0) | ❌(必须先解冻再关)|
| `ForceCloseAction`(强制关账)| ❌ | ✅(`isFrozen && hasBalance`)|
| 看账户 / 看流水 | ✅ | ✅(只读)|
> [!info] Frozen + 有余额 + 想关账 = 用 ForceClose
> Frozen 状态下既不能退也不能扣,但万一就是要终结此账户(纠纷长期无果、业户失联多年、法律保留期满等),走 [[force-close-refund]] / [[force-close-forfeit]] / [[force-close-retain]]。详见 [[account-state-machine]]。
## 常见问题
> [!question] 冻结后能解冻吗?
> 当然能,走 [[unfreeze-after-mediation]]。冻结是临时状态,设计上就是"暂停"。
> [!question] 冻结期间业户能查询余额吗?
> 能。**只读**,业户看得到余额、流水台账、状态(Frozen)、冻结事由。
> [!question] 冻结期间业户能在小程序申请退款吗?
> 看小程序设计。当前 Action 假设手工触发,业户的小程序申请只是一个**业务申请单**,系统不会自动执行退款。物业人工处理时仍会被 `canWithdraw=false` 守护拦截,自然走流程。
> [!question] 冻结理由必填吗?
> 系统层面不强制(`reason` 参数可选)。**业务层面强烈推荐填**,审计追溯、调解复盘、与业户沟通都需要。
> [!question] 冻结时间长了系统会自动解冻吗?
> **不会**。冻结是手工操作,解冻也是手工。如果业务上需要"30 天自动解冻"之类的策略,需要单独写定时任务,但不推荐 —— 调解周期不固定,自动解冻容易在错误的时机解开。
> [!question] 多次冻结会有多个冻结理由吗?
> 当前只有 1 个 `meta.freeze_reason` 字段(后写覆盖前写)。如果想保留历史,可以在解冻时把当前 reason 抄进 `meta.freeze_history[]` 数组,再清空 `freeze_reason`。当前业务量未必需要,先简单实现。
> [!question] 冻结期间能改账户的其他字段吗?
> 看 Policy。当前 Policy 允许 update(改 payer 信息、备注等),但不允许 delete。如果有更严的"冻结期间什么都不能改"需求,在 `DepositAccountPolicy::update()` 加 `!isFrozen()` 检查。
## 异常分支
- 误冻结 → [[unfreeze-after-mediation]] 解开(reason 改 "误操作解除")
- 长期冻结无解 → [[force-close-refund]] / [[force-close-forfeit]] / [[force-close-retain]]
- 冻结期间业户失联 → 留 Frozen 到法律保留期满 → [[force-close-retain]]
## 相关文档
- [[account-state-machine]]
- [[unfreeze-after-mediation]]
- [[force-close-refund]]
- [[exception-deposit-on-frozen]]
- [[forfeit-damage-public-area]]