文件
hl-api-changelog/changelogs-v2/2026-09/09_7377_团期人员配置必填与备品库口径收口-修改接口-管理后台.md
Mimingguang b4ab37a9bc
changelog-filename-gate / validate (push) Failing after 2s
docs(changelogs-v2): #7377 前端回写 not_required
保存人员配置 staffList 必填、备品候选 keyword 转义、加备品行定点查三端点
行为变更,前端实查零改动:saveGroupBatchStaff 请求体恒带 staffList,备品
keyword 原样透传,加行 500 上限解除对调用方透明。
2026-09-09 18:03:10 +08:00

13 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 7377 团期人员配置 staffList 改必填 + 备品候选关键字转义 + 加备品行改定点查 admin jw(GIT) 修改接口 deployed verified not_required mmg 2026-09-09 not_required 2026-09-09 mmg:三端点行为变更,前端零改动。①保存人员 saveGroupBatchStaff(orderV2GroupBatch.js:186) 请求体恒为 {staffList},省略字段路径不存在,清空即传 [](GroupBatchStaffConfigModal handleSave 过滤后数组恒在)。②备品候选 keyword 由 SuppliesPickerModal 原样透传(仅 trim),无前端通配依赖。③加备品行 addGroupBatchSupplies 只传 {suppliesResourceId,quantity},500 上限解除对调用方透明,589518 已正确区分库挂/无备品。 2026-09-09 dev-v3

团期人员配置必填与备品库口径收口

一、给前端的一句话

两处行为变更要注意:保存团期人员配置必须带 staffList 字段(要清空就传 [],别省略);备品候选列表搜 % / _ 不再返回全库。另有一处纯修复不影响调用方——加备品行不再受「备品库超 500 条」的隐性上限。

二、变更接口清单

# 接口 方法 路径 变更类型 说明
1 保存团期人员配置 PUT /v3/admin/group-batch/:productBatchId/staff 修改接口 staffList 由可省略改为必填,缺失返 400;显式传 [] 仍是清空
2 团期物资候选列表 GET /v3/admin/order/group-batch/:groupBatchId/supplies/candidates 修改接口 keyword 转义 LIKE 通配符,% / _ 不再当通配符
3 团期物资新增行 POST /v3/admin/order/group-batch/:groupBatchId/supplies 修改接口 取备品库快照改走定点查,解除「备品库超 500 条后加不进」的隐性上限

三、接口详情

1. 保存团期人员配置 PUT /v3/admin/group-batch/:productBatchId/staff

VO: BatchStaffConfigReqVO / BatchStaffConfigRespVO

使用场景

团期详情的「导游 / 摄影」配置,全量覆盖式保存。

入参

字段 位置 类型 必填 约束 说明
productBatchId Path String 是 正整数 产品侧班期 ID
staffList Body Array 是(本次变更) 可为空数组 全量覆盖列表;显式传 [] 即清空,字段缺失一律 400
staffList[].staffId Body String 是 正整数 资源域人员 ID
staffList[].staffRole Body String 是 LEADER / GUIDE / DRIVER / PHOTOGRAPHER / OTHER,区分大小写 越界值返 400;与该人在资源域的实际类型不符返 582114
staffList[].sortOrder Body Integer 否 默认 0 展示排序
staffList[].remark Body String 否 最长 500 备注

出参

字段 类型 说明
code / message / success Integer / String / Boolean 业务结果
data.staffList Array 保存后的配置快照,含 staffId / staffName / staffPhone / staffRole 等
data.affectedOrderCount Integer 已触发异步扇出的活跃订单数,仅作提示

请求示例

{
  "staffList": [
    {
      "staffId": "1002",
      "staffRole": "GUIDE",
      "sortOrder": 0
    }
  ]
}

响应示例

{
  "code": 200,
  "message": "成功",
  "success": true,
  "data": {
    "staffList": [
      {
        "staffId": "1002",
        "staffName": "李雪梅",
        "staffPhone": "138****1002",
        "staffRole": "GUIDE",
        "sortOrder": 0
      }
    ],
    "affectedOrderCount": 2
  }
}

空数据 / 降级响应

显式传 [] 是合法请求:清空该团期全部人员配置并返回空 staffList,code 仍为 200。

错误响应

{
  "code": 400,
  "message": "staff 配置列表不能缺失;确要清空请显式传空数组 []",
  "data": null,
  "success": false
}

业务边界

  • 字段缺失或字段名写错一律 400,且现有配置零变动、不触发扇出——这正是本次要堵的洞。
  • 团期未创建返 589553、未成团返 589552;人员角色与资源域类型不符返 582114,整批拒绝不落库。
  • 「显式传 [] 即清空」这条既有语义没有改变。

2. 团期物资候选列表 GET /v3/admin/order/group-batch/:groupBatchId/supplies/candidates

VO: SuppliesCandidateRespVO

使用场景

团期物资清单的「从备品库选择」弹窗,支持按分类与关键字筛选。

入参

字段 位置 类型 必填 约束 说明
groupBatchId Path String 是 正整数 团期主订单 ID
categoryCode Query String 否 字典 supplies_category 分类筛选
keyword Query String 否 无长度限制 匹配名称或副标题;本次起 LIKE 通配符被转义

出参

字段 类型 说明
code / message / success Integer / String / Boolean 业务结果
data[].suppliesResourceId String 备品资源 ID
data[].suppliesName / subtitle / category String 备品名称、副标题、分类
data[].billingType / hasCost / basePrice String / Boolean / String 计费方式、是否收费、库价
data[].added / batchSuppliesId Boolean / String 是否已加入本团期清单及对应行 ID

请求示例

GET /v3/admin/order/group-batch/2097500233511362561/supplies/candidates?keyword=%E5%B8%BD

响应示例

{
  "code": 200,
  "message": "成功",
  "success": true,
  "data": [
    {
      "suppliesResourceId": "2023438566624866305",
      "suppliesName": "定制遮阳帽",
      "subtitle": "呼籁旅行专属防晒鸭舌帽",
      "category": "personal_gear",
      "billingType": "PER_PERSON",
      "hasCost": true,
      "basePrice": "15.00",
      "added": false,
      "batchSuppliesId": null
    }
  ]
}

空数据 / 降级响应

无命中返回 data: [],code 仍为 200。

错误响应

{
  "code": 589500,
  "message": "团期不存在",
  "data": null,
  "success": false
}

业务边界

  • keyword 里的 % / _ / \ / ! 一律按字面字符匹配,不再当通配符。
  • 普通关键字的搜索结果不受影响(实测「帽」仍命中「定制遮阳帽」)。
  • 只返上架备品,排序与分页口径未变。

3. 团期物资新增行 POST /v3/admin/order/group-batch/:groupBatchId/supplies

VO: AddSuppliesReqVO

使用场景

团期物资清单新增一行,可从备品库选择(传 suppliesResourceId)或纯手填(传 suppliesName)。

入参

字段 位置 类型 必填 约束 说明
groupBatchId Path String 是 正整数 团期主订单 ID
suppliesResourceId Body String 与 suppliesName 二选一 正整数 备品库资源 ID;传了则名称、分类、计费方式以库为准覆盖入参
suppliesName Body String 与 suppliesResourceId 二选一 最长 100 纯手填备品名
quantity Body Integer 是 大于 0 数量
unitPrice Body String 否 金额字符串 单价,入参优先;不传取库价

出参

字段 类型 说明
code / message / success Integer / String / Boolean 业务结果
data String 新建行主键 batchSuppliesId

请求示例

{
  "suppliesResourceId": "2023438566624866305",
  "quantity": 1
}

响应示例

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

空数据 / 降级响应

无空成功结果;任一校验失败返回 data: null、success: false。

错误响应

{
  "code": 589523,
  "message": "该备品已在本团期物资清单中,请直接调整数量",
  "data": null,
  "success": false
}

业务边界

  • 备品库不可用(资源域故障)与备品本身不可用(不存在 / 已下架)分开报:前者 589522,后者 589519。
  • 同一 suppliesResourceId 重复加入返 589523;纯手填行不参与判重。
  • 团期不在「物料准备中」返 589520,团期不存在返 589500。

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

  • 保存人员配置永远显式带上 staffList:要清空传 [],不要省略字段。省略在改前会静音清空整团配置,现在会 400。
  • 备品搜索框不需要前端做任何转义,直接把用户输入原样传 keyword 即可。
  • 加备品行时 unitPrice 不传即取库价;传了以入参为准(同团期可议价不同)。

五、数据库行为

  • 人员配置:全量覆盖式保存——软删旧行 + 插入新行,随后异步扇出到该班期全部活跃订单的 order_staff_assignment。校验失败时一行都不写。
  • 物资新增:向 order_batch_supplies 插一行;重复 supplies_resource_id 在插入前被拒。
  • 本次无表结构变更、无 Flyway 脚本。

六、边界行为

  • 人员配置越界角色值区分大小写,guide 不等于 GUIDE。
  • 备品候选列表只返上架备品;已下架的既有行不受影响,仍留在清单里。
  • 加备品行的库快照覆盖入参的字段是名称、分类、计费方式;单价例外,入参优先。

六.6、修改前后对比

场景 改前 改后
保存人员配置时不带 staffList(或字段名写错) 静音软删整团人员配置 + 触发全团扇出,返 200 返 400,现有配置零变动
保存人员配置时显式传 [] 清空 清空(不变)
备品候选搜 % 或 _ 返回全库 返回零结果
备品候选搜普通关键字 正常命中 正常命中(不变)
备品库超过 500 条时加第 501 条之后的备品 一律报「所选备品不存在或已下架」,实际是被 500 条上限截断 正常加入
资源域故障时加备品行 报「不存在或已下架」,与备品真下架无法区分 报 589522「备品库查询失败」,与 589519 分开

六.7、影响评估

  • 需要前端配合的只有一条:保存人员配置必须带 staffList。经排查管理后台现有调用是带该字段的,理论上不受影响;但字段名一旦写错,改前是静默清空、改后是 400,属"报错优于静默毁数据"。
  • 备品搜索语义变化只影响把 % / _ 当通配符用的用法,业务上没有这种用法。
  • 加备品行的改动对调用方完全透明,契约与错误码不变,只是不再有隐性上限。

七、不影响范围

  • 团期看板、详情、子订单、合同保险、财务、流团与退单等其余端点未改动。
  • 备品清单的查询、改数量、删除、确认物资四个端点契约不变。
  • 无表结构变更、无网关路由变更、无新增错误码(589519 / 589522 / 589523 / 582114 均为既有)。

八、测试环境已验证

真实网关(api.test.1814.love)逐条实测,dev-v3 分支已部署 hl-resource-service 与 hl-order-service-v3:

用例 结果
保存人员配置缺 staffList(模拟字段名写成 items) 400「staff 配置列表不能缺失;确要清空请显式传空数组 []」
保存人员配置显式传 [] 200,配置清空为 0 条
GUIDE 类型的人配成 PHOTOGRAPHER 582114,配置数仍为 0(零写入)
GUIDE 类型的人配成 GUIDE 200,回显 staffId / staffName / staffPhone / staffRole 全字段
配完后看导游位候选 assigned=true、assignedRole=GUIDE
配完后看摄影位候选 该人不在候选内(勾选态按配置位收敛)
备品候选 keyword=% / keyword=_ 均返 0 条(改前返回全库 15 条)
备品候选 keyword=帽 返 1 条「定制遮阳帽」
从备品库加行 200,库快照生效(billingType=PER_PERSON、hasCost=true、unitPrice=15.00)
同一备品再加一次 589523,清单无重复行
三个写端点传不存在的 ID 589500 / 589521 / 589553,一律零写入

单元测试:hl-order-service-v3 全量 9303 例、hl-resource-service 全量 2707 例,均 0 失败 0 错误。

九、相关历史 PR

  • PR #7028(本次合入,含 2026-09-03 审计的 F-01 / F-02 / F-04 三项中危修复)
  • 前序 #6950(团期人员配置候选列表)、#6986(团期物资备品库选择)

十、相关文档

  • 审计记录:dev-records/records/2026-09-03-local-group-tour-6950-6986-post-merge-audit.md
  • 实施单:docs/group/实施单/07-人员-导游摄影司机.html、docs/group/实施单/10-物资清单.html

关联 / 联系人

  • 工单:#7377(收口审计余项)、#7028(PR)
  • 后端:jw
  • 前端:mmg —— 只需确认保存人员配置时始终带 staffList 字段