Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
14 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 | 8753 | 团期管理员可为团期产品新增子订单:建单入参新增归属定制师 consultantId,非团期产品仍 581008 | admin | jw(GIT) | 修改接口 | deployed | verified | implemented | mmg | cf5af6d6ba2dfb79266edd4b7be53e157ac835f6 | v2.1 | 2026-10-04 | 已合并 dev-v3(ea502ba02)并部署 TEST(order-v3 @ ea502ba02),自签 token 经网关实测:团期管理员为团期产品建单带合法 consultantId → 200、定制师落所选账号;不传 581066、非定制师 / 未绑企微 / 不存在 581067、名单不可用 581068(nacos 注入 1ms 超时实测)、非团期产品 581008,均零落库;ADMIN / CUSTOMIZER 传了 consultantId 也被忽略。前端待做:团期看板 PeriodRow 对团期管理员放开「新增子订单」、建单向导加归属定制师下拉(GET /admin/user/designers)。注意:建单向导的报价接口 POST /admin/product/item/:id/quote 在 TEST 上对非超管均 403(product-v2 存量问题,见 #8753 评论),不解决则团期管理员仍提交不了。前端已交付(2026-10-04):PeriodRow「新增子订单」对团期管理员放开,建单向导 Step2 加「归属定制师」必选下拉(/user/designers 数据源,企微名展示,adminId 雪花字符串透传),step2Errors 前置 581066 校验,报文仅团期管理员带 consultantId;报价 403 为 product-v2 存量问题,留后端另行处理。提交 cf5af6d6b。 | 2026-10-03 | dev-v3 |
order-v3: 团期管理员可为团期产品新增子订单(建单入参新增归属定制师)
服务: hl-order-service-v3
PR: #8769(已合入 dev-v3,合并提交 ea502ba02)
Issue: #8753
⚠️ 关键变化
🟢 POST /v3/admin/order 入参纯新增 consultantId(归属定制师 adminId),出参不变。只有团期管理员会读它,其他角色传了也忽略。
🔴 团期管理员(GROUP_BATCH_MANAGER)从「建单一律 581008」改为「可为团期产品建单,必须选归属定制师」:订单的定制师是所选账号,不是团期管理员本人;建完之后这一单的其余写操作对团期管理员仍是 581008(#8154 不变)。
🟢 三个新错误码:581066 未选归属定制师、581067 所选账号不在定制师名单、581068 定制师名单暂不可用(稍后重试)。
一、背景
原型里团期看板每期都有「新增子订单」,是团期管理员视角。#8154 把订单写端点整体对团期管理员关掉,建单也在其中,前端随之对他隐藏了按钮。jw 10-03 定:团期管理员可以新增子订单,归属定制师选持定制师角色的人。只放开建单还不够——后台建单的定制师默认取当前登录人,团期管理员建出来的单会挂在他自己名下,而他按 #8154 又改不了,所以本次同时要求团期管理员指定归属定制师。
二、变更接口清单
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|---|---|---|---|---|---|
| 1 | 创建订单 | POST | /v3/admin/order |
修改 | 入参新增 consultantId;团期管理员可为团期产品建单;新增错误码 581066 / 581067 / 581068 |
三、接口详情
1. 创建订单 POST /v3/admin/order
VO: OrderCreateReqVO → Result<OrderCreateRespVO>
使用场景
团期看板某一期点「新增子订单」进入建单向导(深链带 productId / productBatchId / departureDate)。团期管理员在向导里多选一项「归属定制师」,提交后订单挂在该定制师名下,由他跟进补资料、收款;团期管理员只看不改。定制师、管理员等其他角色的建单流程不变。
入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| consultantId | Body | Long | 团期管理员必填,其他角色不读 | 须为持定制师角色、在职且已绑企微的后台账号 | 🆕 归属定制师 adminId;下拉数据源 GET /admin/user/designers(返回的 id 即 adminId) |
| productId | Body | Long | ✅ | 团期管理员只能选团期产品(GROUP) | 不变;团期管理员选非团期产品返回 581008 |
| productBatchId | Body | Long | GROUP 产品必填 | 团期管理员必须带 | 不变;团期管理员不带返回 581008 |
| tierSeq / departureDate / adultCount / childCount / youngChildCount / babyCount / customerName / customerPhone / customerRemark / createSource / roomCount / tags / sharerOpenid / customizerId | Body | — | — | — | 不变 |
出参字段表
| 字段 | 类型 | 说明 |
|---|---|---|
| consultantId | String | 取值口径变化:团期管理员建单时为所选归属定制师,其余角色仍为当前登录人 |
| consultantSource | String | 团期管理员建单时为 MANUAL(与后台代下单相同) |
| 其余字段 | — | 不变 |
请求示例
{
"productId": "2044306857534636034",
"tierSeq": 1,
"departureDate": "2026-11-05",
"adultCount": 2,
"customerName": "王建国",
"customerPhone": "13947012345",
"productBatchId": "2106318108807593985",
"roomCount": 1,
"consultantId": "1002"
}
响应示例
团期管理员账号经网关建单,TEST 实际返回(省略了未变字段):
{
"code": 200,
"message": "成功",
"data": {
"id": "2106348497395765250",
"orderNo": "HL20261003193950403",
"orderStatus": "PENDING_PAY",
"consultantId": "1002",
"consultantSource": "MANUAL",
"productName": "冻干粉发短信给",
"departureDate": "2026-11-05",
"returnDate": "2026-11-07",
"totalAmount": "3360.00",
"groupBatchId": "2106348497525788673",
"productBatchId": "2106318108807593985",
"groupOrder": true
},
"success": true
}
空数据 / 降级响应
user-service 的定制师名单拿不到(超时、熔断降级返回空列表、非 200)时,团期管理员建单一律拒绝并返回 581068,不会放行,也不会误报成 581067;其他角色不查名单,不受影响。
错误响应
团期管理员建单的拒绝顺序:范围(581008)→ 未选定制师(581066)→ 名单不可用(581068)→ 不在名单(581067)。
| code | message | 何时出现 |
|---|---|---|
| 581008 | 无权查看此订单 | 团期管理员选了非团期产品,或团期产品没带 productBatchId |
| 581066 | 请选择归属定制师 | 团期管理员没传 consultantId |
| 581067 | 所选归属定制师无效,请重新选择持定制师角色的在职账号 | 账号不存在、非定制师、不在职或未绑企微 |
| 581068 | 定制师名单暂不可用,请稍后重试 | user-service 名单接口不可用 |
{
"code": 581066,
"message": "请选择归属定制师",
"data": null,
"success": false
}
{
"code": 581067,
"message": "所选归属定制师无效,请重新选择持定制师角色的在职账号",
"data": null,
"success": false
}
业务边界
- 只有团期管理员读
consultantId;定制师、管理员等传了也忽略,定制师仍是当前登录人。 - 名单口径 = 持定制师角色 + 在职 + 已绑企微,与
GET /admin/user/designers是同一集合;未绑企微的定制师选不了。 consultantName取所选账号的企微姓名,没有则取用户名(与该定制师登录后自己建单时一致)。- 建单后的改单、改出行人、取消、终止等写操作对团期管理员仍是 581008,改派定制师不在本次范围。
四、契约约束与正确调用方式
- 团期管理员建单必须带
productBatchId与consultantId;前端判断当前角色是团期管理员时,向导里显示「归属定制师」下拉并设为必填。 - 下拉调
GET /admin/user/designers,用返回的id(字符串形式的 adminId)作为consultantId,name作为展示名。不要用GET /admin/user/customizers:那个接口含禁用、锁定和未绑企微的账号,选了会被 581067 拒。 - 581068 是暂时性错误,提示「稍后重试」即可;581067 要让用户换人。
- 建单成功后跳转订单详情:团期管理员只读,详情可看,编辑按钮按 #8154 的 581008 处理。
五、数据库行为
- 零 DDL、零数据迁移。
- 团期管理员建单写入路径与其他角色相同(
order_main等),区别只在consultant_id/consultant_name取所选定制师、consultant_source=MANUAL。 - 建单准备阶段(事务外)多一次 user-service 内部调用
GET /internal/user/admin/by-role-key?roleKey=CUSTOMIZER,只在团期管理员建单时发生。 - 所有拒绝都发生在落库前,零写入。
六、边界行为
- 团期管理员 + 团期产品 + 带班期 + 合法
consultantId→ 建单成功,团期报名户数、人数照常自增,订单groupBatchId非空。 - 团期管理员给非团期产品硬带
productBatchId→ 581008(不是普通角色看到的 581056)。 - 零角色账号(网关未透传角色)不算团期管理员,走普通建单分支,与改前一致。
六.6、修改前后对比
| 场景 | 改前 | 改后 |
|---|---|---|
| 团期管理员为团期产品建单 | 581008 | 带合法 consultantId → 200,定制师 = 所选账号 |
团期管理员不传 consultantId |
581008 | 581066 |
| 团期管理员建非团期产品单 | 581008 | 581008(不变) |
| 团期管理员改这一单 | — | 581008(#8154 不变) |
| 定制师 / 管理员建单 | 定制师 = 当前登录人 | 不变,传了 consultantId 也忽略 |
六.7、影响评估
- 是否破坏向后兼容:否。入参纯新增可选字段,出参不变;只有团期管理员的行为变化(从一律 581008 变为可建团期子订单)。
- 前端是否必须同步上线:否。前端不改时团期管理员看不到按钮,行为与改前一致。要让团期管理员用起来需前端放开按钮、加定制师下拉,并且建单向导的报价接口要能通(见第八节 8.4)。
- 性能:只有团期管理员建单多一次 user-service 内部调用。
- 回滚:revert PR #8769 后重新部署 order-v3,无 DDL、无配置。
七、不影响范围
- 订单详情、列表等读接口:不变。
- 其余订单写接口对团期管理员的 581008:不变(#8154)。
- 小程序端下单(
/v3/mp/...):不经此入口,不变。 GET /admin/user/designers、GET /internal/user/admin/by-role-key:接口本身不变。
八、测试环境已验证
环境:TEST(https://api.test.1814.love) 验证时间:2026-10-03 19:31~19:50
构建身份:order-v3 部署 dev-v3 @ ea502ba02(本单合并提交),两实例滚动完成。探针:团期管理员不传 consultantId 建单,部署前 581008,部署后 8/8 为 581066。
身份:自签 token 直打网关;团期管理员 gbm8154test(单角色),归属定制师测试号 test_admin(1002)。
8.1 正向与归属
| 项 | 结果 |
|---|---|
团期管理员建团期子订单(consultantId=1002) |
200;order_main.consultant_id=1002、consultant_name=test_admin、consultant_source=MANUAL、group_batch_id 非空 |
| 所选定制师 1002 | 订单列表(orderKind=GROUP)能查到这一户,详情 200,改客户备注 200 并落库;另一位定制师查不到 |
| 团期管理员 | 读详情 200;改备注、改出行人均 581008,库内未被改动 |
| 入团 | 建单前 0 户 0 人 → 团期管理员再建一户后 4 户 9 人,产品侧报名人数同步 |
8.2 反向与范围
| 操作 | 结果 |
|---|---|
不传 consultantId |
581066,零落库 |
| 传团期管理员本人 / 持定制师角色但未绑企微 / 不存在的 id | 均 581067,零落库 |
| 非团期产品(不带班期、硬带班期)/ 团期产品不带班期 | 均 581008,零落库 |
ADMIN、CUSTOMIZER 传 consultantId |
200,定制师仍为本人 |
8.3 降级
nacos 只给 order-v3 的 userFeignClient 注入 1ms 超时并重启后,团期管理员带合法 consultantId 建单 7 次均 581068,零落库;验完配置原样还原(SHA-256 逐字节一致)并再次重启。
8.4 建单向导依赖的读接口(团期管理员)
| 接口 | 结果 |
|---|---|
GET /admin/product/line/order-picker、GET /admin/product/item/order-picker、GET /admin/product/item/:id、GET /admin/product/item/:id/pricing-calendar、GET /v3/admin/tag-library |
均 200 |
GET /admin/user/designers |
200,20 人,与「定制师 + 在职 + 已绑企微」的 SQL 名单逐个相同 |
POST /admin/product/item/:id/quote |
🔴 403「无操作权限」——product-v2 存量问题,CUSTOMIZER / ADMIN 同样 403,只有 SUPER_ADMIN 能过;前端提交前必须报价成功,不解决则团期管理员仍提交不了。已在 #8753 列明,待另行处理 |
本地证据
| 项 | 读数 |
|---|---|
| 定向 13 组 | order-v3 607 例 0 失败(新增 Service 10 例、Controller 2 例、ArchTest 2 条规则) |
| 变异 | 删掉 Controller 的身份透传、删掉 Service 的策略调用 → 两条新规则同时变红;已还原 |
| order-v3 全量(有 Docker,两半) | A 10956 / 2 失败,B 4935 / 2 失败 / 7 跳过;1140 个可执行测试类全部有报告;3 条在基底逐条复现,1 条为并发负载下的锁等待抖动(单跑 2×14/14),本单零新增 |
十、相关文档
- Issue
#8753;PR#8769 - 前置:#8154(团期管理员只读守卫)、#8440(同样定点放开 #8154 的先例:退单提交)、#7143(看板「新增子订单」深链)
关联 / 联系人
链接
联系人
- 后端负责人: @jw