Files
uniprop-manual/prop-acc/concepts/meter/meter-vs-meter-reading.md

144 lines
6.2 KiB
Markdown
Raw Normal View History

2026-05-25 23:48:00 +08:00
---
title: prop-acc · meter · 计量表与抄表流水
aliases:
- 计量表与抄表流水
- Meter 与 MeterReading
- 计量表的双对象模式
tags:
- 概念
- prop-acc
- 计量表
- 核心概念
audience:
- 业务人员
- 抄表员
- 财务
status: 已发布
sub_feature: meter
last_review: 2026-05-25
code_version: 2026-05-22
---
# 计量表与抄表流水
计量表模块底层是**两个对象**配合:**Meter**(物理表的配置)+ **MeterReading**(每次抄表的不可变流水)。模式上与 [[../deposit/deposit-account-vs-transaction|押金账户+流水]]同构,但**对象的物理性**让它有几条独特特征:
- **每张表是真实硬件**(电表 / 水表 / 燃气表),挂在具体房屋(`asset_id`)上
- **不直接产收据** —— 抄表产 `Bill`,后续业户付账单再走 [[../adhoc/collection-order-and-receipt|CollectionOrder + Receipt]]
- **没有"账户余额"概念**(没有 balance 字段),业户余额追踪在 [[../prepaid/prepaid-account-vs-transaction|预存款]]
## 为什么用双对象
> [!info] 类比:实体水表
> - **Meter** = 表面板,上面写编号、安装时间、倍率
> - **MeterReading** = 每次抄表的本子记录:几号几月几日读了多少、谁抄的、有没有拍照
如果只有 Meter 没有 Reading → 不知道每月用了多少,无法算账单。
如果只有 Reading 没有 Meter → 不知道表的物理属性(倍率、装在哪、什么费用),Reading 是孤立数字。
所以两个都要。
## 字段速查
### Meter(计量表)
| 字段 | 含义 |
|---|---|
| `id` | 表 ID |
| `community_id` | 所属物业项目 |
| **`asset_id`** | **绑定的房屋资产**(必填,通过 asset 找业户)|
| **`fee_type_id`** | **费用类型**(水费 / 电费 / 燃气费,决定单价)|
| `replaced_meter_id` | 上一代表(`null` = 原生新表,见 [[replacement-chain]]) |
| `code` | 表编号(物理表牌号,通常物业自编)|
| **`multiplier`** | **倍率**(decimal(10,4),工业表 10/100/1000)|
| `initial_reading` | 初始读数(decimal(12,2)) |
| `is_active` | 是否在役 |
| `installed_at` | 安装日期 |
| `decommissioned_at` | 退役日期(null = 在役)|
| `decommission_reason` | 退役原因(5 种枚举,详见 [[decommission-and-locking]])|
| `final_reading` | 退役时最终读数 |
### MeterReading(抄表流水)
| 字段 | 含义 |
|---|---|
| `id` | 流水 ID |
| `meter_id` | 归属表 |
| `read_at` | 抄表日期 |
| `current_reading` | 本次读数(物理表头数字)|
| `previous_reading` | 上次读数(自动从最近一条 reading 取)|
| **`consumption`** | **用量**(=(current - previous) × multiplier,自动算)|
| `source` | 来源:`manual`(手抄) / `remote`(集抄,详见 [[reading-source-and-photo-proof]])|
| `photo_url` | 拍照存证 URL(可选 / 集抄无)|
| `operated_by` | 抄表员 ID(manual 类型必填) |
| `bill_id` | 关联生成的账单(若已生成 Bill,null = 未生成)|
| `memo` | 备注 |
| 创建后**不可变** | 一旦生成只读;若 `bill_id != null` 更不可改(双锁)|
## 两者的契约
- **每张 Meter 可有多条 MeterReading**(理想情况是每月一条)
- **MeterReading 必属于一张 Meter**(`meter_id` NOT NULL)
- **最新 reading 的 current_reading = 该 meter 的"当前累计读数"**(Meter 自身不存 current,从 reading 推出)
- **consumption = (current - previous) × multiplier**:倍率乘进去就是真实用量(度 / 吨 / 立方米)
## 与"账户+流水"型模块的本质差异
| 维度 | Account + Transaction(deposit / prepaid)| **Meter + MeterReading** |
|---|---|---|
| 主对象表达什么 | 账户余额 | **物理表的配置** |
| 流水表达什么 | 资金变动(deposit / refund / consume) | **抄表读数(用量计算源)** |
| 主对象有 balance 吗 | ✅ 有 | **❌ 无**(余额是用量,在 Reading 里) |
| 流水方向 | + / -(余额加减)| **无方向**(只有"本月读了多少") |
| 自动关账 | 看模块(deposit 自动,prepaid 不) | 走"退役 (decommission)" 不是"关账" |
| 写入操作种类 | 多种(deposit / consume / refund / forfeit) | **单一**(抄表 record_reading)+ 换表 / 退役 |
| 直接产 Receipt | 是 | **否,通过 Bill 中转** |
## 业户视角
业户**通常不直接接触 Meter / MeterReading 概念**。看到的是:
- 月底物业 App 推送账单"5 月电费 ¥168,用电 280 度"
- 收据"水费 ¥54"
- 偶尔小程序"我的计量"页可查看本月用量趋势(若开启)
底下的 Meter 和 MeterReading 是后台运营的事。**唯一**会接触的:**业户对账单金额有异议**时,可申请看历次抄表记录(系统应能展示该业户表的全部 reading 历史)。
## 抄表员视角
李师傅是物业聘的抄表员,每月固定时间挨家挨户(或集中点位)读表头数字:
- 用物业 App / 抄表机 录入 → 系统建 MeterReading(`source=manual`,`operated_by=李师傅`)
- 拍照可选(详见 [[reading-source-and-photo-proof]])
- 如果该社区接入集抄系统(IoT 表),系统自动生成 reading(`source=remote`),李师傅不用跑
## 业务人员视角
物业财务的工作:
-`MeterDashboard`:本月待抄表清单、高用量异常、按费用类型用量走势
- 录入 / 校验 reading(若有异议)
- 触发 `GenerateBillsFromMeterReadingsAction` → 自动生成所有未结账的 reading 对应的 Bill
- 月底对账:每张 reading 是否都有对应 Bill,有 Bill 是否已 Paid
## 系统视角:Bill 生成是单独一步
```mermaid
flowchart LR
A[抄表员录入 MeterReading] -.第一步.-> B[MeterReading<br/>bill_id=null]
B -->|GenerateBillsFromMeterReadingsAction| C[Bill 生成<br/>+ MeterReading.bill_id 回写]
C -.业户付账单.-> D[CollectionOrder + Receipt<br/>付款方式可选现金/微信/预存款]
```
**关键**:MeterReading **不直接**产 CollectionOrder + Receipt。要先经过 **Bill 生成步骤**(可能是月底批量,可能是抄表后立即),然后业户**付账单**才走收款流程。计量表是**计费源**,不是收款源。
## 相关文档
- [[replacement-chain]]
- [[multiplier-and-tiered-pricing]]
- [[bill-generation-pipeline]]
- [[reading-source-and-photo-proof]]
- [[decommission-and-locking]]
- [[../prepaid/consume-via-bill-collection-type]](账单视角的收款,与本模块呼应)
- [[../deposit/deposit-account-vs-transaction]](账户+流水模式对比)