225 lines
7.1 KiB
Markdown
225 lines
7.1 KiB
Markdown
|
|
---
|
|||
|
|
title: prop-acc · prepaid · 场景 - 月初批量自动抵扣 job(待补)
|
|||
|
|
aliases:
|
|||
|
|
- 月初自动抵扣
|
|||
|
|
- 批量预存款抵账单
|
|||
|
|
- consume-batch-auto-monthly
|
|||
|
|
- 场景-月初自动抵扣
|
|||
|
|
tags:
|
|||
|
|
- 场景
|
|||
|
|
- prop-acc
|
|||
|
|
- 预存款
|
|||
|
|
- 消费
|
|||
|
|
- 待补
|
|||
|
|
audience:
|
|||
|
|
- 业务人员
|
|||
|
|
- 财务
|
|||
|
|
- 产品
|
|||
|
|
status: 草稿
|
|||
|
|
sub_feature: prepaid
|
|||
|
|
last_review: 2026-05-25
|
|||
|
|
code_version: 2026-05-22
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 场景:月初批量自动抵扣 job(待补)
|
|||
|
|
|
|||
|
|
> [!warning] 本场景**代码未实现**
|
|||
|
|
> 当前所有 consume 操作都需要业务人员**手动后台触发**。本文档描述自动 job 落地后的目标态。设计意图详见 [[auto-deduction-design]]。
|
|||
|
|
|
|||
|
|
预存款的**产品价值核心**。月初 1 日凌晨,Scheduled job 扫所有 Active + 余额>0 的预存款账户,对每个账户找未付账单,按优先级 ([[consume-multiple-bills-priority]]) 自动抵扣。
|
|||
|
|
|
|||
|
|
## 典型情境(目标态)
|
|||
|
|
|
|||
|
|
> [!example] 真实情境(目标态)
|
|||
|
|
> 2026 年 6 月 1 日 00:30,系统自动跑 `PrepaidAutoDeductionJob`:
|
|||
|
|
>
|
|||
|
|
> - 扫描全平台 5 个社区,共 500 个 Active 预存款账户(余额 > 0)
|
|||
|
|
> - 对每个账户找该业户的未付账单(物业费 + 水电费 + ...)
|
|||
|
|
> - 按 due_at 升序抵扣
|
|||
|
|
> - 全部完成耗时 ~5 分钟
|
|||
|
|
>
|
|||
|
|
> 早上 8 点,500 个业户陆续收到推送:
|
|||
|
|
>
|
|||
|
|
> | 业户场景 | 推送内容 |
|
|||
|
|
> |---|---|
|
|||
|
|
> | 余额充足,全抵 | "5 月账单已自动抵扣 ¥1,000,余额 ¥4,000" |
|
|||
|
|
> | 余额部分够 | "已抵 ¥800,水电费 ¥200 余额不足,请充值" |
|
|||
|
|
> | 账户冻结 | (不推送)|
|
|||
|
|
|
|||
|
|
## 业户视角(目标态)
|
|||
|
|
|
|||
|
|
### 您会感受到什么
|
|||
|
|
|
|||
|
|
- 月初某个早晨突然收到推送
|
|||
|
|
- 小程序"我的账单"批量翻为 ✅ Paid
|
|||
|
|
- 小程序"我的预存款"流水里多几笔 consume
|
|||
|
|
- 收到对应数量的 Receipt(每张账单一张)
|
|||
|
|
- **完全无感**(理想状态),不需要任何操作
|
|||
|
|
|
|||
|
|
### 您要做什么
|
|||
|
|
|
|||
|
|
只在以下情况要做:
|
|||
|
|
|
|||
|
|
| 推送内容 | 您要做 |
|
|||
|
|
|---|---|
|
|||
|
|
| "余额不足,X 账单未付" | 充值 → 业务人员手动补抵 / 等下月自动 job |
|
|||
|
|
| "账户冻结无法抵" | 联系物业了解冻结原因 |
|
|||
|
|
| "所有账单已抵,余额还剩 ¥X" | 不用做 |
|
|||
|
|
|
|||
|
|
## 业务人员视角
|
|||
|
|
|
|||
|
|
### Job 执行前
|
|||
|
|
|
|||
|
|
业务人员**不需要任何操作**。Scheduled 配置在系统层,运行无需介入。
|
|||
|
|
|
|||
|
|
### Job 执行过程
|
|||
|
|
|
|||
|
|
后台监控面板(待开发):
|
|||
|
|
|
|||
|
|
- 实时进度:已处理 N / 总共 M 账户
|
|||
|
|
- 实时统计:已抵账单数、抵扣总额、失败数、跳过数
|
|||
|
|
- 失败告警:任何异常立即推送给 ops
|
|||
|
|
|
|||
|
|
### Job 执行后
|
|||
|
|
|
|||
|
|
业务人员看汇总报告(后台 / 邮件):
|
|||
|
|
|
|||
|
|
```markdown
|
|||
|
|
# 2026 年 6 月 1 日 PrepaidAutoDeductionJob 报告
|
|||
|
|
|
|||
|
|
## 统计
|
|||
|
|
- 候选账户:500
|
|||
|
|
- 全抵成功:380(76%)
|
|||
|
|
- 部分抵 / 跳过:80(16%)
|
|||
|
|
- 跨社区拦截:0
|
|||
|
|
- 账户冻结跳过:8(2%)
|
|||
|
|
- 失败(异常):0(0%)
|
|||
|
|
- 其余(余额=0、无未付账单):32(6%)
|
|||
|
|
|
|||
|
|
## 资金动作
|
|||
|
|
- 抵扣总额:¥412,300
|
|||
|
|
- 涉及账单数:835(平均每户 1.6 张)
|
|||
|
|
- 平均抵扣金额:¥513
|
|||
|
|
- 最大单户抵扣:¥3,200(陈先生家,水电+物业+电梯)
|
|||
|
|
|
|||
|
|
## 失败明细
|
|||
|
|
(无)
|
|||
|
|
|
|||
|
|
## 跳过明细(需关注)
|
|||
|
|
- 80 户余额不足,合计欠款 ¥45,000
|
|||
|
|
- 已发推送
|
|||
|
|
- 业务人员可后续手动追缴
|
|||
|
|
|
|||
|
|
## 冻结跳过
|
|||
|
|
- 8 户冻结中
|
|||
|
|
- 需业务人员核实是否解冻
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 异常介入
|
|||
|
|
|
|||
|
|
| 场景 | 业务人员动作 |
|
|||
|
|
|---|---|
|
|||
|
|
| 跳过的余额不足业户 | 联系业户充值 + 后续手动 ConsumeAction |
|
|||
|
|
| 冻结跳过业户 | 核实纠纷 / 风控状态 → [[unfreeze-after-verification|解冻]] |
|
|||
|
|
| Job 失败(系统异常) | 立即联系运维查日志 |
|
|||
|
|
| 某账户重复抵扣(理论上不应该) | 查 transactions 表是否有同一 Bill 被抵两次 → 立即停 job 排查 |
|
|||
|
|
|
|||
|
|
## 系统流程(目标态)
|
|||
|
|
|
|||
|
|
```mermaid
|
|||
|
|
sequenceDiagram
|
|||
|
|
participant Scheduler
|
|||
|
|
participant Job[PrepaidAutoDeductionJob]
|
|||
|
|
participant Account[PrepaidAccount]
|
|||
|
|
participant Bill
|
|||
|
|
participant Consume[ConsumeFromPrepaidAccountAction]
|
|||
|
|
participant 监听器
|
|||
|
|
participant 数据库
|
|||
|
|
participant 业户
|
|||
|
|
|
|||
|
|
Note over Scheduler: 2026-06-01 00:30 触发
|
|||
|
|
|
|||
|
|
Scheduler->>Job: dispatch
|
|||
|
|
Job->>数据库: SELECT prepaid_accounts WHERE status=Active AND balance>0
|
|||
|
|
|
|||
|
|
loop 每个 account
|
|||
|
|
Job->>数据库: SELECT bills WHERE community_id=? AND resident_id=? AND status='unpaid' ORDER BY due_at, amount
|
|||
|
|
|
|||
|
|
loop 每个 bill
|
|||
|
|
alt balance >= bill.amount
|
|||
|
|
Job->>Consume: handle(account, bill, bill.amount)
|
|||
|
|
Consume->>Account: consume()
|
|||
|
|
Consume->>Bill: recordPayment() → Paid
|
|||
|
|
Consume->>监听器: 触发 CollectionOrderCompleted
|
|||
|
|
监听器->>数据库: 建 Receipt
|
|||
|
|
Consume->>数据库: 提交事务
|
|||
|
|
else 余额不够
|
|||
|
|
Job->>Job: 跳过,记日志
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
Job->>数据库: 写汇总报告
|
|||
|
|
Job-->>Scheduler: 完成
|
|||
|
|
Job->>业户: 批量推送通知
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Job 的安全设计(目标态)
|
|||
|
|
|
|||
|
|
| 风险 | 防御 |
|
|||
|
|
|---|---|
|
|||
|
|
| 同一账户被抵两次(job 重跑) | 每笔 consume 关联 Bill,Bill.status=Paid 后跳过 |
|
|||
|
|
| 跨社区误抵 | `ConsumeFromPrepaidAccountAction` 内置守护(consume 模型方法层) |
|
|||
|
|
| Frozen 账户被抵 | `canOperate()` 守护(模型层) |
|
|||
|
|
| 余额为负 | 事务回滚 + amount ≤ balance 守护 |
|
|||
|
|
| Job 长时间运行影响业务 | 分批 chunk(100 / 批);限制最大并发 |
|
|||
|
|
| Job 半夜失败无人发现 | 失败告警(Slack / 钉钉 / 短信)|
|
|||
|
|
| 业户充值后想立即抵(月中)| 业务人员手动 ConsumeAction(不等下月 job)|
|
|||
|
|
|
|||
|
|
## 与手动 ConsumeAction 的关系
|
|||
|
|
|
|||
|
|
| 维度 | 手动 ConsumeAction | 自动 Job |
|
|||
|
|
|---|---|---|
|
|||
|
|
| 触发 | 业务人员后台点击 | Scheduled(月初)|
|
|||
|
|
| 单次范围 | 1 账户 × 1 账单 | 全平台 × 全部账户 × 全部账单 |
|
|||
|
|
| 业务场景 | 个案、运维、补抵 | 月度默认流程 |
|
|||
|
|
| 通知 | 单笔 Receipt | 批量 Receipt + 汇总推送 |
|
|||
|
|
| 复用代码 | `ConsumeFromPrepaidAccountAction` | **同上**(复用,不重写)|
|
|||
|
|
|
|||
|
|
## 实施前已记录的待讨论项
|
|||
|
|
|
|||
|
|
详见 [[auto-deduction-design]] "待讨论 / 决策" 段。简略列表:
|
|||
|
|
|
|||
|
|
- 触发频率(月度 / 周度 / 实时)
|
|||
|
|
- 触发时点(月初固定 / 账单生成事件触发)
|
|||
|
|
- 优先级排序(due_at / amount / bill_type 组合)
|
|||
|
|
- 部分抵扣支持
|
|||
|
|
- 失败通知策略
|
|||
|
|
- 监控指标
|
|||
|
|
|
|||
|
|
## 未来扩展
|
|||
|
|
|
|||
|
|
job 落地后,后续可演化:
|
|||
|
|
|
|||
|
|
| 演化方向 | 价值 |
|
|||
|
|
|---|---|
|
|||
|
|
| **小程序"我的账单"显示"将于 X 月 1 日自动扣"** | 业户预期管理,避免临时余额不足惊讶 |
|
|||
|
|
| **预扣预警**:月底前 7 天扫描"下月账单 > 当前余额"的业户 → 主动提醒充值 | 减少跳过率,提升用户体验 |
|
|||
|
|
| **零余额自动通知**:月初 job 后,余额 = 0 的账户主动推送"请充值" | 提升复购率 |
|
|||
|
|
| **跨账户均衡**(若同业户多社区):未来若放开跨社区抵扣 | 提升资金利用率 |
|
|||
|
|
|
|||
|
|
## 当前替代(job 实现前)
|
|||
|
|
|
|||
|
|
- 业务人员**月初批量手动**逐户处理(见 [[consume-monthly-property-bill]] + [[consume-multiple-bills-priority]])
|
|||
|
|
- 工作量大,容易遗漏 / 顺序错乱
|
|||
|
|
- **这就是 job 紧迫性的来源**
|
|||
|
|
|
|||
|
|
## 相关文档
|
|||
|
|
|
|||
|
|
- [[auto-deduction-design]]
|
|||
|
|
- [[consume-monthly-property-bill]]
|
|||
|
|
- [[consume-multiple-bills-priority]]
|
|||
|
|
- [[consume-meter-bill]]
|
|||
|
|
- [[consume-via-bill-collection-type]]
|
|||
|
|
- [[audit-low-balance-and-overdue]]
|