hl-api-changelog/changelogs-v2/2026-08/07_5655_核单导游摄影族B接口下线-删除接口-管理后台.md
Mimingguang 20255492d0
一些检查失败了
changelog-filename-gate / validate (push) Failing after 1s
chore(v2): 标记 #5655 admin 前端已实现 (hl-admin@ee7a5d58)
族B→族A 切换已上线:直连 guide-fees/photographer-fees + 类别级指纹乐观锁
+ 并入 CategoryTable + 人员下拉仅预填姓名 + 不接 confirm + 候选最小实现。
如实标注待确认项:人员指纹冲突错误码按车辆域 584108 复用,待后端确认。
2026-08-08 09:42:52 +08:00

18 KiB

author, schema, ticket, title, consumer, change_type, backend_status, gateway_status, frontend_status, frontend_owner, frontend_ref, target_release, verified_at, status_note, updated_at, base
author schema ticket title consumer change_type backend_status gateway_status frontend_status frontend_owner frontend_ref target_release verified_at status_note updated_at base
yst(GIT) hl-changelog/v2 5655 核单导游/摄影族B嵌套接口下线,统一走族A扁平接口 admin 删除接口 deployed not_required implemented mmg ee7a5d58 2026-08-07 后端已删除族B guides/photographers 嵌套 GET/PUT 共4个路由并部署测试服;已行为级验证族B 4端点返回404、族A guide-fees/photographer-fees 正常返回。等待前端将导游/摄影页签从族B路径切换到族A扁平接口,frontend_status=pending 表示等待前端真实领取。 2026-08-08 dev-v3

⚠️【删除接口·管理后台】核单导游/摄影族B嵌套接口下线,统一走族A扁平接口 (#5655)

PR: #5658 | 服务: order-v3 | 更新时间: 2026-08-07

1. 接口背景

核单页面的导游、摄影师费用历史上存在两套接口:

  • 族 A保留/settlement/guide-fees/settlement/photographer-fees,按天扁平行结构,与住宿、餐食等页签形态一致。
  • 族 B本次删除/settlement/staff-fees/guides/settlement/staff-fees/photographers,按人嵌套 persons[] 结构。

一笔导游/摄影费用只对应一个人,族 B 的 persons[] 嵌套属于过度设计,且与其他核单页签的平铺形态不一致。本次将族 B 共 4 个路由整体删除,导游/摄影核单统一由族 A 扁平接口承载。

旧路径已删,调用返回 HTTP 404「接口不存在」。 前端必须把导游、摄影师页签的查询/保存调用从族 B 路径切换到族 A 路径。

2. 变更清单

# 接口名 方法 路径 变更类型 说明
1 查询导游人员费用族B GET /v3/admin/order/:orderId/settlement/staff-fees/guides 删除 路由删除,调用返回 HTTP 404
2 全量替换导游人员费用族B PUT /v3/admin/order/:orderId/settlement/staff-fees/guides 删除 路由删除,调用返回 HTTP 404
3 查询摄影师人员费用族B GET /v3/admin/order/:orderId/settlement/staff-fees/photographers 删除 路由删除,调用返回 HTTP 404
4 全量替换摄影师人员费用族B PUT /v3/admin/order/:orderId/settlement/staff-fees/photographers 删除 路由删除,调用返回 HTTP 404

替代接口(族 A,本次未改动,已在线,前端切换目标):

Tab 查询 全量保存 确认
导游 GET /v3/admin/order/:orderId/settlement/guide-fees PUT /v3/admin/order/:orderId/settlement/guide-fees POST /v3/admin/order/:orderId/settlement/guide-fees/confirm
摄影师 GET /v3/admin/order/:orderId/settlement/photographer-fees PUT /v3/admin/order/:orderId/settlement/photographer-fees POST /v3/admin/order/:orderId/settlement/photographer-fees/confirm

3. 接口详情

3.1 已删除族B 导游人员费用查询与保存

  • 原方法与路径
    • GET /v3/admin/order/:orderId/settlement/staff-fees/guides
    • PUT /v3/admin/order/:orderId/settlement/staff-fees/guides
  • 使用场景:已删除。导游核单查询/保存改用 /settlement/guide-fees(见 §3.3)。
  • 认证:原接口要求管理后台登录态;接口删除后,即使登录态有效也返回 HTTP 404。
  • 幂等性:不适用。
  • 限流:无。

3.2 已删除族B 摄影师人员费用查询与保存

  • 原方法与路径
    • GET /v3/admin/order/:orderId/settlement/staff-fees/photographers
    • PUT /v3/admin/order/:orderId/settlement/staff-fees/photographers
  • 使用场景:已删除。摄影师核单查询/保存改用 /settlement/photographer-fees(见 §3.4)。
  • 认证:原接口要求管理后台登录态;接口删除后,即使登录态有效也返回 HTTP 404。
  • 幂等性:不适用。
  • 限流:无。

3.3 替代导游费用族A

  • 接口名:查询导游费用 / 全量保存导游费用 / 确认导游费用
  • 方法与路径
    • GET /v3/admin/order/:orderId/settlement/guide-fees
    • PUT /v3/admin/order/:orderId/settlement/guide-fees
    • POST /v3/admin/order/:orderId/settlement/guide-fees/confirm
  • 使用场景:核单页面导游页签的查询、全量保存、确认。
  • 认证:管理后台登录态 + 订单访问权限。
  • 幂等性GET 只读;PUT 为全量替换语义,需携带 expectedSourceFingerprint 乐观锁指纹(取值为最近一次 GET 返回的 sourceFingerprint,指纹不匹配拒绝写入;POST confirm 重复确认不产生副作用。
  • 限流:无接口级特殊限流。

3.4 替代摄影师费用族A

  • 接口名:查询摄影师费用 / 全量保存摄影师费用 / 确认摄影师费用
  • 方法与路径
    • GET /v3/admin/order/:orderId/settlement/photographer-fees
    • PUT /v3/admin/order/:orderId/settlement/photographer-fees
    • POST /v3/admin/order/:orderId/settlement/photographer-fees/confirm
  • 使用场景:核单页面摄影师页签的查询、全量保存、确认。
  • 认证 / 幂等性 / 限流:与 §3.3 导游一致。

4. 接口入参

4.1 路径参数族A GET / PUT / POST 通用)

字段 类型 必填 说明 校验
orderId String(Long) 订单 ID 正整数

GET 无 Query 参数、无请求体。POST confirm 无请求体。

4.2 PUT 请求体(全量保存)

字段 类型 必填 说明
expectedSourceFingerprint String 乐观锁指纹,取最近一次 GET 返回的 sourceFingerprint;不匹配则拒绝写入
items Array 全量费用行(扁平按天,无嵌套);传 [] 表示清空
excludedCandidateKeys String[] 被排除的候选 candidateKey 列表;无排除传 []

items[] 行字段与 GET 出参行字段一致(见 §5.2),其中 id 已有行需回传、新增行不传。

5. 出参字段

5.1 顶层字段GET data

字段 类型 可空 说明
category String 类别;导游固定 GUIDE,摄影师固定 PHOTOGRAPHER
sourceFingerprint String 乐观锁指纹;PUT 必须通过 expectedSourceFingerprint 回传
totalAmount String(Decimal) 费用合计金额,字符串格式如 "590.00"
cashPaidAmount String(Decimal) 现付金额合计
unconfirmedCount Integer 未确认行数
pendingCandidateCount Integer 待处理候选数
settlementReady Boolean 是否已具备核单条件
blockReasonCode String 不具备核单条件时的机器可读原因;可核单时为 null,如 ITEMS_UNCONFIRMED
editable Boolean 当前是否可编辑
readOnlyReasonCode String 只读原因;可编辑时为 null
items Array 费用行,扁平按天,无嵌套;无明细为 []

5.2 items[] 行字段

导游guide-fees

字段 类型 可空 说明
id String(Long) 费用行 ID雪花,字符串;候选未落库行为 null
candidateKey String 候选键;手工补录行为 null
staffAssignmentId String(Long) 人员派单 ID;无关联为 null
serviceDate String(date) 服务日期(单天),格式 YYYY-MM-DD
name String 导游姓名
serviceType String 服务类型编码,见 §6.1
serviceTypeName String 服务类型名称,如 全陪导游
paymentMethod String 付款方式编码,见 §6.3
paymentMethodName String 付款方式名称
amount String(Decimal) 金额,字符串格式如 "295.00"
settlementConfirmStatus String 核单确认状态编码,见 §6.4
settlementConfirmStatusName String 核单确认状态名称
remark String 备注
sourceType String 来源编码,见 §6.5
sourceTypeName String 来源名称,如 手工补录
sourceActive Boolean 来源是否有效
voucherUrls String[] 凭证 URL;无凭证为 []
completionState String 行完备状态,如 COMPLETE
candidateResolution String 候选处理结果,如 INCLUDED

摄影师photographer-fees与导游同构,仅两个字段名不同:

语义 导游字段名 摄影师字段名
姓名 name photographerName
类型编码/名称 serviceType / serviceTypeName feeType / feeTypeName

摄影师类型枚举见 §6.2。

6. 枚举 / 数据字典

6.1 导游 serviceType

所属字段guide-fees items[].serviceType 类型String

中文
FULL_COURSE_GUIDE 全陪导游
LOCAL_GUIDE 地接导游
COMMENTARY_SERVICE 讲解服务
TEMPORARY_SUPPLEMENT 临时补录

6.2 摄影师 feeType

所属字段photographer-fees items[].feeType 类型String

中文
FOLLOW_SHOOT 跟拍
PORTRAIT 写真
AERIAL_SHOOT 航拍
EDITING_DELIVERY 剪辑出片
CAMERA_DRONE 相机/无人机
OTHER 其他

6.3 paymentMethod

所属字段items[].paymentMethod 类型String

中文
COMPANY_PAID 公司付款
CASH_PAID 现付

6.4 settlementConfirmStatus

所属字段items[].settlementConfirmStatus 类型String

中文
UNCONFIRMED 未确认
CONFIRMED 已确认

6.5 sourceType

所属字段items[].sourceType 类型String

中文 说明
MANUAL 手工补录 核单页手工新增的费用行
其他来源编码 由派单/候选自动带入,以实际返回为准

7. 错误码

7.1 已删除的族B专属错误码不再返回

code 原含义 变更
584023 DRIVER detail 缺 days[] 数组 / 元素缺 service_date 或 daily_fee 字段 删除,不再返回
584024 GUIDE / PHOTOGRAPHER detail 缺 persons[] / 元素缺 name / days / per_day 删除,不再返回
584025 LEADER detail 缺 days 或 per_day 字段 删除,不再返回
584028 OTHER detail 缺 items[] / 元素缺 name / amount 删除,不再返回

前端若存在针对这 4 个错误码的分支处理,可一并清理。

7.2 本次相关错误码

code 含义 触发场景
404 请求地址不存在 调用任一已删除的族B路由staff-fees/guides、staff-fees/photographers
400 请求参数错误 orderId 不是正整数;PUT 请求体字段缺失或非法
403 无访问权限 登录态或角色无权访问
581007 订单不存在 orderId 对应订单不存在

8. 示例

8.1 典型成功GET 导游费用族A

请求:

GET /v3/admin/order/2085641684778958848/settlement/guide-fees
Authorization: Bearer JWT_TOKEN

无请求体。

响应(测试单真实打样):

{
  "code": 200,
  "message": "成功",
  "data": {
    "category": "GUIDE",
    "sourceFingerprint": "a02c66c6...",
    "totalAmount": "590.00",
    "cashPaidAmount": "0.00",
    "unconfirmedCount": 2,
    "pendingCandidateCount": 0,
    "settlementReady": false,
    "blockReasonCode": "ITEMS_UNCONFIRMED",
    "editable": true,
    "readOnlyReasonCode": null,
    "items": [
      {
        "id": "2085641684778958849",
        "candidateKey": null,
        "staffAssignmentId": null,
        "serviceDate": "2026-08-10",
        "name": "王强",
        "serviceType": "FULL_COURSE_GUIDE",
        "serviceTypeName": "全陪导游",
        "paymentMethod": "COMPANY_PAID",
        "paymentMethodName": "公司付款",
        "amount": "295.00",
        "settlementConfirmStatus": "UNCONFIRMED",
        "settlementConfirmStatusName": "未确认",
        "remark": "打样导游",
        "sourceType": "MANUAL",
        "sourceTypeName": "手工补录",
        "sourceActive": true,
        "voucherUrls": [],
        "completionState": "COMPLETE",
        "candidateResolution": "INCLUDED"
      }
    ]
  },
  "success": true
}

8.2 边界PUT 全量保存空 items清空导游费用

请求:

PUT /v3/admin/order/2085641684778958848/settlement/guide-fees
Authorization: Bearer JWT_TOKEN
Content-Type: application/json
{
  "expectedSourceFingerprint": "a02c66c6...",
  "items": [],
  "excludedCandidateKeys": []
}

响应:

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

保存后重新 GET 拉取最新 sourceFingerprint 再渲染。

8.3 业务失败调用已删除的族B旧路径返回 404

请求:

GET /v3/admin/order/2085641684778958848/settlement/staff-fees/guides
Authorization: Bearer JWT_TOKEN

无请求体。

响应:

{
  "code": 404,
  "message": "请求地址不存在",
  "data": null,
  "success": false
}

PUT /settlement/staff-fees/guides、GET/PUT /settlement/staff-fees/photographers 行为一致,均为 HTTP 404。

9. 业务边界

适用

  • 核单页面导游、摄影师页签的查询、保存、确认全部走族 A 扁平接口。
  • 一笔费用一行(按人×天扁平铺开),不存在一人多行嵌套。

不适用

  • 族 B 的 persons[] 嵌套请求体不再有任何承载路径,不得把嵌套 body 改发到族 A族 A 只接受扁平 items[])。
  • 领队、司机、其他人员费用早在 #5380 已删除,本次不涉及。

特殊边界

  • PUT 必须携带最新 expectedSourceFingerprint;并发编辑或保存后未刷新指纹再保存会被拒绝,需重新 GET。
  • items=[] 是合法输入,表示清空该类别费用。

10. 修改前后对比

10.1 接口级对比

能力 改前 改后
导游费用查询 GET /settlement/staff-fees/guides族B,persons[] 嵌套) GET /settlement/guide-fees族A,扁平 items[]
导游费用保存 PUT /settlement/staff-fees/guides族B PUT /settlement/guide-fees族A,带 expectedSourceFingerprint
摄影师费用查询 GET /settlement/staff-fees/photographers族B GET /settlement/photographer-fees族A
摄影师费用保存 PUT /settlement/staff-fees/photographers族B PUT /settlement/photographer-fees族A
族B 4 个路由 可用 已删除,调用返回 HTTP 404

10.2 错误码对比

错误码 改前 改后
584023 / 584024 / 584025 / 584028 族B 请求体校验失败时返回 不再返回族B 路由整体删除)

11. 影响评估 / 回滚

11.1 影响评估

  • 是否破坏向后兼容是。族B 共 4 个路由已删除,未切换的前端版本调用固定 404。
  • 前端是否必须同步上线:是。管理后台必须把导游、摄影师页签的查询/保存切换到族 A 路径,并改为扁平 items[] 请求体(携带 expectedSourceFingerprint)。
  • 后端数据:导游/摄影费用底层存储不变,仅接口承载形态收口;历史数据在族 A 下正常可见。

11.2 回滚边界

  • 前端版本不得回滚到仍调用 staff-fees/guidesstaff-fees/photographers 的版本,否则对应页签固定 404。
  • 后端如需回滚需恢复 4 个路由与 4 个错误码,涉及 PR #5658 整体 revert,由后端评估。

12. 注意事项

  • 切换目标路径是 guide-fees / photographer-fees(短横线、无 staff 前缀),不要拼成 staff-fees/guide-fees 等混合路径。
  • 族A PUT 是全量替换语义:保存时提交整页 items[];只传改动行会丢失未传行。
  • 保存成功后必须重新 GET 获取最新 sourceFingerprint,否则下次 PUT 指纹不匹配被拒。
  • 摄影师行字段是 photographerName / feeType / feeTypeName,与导游的 name / serviceType / serviceTypeName 不同,不要复用同一套字段映射常量。
  • orderId、行 idstaffAssignmentId 均按字符串处理;金额字段(amount / totalAmount / cashPaidAmount)为字符串格式 Decimal。
  • 清理前端对 584023 / 584024 / 584025 / 584028 的错误码分支。

13. 关联 / 联系人

13.1 链接

13.2 联系人

  • 后端负责人: @yst腰苏图

验证证据

  • PR #5658 已合并至 dev-v3,合并提交 7d29484da77e20a706ec611893545c419f6821b2
  • 测试服已部署并行为级验证族B 4 端点GET/PUT staff-fees/guides、GET/PUT staff-fees/photographers均返回 HTTP 404;族A guide-fees / photographer-fees 正常返回业务数据。

前端交付2026-08-08 mmg,hl-admin@ee7a5d58

族B→族A 切换已上线 v2.1。导游/摄影师页签查询/保存直连族A guide-fees/photographer-fees,废弃按人嵌套 StaffFeeTable、并入通用 CategoryTable与住宿/餐食/车辆页签同形态;PUT 携带 expectedSourceFingerprint 类别级指纹乐观锁(照车辆 version 模式 GET attach / 保存后 re-GET 写回 / 冲突刷新)。导游 name/serviceType 与摄影 photographerName/feeType 分别映射未复用;人员下拉保留仅预填姓名族A 无 staffId 落点);未接 confirm 端点(确认语义行级随 PUT;候选最小实现 excludedCandidateKeys 恒 []。

待后端确认:人员费用指纹冲突的错误码 changelog 未给出,前端按车辆域既有 584108 复用做冲突刷新分支;若人员域实际返回别的码,请告之以对齐(不阻塞,缺省时错误照常透传提示,仅无自动刷新)。