文件
hl-api-changelog/changelogs-v2/2026-09/29_8517_预支审批驳回撤回补角色守卫-修改接口-管理后台.md
T
2026-09-29 17:17:35 +08:00

18 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 8517 预支审批中心列表与审批 / 驳回只放行财务与管理员(585008),撤回只放行申请人本人与管理员(585009),带 nacos 回滚开关 admin jw(GIT) 修改接口 deployed verified not_required 已合并 dev-v3(e51832e8d)并部署 TEST,自签 token 经网关实测:列表 11 角色矩阵、不存在 advanceId 的三个写接口、真实预支的审批 / 驳回 / 撤回正反路径、nacos 开关关闭→还原往返(md5 逐字节还原)与服务端 ADVANCE_ACL_DENY 日志正反两面。前端判 not_required:审批中心菜单与通过 / 驳回按钮本来只授超管 / 管理员 / 财务;新错误码由 request.js 拦截器统一弹 message;撤回按钮对非申请人仍显示,点了会提示 585009,出参里没有申请人 id 供前端判断显隐(本单不改出参)。 2026-09-29 dev-v3

order-v3: 预支审批中心列表与审批 / 驳回 / 撤回补角色守卫

服务: hl-order-service-v3 PR: #8531(已合入 dev-v3,合并提交 e51832e8d) Issue: #8517


⚠️ 关键变化

🔴 审批中心列表、审批通过、驳回:只放行超管、管理员、财务,其余角色返回 585008。 改前任意后台账号都能看全公司预支、能审批(订单级预支审批通过会生成出纳待付款),只有团期管理员被挡。

🔴 撤回:只放行申请人本人和超管、管理员,其余返回 585009。 财务也不能撤别人的预支,要拦应走驳回并填原因。

🟢 四个接口的入参、出参、成功码全部不变。 有权限的调用方行为与改前一致。


一、背景

预支按设计由财务审批:管理后台「预支审批」菜单和通过 / 驳回按钮只授给超管、管理员、财务。但这四个接口此前只拒团期管理员,界面上进不去的角色直接调接口就能审批、查看全量预支、撤掉别人待审批的预支。本单补上接口层的判权。


二、变更接口清单

# 接口 方法 路径 变更类型 说明
1 预支审批列表 GET /v3/admin/order/advance-approvals/page 修改 新增判权:只放行 SUPER_ADMIN / ADMIN / FINANCE,其余 585008;出参不变
2 预支审批通过 PUT /v3/admin/order/advance/:advanceId/approve 修改 新增判权:同上,其余 585008;出参不变
3 预支审批驳回 PUT /v3/admin/order/advance/:advanceId/reject 修改 新增判权:同上,其余 585008;出参不变
4 撤回待审批预支 DELETE /v3/admin/order/advance/:advanceId 修改 新增判权:只放行申请人本人与 SUPER_ADMIN / ADMIN,其余 585009;出参不变

三、接口详情

1. 预支审批列表 GET /v3/admin/order/advance-approvals/page

VO: AdvanceApprovalPageReqVO → Result<PageResult<AdvanceApprovalPageItemRespVO>>

使用场景

管理后台「财务管理 → 预支审批」页的列表。本单起只有超管、管理员、财务能查。

入参字段表

字段 位置 类型 必填 约束 说明
page Query Integer ❌ ≥1 页码。行为不变
pageSize Query Integer ❌ ≥1 每页条数。行为不变
status Query String ❌ SUBMITTED / APPROVED / REJECTED / PAID 缺省 SUBMITTED。行为不变
其余筛选项 Query — ❌ — orderId / keyword / scope / payeeName / createdByName / 提交时间区间。行为不变

出参字段表

字段 类型 说明
data PageResult<AdvanceApprovalPageItemRespVO> 结构完全不变(records / total / page / pageSize)

请求示例

GET /v3/admin/order/advance-approvals/page?page=1&pageSize=20&status=SUBMITTED HTTP/1.1
Authorization: Bearer <财务账号 token>

响应示例

{
  "code": 200,
  "message": "成功",
  "data": {
    "records": [],
    "total": 0,
    "page": 1,
    "pageSize": 20
  },
  "success": true
}

空数据 / 降级响应

无数据时 records 为空数组、total 为 0(行为不变)。降级:nacos advance.acl.enforce.role-guard 置 false 时回到改前行为(任意后台角色可查),但服务端每次仍留一条 ADVANCE_ACL_DENY 日志(enforced=false)。开关默认 true。

错误响应

码 符号 触发 本单
585008 ADVANCE_APPROVAL_FORBIDDEN 当前角色不是超管 / 管理员 / 财务(含缺角色的 token) 🆕 新增
585005 ADVANCE_STATUS_ILLEGAL status 不是合法取值 不变

585008 实打响应体(TEST,2026-09-29,定制师):

{
  "code": 585008,
  "message": "仅财务或管理员可查看预支审批、审批或驳回预支",
  "data": null,
  "success": false
}

业务边界

  • 判权在查询之前,被拒时不返回任何数据。
  • 团期管理员也返回 585008(本接口改前对它不设防)。

2. 预支审批通过 PUT /v3/admin/order/advance/:advanceId/approve

VO: OrderAdvanceRespVO(无请求体,出参 Result<OrderAdvanceRespVO>)

使用场景

预支审批页「通过」按钮:待审批(SUBMITTED)→ 已审批(APPROVED);订单级预支同时生成出纳待付款。本单起只有超管、管理员、财务能批。

入参字段表

字段 位置 类型 必填 约束 说明
advanceId Path Long ✅ 预支 ID 行为不变

出参字段表

字段 类型 说明
data OrderAdvanceRespVO 结构完全不变;status=APPROVED,approvedBy 为审批人姓名

请求示例

PUT /v3/admin/order/advance/2104861625016287233/approve HTTP/1.1
Authorization: Bearer <财务账号 token>

响应示例

{
  "code": 200,
  "message": "成功",
  "data": {
    "id": "2104861625016287233",
    "status": "APPROVED",
    "approvedBy": "jw",
    "rejectReason": null
  },
  "success": true
}

空数据 / 降级响应

无空数据语义。降级:nacos 开关置 false 时回到改前行为(除团期管理员外任意后台角色可批),仍留 ADVANCE_ACL_DENY 日志。团期管理员的 581008 不读该开关,关掉也照拒。

错误响应

码 符号 触发 本单
585008 ADVANCE_APPROVAL_FORBIDDEN 当前角色不是超管 / 管理员 / 财务。先于预支存在性校验,预支不存在也返回本码 🆕 新增
581008 ORDER_VIEW_FORBIDDEN 团期管理员(排在最前) 不变
585000 ADVANCE_NOT_FOUND 有权角色操作不存在的预支 不变
585005 ADVANCE_STATUS_ILLEGAL 预支不是待审批 不变
{
  "code": 585008,
  "message": "仅财务或管理员可查看预支审批、审批或驳回预支",
  "data": null,
  "success": false
}

业务边界

  • 被拒时零写入:预支状态不变,也不会生成出纳待付款。
  • 定制师审批自己申请的预支同样返回 585008。
  • 本单不限制「管理员 / 财务审批自己申请的预支」(职责分离不在本单范围)。

3. 预支审批驳回 PUT /v3/admin/order/advance/:advanceId/reject

VO: RejectAdvanceReqVO → Result<OrderAdvanceRespVO>

使用场景

预支审批页「驳回」按钮:待审批(SUBMITTED)→ 已驳回(REJECTED),须填驳回原因。本单起只有超管、管理员、财务能驳。

入参字段表

字段 位置 类型 必填 约束 说明
advanceId Path Long ✅ 预支 ID 行为不变
reason Body String ✅ 非空 驳回原因。行为不变

出参字段表

字段 类型 说明
data OrderAdvanceRespVO 结构完全不变;status=REJECTED,rejectReason 为驳回原因

请求示例

PUT /v3/admin/order/advance/2104861622562627585/reject HTTP/1.1
Authorization: Bearer <财务账号 token>
Content-Type: application/json

{"reason": "门票已由地接社统一采购,无需个人垫付"}

响应示例

{
  "code": 200,
  "message": "成功",
  "data": {
    "id": "2104861622562627585",
    "status": "REJECTED",
    "approvedBy": "jw",
    "rejectReason": "门票已由地接社统一采购,无需个人垫付"
  },
  "success": true
}

空数据 / 降级响应

无空数据语义。降级口径同「审批通过」。

错误响应

码 符号 触发 本单
585008 ADVANCE_APPROVAL_FORBIDDEN 当前角色不是超管 / 管理员 / 财务;先于存在性校验 🆕 新增
581008 ORDER_VIEW_FORBIDDEN 团期管理员 不变
585000 / 585005 — 预支不存在 / 不是待审批 不变
{
  "code": 585008,
  "message": "仅财务或管理员可查看预支审批、审批或驳回预支",
  "data": null,
  "success": false
}

业务边界

  • 被拒时零写入:状态与驳回原因都不变。

4. 撤回待审批预支 DELETE /v3/admin/order/advance/:advanceId

VO: Result<Void>(无请求体)

使用场景

订单详情「预支」弹窗、团期详情「财务」页签里的「撤回」按钮:撤掉一笔还没审批的预支。本单起只有申请人本人和超管、管理员能撤。

入参字段表

字段 位置 类型 必填 约束 说明
advanceId Path Long ✅ 预支 ID 行为不变

出参字段表

字段 类型 说明
data null 不变

请求示例

DELETE /v3/admin/order/advance/2104861626131980289 HTTP/1.1
Authorization: Bearer <申请人本人 token>

响应示例

{
  "code": 200,
  "message": "成功",
  "data": null,
  "success": true
}

空数据 / 降级响应

无空数据语义。降级:nacos 开关置 false 时回到改前行为(除团期管理员外任意后台角色可撤),仍留日志。

错误响应

码 符号 触发 本单
585009 ADVANCE_REVOKE_FORBIDDEN 既不是这笔预支的申请人,也不是超管 / 管理员(财务也返回本码)。非管理员撤不存在的预支也返回本码 🆕 新增
581008 ORDER_VIEW_FORBIDDEN 团期管理员 不变
585000 ADVANCE_NOT_FOUND 超管 / 管理员撤不存在的预支 不变
585005 ADVANCE_STATUS_ILLEGAL 预支已审批 / 已驳回 不变
{
  "code": 585009,
  "message": "仅申请人本人或管理员可撤回该预支",
  "data": null,
  "success": false
}

业务边界

  • 「申请人」指提交这笔预支的后台账号,按账号 ID 判定,不按姓名。
  • 被拒时零写入:预支不删。
  • 期初结转等没有申请人记录的存量预支,只有超管、管理员能撤。

四、契约约束与正确调用方式

  • 新错误码 585008 / 585009 直接透出 message 即可。
  • 撤回按钮目前对所有能看到待审批预支的人显示;非申请人点击会收到 585009。出参里没有申请人账号 ID,本单不改出参,按钮显隐暂不能按申请人精确控制。
  • 同时挂财务与其它角色的账号,要切到财务角色才能进审批中心(后端按当前角色判定)。

五、数据库行为

  • 零 DDL、零数据迁移。
  • 撤回的「申请人」取预支记录既有的创建人字段(提交预支时自动写入);TEST 现存预支该字段全部有值。
  • 被拒绝的请求不写库。

六、边界行为

  • 有权限的调用方:与改前完全一致。
  • 缺角色的 token:列表 / 审批 / 驳回返回 585008;撤回只要是申请人本人仍可撤。
  • 系统内部调用(定时任务、消息消费等无请求的场景)不受限制。
  • 团期管理员:审批 / 驳回 / 撤回仍先返回 581008;列表返回 585008。

六.6、修改前后对比

角色 列表 审批 / 驳回 撤回别人的预支 撤回自己的预支
SUPER_ADMIN / ADMIN 正常 → 正常 正常 → 正常 正常 → 正常 正常 → 正常
FINANCE 正常 → 正常 正常 → 正常 正常 → 585009 正常 → 正常
CUSTOMIZER 正常 → 585008 正常 → 585008 正常 → 585009 正常 → 正常
车务 / 房务 / 房务组长 / 运营 / 客服 正常 → 585008 正常 → 585008 正常 → 585009 正常 → 正常
GROUP_BATCH_MANAGER 正常 → 585008 581008 → 不变 581008 → 不变 581008 → 不变

六.7、影响评估

  • 是否破坏向后兼容:对有权限的调用方否;对无权限的调用方,原来能成功的请求改为返回新错误码。
  • 前端是否必须同步上线:否。
  • 回滚:nacos advance.acl.enforce.role-guard 置 false,TEST 实测 5.6 秒内生效,不需重发服务。

七、不影响范围

  • 创建预支 POST /v3/admin/order/:orderId/advance、借款对象候选、本单预支列表 GET /v3/admin/order/:orderId/advances:判权不变。
  • 团期发起预支、团期财务页签的预支列表:判权不变。
  • 财务出纳付款:本单未改。
  • 小程序端:无影响。

八、测试环境已验证

环境:TEST(https://api.test.1814.love) 验证时间:2026-09-29 17:08~17:15 构建身份:order-v3 部署 dev-v3 @ e51832e8d(本单合并提交),17:08 完成。零写入判据:旧字节里定制师查审批列表返回 200 和数据,新字节才会返回 585008;部署后连打 6 次全部 585008,同时管理员 200。 身份:自签 token 直打网关,未只用超管;TEST 上没有持财务角色的账号,财务身份用 role=FINANCE 的自签 token。

8.1 列表角色矩阵

角色 结果
SUPER_ADMIN / ADMIN / FINANCE 200,status=PAID 返回 2 条
CUSTOMIZER / VEHICLE_MANAGER / ROOM_MANAGER / house_keeper_lead / GROUP_BATCH_MANAGER / OPERATOR / CUSTOMER_SERVICE / 缺角色 585008,data 为 null

8.2 不存在的预支 ID(零写入)

角色 审批 驳回 撤回
CUSTOMIZER / VEHICLE_MANAGER 585008 585008 585009
FINANCE 585000(过守卫) 585000(过守卫) 585009
ADMIN 585000 585000 585000
GROUP_BATCH_MANAGER 581008 581008 581008

前后预支表、出纳执行单表行数不变。

8.3 真实预支的正反路径

在待出发订单 HL20260918082629372 上以定制师身份提交 4 笔预支(门票 380、餐费 260、门票 150、餐费 120):

操作 结果
其他定制师 / 车务管理员 / 申请人本人审批 380 那笔 均 585008,仍待审批,出纳执行单 0 行
其他定制师驳回 585008,驳回原因为空
财务、其他定制师撤回 均 585009,未删除
财务驳回 200,已驳回,出纳执行单 0 行
其他定制师审批 260 那笔 585008;随后财务审批 200,已审批,出纳执行单 1 行
申请人本人撤回 150 那笔 200,已软删
管理员撤回 120 那笔(别人申请的) 200,已软删

8.4 nacos 回滚开关往返

配置 hl-order-service-v3-test.yml(tenant=test)原本不含 advance.* 键,即默认 true。

态 配置 定制师查列表 定制师审批不存在的预支 定制师撤不存在的预支 团期管理员审批
A 无键(默认 true) 585008 585008 585009 581008
B 追加 role-guard: false 200(5.6 秒内生效) 585000(回到改前) 585000(回到改前) 581008(不受开关影响)
C 逐字节还原 585008(9.3 秒内生效) — — —
  • 发布带 casMd5,还原写在 finally 里;还原后 md5 与原值同为 c2206934960057f70b7173159046dc54。
  • 服务端日志(两个实例合计):ADVANCE_ACL_DENY ... enforced=false 只出现在 B 态的 17:14:37~43,共 9 条,与 B 态调用次数一致;A、C 两态只有 enforced=true。

本地证据

项 读数
新增 4 个测试类 51 例全绿(守卫 29、绑定器 6、Controller 7、撤回 9)
预支包 + ArchTest + 错误码门禁 + 切片清单 249/0/0/0
order-v3 全量(有 Docker) 14519 例,9F / 8E;红的 7 个类在基底 48e66bd06 上逐类、逐用例名一致,本单零新增失败
变异 删掉审批端点守卫 → 1 例红;开关判定上提到方法头 → 12 例红;已还原

十、相关文档

  • Issue #8517;PR #8531
  • docs/finance/api/API-SPEC-FINANCE-V1.0.html §2.4.4(补判权口径)
  • docs/group/团期模块接口文档-v2.0.html §0B.9、docs/group/数据模型.html §A.11.12、docs/group/实施单/11-财务与预支.html(错误码表补 585008 / 585009)

关联 / 联系人

链接

联系人

  • 后端负责人: @jw