--- schema: "hl-changelog/v2" ticket: "8507" title: "财务初始化页面 tab 结构纠偏:应为 3 tab(应收初始化/应付初始化/现金银行初始化),删「员工往来」tab,应收初始化内按往来对象选 CUSTOMER/SUPPLIER_RECV(#8507 #8511)" consumer: "admin" author: "yst(GIT)" change_type: "修改接口" backend_status: "deployed" gateway_status: "not_required" frontend_status: "pending" frontend_owner: "" frontend_ref: "" target_release: "" verified_at: "2026-09-30" status_note: "财务初始化(菜单:参数设置/财务初始化)前端页面 tab 结构与原型不符的纠偏单。原型只有 3 个 tab(应收初始化/应付初始化/现金银行初始化),按「初始化场景」划分,初始化里**没有「员工往来」期初**(员工借款/备用金属付款管理业务流程,不在初始化)。当前前端做成了 4 个 tab(客户应收/供应商应付/供应商应收/员工往来),按「往来对象类型」划分,需重构。后端接口零改动、已全部部署测试服并验证通过:应收/应付走 /admin/finance/opening-balances(按 ledgerType 区分 CUSTOMER/SUPPLIER_RECV/SUPPLIER),现金银行走 /admin/finance/fund-accounts(账户期初结存),两套接口互相独立。本文自包含全部入参/出参/枚举/错误码/示例。" updated_at: "2026-09-30" base: "dev-v3" --- # finance:财务初始化三 tab 对齐原型(管理后台) > **性质**:前端实现纠偏。后端接口无新增/无变更,已在测试服就绪。本文告诉前端「正确的 tab 结构 + 每个 tab 怎么调既有接口」。 ## 1. 接口背景 财务初始化是账套启用前录入期初数据的入口(菜单:**参数设置 / 财务初始化**)。 原型 `finance-prototype.html`(页面 id `cfg-fininit`)规定财务初始化**只有 3 个 tab**,按「初始化场景」划分: ``` 财务初始化 ├─ 应收初始化 启用前欠我们的款(客户欠款 + 供应商杂项应收) ├─ 应付初始化 启用前我们欠供应商的款 └─ 现金银行初始化 各资金账户启用前已有结存 ``` **当前前端实现错误**:做成了 4 个 tab(客户应收 / 供应商应付 / 供应商应收 / 员工往来),按「往来对象类型」划分。两处偏差: 1. tab 划分维度错了——应按「初始化场景」(应收/应付/现金银行),不是按「往来对象类型」(客户/供应商/员工)。 2. 多出了「员工往来」tab——原型财务初始化**没有员工往来期初**。员工借款/备用金是「付款管理 / 员工借款」的业务单据流(页面 `loan-stf` / `payex-stfloan`),不属于财务初始化。 **「供应商应收」不是独立 tab**:它是「应收初始化」tab 内部、往来对象选「供应商」时的一种(供应商欠我们的杂项应收:押金退还/赔偿款/口车费/其他应收)。 ## 2. 变更清单(前端 tab 结构改动) | # | 改动 | 说明 | |---|------|------| | 1 | 删除「员工往来」tab | 初始化无此场景 | | 2 | tab 改 3 个并改名 | `应收初始化` / `应付初始化` / `现金银行初始化` | | 3 | 「客户应收」+「供应商应收」合并进「应收初始化」一个 tab | tab 内用「往来对象」下拉(客户/供应商)切换 ledgerType | | 4 | 「供应商应付」改名「应付初始化」 | 固定 ledgerType=SUPPLIER,去掉对象细分字段 | | 5 | 新增「现金银行初始化」tab | 接 `/admin/finance/fund-accounts` 系列接口(账户期初结存) | ## 3. tab ↔ 接口 / 账套映射(核心) | 前端 tab | tab 内「往来对象」 | 调接口 | 传 `ledgerType` | |---|---|---|---| | 应收初始化 | 客户 | `POST /admin/finance/opening-balances` 等 | `CUSTOMER` | | 应收初始化 | 供应商 | 同上 | `SUPPLIER_RECV` | | 应付初始化 | (固定供应商,无此下拉) | 同上 | `SUPPLIER` | | 现金银行初始化 | — | `/admin/finance/fund-accounts` 系列 | —(无 ledgerType 概念) | > 应收初始化一个 tab 对应两个 ledgerType,按用户选的「往来对象」决定传哪个;金额字段填 `openingReceivable`。应付初始化固定 `SUPPLIER`,金额填 `openingPayable`。 --- ## 4. 应收初始化 tab(ledgerType = CUSTOMER / SUPPLIER_RECV) ### 4.1 列表(分页) `GET /admin/finance/opening-balances/page` **入参(query)**: | 字段 | 类型 | 必填 | 说明 | |---|---|---|---| | pageNo | int | 是 | 页码 | | pageSize | int | 是 | 每页 | | ledgerType | string | 是 | `CUSTOMER` 或 `SUPPLIER_RECV` | | kind | string | 否 | `INIT` 初始 / `ADJUST` 期初调整;空=全部 | | refName | string | 否 | 往来对象名模糊搜索 | > 应收初始化 tab 顶部建议加「往来对象」筛选(全部/客户/供应商):客户→`CUSTOMER`、供应商→`SUPPLIER_RECV`、全部→两个 ledgerType 各查一次合并。 **出参(`data.records[]`)**: | 字段 | 类型 | 说明 | |---|---|---| | id | string | 期初行 ID | | ledgerType | string | 账套回显 | | refId | string | 往来对象 ID | | refName | string | 往来对象名称 | | customerCategory | string | 对象细分编码(CUSTOMER=客户分类 / SUPPLIER_RECV=应收性质;SUPPLIER 为 null) | | customerCategoryName | string | **对象细分中文名**(列表直接显示这个;字典不可用为 null) | | companyId | string | 所属公司主体 ID | | companyName | string | 所属公司主体名 | | openingDate | string | 期初基准日(=当前未封账账期起始日),只读 | | kind | string | `INIT` / `ADJUST` | | openingPayable | number | 期初应付(应收 tab 恒 null,忽略) | | openingReceivable | number | **期初应收(本 tab 显示这个金额)** | | evidenceUrl | string | 佐证材料影像 URL(可空) | | recordedByName | string | 录入人姓名 | | createTime | string | 创建时间 | ### 4.2 新建期初 `POST /admin/finance/opening-balances` **表单(按原型应收表单三段递进)**: 1. **往来对象**(下拉必填):`客户` / `供应商` 2. **对象细分**(下拉必填,标签随往来对象变): - 客户 → 标签「客户分类」,选项 = 字典 `fin_customer_category` - 供应商 → 标签「应收性质」,选项 = 字典 `fin_recv_nature` 3. **往来对象名称**(下拉必填): - 供应商 → `GET /admin/supplier/items/list?status=ACTIVE`(取 `supplierId` + `shortName`/`fullName`) - 客户 → 客户列表(按所选客户分类过滤) 4. **应收欠款**(数字必填,>0) 5. **所属公司**(下拉单选必填):`GET /v3/admin/travel-agency/enabled`(取 `agencyId`+`agencyName`) 6. **记账日期**(只读):前端不传,后端落 `openingDate`=当前账期起始日 7. **备注**(文本域选填,≤200 字) **请求体**: | 字段 | 类型 | 必填 | 说明 | |---|---|---|---| | ledgerType | string | 是 | `CUSTOMER`(选了客户)/ `SUPPLIER_RECV`(选了供应商) | | refId | Long | 是 | 往来对象 ID | | refName | string | 是 | 往来对象名称(≤128) | | customerCategory | string | 条件必填 | 对象细分编码:CUSTOMER→fin_customer_category 编码;SUPPLIER_RECV→fin_recv_nature 编码。**两账套均必填** | | companyId | Long | 是 | 所属公司主体 ID | | openingReceivable | number | 是 | 期初应收金额,>0 | | openingPayable | — | 否 | 应收 tab 不传(传了后端也忽略不落库) | | evidenceUrl | string | 否 | 佐证材料影像 URL | | remark | string | 否 | 备注(≤200) | **响应**:`data.id` = 新建期初行 ID。 **请求示例(供应商应收)**: ```json { "ledgerType": "SUPPLIER_RECV", "refId": 2104918057506041857, "refName": "柴河星悦酒店", "customerCategory": "DEPOSIT_REFUND", "companyId": 2051922156798779394, "openingReceivable": 1.01, "remark": "押金退还期初" } ``` **响应示例**: ```json { "code": 200, "message": "成功", "data": { "id": "2105077077235662849" }, "success": true } ``` ### 4.3 期初调整 `POST /admin/finance/opening-balances/adjust` | 字段 | 类型 | 必填 | 说明 | |---|---|---|---| | ledgerType | string | 是 | 同新建 | | refId | Long | 是 | 往来对象 ID(须已有 INIT 行,否则 598404) | | openingReceivable | number | 条件 | **调整后期初应收(全量值非差额)**;CUSTOMER/SUPPLIER_RECV 落库 | | openingPayable | number | 条件 | 调整后期初应付;仅 SUPPLIER 落库 | | evidenceUrl | string | 否 | 佐证影像 | | reason | string | **是** | 调整原因(≤200) | > 分类/性质/公司沿用 INIT 行快照,调整单不开放改。 --- ## 5. 应付初始化 tab(ledgerType = SUPPLIER) 接口同应收(`/admin/finance/opening-balances` 一套),差异: | 项 | 应付初始化 | |---|---| | ledgerType | 固定 `SUPPLIER` | | 往来对象 | 固定「供应商」,无客户/供应商下拉;直接供应商列表 `GET /admin/supplier/items/list?status=ACTIVE` | | customerCategory | **不传**(SUPPLIER 忽略,供应商类别随供应商档案带出不手选) | | 金额字段 | 传 `openingPayable`(期初应付,>0),**不传** `openingReceivable` | 列表看 `openingPayable`(`openingReceivable` 恒 null)。 --- ## 6. 现金银行初始化 tab(走资金账户接口,独立) 此 tab 是**资金账户的期初结存**,与应收/应付的 opening-balances **完全独立**,接 `/admin/finance/fund-accounts`: | 操作 | 接口 | 说明 | |---|---|---| | 列表 | `GET /admin/finance/fund-accounts/page` | 本 tab 列表(列:账户名称/类型/期初结存/操作) | | 新建账户(录期初结存) | `POST /admin/finance/fund-accounts` | 建户时录账户信息+期初结存 | | 期初调整 | `POST /admin/finance/fund-accounts/{id}/opening-adjust` | 唯一改期初途径,落 OPENING 留痕流水 | | 建户表单三组下拉 | `GET /admin/finance/fund-accounts/options` | accountType/nature/channel(字典 fin_fund_account_*) | > ⚠️ `opening-adjust` 差额为 0 时返 `595105`(不落流水),**非 200 幂等**——前端需区分「200 调整成功」vs「595105 无需调整」,不要把 595105 当失败弹错。 --- ## 7. 枚举 / 数据字典 ### 7.1 ledgerType(账套,OpeningLedgerTypeEnum) **所属字段**:`ledgerType` | **类型**:`String` | **必填**:✅ | 值 | 中文 | 金额字段 | 用于 tab | |----|------|------|------| | `SUPPLIER` | 供应商应付(我欠他) | openingPayable | 应付初始化 | | `CUSTOMER` | 客户应收(他欠我们) | openingReceivable | 应收初始化(往来对象=客户) | | `SUPPLIER_RECV` | 供应商应收(他欠我们:押金退还/赔偿款/口车费/其他应收) | openingReceivable | 应收初始化(往来对象=供应商) | ### 7.2 kind(类别) **所属字段**:`kind` | **类型**:`String` | **必填**:❌(查询过滤用) | 值 | 中文 | 说明 | |----|------|------| | `INIT` | 初始 | 首次录入(同对象仅一次) | | `ADJUST` | 期初调整 | 对已有 INIT 的调整留痕 | ### 7.3 应收性质(字典 fin_recv_nature,SUPPLIER_RECV 的 customerCategory) | 值 | 中文 | |----|------| | `DEPOSIT_REFUND` | 押金退还 | | `COMPENSATION` | 赔偿款 | | `CAR_FEE` | 口车费 | | `OTHER` | 其他应收 | ### 7.4 客户分类(字典 fin_customer_category,CUSTOMER 的 customerCategory) 经 `GET /admin/dict/all` 或字典接口取 `fin_customer_category` 当前生效值。 --- ## 8. 下拉数据源汇总 | 下拉 | 接口 / 字典 | |---|---| | 供应商列表 | `GET /admin/supplier/items/list?status=ACTIVE` | | 公司主体 | `GET /v3/admin/travel-agency/enabled` | | 客户分类(应收-客户) | 字典 `fin_customer_category` | | 应收性质(应收-供应商) | 字典 `fin_recv_nature`(押金退还/赔偿款/口车费/其他应收) | | 资金账户类型/性质/渠道 | `GET /admin/finance/fund-accounts/options` | --- ## 9. 错误码 | code | 含义 | 触发场景 | |------|------|----------| | 598401 | 同往来对象 INIT 已录过 | 重复新建初始期初 | | 598403 | 账期已封账 | 封账后新建/调整 | | 598404 | 须先录初始期初 | 调整时无 INIT 行 | | 598405 | 期初金额须大于0 | 金额 ≤0 | | 598407 | 公司主体非法 | companyId 无效 | | 598408 | 客户分类必填 | CUSTOMER 缺 customerCategory | | 598409 | 供应商应收性质必填 | SUPPLIER_RECV 缺 customerCategory | | 598410 | 对象细分取值非法 | customerCategory 不在字典内 | | 595105 | 期初调整差额为 0 | 现金银行 opening-adjust 无需调整(非错误) | --- ## 10. 修改前后对比 | 项 | 改前(当前前端错误) | 改后(对齐原型) | |---|---|---| | tab 数 | 4 个 | **3 个** | | tab 名 | 客户应收/供应商应付/供应商应收/员工往来 | **应收初始化/应付初始化/现金银行初始化** | | 划分维度 | 往来对象类型 | **初始化场景** | | 员工往来 tab | 有(多出) | **删除** | | 供应商应收 | 独立 tab | **并入应收初始化**(往来对象=供应商,ledgerType=SUPPLIER_RECV) | | 现金银行初始化 | 缺 | **新增**(接 fund-accounts 期初) | --- ## 11. 影响评估 / 回滚 - **后端接口变更**:无(零改动,已 deployed) - **是否破坏向后兼容**:前端页面重构,接口契约不变 - **前端是否必须同步上线**:是(当前 4 tab 结构与后端账套语义不符,「员工往来」tab 调任何接口都会失败——后端无员工往来账套) ## 12. 注意事项 - 金额字段二选一:应收 tab 填 `openingReceivable`、应付 tab 填 `openingPayable`,**不要同传两个**(后端按 ledgerType 只落对应方向,另一方向忽略)。 - 记账日期只读、前端不传,后端落当前账期起始日。 - 同一往来对象 INIT 仅可录一次;要改走「期初调整」。 - 「现金银行初始化」与「应收/应付初始化」是两套独立接口(fund-accounts vs opening-balances),不要混用。 ## 13. 关联 / 联系人 ### 13.1 链接 - **Issue**: [#8507](https://git.1814.love/wx/HL/issues/8507) / [#8511](https://git.1814.love/wx/HL/issues/8511) - **PR**: [#8509](https://git.1814.love/wx/HL/pulls/8509) / [#8513](https://git.1814.love/wx/HL/pulls/8513) ### 13.2 联系人 - **后端负责人**: @yst - **前端对接(管理后台)**: 待认领