文件
hl-api-changelog/changelogs-v2/2026-09/13_7612_业务外收支接供应商与经办人-修改接口-管理后台.md
T
yaosutu 6e05bd81aa
changelog-filename-gate / validate (push) Failing after 2s
feat(changelog): 业务外收支接供应商与经办人(#7612) + 员工选择器接口(#7625)
- 13_7612:业务外收支修改接口(破坏性:删 unitName/加 operatorId 必填/OUT 裁剪 6 字段;出参加 flowNo;含供应商弹窗/部门树/员工选择器/类别/收付方式字典 5 个关联接口对接指引)
- 13_7625:新增员工选择器 GET /admin/user/employee-options(不限角色,供经办人下拉)
2026-09-13 14:37:16 +08:00

11 KiB
原始文件 Blame 文件历史

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 7612 业务外收支:外部单位接供应商、经办人改选员工、支出裁剪凭证字段、列表关键词、新增业务单号 admin yst 修改接口 deployed not_required required ⚠️ 破坏性变更:入参删 unitName、加 operatorId 必填、支出(OUT)忽略 6 字段;出参加 flowNo。前端业务外收入/业务外支出两个页面须同迭代联动,否则旧前端提交 400。 2026-09-13 dev-v3

业务外收支 —— 接供应商 + 经办人选员工 + 支出裁剪 + 关键词 + 业务单号

服务: hl-order-service-v3(hl-finance 财务模块) 端: 管理后台 类型: ⚠️ 修改接口(含破坏性入参变更,前端须同迭代联动) 日期: 2026-09-13 关联: Issue #7612 / PR #7619(已合并 dev-v3,已部署测试服)

一、接口背景

业务外收入(IN) / 业务外支出(OUT) 同表同接口、按 direction 区分,前端拆两个菜单页签(收款管理/业务外收入、付款管理/业务外支出)。本次把两个原本"手填"的主数据接成真关联,对齐原型裁剪支出字段、补业务单号、加列表关键词。

二、变更清单

  1. 外部单位接供应商:unitId 后端硬校验"可付款供应商"(不可付款/不存在 → 598507);unitName 改后端自动取供应商全称落快照,入参 unitName 删除(前端免填)。
  2. 经办人改选员工:入参新增 operatorId 必填(员工 adminId),后端校验存在/在职(598508) + 属于所选部门(598509);不再取登录人自动留痕。
  3. 支出(OUT)裁剪字段:payMethod/voucherNo/voucherUrl/feeRate/fee/fundAccountId 后端强制置 null(对齐原型支出无凭证类字段);IN 保留全字段。
  4. 列表关键词:page 新增 keyword(模糊 单位名 / 业务单号)。
  5. 业务单号:出参新增 flowNo(格式 WS-yyyyMMdd-XXXX,创建生成、全局唯一)。

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

  • 创建 POST /admin/finance/nonbiz-flows
  • 编辑 PUT /admin/finance/nonbiz-flows/{id}(仅 PENDING;unitId 变化才重新校验供应商)
  • 详情 GET /admin/finance/nonbiz-flows/{id}
  • 分页 GET /admin/finance/nonbiz-flows/page
  • 提交 PUT /admin/finance/nonbiz-flows/{id}/submit | 审批 PUT /admin/finance/nonbiz-flows/{id}/approve | 删除 DELETE /admin/finance/nonbiz-flows/{id}(仅 PENDING)

四、入参(Create;PUT 同构、少 direction)

字段 类型 必填 说明
direction String ✅ IN 业务外收入 / OUT 业务外支出(编辑不可改)
category String ✅ 收支类别码(见关联接口④,按 direction 分组)
unitId Long(String) ✅ 外部单位 = 供应商 ID(供应商弹窗选,见关联接口①)
operatorId Long(String) ✅🆕 经办人 = 员工 adminId(员工选择器选,见关联接口③)
amount BigDecimal ✅ 收支金额 >0
occurDate Date ✅ 发生日期 yyyy-MM-dd
deptId Long(String) 推荐 所属部门(部门树选,见关联接口②;供经办人"属部门"校验)
feeRate BigDecimal 仅 IN 手续费率 ‰(OUT 忽略)
fee BigDecimal 仅 IN 手续费(OUT 忽略)
fundAccountId Long(String) 仅 IN 入/出账公司账户(OUT 忽略)
payMethod String 仅 IN 收付方式(字典 fin_pay_way,OUT 忽略)
voucherNo String 仅 IN 凭证号(OUT 忽略)
voucherUrl String 仅 IN 凭证影像 URL(OUT 忽略)
remark String≤200 否 备注

❌ 已删除入参:unitName(后端自动落供应商全称快照,前端不要再传)。 ⚠️ OUT 方向:payMethod / voucherNo / voucherUrl / feeRate / fee / fundAccountId 传了也被忽略置 null,前端支出表单不要渲染这些字段。

五、出参

Row(分页):id、flowNo🆕、direction、category、categoryName、unitId、unitName、amount、fee、actualAmount、deptId、operatorName、occurDate、status、payMethod、payMethodName

Detail(详情) = Row 全字段 + feeRate、fundAccountId、operatorId、voucherNo、voucherUrl、remark、createTime

unitName / operatorName 仍返回(快照值),来源改为后端自动落;flowNo 为新增业务单号。出参向后兼容(只增 flowNo,不删字段)。

六、枚举 / 数据字典

字段 来源 取值
direction 后端枚举 IN 业务外收入 / OUT 业务外支出
status 后端枚举 PENDING 草稿 / SUBMITTED 审批中 / APPROVED 已批准 / REJECTED 已驳回 / PAID 已收付讫
category 类别接口 见关联接口④(IN/OUT 各自一组,取 status=NORMAL)
payMethod 字典 fin_pay_way CASH 现金 / BANK_TRANSFER 银行转账 / WECHAT 微信 / ALIPAY 支付宝(仅 IN 用;列表/详情 payMethodName 后端已回填中文,仅下拉才需调字典接口⑤)

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

code message 触发
598507 外部单位不存在或非可付款供应商 unitId 非可付款供应商
598508 经办人不存在或非在职状态 operatorId 非法 / 非 ACTIVE
598509 经办人不属于所选部门 operatorId 不在 deptId 部门成员内
598510 业务单号生成冲突,请重试 单号并发撞号(前端重试即可)
598501 / 598502 / 598506 金额 / 类别 / 方向 校验(原有) 见原有定义

八、示例

典型·新建业务外支出(OUT,无凭证字段)

POST /admin/finance/nonbiz-flows
{
  "direction": "OUT", "category": "DONATION",
  "unitId": "2098964648031109121", "operatorId": "2083457702519873537",
  "amount": 1000.00, "occurDate": "2026-09-13", "deptId": "35", "remark": "公益活动捐赠"
}
→ 200 { "code":200, "message":"成功", "data":{ "id":"2098980881711403010" } }
详情出参含:flowNo="WS-20260913-0001"、unitName="XX供应商全称"、operatorName="金卫"

典型·新建业务外收入(IN,含手续费/收付方式)

POST /admin/finance/nonbiz-flows
{
  "direction": "IN", "category": "RENT",
  "unitId": "2098964648031109121", "operatorId": "2083457702519873537",
  "amount": 5000.00, "feeRate": 6, "fee": 30.00, "fundAccountId": "2095340438490583041",
  "payMethod": "BANK_TRANSFER", "occurDate": "2026-09-13", "voucherNo": "PZ20260913"
}
→ 实收 actualAmount = amount − fee = 4970.00(后端联动重算)

边界·OUT 误传凭证字段(被忽略置 null)

{ "direction":"OUT", ..., "payMethod":"CASH", "voucherNo":"V1", "fee":5 }
→ 创建成功,但库内 payMethod/voucherNo/fee/fundAccountId 均为 null(前端支出表单不应有这些字段)

异常·非法供应商 / 经办人不属部门

{ "unitId":"9999999999999999999", ... }           → { "code":598507, "message":"外部单位不存在或非可付款供应商" }
{ "operatorId":"<非本部门员工>", "deptId":"35", ... } → { "code":598509, "message":"经办人不属于所选部门" }

九、业务边界

  • 供应商校验口径 = "可付款"(主体 ACTIVE + 有生效账户 + 无资质/协议到期),与应付款同口径;停用/黑名单供应商选不中。
  • 编辑(PUT)仅 PENDING 可改;unitId 未变不重新校验供应商(防供应商状态漂移卡死存量草稿),变了才按新供应商硬校验。
  • 经办人 deptId 为空时跳过"属部门"校验(宽松,避免误拦无部门账号);传了 deptId 则 operatorId 必须是该部门成员,否则 598509。
  • 业务单号 flowNo 创建即定、编辑不重取;格式 WS-yyyyMMdd-XXXX(当日序列)。

十、修改前后对比

项 改前 改后
外部单位 手填 unitId + unitName,不验存在 选供应商,后端硬校验 + 自动落 unitName 快照
经办人 后端自动取登录人 入参 operatorId 选员工,校验存在/在职/属部门
支出字段 含凭证/手续费/账户(超原型) OUT 忽略 6 字段,对齐原型
业务单号 无 flowNo(WS-yyyyMMdd-XXXX)
列表搜索 仅 unitId 精确 新增 keyword(单位名/单号模糊)

十一、影响评估 / 回滚

  • 破坏性:旧前端不传 operatorId → 400;传 unitName → 被忽略;OUT 传凭证字段 → 被忽略。前端两个页面必须同迭代联动。
  • 回滚:接口层回退 dev-v3 即可;DDL(fin_nonbiz_flow.flow_no 列)保留无影响。

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

③经办人下拉用本期新增的 GET /admin/user/employee-options(见 PR #7627 / changelog 13_7625),任何登录操作员都能调;不要用旧的 GET /admin/user(限 SUPER_ADMIN/ADMIN 角色,不可用)。

① 供应商下拉/弹窗 — GET /admin/supplier/items/page

  • 入参:page / pageSize / keyword(模糊全称/简称/编码)/ status / typeCode / creditLevel
  • 推荐:?status=ACTIVE&pageSize=20&keyword=,选中取 supplierId 传 nonbiz unitId
  • 出参项:supplierId、supplierNo、fullName、shortName、types、status、statusName、creditLevel、activeAccountCount、contactPhone

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

  • 无入参(需登录)。出参树节点:id(String)、label、parentId(根=0)、children
  • 选中节点 id 传 nonbiz deptId

③ 经办人下拉 — GET /admin/user/employee-options(🆕 本期新增,Issue #7625)

  • 入参:deptId(选) / keyword(选,姓名/企微名/用户名模糊) / page / pageSize
  • 出参项:adminId(String)、username、enterpriseWechatName(姓名)、deptNames
  • 选中取 adminId 传 nonbiz operatorId
  • 鉴权:只要求登录,不限制角色
  • 建议联动:先选部门(②) → 用该 deptId 调本接口过滤本部门员工 → 选经办人

④ 收支类别下拉 — GET /admin/finance/nonbiz-categories?direction=IN|OUT(direction 必填)

  • 出参:code、name、direction、status(NORMAL/DISABLED)、sort;前端取 status=NORMAL

⑤ 收付方式字典 — GET /admin/dict/data/fin_pay_way(仅 IN 下拉用)

  • 出参:dictLabel(中文)、dictValue(码)、sortOrder、status;取 status=ACTIVE

十三、关联 / 联系人