--- title: prop-acc · prepaid · 场景 - 多个未付账单按 due_at 优先级抵扣 aliases: - 多账单抵扣优先级 - 优先抵最早到期账单 - consume-multiple-bills-priority - 场景-多账单优先级抵扣 tags: - 场景 - prop-acc - 预存款 - 消费 audience: - 业户 - 业务人员 status: 已发布 sub_feature: prepaid last_review: 2026-05-25 code_version: 2026-05-22 --- # 场景:多个未付账单按 due_at 优先级抵扣 业户某月有**多张未付账单**(物业费、水电费、电梯维护费等),余额需抵多张。**优先抵最早到期的账单**(避免逾期罚款)。本场景描述业务人员的批量抵扣逻辑,也是 [[auto-deduction-design|自动 job]] 的核心算法。 ## 典型情境 > [!example] 真实情境 > 张阿姨家 5 月有 3 张未付账单: > > | 账单 | 金额 | due_at | > |---|---|---| > | 5 月物业费 | ¥800 | 5 月 15 日 | > | 5 月水电费 | ¥1,200 | 5 月 20 日 | > | Q2 电梯维护费 | ¥300 | 5 月 31 日 | > > 合计 ¥2,300,张阿姨账户余额 ¥2,500。**全部能抵**,但顺序很重要: > > 1. 物业费(5 月 15 日)— 最早到期,先抵 > 2. 水电费(5 月 20 日) > 3. 电梯维护费(5 月 31 日) > > 抵完余 ¥200。 ## 业户视角 ### 您会感受到什么 - 5 月底收到 3 张收据(各账单一张),金额对应原账单 - 小程序"我的预存款"流水按抵扣时间倒序显示 3 笔 consume - 小程序"我的账单"3 张全部 ✅ Paid - 推送通知"5 月 3 张账单已抵扣,余额 ¥200" ### 您要做什么 什么都不用。看明白即可。 > [!info] 余额够不够全付决定行为 > - **够全付**:全部抵,余额剩下的留账户 > - **不够全付**:按优先级先抵最早到期的,后面的留 Unpaid 状态 → 推送"余额不足,请充值" ## 业务人员视角 ### 第 1 步:打开账户 后台 → 预存款 → 找到张阿姨账户 → 进 `ViewPrepaidAccount`(balance=2500)。 ### 第 2 步:逐张抵扣(手动模式) > [!warning] 当前没有"一键全抵"按钮 > 业务人员需要**对每张账单各点一次** `ConsumeAction`。这是 [[auto-deduction-design|自动 job]] 要解决的痛点。 **正确顺序**(按 due_at 升序): | 步骤 | 选 Bill | 抵 amount | 之后余额 | |---|---|---|---| | 1 | 5 月物业费(due 5/15) | 800 | 2500 → 1700 | | 2 | 5 月水电费(due 5/20) | 1200 | 1700 → 500 | | 3 | Q2 电梯维护费(due 5/31) | 300 | 500 → 200 | 每张账单走完整 [[consume-monthly-property-bill]] 流程(Modal → 提交 → 触发监听器 → Receipt)。 ### 第 3 步:核对结果 - 3 张账单全 ✅ Paid - 账户余额 ¥200 - 3 张 Receipt 已生成(分别 ¥800 ¥1,200 ¥300) ## 优先级排序逻辑(自动 job 用) 未来自动 job 实现后,**按以下顺序排序未付账单**: | 排序键 | 升序/降序 | 业务理由 | |---|---|---| | 1. `due_at` | 升序 | **最早到期的先抵**(避免逾期产生滞纳金 / 影响信用) | | 2. `bill_type` | 自定义("物业费" → "水电费" → "其他") | 物业费是核心服务费,优先 | | 3. `amount` | 升序 | 同优先级下,**小额先抵清**(避免余额不够时多张大账单都半抵)| | 4. `created_at` | 升序 | 兜底:早建的先 | 伪代码: ```python unpaid_bills = sorted( bills, key=lambda b: (b.due_at, BILL_TYPE_ORDER[b.bill_type], b.amount, b.created_at) ) balance = account.balance for bill in unpaid_bills: if balance <= 0: break if balance >= bill.amount: consume(account, bill, bill.amount) balance -= bill.amount else: # 余额不够全付该账单 → 跳过,等业户充值 notify(account.resident, "余额不足,无法抵 ¥{bill.amount} 的 {bill.bill_type}") # 或部分抵(看 Bill 是否支持):consume(account, bill, balance); balance = 0; break ``` ## 余额不够全付的策略对比 假设张阿姨账户余额 ¥1,500,3 张账单合计 ¥2,300: | 策略 | 行为 | 结果 | |---|---|---| | **全部跳过** | 余额不够任何一笔不动 | 3 张全 Unpaid,余额 ¥1,500 闲置 | | **按优先级抵到不够为止**(推荐) | 物业费 800 → 余 700;水电费 1200 不够跳过;电梯费 300 余 700 ≥ 300 → 抵 → 余 400 | 物业费 + 电梯费 Paid,水电费 Unpaid,余额 ¥400 | | **按优先级抵 + 部分抵末张** | 物业费 800 → 余 700;水电费 1200 > 700 → 抵 700 部分 → 水电费余 500;电梯费 300 余 0 跳过 | 物业费 Paid + 水电费部分付 + 电梯费 Unpaid + 余额 0 | **推荐第二种**(按优先级抵到不够为止,不做部分抵)。理由: - 简单,Bill 模块不用支持部分付 - 业户看到余额还有钱但有账单未付,会主动充值 - 避免"抵了一半"的复杂状态 **第三种**等 Bill 模块支持部分支付后再考虑。 ## 系统流程(手动模式 3 笔操作) ```mermaid sequenceDiagram participant 财务 participant Filament participant Account participant 数据库 Note over 财务: 余额 2500,3 张未付账单 财务->>Filament: ConsumeAction(物业费 800) Filament->>Account: consume(物业费, 800) Account->>数据库: balance 2500→1700, Bill Paid 财务->>Filament: ConsumeAction(水电费 1200) Filament->>Account: consume(水电费, 1200) Account->>数据库: balance 1700→500, Bill Paid 财务->>Filament: ConsumeAction(电梯费 300) Filament->>Account: consume(电梯费, 300) Account->>数据库: balance 500→200, Bill Paid Note over 数据库: 3 张账单 Paid + 3 张 Receipt + 余额 200 ``` ## 常见问题 > [!question] 业务人员漏抵某张账单怎么办? > 单纯漏抵 → 后续发现再抵一次。如果业户因此被收滞纳金,物业可走 [[../adhoc/cancel-amount-error-redo]] 之类的补救路径。 > [!question] 业务人员抵错优先级(先抵晚到期的)? > 不影响资金正确性(账户余额扣对了,账单状态更新对了)。**业务上**可能让早到期的账单进入逾期。**预防** = 培训业务人员看 due_at,**根治** = 上自动 job。 > [!question] 跨多个业户批量抵扣可以吗? > 当前不行,只能一个账户一个账户操作。**批量是自动 job 的核心需求**。 > [!question] 业务人员选错账单(选了别人的)? > Modal 的账单下拉**已经过滤同业户 + 同社区**,理论上选不到别人的。除非 UI / 数据有 bug,否则不会发生。 > [!question] 部分抵扣场景频繁吗? > 业务上罕见 —— 业户通常一次充够覆盖几个月。如果某业户经常余额不够,业务人员应主动提醒"建议充够 3 个月"。 ## 异常分支 - 单笔抵扣 → [[consume-monthly-property-bill]] - 计量类账单(水电费)→ [[consume-meter-bill]] - 余额不够 → 告知业户充值 - 月初批量(未来)→ [[consume-batch-auto-monthly]] - 账户冻结 → [[unfreeze-after-verification]] ## 相关文档 - [[consume-monthly-property-bill]] - [[consume-meter-bill]] - [[consume-batch-auto-monthly]] - [[auto-deduction-design]] - [[transaction-types]]