客户金额一体化解决方案
信用额度 · 账期 · 客户余额 · 客户欠款 · 客户预付款
适用系统:升鲜宝 SCM 后端 scm--admin与前端 loveinway-admin
文档说明
本文档将客户信用额度、客户账期、客户余额、客户欠款、客户预付款统一到"客户金额中心"的设计口径中,目标是让客户信息页、订单生命周期、对账转应收、收款核销、余额抵扣、逾期拦截和风控强制提交使用同一套金额来源、同一套快照计算、同一套并发幂等规则。
本方案优先兼容现有实现:信用额度继续以 cus_customer.credit_amount、cus_customer.frozen_credit_amount、cus_customer_debt.debt_amount 为核心;账期继续以客户账期主数据和应收/账单快照为核心;客户余额与预付款建议通过资金账户与流水服务统一封装,不建议直接让前端或普通编辑接口维护实时金额。
|--------------------------------------------------------------------------------------------------------------------------------------------|
| 核心结论 可用授信与客户余额必须分开定义:可用授信反映客户信用额度剩余额度;客户余额反映客户可用于抵扣的预付款资金。订单可承接金额可以同时参考"可用余额 + 可用授信",但不要把预付款直接加进 availableCreditAmount,否则会混淆信用额度和客户资金。 |
目录
-
- 方案目标与设计原则
-
- 统一金额口径
-
- 客户金额账户模型
-
- 核心公式与风控判断
-
- 业务生命周期流程
-
- 账期、应收、逾期协同
-
- 数据模型与索引建议
-
- 后端服务与接口设计
-
- 前端页面与交互方案
-
- 并发、幂等与事务一致性
-
- 数据巡检、回填与对账
-
- 实施计划与优先级
-
- 测试用例
-
- 验收标准
-
- 风险与待确认项
1. 方案目标与设计原则
1.1 建设目标
- 统一客户金额视图:客户详情、客户列表、订单页、对账页、收款页看到的授信、余额、欠款、预付款、逾期状态口径一致。
- 统一订单风控:新增、修改、审核、反审核、作废、对账转应收、已支付订单等场景使用同一套金额占用与释放规则。
- 统一账期快照:订单转应收、期初应收、客户账单都写入账期快照和 dueDate,逾期判断基于历史快照,不随主数据变更反向重算。
- 统一客户资金账户:预付款充值、余额冻结、订单抵扣、退款、转预收、核销都写流水,实时余额由账户和流水校验,不靠手工字段维护。
- 统一审计追溯:信用额度强制放行、逾期跳过、余额退款、坏账核销、应收冲抵等高风险动作必须可追溯到单据、策略、操作人和金额快照。
1.2 总体原则
|------------|------------------------------------------------------------------|-------------------------------------------------------|
| 原则 | 说明 | 落地要求 |
| 金额来源唯一 | 每类金额只允许一个主来源,不允许多个模块各算各的。 | 债务看应收,授信看信用占用日志,余额/预付款看资金账户和流水。 |
| 前端只展示和发起动作 | 前端不能直接维护 frozenCreditAmount、debtAmount、frozenPrepayAmount 等实时字段。 | 所有金额变动必须走服务端事务接口。 |
| 快照不可反写 | 历史应收、账单、订单占用日志保留当时金额与账期快照。 | 客户资料、账期、信用额度后续变更不改历史单据。 |
| 先资金后信用 | 订单如果使用客户余额/预付款,应先冻结或扣减可用余额,剩余未覆盖金额再占用授信。 | 避免同一订单同时全额冻结余额和全额冻结授信。 |
| 并发可控 | 金额更新必须具备原子条件、行锁、幂等 key 和明细流水。 | 同一订单重复保存、重复释放、重复转应收不得重复增减金额。 |
| 风控可审计 | 逾期放行、额度不足放行、退款放行必须落策略和原因。 | 记录 policyId、policyName、forceReason、operator、snapshot。 |
1.3 推荐的领域拆分
|---------|-----------------------|----------------------|--------------------------------------------------------|
| 领域 | 负责金额 | 代表动作 | 主服务 |
| 客户信用域 | 授信总额、冻结授信、可用授信、风险敞口 | 授信校验、订单占用、订单释放、强制提交 | CustomerCreditControlService |
| 客户资金域 | 客户余额、预付款余额、冻结预付款、可用余额 | 预存、冻结、释放、消费、退款、余额抵扣 | CustomerFundAccountService |
| 客户应收域 | 客户欠款、未结应收、逾期金额、账龄 | 对账转应收、收款核销、坏账核销、期初应收 | CustomerReceivablePostingService / CustomerDebtService |
| 客户账期域 | 账期主数据、账期快照、到期日、逾期状态 | 账期解析、dueDate 计算、逾期判断 | CustomerReceivablePeriodService |
| 客户金额视图域 | 汇总展示字段、风险提示、可下单额度 | 客户详情、客户列表、订单金额面板 | CustomerAmountSnapshotService |
2. 统一金额口径
客户金额相关字段必须先统一业务含义。下表为推荐口径,后续 DTO、接口字段、页面文案、报表口径均应以该表为准。
|---------|------------------------|-----------------------------------------------|---------------------------------------|--------------------------------------------------------------------|
| 金额项 | 推荐字段 | 业务含义 | 是否可落库 | 维护方式 |
| 授信总额 | creditAmount | 公司允许客户在未付款情况下形成的最高风险额度。为空或小于等于 0 时按不启用额度上限处理。 | 已存在 cus_customer.credit_amount | 客户资料编辑、导入;下调需校验债务+冻结。 |
| 冻结授信 | frozenCreditAmount | 未转应收订单已经占用但尚未转成欠款的信用额度。 | 已存在 cus_customer.frozen_credit_amount | 由授信占用日志原子增减,禁止手工维护。 |
| 客户欠款 | debtAmount | 客户已经形成应收但未结清的金额。 | 已存在 cus_customer_debt.debt_amount | 对账转应收增加;收款/核销/冲抵减少。 |
| 可用授信 | availableCreditAmount | 信用额度剩余可用值,不包含客户预付款。 | 建议计算,不建议手工存 | creditAmount - debtAmount - frozenCreditAmount。 |
| 预付款余额 | prepayBalanceAmount | 客户预先支付且尚未消费或退款的账面预付款余额。 | 建议资金账户表维护 | 预收款增加;抵扣、退款、转出减少。 |
| 冻结预付款 | frozenPrepayAmount | 已被订单锁定、等待订单确认或转应收时消费的预付款。 | 建议资金账户表维护 | 订单保存/审核冻结;作废释放;转应收消费。 |
| 客户可用余额 | availableBalanceAmount | 客户当前可用于抵扣订单或应收的余额。 | 建议计算 | prepayBalanceAmount - frozenPrepayAmount。 |
| 客户净额 | netCustomerAmount | 展示客户资金与债务的净关系,可为正或负。 | 建议计算 | availableBalanceAmount - debtAmount,仅用于展示和报表,不直接替代欠款或余额。 |
| 逾期金额 | overdueAmount | 到期日已过且仍未结清的应收金额。 | 建议计算或快照 | sum(oms_order_bill_debt.still_debt_amount where due_date < 当前日期)。 |
| 可承接订单金额 | orderSupportAmount | 客户可通过余额和授信共同支撑的新订单金额。 | 计算 | availableBalanceAmount + availableCreditAmount;无限授信时显示为余额 + 不限额。 |
|-------------------------------------------------------------------------------------------------------------------------------------------------|
| 余额与预付款的命名建议 建议将"客户余额"定义为"可用余额",即客户预付款余额扣除冻结预付款后的可抵扣金额;将"客户净额"单独作为展示字段,表示可用余额减欠款。不要让同一个 balance 字段有时表示预付款、有时表示净额、有时表示欠款,否则订单风控、对账和报表会出现口径冲突。 |
2.1 不同金额之间的关系
|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 客户资金侧: prepayBalanceAmount = 累计预收 - 累计消费抵扣 - 累计退款 - 累计转出 availableBalanceAmount = prepayBalanceAmount - frozenPrepayAmount 客户应收侧: debtAmount = 已生成应收未结清金额 overdueAmount = 到期日已过且 stillDebtAmount > 0 的应收金额 客户信用侧: availableCreditAmount = creditAmount - debtAmount - frozenCreditAmount riskExposureAmount = debtAmount + frozenCreditAmount 订单侧: prepayDeductAmount = min(订单未支付金额, availableBalanceAmount, 本次选择使用余额金额) creditOccupyAmount = max(订单未支付金额 - prepayDeductAmount, 0) nextExposureAmount = debtAmount + frozenCreditAmount + creditOccupyAmount |
2.2 推荐展示口径
|----------|-------------------------------------|------------------------------------|
| 页面字段 | 展示值 | 说明 |
| 授信总额 | creditAmount | 客户资料维护项。为空/0 可显示"不限制额度"或"未启用额度上限"。 |
| 客户欠款 | debtAmount | 当前未结应收金额,不用预付款余额直接抵减展示。 |
| 冻结授信 | frozenCreditAmount | 未转应收订单占用信用额度。 |
| 可用授信 | availableCreditAmount | 授信剩余额度,不包含余额。若授信不限额,显示"不限"。 |
| 预付款余额 | prepayBalanceAmount | 客户账面预付款。 |
| 冻结余额 | frozenPrepayAmount | 订单已锁定但尚未消费的预付款。 |
| 客户可用余额 | availableBalanceAmount | 可用于订单抵扣、应收冲抵或退款审批的资金。 |
| 客户净额 | availableBalanceAmount - debtAmount | 用于财务视角判断客户整体是预存为主还是欠款为主。 |
| 逾期状态 | overdueState / overdueStateStr | 基于应收明细 dueDate 和 stillDebtAmount。 |
3. 客户金额账户模型
3.1 总体模型
建议采用"客户主档 + 信用占用日志 + 应收欠款表 + 预付款账户 + 金额流水 + 金额快照服务"的组合模型。金额快照服务负责对外展示和风控读取,底层金额表负责事务更新和审计追溯。
|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 客户主档 cus_customer ├─ credit_amount:授信总额 ├─ frozen_credit_amount:冻结授信 └─ period_id:客户账期 客户应收 cus_customer_debt / oms_order_bill_debt ├─ debt_amount:客户欠款 ├─ still_debt_amount:应收明细未结金额 └─ due_date:账期快照计算的到期日 客户资金 cus_customer_fund_account / cus_customer_fund_flow ├─ prepay_balance_amount:预付款余额 ├─ frozen_prepay_amount:冻结预付款 └─ available_balance_amount:可用余额,计算值 客户金额快照 CustomerAmountSnapshotService └─ 汇总授信、欠款、余额、预付款、逾期、可下单额度 |
3.2 现有字段与建议补充字段
|------------------------------|-----------------------------------------------------------------------------------|-----------|-----------------------------------------------|
| 表/对象 | 现有或建议字段 | 用途 | 说明 |
| cus_customer | credit_amount | 授信总额 | 客户新增、编辑、导入、导出维护。 |
| cus_customer | frozen_credit_amount | 冻结授信 | 由 CustomerCreditControlService 原子增减。 |
| cus_customer | period_id | 客户账期 | 客户账期优先级高于客户等级账期。 |
| cus_customer_debt | debt_amount | 客户欠款 | 应收、收款、核销等动作影响。 |
| oms_order_bill_debt | still_debt_amount, due_date, period_* | 应收明细和逾期判断 | 账期快照不可被主数据反向改写。 |
| cus_credit_occupy_log | order_code, occupy_amount, release_amount, occupy_state, idempotent_key | 订单级信用占用 | source_type + order_code 或 idempotent_key 唯一。 |
| cus_credit_occupy_detail_log | stage, scene, before/after amount, delta | 信用占用明细 | 用于审计和问题追踪。 |
| cus_customer_fund_account | prepay_balance_amount, frozen_prepay_amount, version | 客户资金账户 | 若系统已有客户余额/预付款表,则封装适配,不必重复建表。 |
| cus_customer_fund_flow | flow_no, customer_id, business_type, business_no, direction, amount, before/after | 客户资金流水 | 预收、冻结、释放、消费、退款、冲抵都落流水。 |
| cus_prepay_occupy_log | source_type, source_no, occupy_amount, consume_amount, release_amount, state | 订单级余额冻结 | 用于防止预付款被多个订单重复使用。 |
3.3 客户金额快照 DTO
新增或抽取 CustomerAmountSnapshotDTO,客户列表、详情、订单页、授信校验结果均复用该 DTO 或其子集。
|------------------------|-------------------|-----------------------------------------------|
| 字段 | 类型 | 含义 |
| customerId | Long | 客户 ID。 |
| creditAmount | BigDecimal | 授信总额。 |
| debtAmount | BigDecimal | 客户欠款。 |
| frozenCreditAmount | BigDecimal | 冻结授信。 |
| availableCreditAmount | BigDecimal / null | 可用授信;授信不限额时可返回 null 并配合 unlimitedCredit=true。 |
| unlimitedCredit | Boolean | creditAmount 为空或小于等于 0。 |
| prepayBalanceAmount | BigDecimal | 预付款余额。 |
| frozenPrepayAmount | BigDecimal | 冻结预付款。 |
| availableBalanceAmount | BigDecimal | 客户可用余额。 |
| netCustomerAmount | BigDecimal | 客户净额,可用余额 - 欠款。 |
| riskExposureAmount | BigDecimal | 当前风险敞口,欠款 + 冻结授信。 |
| overdueAmount | BigDecimal | 逾期金额。 |
| overdueState | Integer | 是否逾期。 |
| overdueStateStr | String | 逾期状态文案。 |
| earliestDueDate | Date | 最早逾期或最早未结应收到期日。 |
| periodId / periodName | Long / String | 客户当前账期展示。 |
| snapshotTime | DateTime | 快照生成时间。 |
4. 核心公式与风控判断
4.1 信用额度公式
沿用现有授信控制口径:信用额度主要约束未付款风险敞口,不直接把客户余额算进 availableCreditAmount。
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| currentDebt = cus_customer_debt.debt_amount frozenCreditAmount = cus_customer.frozen_credit_amount availableCreditAmount = creditAmount - currentDebt - frozenCreditAmount 编辑/审核已有订单时: 校验时通过 excludeOrderCode 扣除本订单当前占用,避免重复计算。 已支付订单: paymentState = 1 时,nextOrderCreditAmount = 0。 |
4.2 余额与预付款公式
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| prepayBalanceAmount = 预收款累计余额 frozenPrepayAmount = 已被订单冻结但未消费的预付款 availableBalanceAmount = prepayBalanceAmount - frozenPrepayAmount 订单使用余额: requestedUseBalanceAmount = 前端选择或系统默认使用的余额金额 prepayDeductAmount = min(orderUnpaidAmount, availableBalanceAmount, requestedUseBalanceAmount) creditOccupyAmount = max(orderUnpaidAmount - prepayDeductAmount, 0) |
4.3 订单风控判断
|----------|---------------------------------------------------------------------------------------|-----------------------------------------|
| 判断项 | 公式/规则 | 结果 |
| 余额是否足够 | availableBalanceAmount >= requestedUseBalanceAmount | 不足时可自动降低余额使用金额,剩余部分转授信;若用户指定必须余额支付,则失败。 |
| 授信是否足够 | creditAmount <= 0 或 currentDebt + frozenCredit + creditOccupyAmount <= creditAmount | 不足时不允许直接提交,除非风控策略允许跳过额度限制。 |
| 是否逾期 | 存在 stillDebtAmount > 0 且 dueDate < 当前日期的应收 | 默认拦截新订单;可配置"现款/余额单允许逾期客户下单"策略。 |
| 是否允许提交 | 非逾期且余额/授信满足 | allowed=true。 |
| 是否允许强制提交 | 逾期或额度不足命中 B2bRiskControlPolicyService 放行策略 | forceSubmitAllowed=true,并要求记录原因。 |
|-------------------------------------------------------------------------------------------------------|
| 可用授信与可下单金额 可用授信只代表信用额度剩余值;可下单金额可以同时由可用余额和可用授信支撑。因此订单页建议同时展示"可用余额""可用授信""本单余额抵扣""本单授信占用""提交后剩余授信"。 |
4.4 逾期控制策略
|----------|------------|---------------------|-----------------------------|
| 客户状态 | 订单支付方式 | 推荐默认规则 | 可选策略 |
| 无逾期 | 余额/现款/授信 | 按余额和授信充足性判断。 | 无。 |
| 有逾期 | 纯授信单 | 拦截。 | 风控策略允许跳过逾期时可强制提交。 |
| 有逾期 | 余额全额覆盖 | 建议仍默认拦截,避免逾期客户继续交易。 | 可配置"逾期客户仅允许现款/余额单"。 |
| 有逾期 | 现金已支付 | 建议可由策略放行。 | 记录 paymentState、支付凭证、策略。 |
| 有欠款但未逾期 | 余额退款 | 建议拦截或审批。 | 允许退款时必须记录审批原因,避免客户有欠款仍退预付款。 |
5. 业务生命周期流程
5.1 总流程
|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 客户预收款/充值 -> 增加预付款余额,写资金流水 订单新增/修改/审核 -> 读取客户金额快照 -> 可用余额先冻结 -> 剩余未覆盖金额占用授信 -> 写预付款占用日志、信用占用日志、明细日志 订单反审核/作废/取消 -> 释放预付款冻结 -> 释放授信冻结 -> 写释放流水和日志 订单对账转应收 -> 解析账期快照并计算 dueDate -> 生成应收明细 -> 消费已冻结预付款 -> 释放订单冻结授信 -> 客户欠款只增加未被预付款/现款覆盖的部分 收款/核销/冲抵 -> 减少客户欠款 -> 如发生多收,转入预付款余额 -> 更新应收结算状态和客户金额快照 |
5.2 新增订单
-
前端选择客户后调用客户金额快照接口,展示信用额度、欠款、冻结授信、可用授信、预付款余额、可用余额和逾期状态。
-
订单保存前调用金额预校验接口,传入 orderAmount、paymentState、useBalanceFlag、requestedUseBalanceAmount、scene=SAVE。
-
后端计算本单余额抵扣金额 prepayDeductAmount 和本单信用占用金额 creditOccupyAmount。
-
如果客户存在逾期且未命中可放行策略,返回不可提交。
-
保存订单时后端必须再次执行 reserve,不依赖前端预校验结果。
-
reserve 成功后写入订单金额快照,包括本单余额冻结金额、本单授信占用金额、客户金额快照时间。
5.3 修改订单
|-----------|----------------------------|----------------------------------|
| 变更类型 | 处理规则 | 金额影响 |
| 订单金额增加 | 重新计算目标余额冻结和目标授信占用。 | 余额冻结或授信冻结按 delta 增加;不足则修改失败或走风控。 |
| 订单金额减少 | 目标占用小于当前占用。 | 释放多余余额冻结和授信冻结。 |
| 支付状态改为已支付 | 本单不再需要授信占用。 | 释放授信;如果支付来源为预付款,则消费或冻结预付款。 |
| 取消使用余额 | 重新计算余额抵扣为 0。 | 释放余额冻结,剩余金额改为授信占用并重新校验。 |
| 增加使用余额 | 检查 availableBalanceAmount。 | 增加余额冻结,减少授信占用。 |
5.4 审核订单
- 审核前再次调用金额校验,传入 excludeOrderCode,避免把本订单已有冻结重复计算为新增占用。
- 审核动作执行前再次 reserve,确保审核时订单金额、支付状态、余额使用金额未被并发修改。
- 如果前端传入 forceSubmitFlag,后端必须验证风控策略,不得只凭前端参数放行。
- 强制提交必须写入业务日志和风控审计日志,记录额度不足、逾期、余额不足等具体原因。
5.5 反审核、作废、取消
|--------|---------------------------------|-----------------------------------------|---------------|
| 动作 | 预付款处理 | 授信处理 | 幂等要求 |
| 反审核 | 释放本订单仍处于冻结中的预付款。 | releaseOrderCredit(orderCode, '反审核释放')。 | 重复调用不重复释放。 |
| 作废 | 释放预付款冻结;如已消费,必须走退款/冲销流程,不直接改账户。 | 释放授信占用。 | 按订单状态和占用状态判断。 |
| 取消保存草稿 | 释放草稿订单占用。 | 释放授信占用。 | 不存在占用时直接返回成功。 |
| 删除订单 | 原则上只允许未审核、未转应收且占用已释放的订单删除。 | 删除前校验无 active 占用。 | 删除不作为释放的唯一入口。 |
5.6 对账转应收
对账转应收是客户金额从"订单风险占用"进入"应收欠款"的关键节点。必须在同一事务中完成账期快照、应收生成、余额消费、授信释放、欠款增加和日志落地。
|--------|----------------------------------------------------------------------------------|-----------------------------------------------------------------------|
| 步骤 | 处理 | 关键点 |
| 1 | 读取订单余额冻结日志和授信占用日志。 | 使用 source_type + orderCode 加锁。 |
| 2 | 调用 CustomerReceivablePeriodService.resolveSnapshot(customerId, periodStartDate)。 | 写入 period_id、period_name、period_type、period_days、period_day、due_date。 |
| 3 | 按订单金额生成应收明细。 | 应收原始金额可保留全额,便于对账。 |
| 4 | 消费已冻结预付款并写自动冲抵记录。 | 仍需保留抵扣明细,避免直接少记应收导致审计困难。 |
| 5 | 释放本订单冻结授信。 | 风险从 frozenCreditAmount 转为 debtAmount。 |
| 6 | 客户欠款只增加未结金额。 | 未结金额 = 应收金额 - 预付款抵扣 - 现款支付 - 其他核销。 |
| 7 | 更新应收 settlement_state、overdue_state 初始值。 | 后续逾期任务或查询按 dueDate 更新/计算。 |
5.7 收款、核销、预付款冲抵
|-----------|------------------|--------------------------------------------|
| 场景 | 处理方式 | 金额影响 |
| 普通收款核销应收 | 收款单指定应收明细进行核销。 | debtAmount 减少;stillDebtAmount 减少;逾期状态可能恢复。 |
| 收款大于应收 | 超出部分转为客户预付款。 | debtAmount 清零或减少;prepayBalanceAmount 增加。 |
| 使用预付款冲抵欠款 | 生成预付款冲抵单,关联应收明细。 | prepayBalanceAmount 减少;debtAmount 减少。 |
| 预付款退款 | 从可用余额退款。 | prepayBalanceAmount 减少;如客户有欠款或逾期,建议审批或拦截。 |
| 坏账核销 | 经审批减少应收欠款。 | debtAmount 减少;不增加客户余额;必须可审计。 |
6. 账期、应收、逾期协同
6.1 账期快照规则
- 客户账期主数据负责维护账期名称、固定天数、固定日、启用状态、排序和备注。
- 客户账期优先于客户等级账期;客户账期无效或禁用时,建议回退客户等级有效账期。
- 订单转应收、期初应收、客户账单生成时写入账期快照和 dueDate。
- 历史应收和历史账单不随账期主数据变更自动重算。
- 逾期判断以应收明细 stillDebtAmount 和 dueDate 为准,余额/预付款只有在实际冲抵后才减少 stillDebtAmount。
6.2 到期日计算
|----------|------------------------------------|----------------------------------------------|------------------------------------|
| 账期类型 | 配置 | 计算规则 | 示例 |
| 固定天数 | periodType=0, customerPeriodDate=N | dueDate = periodStartDate + N 天。 | 2026-07-03 + 30 天 = 2026-08-02。 |
| 固定日 | periodType=1, periodDay=D | 起算日的日 <= D,取当月 D 日;否则取下月 D 日;目标月份无 D 日则取月末。 | 2026-07-20, 固定日 15 => 2026-08-15。 |
6.3 逾期与余额/预付款的关系
|------------------------------|----------|---------------------------------------|
| 情况 | 是否逾期 | 说明 |
| 应收未结,dueDate 已过,客户有足够预付款但未冲抵 | 仍逾期 | 预付款不能自动消除逾期,必须有冲抵/核销单据。 |
| 应收已被预付款冲抵至 stillDebtAmount=0 | 不逾期 | 逾期基于未结金额。 |
| 订单全额预付款支付,未形成未结应收 | 不产生该订单逾期 | 应收明细可保留全额和结算明细,但 stillDebtAmount 为 0。 |
| 客户存在旧逾期,新订单全额余额支付 | 默认仍拦截 | 可通过风险策略配置允许现款/余额单。 |
6.4 应收快照字段建议
|---------------------|----------------------------------------------------------------------------------------------------------------------------|-------------------------|
| 表 | 建议字段 | 原因 |
| oms_order_bill_debt | period_id, period_name, period_type, period_days, period_day, period_start_date, due_date, overdue_state, settlement_state | 完整还原应收生成时账期规则。 |
| fin_customer_bill | 建议补齐 period_type, period_days, period_day | 客户账单用于催收、授信、账龄分析时需要可追溯。 |
| 客户金额快照 | earliestDueDate, overdueAmount, overdueCount | 客户列表和订单页快速提示风险。 |
7. 数据模型与索引建议
7.1 客户资金账户表
如果现系统已有客户余额或预付款账户表,建议不重复建表,而是通过 CustomerFundAccountService 做适配。若没有统一账户,建议新增以下逻辑表。
|---------------------------|---------------|-------------|
| 字段 | 类型建议 | 说明 |
| id | bigint | 主键。 |
| customer_id | bigint | 客户 ID,唯一索引。 |
| prepay_balance_amount | decimal(18,2) | 预付款账面余额。 |
| frozen_prepay_amount | decimal(18,2) | 冻结预付款。 |
| version | int | 乐观锁版本,可选。 |
| enabled | tinyint | 状态。 |
| create_time / update_time | datetime | 审计字段。 |
7.2 客户资金流水表
|--------------------------------|---------------|--------------------------------------------------------|
| 字段 | 类型建议 | 说明 |
| flow_no | varchar(64) | 流水号,唯一。 |
| customer_id | bigint | 客户 ID。 |
| business_type | varchar(32) | PREPAY_IN、FREEZE、RELEASE、CONSUME、REFUND、OFFSET、ADJUST。 |
| business_no | varchar(64) | 订单号、收款单号、退款单号、核销单号。 |
| direction | tinyint | 1=增加,-1=减少,0=冻结/解冻记录。 |
| amount | decimal(18,2) | 变动金额。 |
| before_balance / after_balance | decimal(18,2) | 变动前后预付款余额。 |
| before_frozen / after_frozen | decimal(18,2) | 变动前后冻结金额。 |
| idempotent_key | varchar(128) | 幂等键。 |
| remark | varchar(255) | 说明。 |
7.3 预付款占用日志
|----------------|-------------------------------|
| 字段 | 说明 |
| source_type | 来源类型,例如 OMS_ORDER。 |
| source_no | 来源单号,例如 orderCode。 |
| customer_id | 客户 ID。 |
| occupy_amount | 累计冻结金额。 |
| consume_amount | 累计消费金额。 |
| release_amount | 累计释放金额。 |
| state | 1=冻结中,2=已消费,3=已释放,4=已作废。 |
| idempotent_key | PREPAY:OMS_ORDER:{orderCode}。 |
7.4 索引与唯一约束
|---------------------------|------------------------------------------------------------------------|----------------|
| 对象 | 索引/约束 | 目的 |
| cus_credit_occupy_log | unique(source_type, order_code) 或 unique(idempotent_key) | 防止同一订单重复占用授信。 |
| cus_prepay_occupy_log | unique(source_type, source_no) | 防止同一订单重复冻结预付款。 |
| cus_customer_fund_account | unique(customer_id) | 一个客户一个资金账户。 |
| cus_customer_fund_flow | unique(idempotent_key), index(customer_id, business_type, business_no) | 流水幂等和查询。 |
| oms_order_bill_debt | index(customer_id, due_date, still_debt_amount, del_flag, enabled) | 逾期查询和风控拦截。 |
| cus_customer_debt | unique(customer_id) | 一个客户一条欠款汇总。 |
7.5 金额原子更新示例
|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| -- 冻结预付款:可用余额必须足够 update cus_customer_fund_account set frozen_prepay_amount = frozen_prepay_amount + #{amount}, update_time = now() where customer_id = #{customerId} and prepay_balance_amount - frozen_prepay_amount >= #{amount}; -- 释放预付款:避免冻结金额为负 update cus_customer_fund_account set frozen_prepay_amount = greatest(frozen_prepay_amount - #{amount}, 0), update_time = now() where customer_id = #{customerId}; -- 消费预付款:从冻结金额和预付款余额同时扣减 update cus_customer_fund_account set prepay_balance_amount = prepay_balance_amount - #{amount}, frozen_prepay_amount = greatest(frozen_prepay_amount - #{amount}, 0), update_time = now() where customer_id = #{customerId} and prepay_balance_amount >= #{amount} and frozen_prepay_amount >= #{amount}; |
8. 后端服务与接口设计
8.1 服务分层
|---------------------------------|--------|--------------------------------------------|
| 服务 | 类型 | 职责 |
| CustomerAmountSnapshotService | 新增/抽取 | 汇总客户授信、欠款、余额、预付款、账期、逾期状态,对列表、详情、订单页提供统一快照。 |
| CustomerCreditControlService | 现有增强 | 授信校验、占用、调整、释放、强制提交策略结果。 |
| CustomerFundAccountService | 新增/适配 | 预付款充值、冻结、释放、消费、退款、冲抵、流水。 |
| CustomerAmountOrderService | 新增编排 | 订单保存/审核前统一协调余额冻结与授信占用。 |
| CustomerReceivablePeriodService | 现有增强 | 解析客户账期快照,计算 dueDate。 |
| CustomerDebtService | 抽取/增强 | 客户欠款汇总维护、应收明细核销、逾期汇总。 |
| CustomerAmountAuditService | 新增 | 强制提交、额度调整、余额退款、坏账核销等审计记录。 |
8.2 客户金额快照接口
|------------------------------------------|--------|--------------|---------------------------------------------------------------------------------------------------------------------------------|
| 接口 | 方法 | 用途 | 关键返回 |
| /cus/mallshop/{id} | GET | 客户详情 | creditAmount, debtAmount, frozenCreditAmount, availableCreditAmount, prepayBalanceAmount, availableBalanceAmount, overdueState。 |
| /cus/mallshop/page | GET | 客户列表 | 授信、欠款、余额、逾期摘要字段。 |
| /cus/customerAmountSnapshot/{customerId} | GET | 订单页选择客户后实时快照 | 完整 CustomerAmountSnapshotDTO。 |
| /cus/mallshop/creditOccupyOrders | GET | 冻结授信订单列表 | orderCode, occupyAmount, stage, occupyTime。 |
| /cus/mallshop/prepayOccupyOrders | GET | 冻结余额订单列表 | orderCode, occupyAmount, state, occupyTime。 |
| /cus/mallshop/fundFlows | GET | 客户资金流水 | 业务类型、金额、前后余额、业务单号。 |
| /cus/mallshop/receivableAging | GET | 应收账龄和逾期明细 | 未结金额、到期日、逾期天数。 |
8.3 订单金额预校验接口
|---------------------------------------------------|----------|-------------------------------------|
| 接口 | 方法 | 用途 |
| /oms/omsorderbill/checkCustomerAmountBeforeSave | POST | 新增/修改订货单保存前校验余额、授信、逾期。 |
| /oms/omsorderbill/checkCustomerAmountBeforeSubmit | POST | 审核提交前校验余额、授信、逾期,支持 forceSubmitFlag。 |
| /oms/omsorderbill/save | POST | 服务端保存时再次 reserve 余额和授信。 |
| /oms/omsorderbill/update | PUT | 按目标金额调整余额冻结和授信占用。 |
| 订单审核接口 | POST/PUT | 审核时再次校验并记录风险策略。 |
| 反审核/作废/取消接口 | POST/PUT | 释放余额冻结和授信占用。 |
| 对账转应收接口 | POST | 消费冻结预付款、释放冻结授信、生成应收和账期快照。 |
8.4 预付款/余额接口
|--------------------------------------|--------|------------------------------|
| 接口 | 方法 | 规则 |
| /fin/customerPrepay/recharge | POST | 客户预收款入账,增加预付款余额,写资金流水。 |
| /fin/customerPrepay/refund | POST | 预付款退款,只能退可用余额;客户有欠款或逾期时建议审批。 |
| /fin/customerPrepay/offsetReceivable | POST | 使用预付款冲抵应收,减少余额和欠款。 |
| /fin/customerPrepay/adjust | POST | 财务调账,必须审批并写原因。 |
| /fin/customerPrepay/flows | GET | 查询客户资金流水。 |
8.5 预校验返回 DTO
|-------------------------------------------------------------------------|----------------|
| 字段 | 含义 |
| allowed | 是否允许直接提交。 |
| creditEnough | 授信是否足够。 |
| balanceEnough | 本次要求使用的余额是否足够。 |
| overdue | 客户是否存在逾期应收。 |
| forceSubmitAllowed | 是否允许强制提交。 |
| message | 前端提示文案。 |
| creditAmount / currentDebt / frozenCreditAmount / availableCreditAmount | 授信相关快照。 |
| prepayBalanceAmount / frozenPrepayAmount / availableBalanceAmount | 余额/预付款相关快照。 |
| orderAmount / paidAmount / prepayDeductAmount / creditOccupyAmount | 本单金额拆分。 |
| exposureAmount / nextExposureAmount | 当前和提交后的风险敞口。 |
| overdueAmount / earliestDueDate | 逾期提示。 |
| riskPolicyId / riskPolicyName / forceSubmitReason | 风控策略与强制提交原因。 |
9. 前端页面与交互方案
9.1 客户列表
|--------|---------------|-------------|
| 字段 | 展示建议 | 交互 |
| 授信总额 | 金额或"不限额"。 | 可筛选额度区间。 |
| 客户欠款 | 金额,欠款大于 0 高亮。 | 点击查看未结应收。 |
| 冻结授信 | 金额。 | 点击查看冻结占用订单。 |
| 可用授信 | 金额或"不限"。 | 低于阈值提示。 |
| 预付款余额 | 金额。 | 点击查看资金流水。 |
| 冻结余额 | 金额。 | 点击查看余额冻结订单。 |
| 可用余额 | 金额。 | 可用于订单抵扣。 |
| 逾期状态 | 正常/逾期/严重逾期。 | 点击查看逾期应收。 |
9.2 客户详情
- 顶部金额卡片:授信总额、可用授信、客户欠款、冻结授信、预付款余额、可用余额、逾期金额、客户净额。
- 授信信息区:支持编辑授信总额,但冻结授信、可用授信只读。额度下调时后端校验 debtAmount + frozenCreditAmount。
- 账期信息区:展示客户账期、等级账期、最终生效账期、到期日示例。
- 占用订单区:分别展示信用占用订单和余额冻结订单。
- 应收明细区:展示未结应收、dueDate、逾期天数、账期快照。
- 资金流水区:展示预存、冻结、释放、消费、退款、冲抵、调账。
9.3 订单页面
|--------|--------------------------|-----------------------------------------------|
| 节点 | 前端行为 | 后端要求 |
| 选择客户 | 加载客户金额面板。 | 调用快照接口,实时返回余额、授信、欠款、逾期。 |
| 录入商品金额 | 实时估算本单金额拆分。 | 以提交时后端计算为准。 |
| 选择使用余额 | 允许输入本单余额抵扣金额,默认值可按业务配置。 | 不能超过可用余额和订单未支付金额。 |
| 保存前校验 | 弹窗提示本单余额抵扣、本单授信占用、提交后授信。 | 调用 checkCustomerAmountBeforeSave。 |
| 审核前校验 | 逾期或额度不足时展示强制提交入口。 | 调用 checkCustomerAmountBeforeSubmit,强制提交必须传原因。 |
| 提交成功 | 刷新客户金额面板。 | 返回最新 CustomerAmountSnapshotDTO。 |
9.4 文案建议
|--------|---------------------------------------------------------------------------------------------|
| 场景 | 推荐文案 |
| 额度不足 | 客户当前可用授信不足,本单需占用授信 {creditOccupyAmount},提交后风险敞口 {nextExposureAmount},超过授信总额 {creditAmount}。 |
| 余额不足 | 客户可用余额不足,本次最多可使用余额 {availableBalanceAmount},剩余金额将占用授信或请调整支付方式。 |
| 逾期拦截 | 客户存在逾期应收 {overdueAmount},最早到期日 {earliestDueDate},请先收款核销或按风控策略强制提交。 |
| 额度下调失败 | 授信额度不能低于当前欠款与冻结授信占用合计:{debtAmount + frozenCreditAmount}。 |
| 退款拦截 | 客户存在未结欠款或逾期应收,预付款退款需先冲抵欠款或走审批。 |
10. 并发、幂等与事务一致性
10.1 幂等键规范
|--------|-------------------------------------------|---------------------------------------|
| 业务 | 幂等键 | 说明 |
| 订单信用占用 | CREDIT:OMS_ORDER:{orderCode} | 复用现有 OMS_ORDER:orderCode 也可,但建议加领域前缀。 |
| 订单余额冻结 | PREPAY:OMS_ORDER:{orderCode} | 同一订单只允许一条 active 预付款占用。 |
| 订单转应收 | AR_POSTING:{orderCode 或 reconciliationNo} | 避免重复生成应收和重复消费预付款。 |
| 收款核销 | RECEIPT:{receiptNo}:{debtId} | 避免同一收款重复核销。 |
| 预付款退款 | PREPAY_REFUND:{refundNo} | 避免重复退款。 |
| 预付款冲抵 | PREPAY_OFFSET:{offsetNo} | 避免重复抵扣应收。 |
10.2 锁顺序
为避免死锁,涉及同一客户多类金额变动时建议固定锁顺序:
-
锁客户资金账户:cus_customer_fund_account where customer_id = ? for update。
-
锁信用占用日志:cus_credit_occupy_log by source_type + orderCode for update。
-
锁预付款占用日志:cus_prepay_occupy_log by source_type + sourceNo for update。
-
锁客户欠款汇总:cus_customer_debt where customer_id = ? for update。
-
写业务单据、金额流水、审计日志。
|------------------------------------------------------------------------------------------------------------------------|
| 事务边界 订单保存、审核、作废、反审核、转应收、收款核销、预付款退款必须以服务端事务为边界。预校验接口只用于提示,不改变金额;最终金额变动以保存/审核/转应收等业务接口内的 reserve/release/consume 为准。 |
10.3 金额精度与负数保护
- 所有金额使用 BigDecimal,统一 scale=2 或按系统币种配置,不允许 double/float。
- 订单金额、抵扣金额、占用金额、释放金额必须 >= 0。
- 消费预付款必须同时满足 prepay_balance_amount >= amount 且 frozen_prepay_amount >= amount。
- 释放冻结金额使用 min(activeOccupyAmount, requestReleaseAmount),避免重复释放造成负数。
- 客户欠款不应小于 0;多收款进入预付款,不把 debtAmount 直接扣成负数。
10.4 强制提交审计
|------------------------|---------------------------------------------------------------|
| 字段 | 说明 |
| customerId / orderCode | 客户与订单。 |
| scene | SAVE、SUBMIT、AUDIT、REFUND、OFFSET。 |
| riskType | OVERDUE、CREDIT_NOT_ENOUGH、REFUND_WITH_DEBT、BALANCE_EXCEPTION。 |
| policyId / policyName | 命中的风控策略。 |
| forceSubmitReason | 操作人填写原因。 |
| operator / operateTime | 操作人和时间。 |
| amountSnapshot | 操作时客户金额快照 JSON。 |
11. 数据巡检、回填与对账
11.1 每日巡检项
|----------|------------------------------------------------------------------------|-------------------------|
| 巡检项 | 规则 | 异常处理 |
| 冻结授信一致性 | cus_customer.frozen_credit_amount = active cus_credit_occupy_log 占用合计。 | 以日志为准或按业务确认修复。 |
| 冻结预付款一致性 | fund_account.frozen_prepay_amount = active prepay_occupy_log 占用合计。 | 查重复订单和重复释放。 |
| 客户欠款一致性 | cus_customer_debt.debt_amount = 未结应收汇总。 | 检查应收生成、收款核销、冲抵、坏账。 |
| 逾期状态一致性 | stillDebtAmount > 0 且 dueDate < 当前日期应标记逾期或查询可计算逾期。 | 修复 overdue_state 或查询逻辑。 |
| 负数金额 | debt、frozen、prepay、occupy 不允许负数。 | 锁定客户,核对流水后修复。 |
| 重复幂等键 | 各日志 idempotent_key 唯一。 | 禁止上线重复数据;历史需合并。 |
11.2 上线前数据检查
- 确认 cus_customer.credit_amount、cus_customer.frozen_credit_amount、cus_customer_debt.debt_amount 字段存在且历史口径正确。
- 确认 cus_credit_occupy_log 与 cus_credit_occupy_detail_log 的 source_type + order_code 或 idempotent_key 唯一约束。
- 确认 oms_order_bill_debt 的 due_date、still_debt_amount、period_* 快照字段完整,逾期查询性能可接受。
- 确认客户余额/预付款历史表与收款、退款、核销流程的关系;若存在多个余额字段,先出字段映射表。
- 确认客户详情页和订单页改造不会直接保存 frozenCreditAmount、debtAmount、frozenPrepayAmount。
11.3 历史数据回填策略
|--------|--------------------------------------------------------|----------------------------|
| 对象 | 回填策略 | 注意事项 |
| 账期快照 | 只回填缺失快照且业务确认需要回填的历史应收。 | 不要因为账期主数据变更重算已正常存在的历史快照。 |
| 客户欠款 | 按未结应收汇总核对 cus_customer_debt。 | 先只读统计,再小批量修复。 |
| 冻结授信 | 按 active 信用占用日志汇总核对 cus_customer.frozen_credit_amount。 | 若日志缺失,不应直接猜测订单占用,需按订单状态确认。 |
| 预付款余额 | 以历史收款/预收/退款/冲抵流水为基础初始化。 | 若历史流水不完整,需财务确认期初余额。 |
| 冻结预付款 | 按未完成订单余额冻结日志汇总。 | 没有冻结日志的历史订单,不建议自动冻结余额。 |
12. 实施计划与优先级
|---------|----------------------------------|--------------------------------------|--------------------------|
| 优先级 | 任务 | 交付物 | 说明 |
| P0 | 确认客户金额口径 | 字段定义表、页面文案、公式说明 | 尤其确认客户余额是否等于可用预付款余额。 |
| P0 | 抽取 CustomerAmountSnapshotService | 统一客户金额快照 DTO | 客户列表、详情、订单页共用。 |
| P0 | 订单授信与余额预校验 | checkCustomerAmountBeforeSave/Submit | 先实现余额抵扣金额和授信占用金额拆分。 |
| P0 | 订单占用/释放统一编排 | CustomerAmountOrderService | 新增、修改、审核、反审核、作废全部接入。 |
| P0 | 对账转应收一体化 | 转应收事务改造 | 账期快照、预付款消费、授信释放、欠款增加同事务。 |
| P1 | 资金账户与流水 | CustomerFundAccountService | 如已有表,先适配;如没有,新增账户和流水表。 |
| P1 | 前端客户金额面板 | 客户列表/详情/订单页 | 展示授信、欠款、余额、预付款、逾期。 |
| P1 | 风控策略与审计 | 强制提交日志和报表 | 支持逾期放行、额度不足放行、现款单放行。 |
| P1 | 数据巡检脚本 | 一致性 SQL、修复脚本 | 冻结授信、冻结预付款、客户欠款、逾期状态。 |
| P2 | 报表与监控 | 金额异常看板 | 负数金额、重复幂等、逾期金额、强制提交。 |
12.1 开发改造清单
|-------------------|-----------------------------------------|
| 模块 | 改造点 |
| 后端 cus | 客户金额快照、客户详情 DTO、信用额度下调保护、冻结订单列表、资金流水列表。 |
| 后端 oms | 订单保存/修改/审核前校验,余额冻结、授信占用、占用差额调整。 |
| 后端 fin/receivable | 预收款入账、预付款抵扣、退款、收款核销、转应收同事务处理。 |
| 后端 period | 账期快照解析、dueDate 计算、逾期查询。 |
| 前端 mallshop | 客户金额字段展示、详情卡片、占用订单、资金流水、应收明细。 |
| 前端 omsorderbill | 客户金额面板、使用余额、授信校验、强制提交原因。 |
| 数据库 | 账户表、流水表、预付款占用日志、索引、巡检 SQL。 |
13. 测试用例
13.1 金额公式测试
|-----------|------------------------------------------------------|-------------------------------------|
| 场景 | 数据 | 预期 |
| 授信充足 | credit=1000, debt=200, frozenCredit=100, 新订单未支付 600 | 允许;本单授信占用 600;提交后风险敞口 900。 |
| 授信不足 | credit=1000, debt=200, frozenCredit=100, 新订单未支付 800 | 不允许;提交后风险敞口 1100。 |
| 授信不限额 | credit=null 或 0, 无逾期,新订单任意金额 | 额度上限不拦截,但仍校验逾期。 |
| 余额全额覆盖 | availableBalance=500, order=500 | 本单余额冻结 500,授信占用 0。 |
| 余额部分覆盖 | availableBalance=300, order=800, credit 足够 | 余额冻结 300,授信占用 500。 |
| 余额不足且授信不足 | availableBalance=100, creditAvailable=200, order=500 | 不允许,除非调整支付或风控允许额度不足放行。 |
| 客户净额展示 | availableBalance=300, debt=500 | 客户净额=-200,但客户余额仍显示 300,客户欠款仍显示 500。 |
13.2 订单生命周期测试
|-----------------|------------------------------------|
| 场景 | 预期 |
| 订单从 300 修改为 500 | 冻结余额/授信只按差额增加 200,不重复冻结 500。 |
| 订单从 500 修改为 300 | 释放差额 200,日志记录 before/after。 |
| 订单反审核或作废 | 余额冻结和授信占用全部释放;重复释放结果不变。 |
| 订单对账转应收 | 冻结授信减少,客户欠款增加未结部分;冻结预付款消费并减少预付款余额。 |
| 已支付订单 | 不占用授信;如为预付款支付,则消费预付款并写流水。 |
| 金额为 0 的订单 | 不冻结余额,不占用授信。 |
| 并发两个订单占用同一客户余额 | 只能在可用余额和授信条件满足时成功;失败请求返回明确错误。 |
13.3 账期与逾期测试
|-------------------------------------|---------------------------------------------------|
| 场景 | 预期 |
| 客户配置账期 A,客户等级配置账期 B | 新应收使用客户账期 A。 |
| 客户无账期,客户等级配置账期 B | 新应收使用等级账期 B。 |
| 客户账期禁用,客户等级账期启用 | 推荐回退等级账期;如业务确认不回退,则快照为空。 |
| 修改账期天数 | 历史 oms_order_bill_debt 和 fin_customer_bill 不自动变化。 |
| 应收已过 dueDate 且 stillDebtAmount > 0 | 客户为逾期,订单默认拦截。 |
| 预付款冲抵逾期应收至 0 | 逾期状态消除或查询不再显示逾期。 |
13.4 额度下调与退款测试
|-------------------------------------|------------------------------------|
| 场景 | 预期 |
| 客户额度从 1000 下调到 debt+frozenCredit 以下 | 后端拒绝。 |
| 客户有可用余额但也有逾期欠款,申请退款 | 默认拒绝或进入审批;不能直接退款。 |
| 收款大于应收 | 应收结清,多收部分进入预付款余额。 |
| 预付款冲抵欠款 | 余额减少,欠款减少,应收明细 stillDebtAmount 减少。 |
14. 验收标准
|--------|-------------------------------------------------------------------------------------|
| 类别 | 验收标准 |
| 金额口径 | 客户详情、客户列表、订单页展示的授信、欠款、余额、预付款、逾期状态一致。 |
| 可用授信 | availableCreditAmount 按 creditAmount - debtAmount - frozenCreditAmount 计算,不直接混入预付款。 |
| 客户余额 | availableBalanceAmount 按 prepayBalanceAmount - frozenPrepayAmount 计算,不能被订单重复使用。 |
| 订单占用 | 新增、修改、审核、反审核、作废、删除、转应收均能正确占用/释放余额和授信。 |
| 转应收 | 同一事务内完成账期快照、预付款消费、授信释放、欠款增加和流水日志。 |
| 逾期控制 | 逾期判断基于 oms_order_bill_debt 的 stillDebtAmount 和 dueDate;预付款未冲抵前不自动消除逾期。 |
| 幂等并发 | 同一订单重复保存、重复释放、重复转应收不会重复增减金额。 |
| 额度下调 | 新授信额度不能低于当前欠款与冻结授信合计。 |
| 审计 | 强制提交、逾期放行、额度不足放行、预付款退款、坏账核销都有审计记录。 |
| 巡检 | 冻结授信、冻结预付款、客户欠款、逾期状态一致性检查无异常,或异常有明确修复/豁免。 |
15. 风险与待确认项
15.1 待业务确认
|-----------------------------------------------------------------|--------------------------------------------------|
| 问题 | 建议默认口径 |
| 客户余额是否等于预付款可用余额? | 建议是。若历史余额为净额,请新增 netCustomerAmount,不要复用 balance。 |
| 下单是否默认优先使用余额? | 建议做成客户/系统配置:默认不自动抵扣,由业务勾选;商城端可按业务默认自动抵扣。 |
| 逾期客户全额余额支付是否允许下单? | 建议默认拦截,可通过风控策略允许现款/余额单。 |
| 客户有欠款时是否允许退预付款? | 建议默认拦截或审批,优先冲抵欠款。 |
| 固定天数账期是否允许 0 天? | 需确认;允许时表示当天到期。 |
| 客户账期禁用后是否回退客户等级账期? | 建议回退有效等级账期。 |
| 客户账单 fin_customer_bill 是否补齐 period_type/period_days/period_day? | 建议补齐,便于催收和审计。 |
15.2 技术风险与规避
|---------------|-------------------------------------|
| 风险 | 规避措施 |
| 余额、预付款、净额字段混用 | 先完成字段字典和页面文案统一,再开发。 |
| 预校验通过但保存失败 | 正常现象;最终以保存事务内 reserve 为准,前端需展示友好提示。 |
| 重复释放导致金额不一致 | 释放按占用日志状态和剩余可释放金额处理,保证幂等。 |
| 转应收中途失败 | 账期快照、余额消费、授信释放、欠款增加必须同事务。 |
| 历史数据缺失流水 | 先做只读统计和财务确认,不直接批量推导资金余额。 |
| 风控强制提交被滥用 | 策略、权限、原因、金额快照、操作人必须落审计并可报表追踪。 |
结语
本方案的核心不是新增更多金额字段,而是把客户金额拆成"信用额度、应收欠款、预付款余额、账期逾期"四个可追溯账户,并通过客户金额快照服务统一输出。这样既能保留现有信用额度和账期实现,又能把客户余额和预付款纳入订单生命周期与财务核算,最终形成客户金额的统一风控、统一展示、统一审计和统一对账。