文件
hl-api-changelog/changelogs-v2/2026-09/30_8664_公司借款单笔收回-新增接口-管理后台.md
T
2026-10-01 12:25:40 +08:00

9.1 KiB
原始文件 Blame 文件历史

schema, ticket, title, consumer, author, change_type, backend_status, gateway_status, frontend_status, frontend_owner, frontend_ref, target_release, verified_at, base, updated_at, status_note
schema ticket title consumer author change_type backend_status gateway_status frontend_status frontend_owner frontend_ref target_release verified_at base updated_at status_note
hl-changelog/v2 8664 公司借款收回新增单笔形态:POST /admin/finance/company-loans/{id}/recover admin yst(GIT) 新增接口 merged verified implemented hl-admin(claude-opus-4-8) c32b35c9527dde6bdc21386e1c6d47ad1f33bb96 v2.1 2026-10-01 dev-v3 2026-10-01 公司借款「借出方向」的收回(借出的钱到期收回)新增单笔形态——已付款借出单按单笔收款,与既有按单位合并收款(§1.4.3 recover/settle)共用 settle 核心。原型收回入口并入「支付管理/公司借款支付」已付款台账行「收款登记」;原「收款管理/公司借款收回」按单位汇总收银台原型入口下线(合并收款三端点后端保留可用)。前端已交付:入口挂「支付管理/公司借款支付」已付款台账行「收款登记」,弹窗拉详情默认欠收全额可改部分,fee 内扣预览,提交即禁按钮防连点,SETTLED 禁提交,收齐按 settledLoanIds 提示核销并刷台账;unitId/unitType 不入参。(此前 frontmatter 误标 implemented 无 ref,本次实证交付后补齐。)

【新增接口·管理后台】公司借款单笔收回 POST /admin/finance/company-loans/{id}/recover (#8664)

PR: #8670 | 服务: hl-order-service-v3(hl-finance 模块,8086) | 更新时间: 2026-09-30

1. 接口背景

公司借款「借出方向」(direction=OUT,公司借钱给供应商/员工)的到期收回,原只有「按单位汇总收银台」一种形态(勾选同一单位多笔借款单合并收款,§1.4.1-1.4.3)。本次按业务拍板新增单笔形态:在「支付管理 / 公司借款支付」的已付款台账行上对单笔借出单直接「收款登记」——已付款的借出单逐笔收回,无需按单位聚合勾选。

只写"为什么",不涉及实现:收回动作的入口从「按单位汇总收银台」下沉到「已付款借出单行」,更符合"只有已付款的台账才能收回"的业务直觉,也避免跨单位合并的复杂度(用户明确不需要跨单位合并收款,单笔即可)。

2. 变更清单

# 接口 方法 路径 变更类型 说明
1 公司借款单笔收回 POST /admin/finance/company-loans/{id}/recover 新增接口 按单笔借款单收回,与合并收款共用 settle 核心

合并收款三端点(§1.4.1 可选借款单 / §1.4.2 手续费试算 / §1.4.3 合并收款提交)保留可用,本次仅新增单笔便捷形态。

3. 接口详情

3.1 公司借款单笔收回

  • 使用场景:出纳在「支付管理 / 公司借款支付」的已付款台账,对某笔 direction=OUT(借出)且未收齐的借款单做收回登记(收欠收全额或部分金额)。
  • 认证:需管理后台 JWT。
  • 幂等性:否(每次调用产生一笔还款流水 GH- + 一笔资金流水 IN + 一条 RECOVER 操作流水;重复提交会重复入账,前端提交后应禁用按钮防连点)。
  • 限流:无。

行为:按本单收回指定金额 → 写还款流水(GH- 取号)+ 资金流水单笔 IN(bizType=COMPANY_LOAN)+ RECOVER 操作流水 + CAS 状态重算(收齐转已核销)+ 联动入账账户结存。与合并收款 §1.4.3 共用 recoverSettle settle 核心,守卫完全一致。

4. 接口入参

4.1 路径参数

字段 类型 必填 说明
id Long ✅ 借款单ID(path)

4.2 请求体字段

字段 类型 必填 说明 校验规则
amount BigDecimal ✅ 本次收回金额 >0 且 ≤ 该单剩余余额,否则 599309
fundAccountId Long ✅ 入账资金账户ID 须存在且 ACTIVE(fin_fund_account)
feeRate BigDecimal ❌ 手续费率(‰) 默认 0;fee = amount × feeRate / 1000,实收 = amount − fee
voucherUrl String ❌ 收款凭证影像URL —

⚠️ unitId / unitType 不入参——后端从借款单反查归属单位,前端无需也不应传(防传错串单)。

5. 出参(响应)

复用合并收款 CompanyLoanRecoverSettleRespVO:

字段 类型 说明
totalAmount BigDecimal 本次收回金额(=入参 amount)
actualAmount BigDecimal 实收(= totalAmount − fee)
fee BigDecimal 手续费
repayIds Long[] 还款流水ID列表(单笔恒单元素)
settledLoanIds Long[] 本次收齐转已核销的借款单ID(收齐时含本单 id,未收齐为空)

6. 枚举 / 数据字典

本接口入参/出参无枚举字段。相关业务方向(由后端从借款单反查,前端不传):

6.1 direction(借款方向,借款单自身字段)

值 中文 说明
OUT 借出 公司借钱给单位/员工,到期收回(本接口只收 OUT 单)
IN 借入 公司向单位/员工借钱,到期归还(走归还链路,非本接口)

7. 错误码

code 含义 触发场景
599301 借款单不存在 id 查无此单
599310 借款方向不匹配 该单非 OUT(借出),借入单不能走收回
599308 借款单已核销 已收齐核销的单不可再收
599302 借款单状态不可收 非可收回状态(如待付款未放款)
599309 收回金额超剩余余额 amount > 该单剩余余额
599303 手续费率非法 feeRate < 0 或 ≥ 1000
599307 还款单号取号耗尽 GH- 单号序列耗尽(极少)
595001 资金账户不存在 fundAccountId 查无此账户
595006 资金账户不可用 账户非 ACTIVE

8. 示例

8.1 典型成功(足额收齐,无手续费)

请求:

POST /admin/finance/company-loans/101234/recover
Authorization: Bearer <token>
Content-Type: application/json

{
  "amount": 5000.00,
  "fundAccountId": 88
}

响应(收齐转已核销):

{
  "code": 0,
  "data": {
    "totalAmount": 5000.00,
    "actualAmount": 5000.00,
    "fee": 0.00,
    "repayIds": [900001],
    "settledLoanIds": [101234]
  },
  "msg": ""
}

8.2 边界(部分收回 + 含手续费)

请求:

{
  "amount": 2000.00,
  "fundAccountId": 88,
  "feeRate": 5,
  "voucherUrl": "https://oss.example.com/voucher/x.jpg"
}

响应(部分收回,settledLoanIds 为空;fee=2000×5/1000=10,实收 1990):

{
  "code": 0,
  "data": {
    "totalAmount": 2000.00,
    "actualAmount": 1990.00,
    "fee": 10.00,
    "repayIds": [900002],
    "settledLoanIds": []
  },
  "msg": ""
}

8.3 业务失败(超额收回)

请求:

{ "amount": 99999.00, "fundAccountId": 88 }

响应:

{ "code": 599309, "msg": "收回金额超剩余余额", "data": null }

9. 业务边界

  • ✅ 适用:direction=OUT(借出)、未收齐(核销中 / 部分核销)的借款单。
  • ❌ 不适用:借入单(IN,走归还链路)→ 599310;已收齐核销单 → 599308;待付款未放款单 → 599302。
  • ⚠️ 特殊:amount 收齐该单余额时本单转已核销(settledLoanIds 含本单 id);未收齐则保持核销中(settledLoanIds 为空),可再次调用收回剩余。

10. 修改前后对比

新增接口,无修改前版本。与原「按单位合并收款」的关系:

维度 按单位合并收款(§1.4.3) 单笔收回(本接口)
入口 勾选同单位多笔合并 单笔直接收
入参 unitId + items[](多单填额) path id + 单 amount
还款流水 多单逐笔 单笔一条
共用 — 与本接口共用 settle 核心,守卫一致

11. 影响评估 / 回滚

  • 是否破坏向后兼容:否(纯新增端点)。
  • 前端是否必须同步上线:否(前端可在「公司借款支付」已付款行接入本接口实现单笔收款登记;不接入不影响既有合并收款)。
  • 回滚方式:revert PR #8670 即可下线本端点,无数据迁移、无缓存清理。

12. 注意事项

  • 原型/菜单侧:收回原型入口已并入「支付管理 / 公司借款支付」已付款台账行「收款登记」;原「收款管理 / 公司借款收回」按单位汇总收银台原型入口已下线。前端实现管理后台时,单笔收款登记建议挂在已付款借出单行(只有已付款台账能收回)。
  • 提交后请禁用按钮防连点(非幂等,重复提交会重复入账)。
  • 合并收款三端点后端保留可用,如未来仍提供按单位合并入口可继续用 §1.4.1-1.4.3。

13. 关联 / 联系人