升鲜宝客户客户金额应用解决方案---升鲜宝生鲜配送供应链管理系统源代码服务(客户订货端、分拣端、仓库PDA、供应商协同端、采购端、配送端、溯源端)

客户金额一体化解决方案

信用额度 · 账期 · 客户余额 · 客户欠款 · 客户预付款

适用系统:升鲜宝 SCM 后端 scm--admin与前端 loveinway-admin

文档说明

本文档将客户信用额度、客户账期、客户余额、客户欠款、客户预付款统一到"客户金额中心"的设计口径中,目标是让客户信息页、订单生命周期、对账转应收、收款核销、余额抵扣、逾期拦截和风控强制提交使用同一套金额来源、同一套快照计算、同一套并发幂等规则。

本方案优先兼容现有实现:信用额度继续以 cus_customer.credit_amount、cus_customer.frozen_credit_amount、cus_customer_debt.debt_amount 为核心;账期继续以客户账期主数据和应收/账单快照为核心;客户余额与预付款建议通过资金账户与流水服务统一封装,不建议直接让前端或普通编辑接口维护实时金额。

|--------------------------------------------------------------------------------------------------------------------------------------------|
| 核心结论 可用授信与客户余额必须分开定义:可用授信反映客户信用额度剩余额度;客户余额反映客户可用于抵扣的预付款资金。订单可承接金额可以同时参考"可用余额 + 可用授信",但不要把预付款直接加进 availableCreditAmount,否则会混淆信用额度和客户资金。 |

目录

    1. 方案目标与设计原则
    1. 统一金额口径
    1. 客户金额账户模型
    1. 核心公式与风控判断
    1. 业务生命周期流程
    1. 账期、应收、逾期协同
    1. 数据模型与索引建议
    1. 后端服务与接口设计
    1. 前端页面与交互方案
    1. 并发、幂等与事务一致性
    1. 数据巡检、回填与对账
    1. 实施计划与优先级
    1. 测试用例
    1. 验收标准
    1. 风险与待确认项

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 新增订单

  1. 前端选择客户后调用客户金额快照接口,展示信用额度、欠款、冻结授信、可用授信、预付款余额、可用余额和逾期状态。

  2. 订单保存前调用金额预校验接口,传入 orderAmount、paymentState、useBalanceFlag、requestedUseBalanceAmount、scene=SAVE。

  3. 后端计算本单余额抵扣金额 prepayDeductAmount 和本单信用占用金额 creditOccupyAmount。

  4. 如果客户存在逾期且未命中可放行策略,返回不可提交。

  5. 保存订单时后端必须再次执行 reserve,不依赖前端预校验结果。

  6. 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 锁顺序

为避免死锁,涉及同一客户多类金额变动时建议固定锁顺序:

  1. 锁客户资金账户:cus_customer_fund_account where customer_id = ? for update。

  2. 锁信用占用日志:cus_credit_occupy_log by source_type + orderCode for update。

  3. 锁预付款占用日志:cus_prepay_occupy_log by source_type + sourceNo for update。

  4. 锁客户欠款汇总:cus_customer_debt where customer_id = ? for update。

  5. 写业务单据、金额流水、审计日志。

|------------------------------------------------------------------------------------------------------------------------|
| 事务边界 订单保存、审核、作废、反审核、转应收、收款核销、预付款退款必须以服务端事务为边界。预校验接口只用于提示,不改变金额;最终金额变动以保存/审核/转应收等业务接口内的 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 为准,前端需展示友好提示。 |
| 重复释放导致金额不一致 | 释放按占用日志状态和剩余可释放金额处理,保证幂等。 |
| 转应收中途失败 | 账期快照、余额消费、授信释放、欠款增加必须同事务。 |
| 历史数据缺失流水 | 先做只读统计和财务确认,不直接批量推导资金余额。 |
| 风控强制提交被滥用 | 策略、权限、原因、金额快照、操作人必须落审计并可报表追踪。 |

结语

本方案的核心不是新增更多金额字段,而是把客户金额拆成"信用额度、应收欠款、预付款余额、账期逾期"四个可追溯账户,并通过客户金额快照服务统一输出。这样既能保留现有信用额度和账期实现,又能把客户余额和预付款纳入订单生命周期与财务核算,最终形成客户金额的统一风控、统一展示、统一审计和统一对账。

相关推荐
水如烟5 小时前
孤能子视角:三十六计之隔岸观火——时序相位选择
人工智能
‿hhh5 小时前
Dify核心模块详解:从文本生成到智能体
人工智能·学习·microsoft·agent·上下文·记忆
大鱼>6 小时前
模型可解释性:特征重要性/SHAP/LIME
人工智能·python·机器学习·lstm
霖大侠6 小时前
Decoupled and Reusable Adaptation for Efficient Cross-Modal Transfer
人工智能·深度学习·算法·机器学习·transformer
武子康6 小时前
调查研究-216 Tesla Robotaxi 进了 Miami,但真正的考题才刚开始
人工智能·llm·自动驾驶
LaughingZhu6 小时前
Product Hunt 每日热榜 | 2026-07-05
人工智能·经验分享·深度学习·神经网络·产品运营
海兰6 小时前
【AI编程思考:第六篇】学习记忆与 Agent 状态:让 AI 真正“记得”你
人工智能·学习·ai编程
Dragon Wu6 小时前
ComfyUI ReActor需要下载检测模型的解决方案
人工智能·ai
雨辰AI6 小时前
【零基础实战】大模型入门面试 100 问:基础概念 + 环境实操(一问一答版,直接背诵)
人工智能·ai·面试·职场和发展·ai编程