Compare commits

..

2 Commits

Author SHA1 Message Date
Willie
92f3c6698e meter 子模块 · 轮 2:14 场景 + 知识地图收尾
写 14 个场景到 prop-acc/scenarios/meter/,覆盖 4 类业务:

📦 表管理(4):
- init-new-community-batch(新社区批量建表 + 初始读数 Excel 导入,
  走 MeterInitializationImporter + BaseImporter chunk rollback)
- register-single-meter(单独新增一张表,陈先生厨房分户表)
- replace-broken-meter(换表场景,旧表 5000 → 新表 -R1 后缀 + initial 5000 继承,
  ReplaceMeterAction 完整流程)
- decommission-without-replacement(退役不换表,3 种典型情境:
  房屋拆除 / 商铺撤店 / 法定年限到)

📊 抄表(4):
- read-single-meter-manual(后台单录,李师傅集抄掉线补抄)
- read-batch-via-excel-import(MeterReadingsImporter + 模板下载流程 +
  双义列名 silent corruption 已知风险)
- read-via-iot-remote-source(集抄系统对接,API + 防重放 + 与 deposit/prepaid 集成)
- read-with-photo-proof(物理表头照片,业户争议时关键凭证)

💰 账单生成(3):
- generate-bill-tiered-pricing(progressive 累进算法完整算例 35 吨水的三段计算,
  对比 full-tier 简陋实现)
- generate-bill-with-multiplier(工业表 multiplier=10 算例 + 抄表员录入注意事项)
- generate-bill-min-max-cap(漏水 max 封顶 + 零用量 min 兜底 + 正常范围三情境)

🛡️ 异常/审计(3):
- exception-high-consumption(HighConsumptionReadingsListWidget 预警 +
  分级处置 + 完整排查流程)
- exception-readings-locked-after-bill(双锁机制下的修正流程,当前手工 +
  未来 VoidBillAction 设计目标态,issue.md Q5 待补)
- audit-meters-needing-reading(MetersNeedingReadingListWidget +
  月度完成率 99% 目标 + 月度报告模板)

每篇结构:典型情境 → 业户/抄表员/业务人员视角 → 系统流程(mermaid)→
对比表 / 算例 → 常见问题 → 异常分支 → 相关文档(WikiLinks)。

meter 模块特性在场景中持续强调:
- 物理硬件维度(非抽象账户)
- 不直接产 Receipt(走 Bill 中转)
- 三层业务分层(Calculator + Service + Action)
- 双锁机制(创建即不可改 + 有 Bill 更严)
- 抄表来源 + 拍照存证 + 集抄对接
- progressive 累进 vs full-tier 简陋实现的设计正确性
- 倍率 + 阶梯 + min/max 三层叠加算法

收尾:
- prop-acc/maps/meter-knowledge-map.md:14 场景全部 ,加完成 callout
- prop-acc/maps/knowledge-map.md:meter 行状态改 " 21 篇"
- prop-acc/index.md:同步

meter 子模块完整覆盖:6 概念 + 14 场景 + 1 知识地图 = 21 篇。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 00:31:08 +08:00
Willie
6bdaa31017 vault backup: 2026-05-26 00:28:09 2026-05-26 00:28:09 +08:00
8 changed files with 1048 additions and 25 deletions

View File

@@ -197,6 +197,9 @@
},
"active": "849c5ff8936a2b67",
"lastOpenFiles": [
"prop-acc/scenarios/meter/exception-readings-locked-after-bill.md",
"prop-acc/scenarios/meter/exception-high-consumption.md",
"prop-acc/scenarios/meter/generate-bill-min-max-cap.md",
"prop-acc/scenarios/meter/generate-bill-with-multiplier.md",
"prop-acc/scenarios/meter/generate-bill-tiered-pricing.md",
"prop-acc/scenarios/meter/read-with-photo-proof.md",
@@ -222,9 +225,6 @@
"prop-acc/scenarios/prepaid/close-with-zero-balance-decision.md",
"prop-acc/scenarios/prepaid/close-resident-moveout.md",
"prop-acc/scenarios/prepaid/unfreeze-after-verification.md",
"prop-acc/scenarios/prepaid/freeze-suspected-fraud.md",
"prop-acc/scenarios/prepaid/refund-partial-after-consume.md",
"prop-acc/scenarios/prepaid/refund-full-resident-moveout.md",
"prop-acc/scenarios/prepaid",
"prop-acc/concepts/prepaid",
"prop-acc/scenarios/deposit",

View File

@@ -26,7 +26,7 @@ last_review: 2026-05-25
| **一次性收费** | IC 卡、装修证、泳票等单次购买 | [adhoc 知识地图](maps/adhoc-knowledge-map.md) | ✅ 28 篇 |
| **保证金** | 装修押金等代管资金,完工后退还 | [deposit 知识地图](maps/deposit-knowledge-map.md) | ✅ 25 篇 |
| **预存款** | 业户预存,自动抵扣月度账单 | [prepaid 知识地图](maps/prepaid-knowledge-map.md) | ✅ 23 篇 |
| **计量表** | 水表/电表/燃气表,抄表生成账单 | [meter 知识地图](maps/meter-knowledge-map.md) | 🟡 6 概念已完成,14 场景待补 |
| **计量表** | 水表/电表/燃气表,抄表生成账单 | [meter 知识地图](maps/meter-knowledge-map.md) | ✅ 21 篇 |
| **账单** | 周期性账单 + 计量账单 | _待补_ | 🚧 |
| **收款订单** | 一次收款的支付方式、银行账户记录 | _待补_ | 🚧 |
| **收据** | 成功收款后生成的凭证 | _待补_ | 🚧 |

View File

@@ -22,7 +22,7 @@ last_review: 2026-05-25
| adhoc | 一次性收费 | IC 卡、装修证、泳票等单次购买 | [adhoc 知识地图](adhoc-knowledge-map.md) | ✅ 25 场景 + 3 概念 |
| prepaid | 预存款 | 业户预存,自动抵扣月度账单 | [prepaid 知识地图](prepaid-knowledge-map.md) | ✅ 16 场景 + 6 概念 + 1 地图 = 23 篇 |
| deposit | 保证金 | 装修押金等代管资金,完工后退还 | [deposit 知识地图](deposit-knowledge-map.md) | ✅ 18 场景 + 6 概念 + 1 地图 = 25 篇 |
| meter | 计量表 | 水表/电表/燃气表,抄表生成账单 | [meter 知识地图](meter-knowledge-map.md) | 🟡 6 概念已完成,14 场景待补 |
| meter | 计量表 | 水表/电表/燃气表,抄表生成账单 | [meter 知识地图](meter-knowledge-map.md) | ✅ 14 场景 + 6 概念 + 1 地图 = 21 篇 |
| billing | 账单 | 周期性账单 + 计量账单 | _待补_ | 🚧 |
| payment-order | 收款订单 | 一次收款的支付方式、银行账户记录 | _待补_ | 🚧 |
| receipt | 收据 | 成功收款后生成的凭证 | _待补_ | 🚧 |

View File

@@ -60,35 +60,33 @@ code_version: 2026-05-22
| [抄表来源与拍照存证](../concepts/meter/reading-source-and-photo-proof.md) | `manual` 手抄 vs `remote` 集抄 + `photo_url` 凭证,业户争议时的证据 |
| [表退役与读数锁定](../concepts/meter/decommission-and-locking.md) | 5 种退役原因 + Reading 双锁机制(创建即不可改,有 Bill 更不可改) |
## 场景手册(14 篇,**待补充 ✋**)
> 🚧 概念骨架已就位,场景文档将在下一轮(轮 2)产出。预定结构如下。
## 场景手册(14 篇,**全部完成 ✅**)
### 📦 表管理(4 篇)
- 🚧 [新社区批量建表 + 初始读数 Excel 导入](../scenarios/meter/init-new-community-batch.md)
- 🚧 [单独新增一张表(后台单录)](../scenarios/meter/register-single-meter.md)
- 🚧 [换表:旧表故障/退役,新表带 -R1 后缀,初始读数继承](../scenarios/meter/replace-broken-meter.md)
- 🚧 [退役不换表(房屋拆除 / 业户永久弃用)](../scenarios/meter/decommission-without-replacement.md)
- [新社区批量建表 + 初始读数 Excel 导入](../scenarios/meter/init-new-community-batch.md)
- [单独新增一张表(后台单录)](../scenarios/meter/register-single-meter.md)
- [换表:旧表故障/退役,新表带 -R1 后缀,初始读数继承](../scenarios/meter/replace-broken-meter.md)
- [退役不换表(房屋拆除 / 业户永久弃用)](../scenarios/meter/decommission-without-replacement.md)
### 📊 抄表(4 篇)
- 🚧 [单张表后台手动录入](../scenarios/meter/read-single-meter-manual.md)
- 🚧 [一次导入整月所有读数(Excel 批量)](../scenarios/meter/read-batch-via-excel-import.md)
- 🚧 [集抄系统自动推送(`source=remote`)](../scenarios/meter/read-via-iot-remote-source.md)
- 🚧 [抄表拍照存证(物理表头照片)](../scenarios/meter/read-with-photo-proof.md)
- [单张表后台手动录入](../scenarios/meter/read-single-meter-manual.md)
- [一次导入整月所有读数(Excel 批量)](../scenarios/meter/read-batch-via-excel-import.md)
- [集抄系统自动推送(`source=remote`)](../scenarios/meter/read-via-iot-remote-source.md)
- [抄表拍照存证(物理表头照片)](../scenarios/meter/read-with-photo-proof.md)
### 💰 账单生成(3 篇)
- 🚧 [阶梯水电价生成账单(progressive 累进算例)](../scenarios/meter/generate-bill-tiered-pricing.md)
- 🚧 [工业表 10x 倍率生成账单](../scenarios/meter/generate-bill-with-multiplier.md)
- 🚧 [单笔账单上下限封顶(防异常用量爆账)](../scenarios/meter/generate-bill-min-max-cap.md)
- [阶梯水电价生成账单(progressive 累进算例)](../scenarios/meter/generate-bill-tiered-pricing.md)
- [工业表 10x 倍率生成账单](../scenarios/meter/generate-bill-with-multiplier.md)
- [单笔账单上下限封顶(防异常用量爆账)](../scenarios/meter/generate-bill-min-max-cap.md)
### 🛡️ 异常 / 审计(3 篇)
- 🚧 [高用量异常(漏水 / 电器故障),`HighConsumptionReadingsListWidget` 预警](../scenarios/meter/exception-high-consumption.md)
- 🚧 [已生成 Bill 的 Reading 锁定,要修正需作废 Bill](../scenarios/meter/exception-readings-locked-after-bill.md)
- 🚧 [待抄表清单 + 月度抄表完成率(`MetersNeedingReadingListWidget`)](../scenarios/meter/audit-meters-needing-reading.md)
- [高用量异常(漏水 / 电器故障),`HighConsumptionReadingsListWidget` 预警](../scenarios/meter/exception-high-consumption.md)
- [已生成 Bill 的 Reading 锁定,要修正需作废 Bill](../scenarios/meter/exception-readings-locked-after-bill.md)
- [待抄表清单 + 月度抄表完成率(`MetersNeedingReadingListWidget`)](../scenarios/meter/audit-meters-needing-reading.md)
## 跨域引用
@@ -129,6 +127,9 @@ code_version: 2026-05-22
---
> [!info] 概念已完成,场景待补
> 本轮(轮 1)产出:6 个概念 + 本子模块地图 + 域总图更新。
> 下一轮(轮 2)产出:14 个场景文档,基于本知识地图骨架填充。
> [!success] meter 子模块:6 概念 + 14 场景 + 1 知识地图 = **21 篇完成**
>
> 写作日期:2026-05-26
> 对应代码版本:2026-05-22(详见 `packages/prop-acc/issue.md` Q5 段)
>
> 如果发现遗漏的场景或需要补充的细节,告诉我,可以单独补充新文档。

View File

@@ -0,0 +1,261 @@
---
title: prop-acc · meter · 场景 - 待抄表清单 + 月度抄表完成率
aliases:
- 待抄表清单
- 抄表完成率
- audit-meters-needing-reading
- MetersNeedingReadingListWidget
- 场景-待抄表审计
tags:
- 场景
- prop-acc
- 计量表
- 审计
audience:
- 业务人员
- 财务
- 抄表员
status: 已发布
sub_feature: meter
last_review: 2026-05-26
code_version: 2026-05-22
---
# 场景:待抄表清单 + 月度抄表完成率
物业**月底**核对:本月**应抄**多少张表(在役表数)vs **已抄**多少张(本月有 reading 的表)。差额 = **待抄表清单**(可能是抄表员漏抄 / 集抄掉线)。`MetersNeedingReadingListWidget``MeterDashboard` 实时显示。
## 典型情境
> [!example] 真实情境
> 5 月 28 日王主管打开 `MeterDashboard`,看 `MetersNeedingReadingListWidget`:
>
> - 嘉禾花园在役表 1,200 张
> - 本月已抄 1,150 张
> - **待抄 50 张**
>
> 分析:
> - 30 张:集抄掉线(`source=remote` 应自动推但没推)
> - 15 张:抄表员遗漏(手抄区域漏了)
> - 5 张:业户家无人无法入户读表
>
> 5/30 截止前必须补齐(否则当月账单缺漏)。
## 业务人员视角
### Widget 显示
`MetersNeedingReadingListWidget`(MeterDashboard):
| 列 | 内容 |
|---|---|
| 业户 / 资产 | 房号 + 业户姓名 |
| 表编号 | meter code |
| 费用类型 | 水/电/燃气 |
| 上次抄表日期 | 上月 read_at |
| 抄表来源 | manual / remote(看历史)|
| 状态 | 未抄 / 部分缺漏 |
| 操作 | 链接到该 meter 的录入入口 |
排序:**按上次抄表日期升序**(最久没抄的优先,可能问题最大)。
### 完成率计算
```
本月完成率 = 本月已抄表数 / 在役表总数
= 1150 / 1200
= 95.8%
```
业务上通常**目标 > 99%**(漏抄太多说明流程有问题)。
### 分级处置
| 待抄类型 | 数量 | 处置 |
|---|---|---|
| 集抄掉线 | 30 | 联系集抄运营商 + 抄表员现场补抄 |
| 抄表员漏抄 | 15 | 抄表员立即补抄 |
| 业户无人 | 5 | 多次上门 / 与业户约时间 / 估算用量(罕见) |
### 处理流程
```mermaid
flowchart TD
A[Widget 显示 50 张待抄] --> B{分类}
B -->|集抄掉线 30 张| C[联系集抄运营商]
C --> D{原因}
D -->|网关故障| E[运营商修复 → 重推数据]
D -->|个别表故障| F[抄表员现场补抄 + 走 replace-broken-meter]
B -->|抄表员漏抄 15 张| G[立即补抄]
B -->|业户无人 5 张| H[多次上门 / 约时间]
H --> I{约不上}
I -->|是| J[估算用量 / 用 min_amount 兜底 / 延后处理]
I -->|否| G
E --> K[完成率回升]
F --> K
G --> K
```
### 月度执行清单
每月最后一周(25-30 号),业务人员清单:
- [ ] 25 号:看 Widget,记录待抄数 + 分类
- [ ] 26-28 号:跟进集抄运营商 + 抄表员补抄
- [ ] 29 号:再看 Widget,核对剩余待抄
- [ ] 30 号:截止前完成 99%+,剩余的特殊处理
- [ ] 月初(1 号):看完成率报告 + 触发账单生成
## 抄表员视角(李师傅)
### 自己的清单
抄表员手机 App 上显示**本月分配的清单**(类似 widget 但只显示自己负责的区域)。
每天进度:
- 上午:看清单 + 规划路线
- 现场抄表 + 拍照 + 录入
- 下午回办公室:补录 / 同步
完成度自我管理。月底向王主管报告:"本月我负责的 X 张表已完成 Y 张,剩 Z 张是 [原因] 需 [协助]"。
## `MetersNeedingReadingListWidget` 实现
> [!info] 当前实现的逻辑
>
> SQL 大概:
>
> ```sql
> -- 在役表里,本月没有 reading 的
> SELECT m.*, MAX(r.read_at) AS last_read_at
> FROM acc_meters m
> LEFT JOIN acc_meter_readings r ON r.meter_id = m.id
> WHERE m.is_active = true
> AND m.community_id = ?
> -- 本月起没有 reading
> AND m.id NOT IN (
> SELECT meter_id FROM acc_meter_readings
> WHERE read_at BETWEEN '2026-05-01' AND '2026-05-31 23:59:59'
> )
> GROUP BY m.id
> ORDER BY last_read_at ASC;
> ```
>
> 关键:
> - 只看在役表(退役表 `is_active=false` 不算)
> - "本月没 reading" = 待抄
> - "上次抄表日期久远" = 优先级高
## 报表 / 周报
王主管月初出报告(给物业总经理 / 财务总监):
```markdown
# 2026 年 5 月 嘉禾花园抄表完成率报告
## 总览
- 在役表:1,200 张
- 本月已抄:1,200 张(目标 99%,实际 100%)
- 完成率:100% ✅
## 抄表来源分布
- 集抄(remote):1,160 张(96.7%)
- 手抄(manual):40 张(3.3%)
- 集抄掉线补抄:30 张
- 业户无人后多次上门:10 张
## 异常事件
- 集抄掉线高峰:5/25 一天 30 张(网关故障 4 小时,运营商已修)
- 单户长期无人:王先生(15-7-203),已联系成功 + 补抄
## 趋势
- 4 月完成率 99.8%(漏 2 张次月补)
- 5 月完成率 100%(全部当月完成)
- 集抄稳定性提升(运营商升级了网关)
## 建议
- 与集抄运营商签更严的 SLA(网关掉线 < 1 小时)
- 给抄表员增加"无人户备份方案"(预约 + 业户授权代抄)
```
## 业户视角
业户**通常不感知**这个审计动作。极少数情况:
| 业户场景 | 业户感知 |
|---|---|
| 业户无人导致漏抄,下月补 | 收到的下月账单可能比往常高(两个月用量)|
| 集抄掉线导致补抄 | 物业可能上门 / 微信问"麻烦看下您家水表读数发我下" |
| 长期补不上 | 物业按"平均月用量"估算账单(业户可能不爽)|
## 与其他审计的对比
| 审计场景 | 关注什么 | 频率 |
|---|---|---|
| **本场景(待抄表)** | 月度抄表完成率 | 月度 |
| [[exception-high-consumption|高用量预警]] | 异常用量预防 | 月度(抄表完成后)|
| [[../deposit/audit-monthly-deposit-balance|押金月度对账]] | 账面 vs 银行平衡 | 月度 |
| [[../prepaid/audit-low-balance-and-overdue|预存款低余额]] | 业户预存款健康度 | 每周 / 月度 |
各模块审计**频率与关注点不同**,本场景是 meter 模块的**最重要月度审计**。
## 常见问题
> [!question] 完成率 < 95% 的常见原因?
> - 集抄设备大面积故障
> - 抄表员人手不足
> - 业户长期无人 / 拒绝抄表
> - 系统 bug(meter 状态错乱)
>
> 长期完成率低 → 升级集抄 / 改流程 / 加人手。
> [!question] 漏抄的表下月一起算可以吗?
> 可以,但**业户体验差**(账单突然翻倍)。推荐:
> - 当月尽量补齐
> - 实在补不齐 → 让业户**自报**读数(业务上接受,需核对)
> - 估算用量(罕见,看物业政策)
> [!question] 业户长期无人怎么办?
> - 多次上门(2-3 次)
> - 业户授权代抄(物业拿钥匙 / 业户邻居代抄)
> - 估算用量(按往月平均算)
> - 长期(> 6 个月)无人 → 标记为"特殊处理户",月度估算 / 等业户回来再补
> [!question] 集抄运营商频繁掉线,物业如何制约?
> 合同 SLA:
> - 集抄运营商承诺 99% 在线率
> - 违约罚款(掉线超 X 小时罚 Y 元)
> - 严重违约 → 解约换供应商
> [!question] 漏抄但已经生成账单(只是少了 N 户)能补充生成吗?
> 可以。补抄 → 录 reading → 触发 [[bill-generation-pipeline|GenerateBills]] 对新 reading 生成 Bill。已有 Bill 不受影响。
## 升级机会(待补)
`MetersNeedingReadingListWidget` 当前简版,可升级为:
- **更精准的"待抄"判定**(按抄表周期,不一定按月)
- **完成率趋势图**(月度趋势线)
- **抄表员效率排名**(谁抄得快 / 准)
- **预警机制**(月底前 7 天若完成率 < 90% 自动告警)
## 异常分支
- 高用量预警(完成抄表后)→ [[exception-high-consumption]]
- 已生成 Bill 的 reading 错(本场景兜底)→ [[exception-readings-locked-after-bill]]
- 集抄系统 → [[read-via-iot-remote-source]]
- 单录补抄 → [[read-single-meter-manual]]
## 相关文档
- [[bill-generation-pipeline]]
- [[exception-high-consumption]]
- [[exception-readings-locked-after-bill]]
- [[read-via-iot-remote-source]]
- [[read-single-meter-manual]]
- [[../deposit/audit-monthly-deposit-balance]](类似月度对账模式)

View File

@@ -0,0 +1,239 @@
---
title: prop-acc · meter · 场景 - 高用量异常(漏水/电器故障)
aliases:
- 高用量预警
- 漏水告警
- exception-high-consumption
- HighConsumptionReadingsListWidget
- 场景-高用量异常
tags:
- 场景
- prop-acc
- 计量表
- 异常
audience:
- 业务人员
- 业户
- 抄表员
status: 已发布
sub_feature: meter
last_review: 2026-05-26
code_version: 2026-05-22
---
# 场景:高用量异常(漏水/电器故障)
业户**用量异常**(漏水 / 电器故障 / 偷电),系统通过 `HighConsumptionReadingsListWidget` 在月度抄表数据出来后**主动预警**,业务人员介入排查,避免账单生成后业户暴击 / 投诉。
## 典型情境
> [!example] 真实情境
> 5 月底集抄 / 批量抄表完成,王主管打开 `MeterDashboard`:
>
> - `HighConsumptionReadingsListWidget` 显示 **本月用量 top 20** 的 reading
> - 其中前 3 名:
>
> | 业户 | 表 | 上月 | 本月 | 用量 | 异常? |
> |---|---|---|---|---|---|
> | 张阿姨(12-3-501) | 水表 | 12 吨 | **800 吨** | 800 | 🔴 极度异常(漏水) |
> | 陈先生(12-3-502) | 电表 | 200 度 | **2,800 度** | 2,800 | 🔴 异常高(空调故障 / 偷电) |
> | 商铺一楼餐厅 | 电表 | 1,500 度 | **3,200 度** | 3,200 | 🟡 警告(正常波动?旺季?)|
>
> 王主管立即处理。
## 业务人员视角
### Widget 显示
`HighConsumptionReadingsListWidget`(后台 → MeterDashboard):
| 列 | 内容 |
|---|---|
| 业户 / 资产 | 房号 + 业户姓名 |
| 表编号 | meter code |
| 上月用量 | previous reading 推出 |
| 本月用量 | consumption |
| 倍数 | 本月 / 上月 |
| 抄表日期 | read_at |
| 操作 | 链接到 reading 详情 / 查看 / 联系业户 |
排序:**按 consumption 降序 top 20**(简版实现,详见下方"待补")。
### 分级处置
| 级别 | 触发 | 处置 |
|---|---|---|
| 🔴 **极度异常**(>10× 历史平均) | 漏水 / 大型故障 | 立即联系业户 + 派人现场检查 |
| 🔴 **高异常**(>3× 历史平均) | 设备故障 / 习惯改变 | 联系业户确认 |
| 🟡 **警告**(>1.5× 历史平均) | 正常波动 / 季节性 | 推送提醒 / 标记观察 |
| 🟢 **正常** | < 1.5× | 不处理 |
### 处理流程(漏水案例)
```mermaid
flowchart TD
A[Widget 显示张阿姨水 800 吨] --> B[王主管联系张阿姨]
B --> C{业户回应}
C -->|"我不知道,你来看看"| D[派维修队上门]
C -->|"啊?我不可能用这么多"| D
C -->|"我装修了用水多"| E[业户接受账单]
D --> F{查到原因?}
F -->|墙内暗水管漏水| G[维修 + 重算账单]
F -->|无可见漏水点| H[换表测试是否表故障]
H --> I{换表后情况}
I -->|新表用量正常| J[确认旧表故障 + 走修正流程]
I -->|新表用量仍异常| K[排查家电 / 业户习惯]
G --> L[与业户协商:走 max 封顶/部分减免/重算]
J --> L
```
### 修正账单(若证实表故障)
如果证实是表故障 / 抄表错:
1. 走 [[replace-broken-meter|换表]]([[decommission-and-locking|退役旧表]])
2. 旧 reading 已生成 Bill → 走 [[exception-readings-locked-after-bill|作废 Bill]] 流程
3. 重新算正确用量 → 重生成 Bill
4. 业户付正确金额
## `HighConsumptionReadingsListWidget` 实现现状
> [!info] 当前实现简版,issue.md Q5 已标待升级
> 当前:**按 consumption 降序 top 20**,不是统计学意义的异常检测。
>
> issue.md Q5"待补":
>
> - **3σ 异常**(对比历史 3 个月平均的标准差)
> - **倒走告警**(current < previous)
> - **0 读数告警**(可能表故障)
>
> 当前简版的缺陷:
> - 排名靠前的可能是商铺 / 工业表(正常用量大),不是真异常
> - 漏掉"中等用量但异常波动"的住户(从 12 吨涨到 50 吨,绝对数小但相对倍数高)
> - 没区分"业户家用电习惯变了"vs"漏水 / 故障"
业务人员**需自行判断**(看 Widget 内容 + 历史用量对照 + 联系业户)。
## 业户视角
### 您可能收到的联系
物业打电话 / 微信 / 上门:
> 张阿姨您好,您家本月水量异常高(800 吨,平时 12 吨)。请问您家最近是否有装修 / 漏水 / 大量用水活动?如有疑问,我们可派维修队上门检查。
### 您要做的
| 情况 | 您要做 |
|---|---|
| 确实在装修 / 大量用水 | 接受账单 + 看是否触发 [[generate-bill-min-max-cap|max 封顶]] 减免 |
| 不知道原因 / 怀疑漏水 | 同意物业派人上门检查 |
| 怀疑表 / 系统错 | 要求看 [[read-with-photo-proof|抄表照片]] + 派人现场再读一次 |
### 检测到漏水后的减免
物业**通常会减免**(看政策):
- 部分减免(承担一半 / 30%)
- 全免(罕见,看物业宽厚)
- 按"平时月用量"算账(常见)
- max 封顶后业户支付封顶值,差额物业承担
具体看物业与业户的协商 + 物业的"漏水维修保险"理赔。
## 系统流程
```mermaid
sequenceDiagram
participant 集抄/抄表员
participant 系统
participant Widget[HighConsumptionReadingsListWidget]
participant 王主管
participant 业户
集抄/抄表员->>系统: 推 / 录入本月 reading
系统->>系统: 建 MeterReading + 算 consumption
Note over 系统: 月度数据完成
王主管->>Widget: 打开 MeterDashboard
Widget->>系统: SELECT TOP 20 reading ORDER BY consumption DESC
系统-->>Widget: 显示 top 20 异常清单
王主管->>王主管: 看清单 → 分级处置
loop 每个 🔴 异常
王主管->>业户: 联系 + 排查
alt 漏水 / 故障
王主管->>系统: 走修正流程(换表 / 作废 Bill 重算)
else 业户认账
王主管->>系统: 接受 + 触发 max 封顶减免(若适用)
end
end
```
## 高用量的常见原因清单
| 原因 | 业户感知 | 处置 |
|---|---|---|
| **水管漏水**(墙内 / 管井) | 业户不知道,直到账单异常 | 派维修队 + 修管子 + 减免 |
| **马桶漏水**(节流阀坏) | 业户偶尔听到流水声 | 业户自修 / 物业协助 |
| **空调 24h 不关** | 业户习惯 | 业户调整 / 接受账单 |
| **旧冰箱故障**(压缩机一直跑) | 业户不知道 | 业户换冰箱 |
| **电热水器**(储热式漏电 / 一直加热) | 业户不知道 | 业户检查 |
| **业户偷电 / 绕表** | 物业 / 国家电网监管 | 法律责任 |
| **抄表错** | (系统层面)| 走 [[exception-readings-locked-after-bill|修正]] |
| **集抄数据错** | (系统层面)| 同上 |
| **表故障**(乱跳)| 业户长期感觉 | [[replace-broken-meter|换表]] |
| **大型装修 / 大量用水活动** | 业户自知 | 业户接受账单 |
## 常见问题
> [!question] Widget 显示的"top 20"是当月吗?
> 看 Widget 实现。可能是:
>
> - 本月(`read_at` 在当月)
> - 最近 30 天
> - 所有未结账 reading
>
> 业务上推荐"本月",每月初看一遍 + 月底再看一遍。
> [!question] 排查发现是抄表错 + 已经生成 Bill 了怎么办?
> 走 [[exception-readings-locked-after-bill]] 流程:作废 Bill → 修正 reading → 重生成 Bill。复杂,需运维 / 高权限介入。
> [!question] 业户漏水但拒不修怎么办?
> 物业**强烈建议** + **法律手段**(漏水可能影响楼下邻居,涉及侵权)。系统层面无法干预。
> [!question] 商铺 / 工业用户的"高用量"和住宅"高用量"判断标准应该一样吗?
> **不一样**。商铺正常用量本来就大。Widget 当前简版**无区分**,需业务人员自己判断。
>
> 升级建议:Widget 按 `asset_type`(住宅 / 商铺 / 工业)分别统计 + 各自的"异常阈值"。
> [!question] 排查后没找到原因(业户也说没漏水也没新增电器)?
> 几个可能:
> - 业户家有人偷接电(罕见)
> - 表故障(漂移)→ 换表观察一个月
> - 集抄 / 抄表系统 bug(同时多户异常?排查系统)
> [!question] 高用量预警之外,有"用量异常低"(可能业户搬走 / 表故障 0 读数)预警吗?
> 当前**无**(只有高用量 widget)。需求详见 issue.md Q5"待补"。
## 异常分支
- 排查确认是抄表错 → [[exception-readings-locked-after-bill]] 修正
- 排查确认是表故障 → [[replace-broken-meter|换表]]
- 业户接受账单 → 走 [[generate-bill-min-max-cap|max 封顶]](若适用)
- 待抄表清单(对偶场景)→ [[audit-meters-needing-reading]]
## 相关文档
- [[multiplier-and-tiered-pricing]]
- [[generate-bill-min-max-cap]]
- [[exception-readings-locked-after-bill]]
- [[replace-broken-meter]]
- [[audit-meters-needing-reading]]
- [[reading-source-and-photo-proof]]

View File

@@ -0,0 +1,249 @@
---
title: prop-acc · meter · 场景 - 已生成 Bill 的 Reading 锁定,要修正需作废 Bill
aliases:
- Reading 锁定
- 已落账 reading 修正
- exception-readings-locked-after-bill
- 作废 Bill 重算
- 场景-已落账读数修正
tags:
- 场景
- prop-acc
- 计量表
- 异常
- 数据完整性
audience:
- 业务人员
- 架构师
status: 已发布
sub_feature: meter
last_review: 2026-05-26
code_version: 2026-05-22
---
# 场景:已生成 Bill 的 Reading 锁定,要修正需作废 Bill
`MeterReading` 一经创建**不可改**;**一旦生成 Bill 更不可改 / 不可删**(双锁,见 [[decommission-and-locking]])。如果发现已落账 reading 数据错(抄表录错 / 集抄错传 / 业户质疑成功),需走**复杂修正流程**:**先作废 Bill → 改 reading(实际是建新 reading + 标旧 reading 作废)→ 重生成 Bill**。
## 典型情境
> [!example] 真实情境
> 5 月底抄表 + 自动生成账单。陈先生 5 月电费账单 ¥1,200(2,800 度,异常高,触发 [[exception-high-consumption|高用量预警]])。
>
> 物业派人排查,发现:
> - **抄表员李师傅手抖**:把 1,500 录成 2,500
> - 实际本月用量 ~1,500 度,账单应 ¥600 左右(不是 1,200)
>
> 陈先生质疑成功,物业要把账单从 1,200 改成 ~600。但:
> - **Reading 不可改**(系统层面双锁)
> - **Bill 已经生成 + 关联 reading**
>
> 需要走**作废 + 重算**的组合流程。
## 当前实施状态
> [!warning] **当前系统不支持自动化此流程**
>
> issue.md Q5 "待补"段明确记录:
>
> > **"作废已生成 Bill 的 MeterReading"组合流程**:当前 Reading 一旦生成 Bill 即锁定。要修正错误读数需要先**作废 Bill** 再改 Reading 再重新生成。这个组合流程类似 AdHocEvent 的 `VoidAction`(级联废 + 留 voided 审计),需要单独设计。等业务方明确"已收款的 Bill 应该怎么撤销"再做(可能涉及红字 Bill / 退款)。
>
> **当前替代**:运维 / 高权限人员通过 tinker 手工处理。本场景描述**业务流程层**和**未来的目标态**。
## 业务人员视角(当前手工处理)
### 第 1 步:确认要修正
- 业户质疑账单 + 提供合理证据(自家拍照 / 历史数据对照)
- 物业核对:抄表照片 / 集抄数据 / 物理表
- 内部决定:确实要修正
### 第 2 步:看账单是否已付
| 账单状态 | 处理路径 |
|---|---|
| **未付**(Unpaid)| 简单:作废 Bill → 重算 |
| **已付**(Paid,业户付现金/微信)| 复杂:作废 Bill → 业户**退款** → 重新出账单 → 业户**重付** |
| **已付**(用 [[../prepaid/consume-monthly-property-bill|预存款抵扣]])| 复杂:作废 Bill → 预存款**反向充值** → 重新出账单 → 重新抵扣 |
### 第 3 步:走"作废 Bill"流程
当前**没专用 UI** —— 联系运维 / 高权限人员:
```php
// tinker 操作示意(运维)
DB::transaction(function () use ($readingId) {
$reading = MeterReading::find($readingId);
$oldBill = Bill::find($reading->bill_id);
// 1. 作废 Bill
$oldBill->update([
'status' => BillStatus::Voided,
'voided_at' => now(),
'voided_reason' => '抄表录错,需重算',
]);
// 2. 解锁 reading(把 bill_id 设 null,让它可被处理)
$reading->update(['bill_id' => null]);
// 或者:标 reading 作废,新建一条修正 reading
$reading->update(['voided_at' => now(), 'voided_reason' => '录错']);
});
```
### 第 4 步:建修正 reading
如果走"建新 reading"路径:
```php
$correctReading = MeterReading::create([
'meter_id' => $oldReading->meter_id,
'read_at' => $oldReading->read_at, // 同抄表日期
'current_reading' => 1500, // 改成正确值
'source' => MeterReadingSource::Manual,
'operated_by' => $currentAdmin->id,
'memo' => "修正:原 reading #{$oldReading->id} 数值录错(2500 → 1500)",
]);
```
### 第 5 步:重生成 Bill
走 [[bill-generation-pipeline]]:对新 reading 调 `GenerateBillsFromMeterReadingsAction`
### 第 6 步:处理已付款的差额
如果旧账单已被业户付了:
- **业户付现金**:物业现场退差额(¥1,200 - ¥600 = ¥600)
- **微信付**:物业微信退款
- **预存款抵扣**:走"反向 consume"(技术上是 `PrepaidAccount::deposit` 把钱充回 → 然后从新账单扣)
### 第 7 步:通知业户
完整说明:
- 旧账单 ¥1,200 已作废(原因:抄表录错)
- 新账单 ¥600
- 差额已退还(或预存款已回填)
## 未来目标态(待开发)
类似 AdHocEvent 的 `VoidAction`(级联废 + 留 voided 审计):
```mermaid
sequenceDiagram
participant 业务
participant Filament
participant VoidBillAction[待开发]
participant 数据库
业务->>Filament: 找到要作废的 Bill → VoidBillAction
Filament->>VoidBillAction: handle(bill, reason)
VoidBillAction->>数据库: Bill.status=Voided + voided_reason + voided_at
VoidBillAction->>数据库: Reading.bill_id=null(解锁)
VoidBillAction->>数据库: 若已付:建红字 Receipt + 退款 / 预存款回填
Filament-->>业务: 完成
业务->>Filament: 建修正 MeterReading(同 read_at)
Filament->>数据库: 新建 reading
Filament->>VoidBillAction[GenerateBills]: handle(new reading)
数据库->>数据库: 建新 Bill(amount=正确值)
```
## 系统视角:双锁的设计意义
为什么 Reading 创建后不可改(第 1 锁)+ 有 Bill 更不可改(第 2 锁)?
| 反例(若允许改)| 后果 |
|---|---|
| 业务人员直接改 Reading 数据 | 历史 Bill 仍是旧金额,Reading 是新数据 → 不一致 |
| 改 Reading 同时改 Bill | 已付的钱怎么办?业户付了 1200 你改成 600 → 600 凭空消失 |
| 业户已付 + 物业改 Reading 改小金额 | 物业账面收入虚高(实际收 1200,账面记 600,差额 600 不知去向)|
**双锁强制**业务人员走"作废 + 重生成"流程,**留下完整审计痕迹**(旧 Bill voided + 新 Bill 创建 + 退款 / 预存款回填记录)。
## 业户视角
业户**不直接接触系统层**,只感受:
- 提出异议
- 物业核实
- 收到说明:"经核实,5 月账单 ¥1,200 是抄表录错,实际应付 ¥600。已作废原账单,新账单已发,差额 ¥600 已退到您微信"
- 收到**红字凭证**(若已付,作废 + 退款)
- 收到**新账单**
整个流程业户感知:"物业认错 + 退钱 + 重发账单",是**正面体验**(物业承认错误并改正)。
## 流水台账(完整修正过程)
| 时间 | 动作 | Reading | Bill |
|---|---|---|---|
| 5/26 | 抄表录错 | #1(current=2500, bill_id=Bill#A) | Bill#A(amount=1200, Unpaid) |
| 5/27 | 业户质疑 + 核实 | (不变) | (不变) |
| 5/30 | 作废 Bill | #1.voided=true, bill_id=null | Bill#A.status=Voided, voided_reason="抄表录错" |
| 5/30 | 建修正 reading | #2(current=1500, bill_id=null) | (无) |
| 5/30 | 重生成 Bill | #2.bill_id=Bill#B | Bill#B(amount=600, Unpaid) |
| 5/31 | 业户付款 | (不变) | Bill#B.status=Paid |
整条修正记录可审计。
## 常见问题
> [!question] 如果原账单未付,作废就行,不用退款?
> 是的。未付 → 作废 → 不开账单 → 业户没付任何钱。重生成新账单业户直接付新账单即可。
> [!question] 业户已经付了,作废 Bill 之后如何退款?
> 看付款方式:
> - **现金 / 微信 / POS**:物业按渠道退
> - **预存款抵扣**:`PrepaidAccount::deposit` 反向充值(技术上是建一笔 deposit 流水把钱"还"回预存款余额)→ 然后业户继续用预存款付新账单
>
> 当前**没自动化**,需运维 / 业务流程操作。
> [!question] 已经走过红字流程的 deposit/prepaid 模块,meter 为什么没有?
> meter 模块**直接产 Bill 不直接产 Receipt**,与 deposit/prepaid 直接产 Receipt 的模式不同。"红字 Bill" 的设计需要 Bill 模型支持(增加 `voided_at` / `voided_reason` 字段 + 业务流程),issue.md Q5 标记为"待补"。
> [!question] 抄表员经常录错怎么办?
> 系统层面:
> - 强制拍照([[reading-source-and-photo-proof]] + [[read-with-photo-proof]])
> - Form 上显示 previous 读数 + 异常告警(本月差与上月差比超过 X 倍 → 提示)
>
> 业务层面:
> - 抄表员培训
> - 关键抄表数据二次审核(双签)
> - 升级集抄([[read-via-iot-remote-source]])减少人工录入
> [!question] "修正 reading" 是建新 reading 还是改旧?
> 看实现:
> - **改旧**(直接 update)→ 简单但丢失历史(原数据没了)
> - **建新 + 标旧 voided**(推荐)→ 复杂但完整保留审计
>
> 当前 issue.md 倾向"建新 + 标旧 voided"模式(类似 AdHocEvent VoidAction)。需要给 Reading 表加 `voided_at` / `voided_reason` 字段。
> [!question] 长期不修复这个 gap 有什么风险?
> - 业务人员**每次修正都要联系运维**(慢、不可扩展)
> - 修正没有标准化流程 → 容易出错(漏退款 / 漏作废)
> - 审计困难(运维 tinker 操作的痕迹靠日志,不像 UI 操作那么清晰)
> - 业户体验差(响应慢)
>
> 业务方提需求时优先级会上来。
## 相关 issue.md 待补
```
- "作废已生成 Bill 的 MeterReading"组合流程:
类似 AdHocEvent 的 VoidAction(级联废 + 留 voided 审计),需要单独设计。
等业务方明确"已收款的 Bill 应该怎么撤销"再做(可能涉及红字 Bill / 退款)
```
## 异常分支
- 抄表员录错预防 → [[read-with-photo-proof|拍照存证]] + Form 守护
- 高用量触发预警 → [[exception-high-consumption]]
- 表故障导致错读 → [[replace-broken-meter|换表]] + 走本场景修正
## 相关文档
- [[decommission-and-locking]]
- [[bill-generation-pipeline]]
- [[exception-high-consumption]]
- [[replace-broken-meter]]
- [[../adhoc/cancel-amount-error-redo]](adhoc 模块的类似 void 流程参考)

View File

@@ -0,0 +1,273 @@
---
title: prop-acc · meter · 场景 - 单笔账单上下限封顶(防异常用量爆账)
aliases:
- min max 封顶
- 账单封顶
- generate-bill-min-max-cap
- 场景-账单上下限封顶
tags:
- 场景
- prop-acc
- 计量表
- 账单生成
- 异常防御
audience:
- 业务人员
- 财务
- 业户
status: 已发布
sub_feature: meter
last_review: 2026-05-26
code_version: 2026-05-22
---
# 场景:单笔账单上下限封顶(防异常用量爆账)
`RatePlan` 上的 `min_amount` / `max_amount` 字段为单笔账单设置**上下限**:
- **`max_amount`** 防止极端用量(漏水 / 设备故障)导致离谱账单 → 业户友好,但物业承担差额
- **`min_amount`** 防止零用量 / 极低用量逃避基础服务费 → 物业兜底,但业户可能不爽
本场景演示三种触发情境。
## 典型情境
### 情境 1:漏水触发 max 封顶
> [!example] 真实情境
> 张阿姨家**水管漏水**(藏在墙里没发现),5 月用水 **800 吨**(平时 12 吨)。按阶梯计价:
>
> ```
> 0-20 吨段:20 × 3.0 = 60
> 21-30 吨段:10 × 4.5 = 45
> 31-800 吨段:770 × 6.0 = 4,620
> 算出金额:4,725 元
> ```
>
> RatePlan 配置 `max_amount = 1,500`,触发封顶:
>
> ```
> final_amount = min(4725, 1500) = 1500
> ```
>
> 账单 ¥1,500,差额 ¥3,225 物业承担(走维修保险 / 业务减免)。
### 情境 2:零用量触发 min 兜底
> [!example] 真实情境
> 王先生整月**出差不在家**,水表读数无变化(consumption=0)。按阶梯算 = 0 元。但物业配置 `min_amount = 20`,兜底:
>
> ```
> final_amount = max(0, 20) = 20
> ```
>
> 账单 ¥20,理由"基础服务费 / 管网维护费"。王先生抱怨"我没用水为什么收钱?",物业解释:小区水管 / 表的维护是公共成本,按户分摊。
### 情境 3:正常范围,无封顶
> [!example] 真实情境
> 陈先生 5 月用水 35 吨,按阶梯算 135 元。RatePlan 配置 `min_amount=20`, `max_amount=1500`:
>
> ```
> final_amount = max(20, min(135, 1500)) = 135
> ```
>
> 账单 ¥135,封顶规则**不触发**(在合理范围内)。
## min / max 算法
```
if (max_amount !== null && calculated > max_amount) calculated = max_amount;
if (min_amount !== null && calculated < min_amount) calculated = min_amount;
final_amount = calculated;
```
或等价:`final_amount = max(min_amount ?? 0, min(calculated, max_amount ?? INF))`
详见 [[multiplier-and-tiered-pricing|倍率与阶梯计价]]"第 3 层 min/max 封顶"段。
## 系统流程
```mermaid
sequenceDiagram
participant Calc[MeterBillCalculator]
participant Service[MeterBillGenerationService]
participant DB
Calc->>Calc: 阶梯算法 → calculated_amount
Note over Calc: 假设漏水算出 4725
Calc->>Calc: max_amount 检查
alt calculated > max_amount(4725 > 1500)
Calc->>Calc: final = max_amount = 1500
else 在范围内
Calc->>Calc: 通过
end
Calc->>Calc: min_amount 检查
alt final < min_amount
Calc->>Calc: final = min_amount
else 在范围内
Calc->>Calc: 通过
end
Calc-->>Service: 1500
Service->>DB: 建 Bill(amount=1500, sourceable=reading)
Note over DB: 业务上是否记录"封顶减免"?目前 Bill 表无此字段,留作业务备注
```
## 业户视角
### Max 封顶(漏水)
业户收到的账单:
```
2026 年 5 月水费账单
用水量:800 吨 ⚠️ 用量异常高
按阶梯算应付:¥4,725.00
封顶后实付:¥1,500.00
差额减免:¥3,225.00(由物业 / 维修保险承担)
应付:¥1,500.00
```
> [!info] 账单展示封顶信息
> **强烈推荐**账单展示"按阶梯算 X,封顶 Y,差额 Z 由物业承担"。让业户明白封顶的存在 + 物业的友好。
业户会**感激物业封顶**,但更会**自查漏水 / 设备故障**。
### Min 兜底(零用量)
业户收到的账单:
```
2026 年 5 月水费账单
用水量:0 吨
按阶梯算应付:¥0.00
基础费(min):¥20.00
应付:¥20.00
```
业户可能**不接受**:"我没用水为什么收钱?"。物业要解释:
- 水管 / 公共部位维护成本
- 物业服务费的"基础保障"性质(签合同时已告知)
- 法律 / 政策依据(若有)
## 业务人员视角
### 配置 min / max
后台 → 费率管理 → RatePlan → 编辑 → 填字段:
| 字段 | 推荐值(参考)|
|---|---|
| `min_amount` | 10-30 元(看物业 + 费用类型)|
| `max_amount` | 1000-5000 元(看业户类型,商铺可以更高)|
> [!warning] 配置要谨慎
>
> **max 配低**:正常用量也被封顶 → 物业损失收入。例如 max=300,商铺正常月费 ¥500 → 物业每月被减免 ¥200。**严重 bug**。
>
> **max 配高**(或不配):无封顶 → 极端用量爆账户,业户投诉 + 法律风险。
>
> **min 配高**:业户不满 + 投诉。
>
> **配置后用极端值算例验证**(0 度 / 极少 / 正常 / 极高 各算一遍看是否合理)。
### 触发封顶后的业务流程
| 触发 | 业务人员动作 |
|---|---|
| max 触发(异常高用量)| 联系业户排查([[exception-high-consumption]]) → 减免数额可能要审批 |
| min 触发(零 / 极低用量)| 通常无需介入,业户接受 min 即可 |
| 频繁 max 触发 | 评估是否表 / 设备有问题(漏水 / 故障)|
### 封顶减免的会计处理
封顶差额(`max_amount` 触发时,实际应付 vs 物业承担)的会计处理:
| 选项 | 实现 |
|---|---|
| **物业直接承担**(本系统当前简化)| Bill.amount 直接是封顶后金额。账面收入 ¥1,500(实际应是 ¥4,725)→ 物业少收 ¥3,225 |
| **走维修保险**(高大上)| 物业向保险公司报销 ¥3,225,账面通过应收 / 已收 走完整流程 |
| **业户与物业分摊**(罕见)| 部分协议:超过封顶部分 50% 业户 50% 物业 |
当前**最简单实现**:物业直接承担。其他方案需要业务方提需求。
## 财务视角
### 月度报表统计封顶情况
```sql
-- 本月触发 max 封顶的 reading(假设 Bill 不存"封顶前 amount",我们用 reading 算)
SELECT
r.id AS reading_id,
r.consumption,
-- 重算应付(简化,实际要走 Calculator 逻辑)
-- calculate(consumption, ratePlan) AS expected_amount
b.amount AS billed_amount,
-- (expected - billed) AS reduction
rp.max_amount
FROM acc_meter_readings r
JOIN acc_meters m ON r.meter_id = m.id
JOIN fee_types ft ON m.fee_type_id = ft.id
JOIN rate_plans rp ON ft.current_rate_plan_id = rp.id
JOIN acc_bills b ON r.bill_id = b.id
WHERE b.amount = rp.max_amount -- 简化判断:Bill 金额刚好等于封顶值 = 大概率封顶触发了
AND b.created_at BETWEEN '2026-05-01' AND '2026-05-31';
```
业务用途:看月度物业因封顶减免多少收入。若太多 → 调整 max 或排查根因(频繁漏水 / 设备故障)。
## 常见问题
> [!question] min_amount 是 0 / null 时不兜底?
> 是的。若 `min_amount=null`,系统不兜底,零用量账单 = 0 元(可能不开账单)。物业政策决定是否兜底。
> [!question] max 触发后业户反悔说"我自查没漏水,你怎么算出我用 800 吨的?"
> 业务人员排查:
> - 看 reading 数据(读数对吗?抄表照片有吗?)
> - 派人现场核对物理表
> - 找漏水点(物业派维修人员)
> - 若证实表故障 → 走 [[replace-broken-meter|换表]],并重算账单(走 [[exception-readings-locked-after-bill|修正流程]])
>
> 若所有证据都指向"确实用了 800 吨"(且业户家有漏水迹象)→ 业户认账,封顶后金额是优惠了。
> [!question] min 触发后业户拒付怎么办?
> 物业说服 + 法律协议层面要求(物业合同里通常有"基础服务费"条款)。坚决拒付 → 进入逾期催收。
> [!question] 不同业户(住宅 vs 商铺)封顶不同可以吗?
> 看 RatePlan 设计。当前可能"每个 FeeType 一份 RatePlan",所以同 FeeType 共用 min/max。如果要区分,可:
>
> - 给商铺单独建 FeeType + RatePlan
> - 或扩展 RatePlan 支持多档 min/max(改 schema)
> [!question] 跨月用量(忘了抄一个月,两个月用量算一笔)会触发 max 吗?
> 可能会(双月用量翻倍)。**预防**:不要漏抄(走 [[audit-meters-needing-reading|审计]] 监控)。漏抄了发现:
> - 把这笔大账单**人工拆**成两个月(系统不直接支持,业务流程做)
> - 或当作正常账单收 + 与业户沟通
> [!question] 封顶后差额怎么入账?
> 当前最简单实现:Bill.amount 直接是封顶后金额,差额不入账(物业默默承担)。
>
> 严格会计:差额应记入"管理费用 / 维修保险报销 / 服务减免"科目。需扩展 schema 才能精确处理。
## 异常分支
- 阶梯计价(本场景叠加)→ [[generate-bill-tiered-pricing]]
- 工业表倍率叠加 → [[generate-bill-with-multiplier]]
- 异常高用量(可能触发 max)→ [[exception-high-consumption]]
- 读数错误导致离谱算账 → [[exception-readings-locked-after-bill]] 修正
## 相关文档
- [[multiplier-and-tiered-pricing]]
- [[bill-generation-pipeline]]
- [[generate-bill-tiered-pricing]]
- [[generate-bill-with-multiplier]]
- [[exception-high-consumption]]