文件
hl-api-changelog/changelogs-v2/2026-09/13_expense_费用报销多状态与申请人经办人-修改接口-管理后台.md
yaosutu 9ad6178c3c
changelog-filename-gate / validate (push) Failing after 2s
docs(finance): 费用报销 changelog 冲抵勾稽自包含——内联 offsettable 用法
原 §七 错误码 599107/599113 写"见 PR #7566 冲抵借款 changelog"违反自包含铁律。
本次补全:599107/599113 拆行写清触发条件 + 新增「冲抵勾稽(自包含)」段——
内联 GET /admin/finance/staff-loans/offsettable 端点用法与出参(balanceAmt 可冲上限)、
use=min(报销剩余额度,借款余额) 勾稽规则、offsetLoanAmt/payableAmt 关系,
指向员工借款申请与审批篇准确文件名。
2026-09-13 17:51:23 +08:00

11 KiB

schema, ticket, title, consumer, author, change_type, backend_status, gateway_status, frontend_status, frontend_owner, frontend_ref, target_release, verified_at, status_note, updated_at, base
schema ticket title consumer author change_type backend_status gateway_status frontend_status frontend_owner frontend_ref target_release verified_at status_note updated_at base
hl-changelog/v2 7472/7486/7502 费用报销:列表多状态筛选+详情付款记录、表单补申请人/收款账号/申请凭证、列表详情透出经办人 admin yst 修改接口 deployed not_required verified mmg e5ca470ae4ef69cb574b2b5d3c8a2ab4666b8f50 2026-09-13 费用报销三件套:①page 加 statuses 多状态筛选 + detail 聚合 payRecords 付款记录 ②create/update 入参加 applicantId/payeeAccount/voucherUrl(出参透出 applicantName) ③page/detail 出参加 operatorId/operatorName 经办人。错误码 598705 文案放宽。出参只增不删向后兼容,入参新增均选填。 前端已交付(e5ca470a):状态筛选 statuses 多选非空优先,详情补申请人/经办人/收款账号/申请凭证+PAID 付款记录块,表单加申请人(员工选择器)/收款账号/申请凭证,部门切组织树字符串透传,经办人只读透出。 2026-09-13 dev-v3

费用报销 —— 多状态筛选 + 付款记录 + 申请人/经办人 + 表单补列

服务: hl-order-service-v3(hl-finance 财务模块) 端: 管理后台 类型: 修改接口(出参只增不删向后兼容,入参新增均选填,非破坏) 日期: 2026-09-13 关联: Issue #7472 / #7486 / #7502;PR #7479 / #7496 / #7505(已合并 dev-v3)

一、接口背景

费用报销主链:申请 → 提交 → 审批 → 出纳付款。本批三件增强列表/详情的查询与展示能力,并补齐表单字段(申请人、收款账号、申请凭证)。报销付款链路见配套 changelog《费用支付(出纳)对接说明》。

二、变更清单

  1. 列表多状态筛选:GET /page 入参新增 statuses(多状态数组)。
  2. 详情聚合付款记录:GET /{id} 出参新增 payRecords(出纳付款流水,含付款凭证)。
  3. 表单补列:create/update 入参新增 applicantId / payeeAccount / voucherUrl;出参透出 applicantId / applicantName / payeeAccount / voucherUrl。
  4. 透出经办人:page Row / detail 出参新增 operatorId / operatorName。
  5. 错误码 598705 文案放宽:「部门或公司主体非法」→「部门/公司主体/申请人非法」(码值不变)。

三、接口详情(路径不变)

  • 分页 GET /admin/finance/expenses/page
  • 创建 POST /admin/finance/expenses
  • 详情 GET /admin/finance/expenses/{id}
  • 编辑 PUT /admin/finance/expenses/{id}(仅 PENDING)
  • 删除 DELETE /admin/finance/expenses/{id}(仅 PENDING)
  • 提交 PUT /admin/finance/expenses/{id}/submit | 审批 PUT /admin/finance/expenses/{id}/approve | 驳回 PUT /admin/finance/expenses/{id}/reject

四、入参

4.1 分页 GET /page

字段 类型 必填 说明
status String 否 单据状态单值
statuses List<String> 否🆕 单据状态多值(IN 查询,如 ["APPROVED","PAID"])。非空优先于 status;与 status 均空=全部
departmentId Long(String) 否 部门 ID(空=不限)
company String 否 公司主体名(空=不限)
keyword String 否 关键字(报销单号 / 公司主体名模糊)
page / pageSize Integer 否 分页

4.2 创建 / 编辑(PUT 同构)

字段 类型 必填 说明
expenseCategory String ✅ 费用分类末级名称(fin_expense_category level=2 正常项)
departmentId Long(String) ✅ 部门 ID(组织树选,关联接口②)
company String ✅ 公司主体名(travel_agency 启用项,关联接口④,传 agencyName 名字)
amount BigDecimal ✅ 报销金额 >0
reason String ✅ 报销事由
applicantId Long(String) 否🆕 申请人 adminId(员工选择器选,关联接口③)。传则后端反查企微名落 applicantName 快照;不传存空(过渡期选填,前端全量跟上后收紧必填)
payeeAccount String≤128 否🆕 收款账号(手填,本期明文)
voucherUrl String≤512 否🆕 申请凭证影像 URL(≠ 出纳付款凭证 payRecords.voucherUrl,两者不同字段)
offsetLoanIds List<Long(String)> 否 勾选冲抵的借款单 ID 列表(冲抵借款勾连,见 PR #7566;非空时 applicantId 必填否则 599112)

五、出参

5.1 Row(分页)

id、expenseNo(FY-单号)、expenseCategory、departmentId、departmentName、company、amount、payableAmt(=amount−offsetLoanAmt)、reason、applicantId🆕、applicantName🆕、payeeAccount🆕、voucherUrl🆕、status、operatorId🆕、operatorName🆕、createTime

5.2 Detail(详情)= Row 全字段 + 以下

offsetLoanAmt、fundAccountId、approvalInstanceId、rejectReason、paidAt,及 payRecords🆕(见下)

5.3 payRecords🆕(付款记录,仅 PAID 有值,按付款时间升序)

字段 类型 说明
flowNo String 资金流水号(LS- 前缀)
fundAccountName String 出账账户名(fin_fund_account 反查回填)
amount BigDecimal 实际打款金额
fee BigDecimal 手续费
payDate DateTime 付款时间
voucherUrl String 出纳付款回单/凭证影像 URL(≠ 申请凭证)

⚠️ payRecords 每项只有 voucherUrl,没有 voucherNo(资金流水表无凭证号列)。

六、枚举 / 数据字典

字段 取值
status / statuses PENDING 草稿 / SUBMITTED 审批中 / APPROVED 已批准 / REJECTED 已驳回 / PAID 已付讫
expenseCategory 费用分类末级(fin_expense_category level=2 正常项,见关联接口⑤)

七、错误码(HTTP 恒 200,判 code,按 message 原样提示)

code message 说明
598705 部门/公司主体/申请人非法 文案放宽(原"部门或公司主体非法"):部门须在组织树 / 公司主体须 travel_agency 启用 / 申请人须存在且带真名
599112 冲抵借款时申请人必填 offsetLoanIds 非空但 applicantId 空
599107 借款可冲余额不足,请重新勾选 勾选借款的 balanceAmt(可冲上限)不足以覆盖拟冲额
599113 勾选借款与报销申请人不一致 offsetLoanIds 里借款单的借款人 ≠ 本报销单 applicantId

冲抵勾稽(自包含):勾选冲抵用 GET /admin/finance/staff-loans/offsettable?staffId=<申请人adminId> 查本申请人名下可冲借款,返回 [{id, loanNo, amount, repaidAmt, balanceAmt(可冲上限), loanDate, purpose}],前端勾选后把选中借款单 id 数组传 offsetLoanIds。按勾选顺序逐笔 use=min(报销剩余额度, 该借款 balanceAmt);后端汇总落 offsetLoanAmt,payableAmt = amount − offsetLoanAmt(出纳按此差额付款)。借款单侧字段/状态机详见 13_staffloan_员工借款申请与审批-新增接口-管理后台.md。

八、示例

典型·创建报销(含申请人/收款账号/申请凭证)

POST /admin/finance/expenses
{
  "expenseCategory": "差旅费", "departmentId": "35",
  "company": "内蒙古呼籁国际旅行社有限公司", "amount": 1500.00, "reason": "出差海拉尔",
  "applicantId": "2083457702519873537", "payeeAccount": "6222020200112233", "voucherUrl": "https://oss/apply-voucher.jpg"
}
→ 200 { "code":200, "data":{ "id":"..." } }
详情出参含:applicantName="金卫"、operatorName="<当前登录人>"

典型·列表多状态筛选

GET /admin/finance/expenses/page?statuses=APPROVED&statuses=PAID&page=1&pageSize=20
→ 返回 APPROVED 或 PAID 的报销单(statuses 非空优先)

边界·详情付款记录(PAID 才有值)

GET /admin/finance/expenses/{id}   (status=PAID)
→ payRecords=[{ "flowNo":"LS2026...","fundAccountName":"呼籁国际-基本户","amount":1500.00,"fee":0,"payDate":"...","voucherUrl":"https://oss/pay-receipt.jpg" }]
   status 非 PAID 时 payRecords=[] 空数组

九、业务边界

  • statuses 多状态与 status 单值:statuses 非空优先,两者均空=全部。
  • applicantName / operatorName 为后端反查企微名落的快照/展示值,前端不要传,只读。
  • operatorId / operatorName = 当前登录人(created_by)留痕,只读透出,前端不能传、仅展示;老数据或反查失败时 operatorName 为 null(不 fail-fast)。
  • applicantId 传了非法(不存在/无真名)→ fail-fast 598705;不传则存空。

十、修改前后对比

项 改前 改后
列表状态筛选 仅 status 单值 +statuses 多值(优先)
详情付款记录 无 +payRecords(含付款凭证)
申请人 无 +applicantId(选)/applicantName(快照)
收款账号/申请凭证 无 +payeeAccount / voucherUrl
经办人 不透出 +operatorId / operatorName(只读)
598705 文案 部门或公司主体非法 部门/公司主体/申请人非法

十一、影响评估 / 回滚

  • 非破坏:出参只增不删向后兼容;入参新增均选填。旧前端不联动也能跑(看不到新字段/新筛选)。
  • 回滚:接口层回退即可;DDL(V20260910_110 加 applicant_id/applicant_name/payee_account/voucher_url 4 列)保留无影响。

十二、关联接口(前端对接数据源,均现成)

② 部门组织树 — GET /admin/wechat/departments/tree

  • 出参树节点:id(String)、label、parentId(根=0)、children;选中 id 传 departmentId

③ 申请人下拉(员工选择器) — GET /admin/user/employee-options(🆕 不限角色,见 changelog 13_7625)

  • 入参:deptId / keyword / page / pageSize;出参:adminId、username、enterpriseWechatName、deptNames
  • 选中取 adminId 传 applicantId

④ 所属公司下拉 — GET /v3/admin/travel-agency/enabled(启用列表下拉)

  • 出参项:agencyId、code、agencyName、isPrimary(1=主体公司,前端可默认选中)、sortOrder
  • ⚠️ 选中后传 agencyName(公司主体名字符串)给报销 company,不是 agencyId

⑤ 费用分类 — fin_expense_category level=2 正常项(按现有费用分类接口/字典取,此处不展开)

十三、关联 / 联系人