8.3 KiB
title, aliases, tags, audience, status, sub_feature, last_review, code_version
| title | aliases | tags | audience | status | sub_feature | last_review | code_version | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| prop-acc · meter · 场景 - 换表:旧表故障/退役,新表带 -R1 后缀 |
|
|
|
已发布 | meter | 2026-05-26 | 2026-05-22 |
场景:换表,旧表故障/退役,新表带 -R1 后缀
物理表老化 / 损坏 / 校验未过,需要换新表。系统通过 ReplaceMeterAction 一步完成:旧表退役 + 新表建立 + replaced_meter_id 关联 + 初始读数继承。新表自动编号 <旧编号>-R1。
典型情境
[!example] 真实情境 张阿姨家电表(编号 E-501)用了 8 年,2026 年 5 月例行校验未通过(读数漂移),物业要换新表。
换表当天:
- 抄表员李师傅现场读旧表:5000 度
- 卸下旧表 + 装上新表
- 新表出厂读数:0(物理上)
- 系统操作:
ReplaceMeterAction系统结果:
- 旧表 E-501:
is_active=false,decommissioned_at=今天,decommission_reason=Replaced,final_reading=5000- 新表 E-501-R1:
is_active=true,installed_at=今天,replaced_meter_id=旧表 ID,initial_reading=5000(继承), multiplier 继承
抄表员视角(李师傅)
第 1 步:现场操作
到张阿姨家:
- 检查旧表状态(确认换表必要性)
- 拍照存证旧表当前读数(关键!后续争议时凭证)
- 物理换表(断电 → 换表 → 通电)
- 拍照新表初始状态(出厂 0)
- 把信息回传业务人员(微信 / App / 当面)
[!warning] 拍照不能省 旧表读数没拍照 = 系统里填的"5000" 没物理证据 = 业户事后质疑"我家明明只用了 4500" 时物业百口莫辩。
第 2 步:报回业务
抄表员把信息汇总给王主管(业务人员):
- 旧表编号:E-501
- 旧表最后读数:5000
- 换表日期:2026-05-26
- 退役原因:校验未过(
Replaced) - 新表型号:同型号(multiplier=1)
业务人员视角
第 1 步:打开旧表
后台 → 计量表 → 找 E-501 → 进 ViewMeter。
第 2 步:点 ReplaceMeterAction
右上角"换表"按钮(标签可能是"更换")。
[!warning] 按钮可见性 守护:
is_active=true+ Policy->authorize('replace')。已退役表此按钮灰化。
Modal 表单:
| 字段 | 填什么 |
|---|---|
旧表最后读数(final_reading) |
5000(抄表员现场读) |
退役原因(decommission_reason) |
Replaced(其他 4 种见 decommission-and-locking) |
| 退役日期 | 2026-05-26(默认今天) |
| 新表编号 | E-501-R1(系统自动生成,nextReplacementCode(),可改但不推荐) |
| 新表 multiplier | 1.0(默认继承旧表) |
| 新表安装日期 | 2026-05-26(默认今天) |
| 备注 | "校验未通过,换新表" |
第 3 步:提交
系统在一个事务内:
- 校验旧表
is_active=true(否则按钮就不该出现) - 旧表 update:
is_active = falsedecommissioned_at = 2026-05-26decommission_reason = Replacedfinal_reading = 5000
- 建新表:
code = E-501-R1(nextReplacementCode($oldCode))is_active = trueinstalled_at = 2026-05-26replaced_meter_id = 旧表 IDinitial_reading = 5000(继承自旧表 final_reading)multiplier = 1.0(继承)community_id/asset_id/fee_type_id继承
第 4 步:验证 + 通知
后台 → 计量表 → 看新旧两张表 → 确认数据正确。
业户可不通知(业户对系统层无感)。
系统流程
sequenceDiagram
participant 抄表员
participant 王主管
participant Filament
participant ReplaceMeterAction
participant 数据库
抄表员->>抄表员: 现场拍照 + 换表(物理)
抄表员->>王主管: 旧表读数 5000,换表完成
王主管->>Filament: ViewMeter(旧表) → ReplaceMeterAction
Filament->>ReplaceMeterAction: handle(oldMeter, finalReading=5000, reason=Replaced)
ReplaceMeterAction->>数据库: 开启事务
ReplaceMeterAction->>数据库: 1. 旧表 update:is_active=false, decommissioned_at, decommission_reason=Replaced, final_reading=5000
ReplaceMeterAction->>数据库: 2. 建新表:code=E-501-R1, is_active=true, replaced_meter_id=旧表id, initial_reading=5000, multiplier=1
ReplaceMeterAction->>数据库: 提交事务
Filament-->>王主管: 跳转新表 ViewMeter
旧表 / 新表数据对照
| 字段 | 旧表 E-501 | 新表 E-501-R1 |
|---|---|---|
code |
E-501 | E-501-R1 |
is_active |
false | true |
installed_at |
2018-XX-XX(原值) | 2026-05-26 |
decommissioned_at |
2026-05-26 | null |
decommission_reason |
Replaced | null |
final_reading |
5000 | null |
initial_reading |
(历史值不动) | 5000(继承) |
multiplier |
1 | 1(继承) |
replaced_meter_id |
null | 旧表 id |
community_id, asset_id, fee_type_id |
不动 | 继承 |
5 月份的抄表 + 账单
换表那个月的账单:
本月用量 = current(新表第一次抄)+ initial(=5000) - previous(=5000)
= (50 + 5000) - 5000
= 50 度
新表 5 月底第一次抄读到 50(物理表头),系统存 current_reading = 50 + 5000 = 5050,previous_reading = 5000(继承),consumption = 50。账单按 50 度算,业户感觉不到换表。
[!info] 抄表员录入逻辑 抄表员现场看到新表是 50,系统应自动加上 5000 存为 5050(避免抄表员手动算)。或者抄表员录 50,系统在保存时自动加 5000。具体实现看
MeterReadingsRelationManager的 form。
业户视角
业户几乎感受不到 —— 只看到下月账单仍是正常用量。
唯一感知:换表当天可能短暂断电断水(物理操作)。物业应提前通知业户。
整链追溯
如果以后这张 E-501-R1 又出问题再换 → 新表 E-501-R2,replaced_meter_id 指 R1。如此累加:
E-501 (原生) → E-501-R1 (第 1 次换) → E-501-R2 (第 2 次换) → E-501-R3 ...
详见 replacement-chain"整条链的追溯"段。
常见问题
[!question] 旧表
final_reading填错了能改吗? 旧表的final_reading严格上属于"已退役表的字段",MeterPolicy::update()在is_active=false时拒绝改(decommission-and-locking 守护)。改错的话:
- 通过 tinker 修(运维操作,留备注)
- 或者把
decommissioned_at = null让表"复活"(Policy 可能不允许),再走完整换表流程预防:换表 Modal 提交前与抄表员书面确认 final_reading。
[!question] 新表 multiplier 与旧表不同可以吗? 可以(form 上可改),但强烈不推荐。理由见 replacement-chain"常见问题"段:不同 multiplier 让用量计算公式变,业户对账困难。
[!question] 新表编号 -R1 不喜欢能改成别的吗? Modal 表单允许改
code,但强烈不推荐:
-R1是标准化命名,审计 / 报表 / 后续换表的-R2都基于这个 pattern- 改成自定义 code(如 "E-501-NEW")会破坏
nextReplacementCode()算法,下次换表生成E-501-NEW-R1看着别扭
[!question] 换表后业户对历史账单有异议怎么办? 历史 reading 都关联到旧表(
meter_id=旧表 id),不会因换表丢失。审计可:
- 后台找旧表 → 看历次 reading(只读)
- 拿物理表照片(若有)
- 拿换表前的累计读数(旧表 final_reading)对照
[!question] 业户搬走永久弃用表,这种"换表"怎么处理? 那不是换表,是 decommission-without-replacement。
decommission_reason=Removed或Expired,不建新表。
[!question] 旧表是 active 但有未结账 reading,能换表吗? 系统不阻止(Action 不查未结账 reading)。但业务上:
- 应先生成未结账 reading 的 Bill(走 bill-generation-pipeline)
- 否则换表后那些 reading 永远不会被处理(它们关联旧表)
推荐流程:换表前先把旧表当月抄表录入 + 生成 Bill → 然后再换表。
异常分支
- 不换表只退役 → decommission-without-replacement
- 误换表想撤销 → 困难,见 replacement-chain"常见问题"段
- 单纯换 multiplier 不换表 → 不推荐(应换表保留历史)