Files
uniprop-manual/prop-acc/scenarios/prepaid/consume-monthly-property-bill.md
2026-05-25 23:22:55 +08:00

7.5 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 · prepaid · 场景 - 手动抵扣月度物业费
抵扣物业费
预存款抵账单
consume-monthly-property-bill
场景-预存款抵月物业费
场景
prop-acc
预存款
消费
业户
业务人员
已发布 prepaid 2026-05-25 2026-05-22

场景:手动抵扣月度物业费

预存款最高频操作 —— 月底物业费账单出来后,业务人员后台手动触发 ConsumeAction,从业户的预存款余额扣对应金额、Bill 状态翻 Paid。未来批量自动 job 落地后,这条路径变成"运维个例兜底"(详见 auto-deduction-design)。

典型情境

[!example] 真实情境 张阿姨的 12-3-501 房 5 月物业费账单 ¥800 已出账。张阿姨预存款账户余额 ¥4,200。物业财务王主管月初批量为 100+ 户业户做物业费抵扣,张阿姨是其中一户。

业户视角

您会感受到什么

  • 5 月底账单出来后,几天内收到推送:

    "您的 5 月物业费 ¥800 已自动从预存款扣减,余额 ¥3,400"

  • 收到收据:"物业费 ¥800(5 月)"
  • 小程序"我的预存款"显示新流水:-800.00 抵扣 物业费(5月)
  • 小程序"我的账单"显示该账单 已付

您要做什么

什么都不用做。看看就行 ——

  • 如果余额够,账单自动归零,无感
  • 如果余额不够,会收到"余额不足"提示,需要您手动充值或现金/微信付

[!info] 与现金付的差异 业户拿到的收据长一样(都是"物业费 ¥800"),只是结算来源不同。详见 consume-via-bill-collection-type

业务人员视角

第 1 步:确认账单已生成

后台 → 账单(Bill)模块 → 5 月物业费账单批量 → 状态 Unpaid → 列表里有张阿姨的账单。

第 2 步:打开张阿姨的预存款账户

后台 → 预存款 → 账户列表 → 按业户姓名搜 → 找到 Active 账户(balance=4200)→ 进 ViewPrepaidAccount

第 3 步:点击 ConsumeAction(标签"消费抵扣")

[!warning] 按钮可见性 ConsumeAction 守护:canOperate()(Active only)+ balance > 0 + Policy ->authorize('consume')。Frozen / Closed / 零余额账户灰化。

Modal 表单:

字段 填什么
关联账单(Bill) 选业户的未付账单(下拉显示该业户 community 内 status=unpaid 的账单)
抵扣金额 自动带入账单金额(可改,部分抵扣场景)
备注 选填,如 "5 月物业费手动抵扣"

第 4 步:提交

系统调 ConsumeFromPrepaidAccountAction,事务内:

  1. 校验 canOperate()(Active only)
  2. 校验跨社区(Bill 与 Account 必须同 community)
  3. 校验余额(≥ 抵扣金额)
  4. CollectionOrder(type=Bill,actual=+800,meta.fund_source=prepaid,Completed)
  5. CollectionOrderBill 关联 CO 与 Bill
  6. PrepaidAccount::consume($bill, $amount):
    • PrepaidTransaction(type=consume,amount=800,balance_before=4200,balance_after=3400,related_bill_id=...,关联 CO)
    • 更新 balance=3400
  7. Bill::recordPayment($amount):
    • 更新 Bill.status=Paid
  8. 触发 CollectionOrderCompleted → Listener 建 Receipt(走 Bill 渠道,文案"物业费 ¥800")

第 5 步:给收据 / 通知

后台找到新建 Receipt → 发业户(微信 / 邮件)。

系统流程

sequenceDiagram
    participant 业户
    participant 财务
    participant Filament
    participant ConsumeAction
    participant PrepaidAccount
    participant Bill
    participant 数据库
    participant 监听器

    Note over 业户,财务: 5 月物业费账单已出,张阿姨 balance=4200

    财务->>Filament: ViewPrepaidAccount → ConsumeAction(选 Bill, 800)
    Filament->>ConsumeAction: handle(account, bill, 800)
    ConsumeAction->>PrepaidAccount: canOperate() ? Active=true
    ConsumeAction->>PrepaidAccount: community_id match Bill? yes
    ConsumeAction->>PrepaidAccount: balance >= 800? 4200≥800 yes
    ConsumeAction->>数据库: 开启事务
    ConsumeAction->>数据库: 1. 建 CO(type=Bill, +800, meta.fund_source=prepaid)
    ConsumeAction->>数据库: 2. 建 CollectionOrderBill 关联
    ConsumeAction->>PrepaidAccount: 3. consume(bill, 800)
    PrepaidAccount->>数据库: 建 PrepaidTransaction(consume, 4200→3400, related_bill_id)
    PrepaidAccount->>数据库: 更新 balance=3400
    ConsumeAction->>Bill: 4. recordPayment(800)
    Bill->>数据库: status=Paid
    ConsumeAction->>监听器: 5. 触发 CollectionOrderCompleted
    监听器->>数据库: 建 Receipt("物业费 ¥800")
    ConsumeAction->>数据库: 提交事务
    Filament-->>财务: 成功
    财务-->>业户: 推送 + 收据

流水台账(本场景在累计流水中)

流水 type amount balance_before balance_after related_bill_id 备注
1 deposit 5000 0 5000 首次充值
2 consume 800 5000 4200 Bill #5月物业费 本场景
(后续 4 月 5 月各 800 ...)

5 月账单进入 Paid 状态,张阿姨账户余额变 ¥3,400。

部分抵扣的特殊情况

若业户余额不够全付(例如余额 ¥500,账单 ¥800):

选项 当前实现
抵扣 ¥500,账单剩 ¥300 待付 Bill::recordPayment() 是否支持部分支付
全部跳过(不抵) 等业户充值或其他方式付

当前推荐:跳过,告知业户"余额不足,请充值或选其他方式付"。部分抵扣需 Bill 模块配合。

常见问题

[!question] Modal 表单里"关联账单"下拉如何过滤? 系统只显示:

  • 与本账户同社区(community_id 一致)
  • 业户本人(resident_id 一致)
  • 状态 Unpaid
  • 按 due_at 升序(最早到期的先,引导业务人员优先抵)

多个账单 → consume-multiple-bills-priority

[!question] 抵扣后业户问"我用预存款付的为啥收据写'物业费'?" 这是有意设计(详见 consume-via-bill-collection-type):业户感知一致,不管怎么付,收据都长一样。如果业户想知道"是用预存款付的",可在小程序"我的账单"看到付款方式 = "预存款抵扣"。

[!question] 抵扣失败如何排查? 看后台 / 日志的错误信息:

  • "账户冻结" → 解冻
  • "跨社区不允许" → 业务人员选错账单 / 账户
  • "余额不足" → 业户先充值
  • "账单已 Paid" → 不要重复抵扣

[!question] 月底 100+ 户挨个 Modal 抵扣太慢了吧? 是的,这就是月初批量自动抵扣 job 的存在意义(详见 auto-deduction-design)。job 实现前业务人员必须挨个手动。

[!question] 已抵扣的账单想撤回怎么办? 不可变流水设计。如果抵错(例如抵了别人的账单):

  • 走退款 refund-partial-after-consume —— 但这退的是预存款余额,不是"撤销抵扣"
  • 撤销账单需 Bill 模块支持 reverse,不在本场景
  • 实际:预防胜于补救,Modal 表单提交前再三确认 Bill ID

异常分支

相关文档