Files
uniprop-manual/prop-acc/concepts/meter/multiplier-and-tiered-pricing.md
2026-05-25 23:53:01 +08:00

245 lines
6.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: prop-acc · meter · 倍率与阶梯计价
aliases:
- 倍率
- 阶梯计价
- multiplier
- tiered pricing
- min max 封顶
tags:
- 概念
- prop-acc
- 计量表
- 计费
audience:
- 业务人员
- 财务
- 架构师
status: 已发布
sub_feature: meter
last_review: 2026-05-25
code_version: 2026-05-22
---
# 倍率与阶梯计价
抄表生成账单的金额由三层叠加算出:**倍率(multiplier)** × **阶梯计价(tiered)** + **min/max 封顶**。这三层都在 `MeterBillCalculator` 内实现(纯算,无 DB IO),是 prop-acc 模块中**最严谨的算法之一**。
## 一句话总览
```
本月用量 = (current_reading - previous_reading) × multiplier
本月金额 = 阶梯计价(本月用量, RatePlan)
最终金额 = clamp(本月金额, min, max)
```
详见下文每层展开。
## 第 1 层:倍率(multiplier)
### 用途
工业 / 集团表的**实际计量值远大于表头数字**:
| 表型 | 表头读数 | multiplier | 实际用量 |
|---|---|---|---|
| 家用单相表 | 280 度 | 1 | 280 度 |
| 三相工业表 | 28 度 | **10** | 280 度 |
| 大型集团表(高压侧)| 28 度 | **100** | 2,800 度 |
物理原理:工业表为了在小表头显示大用量,内部有变压 / 分流比。multiplier 就是这个比值。
### 字段精度
```php
// migration
$table->decimal('multiplier', 10, 4);
// model casts
'multiplier' => 'decimal:4',
```
decimal(10,4) 精度足够工业场景(常见 1.0 / 10.0 / 100.0 / 1000.0,极少数 0.5 / 1.25 等特殊变比)。
### 用量计算
```
consumption = (current_reading - previous_reading) × multiplier
```
例:三相表上月 280,本月 308,multiplier=10:
```
consumption = (308 - 280) × 10 = 280 度
```
业户账单按"280 度"算,不是"28 度"。
## 第 2 层:阶梯计价(Tiered Pricing)
### 用途
水电气**阶梯递增**:用得越多,单价越高。鼓励节约,符合国家政策。
例:某市水阶梯计价:
| 阶梯 | 月用水(吨)| 单价 |
|---|---|---|
| 第一阶梯 | 0-20 | 3.0 元/吨 |
| 第二阶梯 | 21-30 | 4.5 元/吨 |
| 第三阶梯 | 30 以上 | 6.0 元/吨 |
业户本月用 35 吨:
| 段 | 用量 | 单价 | 段金额 |
|---|---|---|---|
| 0-20 吨(第一阶梯) | 20 | 3.0 | 60 |
| 21-30 吨(第二阶梯) | 10 | 4.5 | 45 |
| 31-35 吨(第三阶梯) | 5 | 6.0 | 30 |
| **合计** | **35** | | **135** |
### Progressive 累进 vs Full-tier 简陋实现
> [!info] 本系统采用 **progressive 累进**(正确算法),不是 full-tier 简陋实现。
| 算法 | 35 吨水 |
|---|---|
| **Progressive 累进**(本系统)| 20 × 3 + 10 × 4.5 + 5 × 6 = 135 元 ✅ |
| Full-tier 简陋(错)| 35 × 6 = 210 元 ❌(整月用量按最高阶梯计)|
| Mixed(更错)| 35 × 4.5 = 157.5 元 ❌ |
progressive 是国家政策标准做法,简陋实现是市场上劣质系统的常见 bug。`MeterBillCalculator::calculateTiered()` 实现得对,所以我们的账单准确。
### RatePlan + RateTier 模型
阶梯定义在 `RatePlan` + `RateTier` 模型里(不属于本子模块,在更通用的费率模块):
```
RatePlan ─── RateTier (1..n)
├── tier=1, lower=0, upper=20, unit_price=3.0
├── tier=2, lower=20, upper=30, unit_price=4.5
└── tier=3, lower=30, upper=null, unit_price=6.0
```
`fee_type_id`(在 Meter 上)指向 RatePlan,Calculator 拿到 RatePlan → 按 tier 累加段金额。
## 第 3 层:min / max 封顶
### 用途
防止**极端用量**导致离谱账单:
| 场景 | 问题 | 封顶方案 |
|---|---|---|
| 业户家漏水,1 月用 1000 吨 | 按阶梯算 ~ 6000+ 元 | `max=2000` 封顶,差额走维修保险 |
| 表故障读 0 度 | 业户不付钱了 | `min=20` 兜底(至少收基础费)|
| 业户家整月没人(零用量)| 看物业政策 | `min=20` 仍要收(物业服务费性质)|
### 实现
`RatePlan` 上有 `min_amount` / `max_amount` 字段:
```
final_amount = max(min_amount, min(calculated_amount, max_amount))
```
例:计算出 ¥6,000 但 `max_amount=2000` → 实际收 ¥2,000,差额 ¥4,000 由物业 / 维修保险承担(账面体现为"封顶减免")。
### 业务上的取舍
> [!warning] 封顶不是万能的
> max 封顶让业户感激,但物业要承担差额。建议:
>
> - 设合理的 max(覆盖正常波动范围)
> - 异常用量先排查([[exception-high-consumption]])再决定是否减免
> - 封顶降低收入,需评估对物业财务可持续性影响
min 类似:
> [!info] min 的政策意义
> min 通常对应"管网维护费 / 基础服务费",即使零用量也要分摊管网成本。但在国家政策严格的地区,要明确告知业户"min 是什么"。
## 完整算法流程
```mermaid
flowchart TD
A[抄表 current_reading] --> B[查询上次 reading]
B --> C[计算 consumption =<br/>(current - previous) × multiplier]
C --> D[加载 RatePlan + RateTier]
D --> E[Calculator.calculateTiered<br/>按阶梯累加段金额]
E --> F{有 min/max?}
F -->|有 max & 金额超| G[封顶到 max]
F -->|有 min & 金额低| H[补到 min]
F -->|正常范围| I[原值]
G --> J[最终账单金额]
H --> J
I --> J
```
## 完整算例
电费阶梯(假设):
| 阶梯 | 用电度数 | 单价 |
|---|---|---|
| 1 | 0-200 | 0.5 |
| 2 | 200-400 | 0.6 |
| 3 | 400+ | 0.8 |
`min_amount=10`,`max_amount=500`
工业表(三相,multiplier=10),5 月抄表 308,上月 280:
```
1. consumption = (308 - 280) × 10 = 280 度
2. 阶梯:200 × 0.5 + 80 × 0.6 = 100 + 48 = 148 元
3. 封顶:10 ≤ 148 ≤ 500 → 不动
4. 最终账单:148 元
```
家用表(multiplier=1),5 月抄表 1100,上月 800:
```
1. consumption = (1100 - 800) × 1 = 300 度
2. 阶梯:200 × 0.5 + 100 × 0.6 = 100 + 60 = 160 元
3. 封顶:10 ≤ 160 ≤ 500 → 不动
4. 最终账单:160 元
```
漏水 case(家用表,水阶梯,multiplier=1),本月用 1000 吨:
```
1. consumption = 1000 吨
2. 阶梯:20 × 3 + 10 × 4.5 + 970 × 6 = 60 + 45 + 5820 = 5925 元
3. 封顶:5925 > max_amount(假设 2000)→ 封到 2000
4. 最终账单:2000 元(差额 3925 由物业 / 维修保险承担)
```
## 业务人员视角
- **配置阶梯**:在 RatePlan + RateTier 模型里设置(不在 meter 子模块,通常运营 / 财务总监来设)
- **配置倍率**:建表时 / 后续编辑表时填(`MeterForm`,默认 1)
- **核对账单**:看到异常金额时,顺着 Calculator 算法手工验算
## 财务视角
- 阶梯计价 = 政策合规
- 倍率确保工业表账单正确
- min/max 封顶 = 风险控制 + 业户友好(max)
## 业户视角
业户**不需要懂这套算法**,看到的是账单金额。但**对账时**要能理解:
- 上月读数 → 本月读数 → 用量(度 / 吨 / 立方米)
- 用量 → 阶梯单价 → 金额
- 如有封顶 → 凭证显示
## 相关文档
- [[meter-vs-meter-reading]]
- [[bill-generation-pipeline]]
- [[generate-bill-tiered-pricing]]
- [[generate-bill-with-multiplier]]
- [[generate-bill-min-max-cap]]
- [[exception-high-consumption]]