- 13_7612:业务外收支修改接口(破坏性:删 unitName/加 operatorId 必填/OUT 裁剪 6 字段;出参加 flowNo;含供应商弹窗/部门树/员工选择器/类别/收付方式字典 5 个关联接口对接指引) - 13_7625:新增员工选择器 GET /admin/user/employee-options(不限角色,供经办人下拉)
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 | 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 区分,前端拆两个菜单页签(收款管理/业务外收入、付款管理/业务外支出)。本次把两个原本"手填"的主数据接成真关联,对齐原型裁剪支出字段、补业务单号、加列表关键词。
二、变更清单
- 外部单位接供应商:
unitId后端硬校验"可付款供应商"(不可付款/不存在 → 598507);unitName改后端自动取供应商全称落快照,入参 unitName 删除(前端免填)。 - 经办人改选员工:入参新增
operatorId必填(员工 adminId),后端校验存在/在职(598508) + 属于所选部门(598509);不再取登录人自动留痕。 - 支出(OUT)裁剪字段:
payMethod/voucherNo/voucherUrl/feeRate/fee/fundAccountId后端强制置 null(对齐原型支出无凭证类字段);IN 保留全字段。 - 列表关键词:page 新增
keyword(模糊 单位名 / 业务单号)。 - 业务单号:出参新增
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 / changelog13_7625),任何登录操作员都能调;不要用旧的GET /admin/user(限 SUPER_ADMIN/ADMIN 角色,不可用)。
① 供应商下拉/弹窗 — GET /admin/supplier/items/page
- 入参:page / pageSize / keyword(模糊全称/简称/编码)/ status / typeCode / creditLevel
- 推荐:
?status=ACTIVE&pageSize=20&keyword=,选中取supplierId传 nonbizunitId - 出参项:supplierId、supplierNo、fullName、shortName、types、status、statusName、creditLevel、activeAccountCount、contactPhone
② 部门树 — GET /admin/wechat/departments/tree
- 无入参(需登录)。出参树节点:id(String)、label、parentId(根=0)、children
- 选中节点
id传 nonbizdeptId
③ 经办人下拉 — GET /admin/user/employee-options(🆕 本期新增,Issue #7625)
- 入参:deptId(选) / keyword(选,姓名/企微名/用户名模糊) / page / pageSize
- 出参项:adminId(String)、username、enterpriseWechatName(姓名)、deptNames
- 选中取
adminId传 nonbizoperatorId - 鉴权:只要求登录,不限制角色
- 建议联动:先选部门(②) → 用该 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
十三、关联 / 联系人
- Issue:https://git.1814.love:8443/wx/HL/issues/7612
- PR:https://git.1814.love:8443/wx/HL/pulls/7619
- 配套(经办人下拉接口):Issue #7625 / PR #7627 / changelog
13_7625_员工选择器接口-新增接口-管理后台.md - 负责人:yst(腰苏图)