--- schema: "hl-changelog/v2" ticket: "7521/7520" title: "员工借款支付(支付管理/员工借款支付):出纳放款 + 还款核销(现金/转账登记·红冲·报销冲抵)对接说明" consumer: "admin" author: "yst" change_type: "修改接口" backend_status: "deployed" gateway_status: "not_required" frontend_status: "verified" frontend_owner: "mmg" frontend_ref: "2a2ec01df823c841f5a608a9ee6b6ffeb09ce133" target_release: "" verified_at: "2026-09-13" status_note: "📘 员工借款 APPROVED 后进出纳待放款队列,复用统一出纳接口 /admin/finance/cashier/* 按 payType/bizType=STAFF_LOAN 路由登记放款;放款后本页/出纳侧再做还款核销——现金/转账还款登记 POST /admin/finance/staff-loans/{id}/repays、红冲 DELETE /repays/{repayId}、报销冲抵走报销单 offsetLoanIds。本篇覆盖「支付管理/员工借款支付」菜单的放款+核销。申请+审批见《员工借款(付款管理/员工借款)》篇。菜单 V20260913_001 已挂载(PR #7642)。 前端已交付(eb6812c2):新建 pay/staff-loan 薄壳(CashierQueuePage pay-type=STAFF_LOAN),CashierQueuePage validator 白名单加 STAFF_LOAN、isExpense 泛化 isInternalLine(EXPENSE+STAFF_LOAN 同属内部单据线:无手续费、金额即全额),queueNotice/队列借款人列分叉;放款走 cashier/pay bizType=STAFF_LOAN;finance-route.spec 登记两菜单。⚠️还款核销登记/红冲本期归属本页(出纳侧),前端若把还款做在申请页需挪到本页。 核销归属修正已落地(2a2ec01d):还款登记/红冲从申请页挪出纳侧(支付页台账行内还款核销弹窗),申请页 repayRecords 纯只读。" updated_at: "2026-09-13" base: "dev-v3" --- # 员工借款支付(支付管理/员工借款支付)—— 出纳放款 + 还款核销 > **服务**: hl-order-service-v3(hl-finance 财务模块·出纳域 + 员工借款域) > **端**: 管理后台 > **类型**: 📘 对接说明(出纳域接口复用 + 员工借款还款核销端点) > **日期**: 2026-09-13 > **关联**: Epic #7520;PR #7549 / #7557 / #7566;菜单挂载 PR #7642(均已合并 dev-v3) ## 一、接口背景 员工借款单 `APPROVED`(审批通过)后进入**出纳待放款队列**,出纳登记线下放款(系统不真付款,只记已付)、回写借款单 PAID;放款后员工以**现金还款**或**报销冲抵**核销,直至 SETTLED。这些"放款 + 核销"动作对应原型菜单「支付管理 / 员工借款支付」(原型 notice:*"员工借款审批通过后进入本队列,出纳在此登记线下付款流水…以现金还款或报销冲抵核销"*)。 借款的**申请与审批**在「付款管理 / 员工借款」,见配套 changelog《员工借款(付款管理/员工借款)》。 ## 二、菜单↔功能↔接口 对应表 | 菜单 | 功能 | 接口 | |---|---|---| | 支付管理/员工借款支付 | 待放款队列 | `GET /admin/finance/cashier/queue?payType=STAFF_LOAN` | | 支付管理/员工借款支付 | 登记放款(出纳放款) | `POST /admin/finance/cashier/pay`(bizType=STAFF_LOAN) | | 支付管理/员工借款支付 | 已放款台账 | `GET /admin/finance/cashier/payments/page?bizType=STAFF_LOAN` | | 支付管理/员工借款支付 | **还款核销·现金/转账登记** | `POST /admin/finance/staff-loans/{id}/repays` | | 支付管理/员工借款支付 | **还款核销·红冲(撤销)** | `DELETE /admin/finance/staff-loans/repays/{repayId}` | | 支付管理/员工借款支付 | **还款核销·报销冲抵** | 报销单 `offsetLoanIds`(见《费用报销》) | > 菜单 path(已挂载):员工借款支付 = `/finance/pay/staff-loan`。 ## 三、放款链路(借款视角) ``` 借款单 approve(APPROVED) → 出纳队列出现该待放款单 → 出纳登记放款(cashier/pay, bizType=STAFF_LOAN) → 记资金流水 OUT + 回写借款单 PAID(落 fund_account_id/paid_at)+ 重算账户结存 → 已放款台账可查 / 借款详情 paidAt+fundAccountId 回显 ``` ## 四、放款接口(出纳域现有接口,按 STAFF_LOAN 过滤) ### ① 出纳待放款队列 — `GET /admin/finance/cashier/queue` - 入参:`payType=STAFF_LOAN`(员工借款)+ page/pageSize - 队列源:fin_staff_loan 状态 APPROVED 的借款单 - **员工借款支付页"待放款"列表 = 本接口 payType=STAFF_LOAN** ### ② 登记放款 — `POST /admin/finance/cashier/pay` - 入参:`bizType=STAFF_LOAN` + `bizId`(借款单ID) + 出账账户 fundAccountId + 金额 + 手续费 + 付款日期 + 凭证 voucherUrl 等 - 动作:记资金流水 OUT + 回写借款单 APPROVED→PAID(落 fund_account_id/paid_at)+ 重算账户结存 - 并发/幂等:放款前 selectForUpdate 锁借款行 + 锁内校验存在且 APPROVED,已 PAID 不可重复放款(598602) ### ③ 已放款流水台账 — `GET /admin/finance/cashier/payments/page` - 入参:`bizType=STAFF_LOAN` + page/pageSize - **员工借款支付页"已放款"列表 = 本接口 bizType=STAFF_LOAN** ## 五、还款核销(借款域接口) 放款后员工还款,核销至 SETTLED。两条通道: ### ① 现金/转账还款登记 — `POST /admin/finance/staff-loans/{id}/repays` 记资金流水 IN(钱回账户)+ CAS 重算借款状态(SUM0,超剩余余额 → 599106 | | fundAccountId | Long(String) | ✅ | 入账资金账户(关联接口②) | | voucherUrl | String | 否 | 还款凭证影像 URL | | repaidAt | DateTime | 否 | 还款时间(默认当前时间) | 返 `{id}`。 ### ② 还款记录查询 — `GET /admin/finance/staff-loans/{id}/repays` → `List`:id/repayNo(HK- 前缀)/loanId/amount/repayWay/repayWayName/fundAccountId(EXPENSE_OFFSET 恒 null)/voucherUrl/repaidAt/createTime。 ### ③ 还款红冲(撤销)— `DELETE /admin/finance/staff-loans/repays/{repayId}` 反向 OUT 流水 + 软删还款行 + 状态回退。**EXPENSE_OFFSET 行不可手工红冲** → 599111。 ### ④ 报销冲抵(不产生资金流水) 报销单勾选 `offsetLoanIds` 冲抵本申请人名下借款 → 生成 EXPENSE_OFFSET 还款行(不记资金流水),报销 reject/delete/update 时回冲。详见《费用报销》changelog。 ## 六、字段对接要点 | 前端展示 | 来源 | |---|---| | 待放款列表 | `cashier/queue?payType=STAFF_LOAN` | | 已放款列表 | `cashier/payments/page?bizType=STAFF_LOAN` | | 登记放款动作 | `cashier/pay`(bizType=STAFF_LOAN) | | 还款核销(现金/转账) | `staff-loans/{id}/repays` POST | | 还款记录/核销进度 | `staff-loans/{id}/repays` GET / 借款详情 repayRecords | | 还款红冲 | `staff-loans/repays/{repayId}` DELETE | ## 七、错误码(HTTP 恒 200,判 code,按 message 原样提示) **放款(出纳域)**:598602 借款单已放款不可重复 / 598607 bizType 非法(文案含 STAFF_LOAN)等既有码。 **还款核销(借款域)**: | code | message | 触发 | |---|---|---| | 599106 | 还款金额超过借款剩余余额 | 还款 amount>balanceAmt | | 599108 | 还款单号生成冲突,请重试 | 还款单号撞号 | | 599109 | 还款记录不存在或已撤销 | repayId 无效 | | 599110 | 还款方式非法(仅支持现金/转账) | 手工还款传 EXPENSE_OFFSET | | 599111 | 报销冲销还款不可手工撤销 | 红冲 EXPENSE_OFFSET 行 | ## 八、示例 ### 典型·登记放款 ```json POST /admin/finance/cashier/pay { "bizType":"STAFF_LOAN", "bizId":"<借款单ID>", "fundAccountId":"2095340438490583041", "amount":5000.00, "fee":0, "payDate":"2026-09-13", "voucherUrl":"https://oss/pay.jpg" } → 记资金流水 OUT + 借款单 APPROVED→PAID ``` ### 典型·现金还款核销 ```json POST /admin/finance/staff-loans/{id}/repays { "repayWay":"CASH", "amount":2000.00, "fundAccountId":"2095340438490583041" } → 记资金流水 IN + 重算状态(SUM