文件
hl-api-changelog/changelogs-v2/2026-09/26_8375_房务配房列表合并抢单池户级与团期两张列表-新增接口-管理后台.md
T
Mimingguang e488c685d5
changelog-filename-gate / validate (push) Failing after 2s
chore(changelog): #8375 前端回写 verified(mmg,beb6e18b,v2.1)
2026-09-27 09:28:23 +08:00

31 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 8375 房务配房列表改版:并入订单列表,新增两个读端点(户级/团期),旧池端点标废弃,菜单与通知链接改向 admin wx(GIT) 新增接口 deployed verified verified mmg beb6e18b55866f9914811362638b7d3713044d70 v2.1 2026-09-27 订单列表新增两个读端点替代房务抢单池;五个旧读端点标 @Deprecated;三个错误码文案改动(去「抢单池」);菜单 101/102 下线;团期通知链接改为订单列表。后端三个 PR(product-v2/#8381、order-v3/#8382、user-service/#8379)已合入 dev-v3 并部署测试服,逐条实测验证通过。前端 2026-09-27 已交付并回写 verified:订单列表重写为表格模式(产品页签全部/核心/定制/团期+状态页签户级七桶/团期三桶+scope 全部/我的+「开始配房」canStartAllocation 唯一依据+?groupBatchId= 团期定位),旧抢单池两页与五个旧读端点调用已删除,写口(claim/transfer/release/takeover)不变仅改入口;house-allocation-orders spec 8 例+房务域 161 例全绿(mmg,beb6e18b,v2.1)。 2026-09-26 dev-v3

房务订单列表改版:新读端点替代抢单池、旧端点标废弃、菜单下线、通知改向(管理后台)

服务: hl-order-service-v3(端口 8086/8186)/ hl-user-service(端口 8089/8189) PR: #8381(product-v2)/ #8382(order-v3)/ #8379(user-service) Issue: #8375 日期: 2026-09-26 影响范围: 房务管家 › 订单列表的页签切换、筛选项恢复、「开始配房」入口改向、所有房务角色的可见范围放开、旧页面与菜单下线


⚠️ 关键变化

  1. 新增两个读端点,替代房务抢单池两个旧页面:

    • GET /v3/admin/order/house-allocation/households:户级(核心/定制订单)
    • GET /v3/admin/order/house-allocation/group-batches:团期订单
  2. 五个旧读端点标 @Deprecated,行为不变,但前端改调新端点:

    • GET /v3/admin/order/grab-pool/hotel-requirements
    • GET /v3/admin/order/grab-pool/group-batches
    • GET /v3/admin/order/grab-pool/my-claims/hotel
    • GET /v3/admin/order/grab-pool/my-claims/group-batches
    • GET /v3/admin/order/grab-pool/all-claims/hotel
  3. 权限视图放开:两个新端点都挂读门 HouseReadPermission,不限 scope=all;普通房务也能看全员认领情况(旧的 all-claims/hotel 仍返回 808092)。

  4. 认领写口不变:保持现有逻辑,只是入口从池页改到列表行:

    • 户级:POST /v3/admin/order/hotel-requirements/{requirementId}/claim
    • 团期:POST /v3/admin/order/grab-pool/group-batches/{groupBatchId}/claim
  5. 三个错误码文案改动,去掉"抢单池"页面名:

    • 808650:改为「团期订单须整团认领后配房,不支持逐户认领 / 转单」
    • 808612:改为「该团期尚未被房务整团认领」
    • 808001:改为「该需求已被其他房务认领或状态已变化,请刷新后重试」
  6. 菜单下线:房务抢单池菜单(菜单 101 与 102)已在 user-service 侧置为 INACTIVE,部署后生效。

  7. 团期通知链接改向:站内链接由 /housekeeper/grab-pool-group?groupBatchId= 改为 /housekeeper/orders?groupBatchId=(订单列表团期页签)。


一、背景

房务原来要在"订单列表"和"房务抢单池"两个页面之间来回切,体验割裂。本次改版将待配房的单并入订单列表,整合三类订单视图:

  • 待配房:所有房务都能点「开始配房」认领
  • 配房中:谁在做,全员可见
  • 已认领:可按「我的」或「全部」筛选

新端点按以下规则返回行:

  • 户级行(order_main 表,group_batch_id 与 product_batch_id 都为空)
    • 待配房:status=PENDING 且 claimer_id IS NULL
    • 已认领:status=PENDING 且 claimer_id IS NOT NULL
  • 团期行(order_group_batch 表,整团一行)
    • 待配房:house_claimer_id IS NULL 且 requirement_confirmed=1 且 batch_status=RESOURCE_PREPARING
    • 已认领:house_claimer_id IS NOT NULL(任意阶段)

二、变更接口清单

# 接口 方法 路径 变更类型 说明
1 房务配房列表·户级 GET /v3/admin/order/house-allocation/households 新增接口 户级页签(核心/定制订单),分页返回
2 房务配房列表·团期 GET /v3/admin/order/house-allocation/group-batches 新增接口 团期页签,整团一行

旧端点标废弃(行为不变):GET /v3/admin/order/grab-pool/hotel-requirements、/grab-pool/group-batches、/grab-pool/my-claims/hotel、/grab-pool/my-claims/group-batches、/grab-pool/all-claims/hotel 加 @Deprecated,详见第五章节。

网关无改动(均在既有 /v3/admin/order/ 前缀下);新路径已验证可达。


三、接口详情

1. 房务配房列表·户级 GET /v3/admin/order/house-allocation/households

VO: HouseAllocationHouseholdPageReqVO → HouseAllocationHouseholdPageRespVO

使用场景

房务管家 › 订单列表的核心和定制页签,以及全部页签的户级数据部分。返回户级订单(order_main),按待配房/已认领分行展示,支持 scope 筛选当前用户或全员,按多种条件排序和分页。

入参字段表

字段 位置 类型 必填 约束 说明
scope Query String 否 all | mine,小写 默认 all;mine 则只返回当前用户认领的行,pendingClaim 桶恒为 0
status Query String 否 pendingClaim | unfinished | claiming | pendingConfirm | confirmed | exception,或空 默认 unfinished;空串表示全部;返回对应 house_status 的行
productType Query String 否 CORE | CUSTOM,或空 空或不传表示全部户级行;不接受 productType=GROUP(团期订单走团期端点)
keyword Query String 否 @Size(max=32) 模糊匹配:订单号 / 团号 / 客人姓名 / 产品名(OR)
productName Query String 否 — 模糊匹配产品名
consultantId Query Long 否 — 定制师 ID,精确匹配
guestName Query String 否 — 客人姓名,模糊匹配
departDateFrom Query LocalDate 否 yyyy-MM-dd 出发日期起
departDateTo Query LocalDate 否 yyyy-MM-dd 出发日期止(含)
claimedAtFrom Query LocalDateTime 否 yyyy-MM-dd'T'HH:mm:ss 认领时间起;传了就等于只看已认领的行
claimedAtTo Query LocalDateTime 否 yyyy-MM-dd'T'HH:mm:ss 认领时间止
page Query Integer 否 @Min(1) 默认 1
pageSize Query Integer 否 @Min(1) @Max(100) 默认 20
sortBy Query String 否 departDate,asc | createTime,desc | claimedAt,desc 默认 departDate,asc;无论选哪个,都先按手动加急(manual_urgent DESC, manual_urgent_at DESC)排

出参字段表

字段 类型 说明
list List<HouseAllocationHouseholdRespVO> 分页结果行
total Long 满足条件的总行数
stats HouseAllocationHouseholdStatsVO 各页签的计数(与列表共用筛选条件,忽略 status)

行字段详情(HouseAllocationHouseholdRespVO):

字段 类型 说明
id String requirementId,前端「开始配房」时用此值
orderId String 订单 ID,进户级详情时用
orderNo / teamNo String 订单号 / 团号
guestName String 客人姓名
personsDesc String 人数描述(如「2成人1儿童」)
productType String 产品类型(CORE/CUSTOM/ROUTE/…)
productName String 产品名称
productNo String 产品编号;来自 product-v2 批量查询,取不到时为 null(见降级响应)
route String 行程描述
cities List<String> 城市列表
departDate LocalDate 出发日期
nights Integer 晚数
totalAmount String 订单金额(后端计算,已序列化为字符串)
consultantId String 定制师 ID
consultantName String 定制师姓名
consultantRemark String 定制师备注
requirementNote String 需求备注
dispatchRemark String 派车备注
special String 特殊需求
requirementVersion Integer 需求版本号
requirementStatus String 对外状态(PENDING/PROCESSING/DONE/…)
houseStatus String 枚举码:PENDING_CLAIM / CLAIMING / PENDING_FINALIZE / CONFIRMED / EXCEPTION;与旧 VO 的中文名不同
houseStatusLabel String 中文显示名(「待配房」/「配房中」/「待确认」/「已确认」/「异常」)
claimerId String 当前认领人 ID;待配房行为 null
claimerName String 当前认领人名字;待配房行为 null
claimedAt LocalDateTime 认领时间;待配房行为 null
isMine Boolean 认领人是否当前用户
canStartAllocation Boolean 前端「开始配房」按钮的唯一依据(true 时显示,false 时隐藏);条件:status=PENDING 且 claimerId IS NULL 且当前用户有写权限
manualUrgent Boolean 手动加急标记
manualUrgentAt LocalDateTime 加急时间
urgencyLevel String 紧急度标签(LOW/MEDIUM/HIGH)
urgencyLabel String 紧急度中文名(「低」/「中」/「高」)
daysToDepart Integer 距出发还有几天(负数表示已出发)
isRework Boolean 是否返工
reworkPrevClaimerName String 上次认领人名字
exceptionCount Integer 已认领行:该户有几个未处理异常待办;待配房行为 0
todoCount Integer 已认领行:该户有几个待办;待配房行为 0
primaryAction HousePrimaryActionVO 只在 isMine=true 时返回;包含转单、释放等操作信息
createTime LocalDateTime 需求创建时间

stats 分桶计数(HouseAllocationHouseholdStatsVO):

字段 类型 说明
pendingClaim Long 待配房行数;scope=mine 时恒为 0
claiming Long house_status=CLAIMING 的行数
pendingConfirm Long house_status=PENDING_FINALIZE 的行数
confirmed Long house_status=CONFIRMED 的行数
exception Long house_status=EXCEPTION 或订单有未处理异常待办的行数
unfinished Long 待配房 + 配房中 + 待确认 + 异常 的行数;与 status=unfinished 的查询结果同源
all Long 待配房 + 已认领 的总行数;与不传 status 的查询结果同源

请求示例

GET /v3/admin/order/house-allocation/households?scope=all&status=pendingClaim&productType=CORE&page=1&pageSize=20&sortBy=departDate,asc HTTP/1.1
Host: api.test.1814.love:9443
Authorization: Bearer ***

无请求体。

响应示例

{
  "code": 200,
  "message": "成功",
  "success": true,
  "data": {
    "list": [
      {
        "id": "2097250563497385985",
        "orderId": "770145",
        "orderNo": "O20260926001",
        "teamNo": null,
        "guestName": "张三",
        "personsDesc": "2成人1儿童",
        "productType": "CORE",
        "productName": "日本东京 6 日游",
        "productNo": "P002301",
        "route": "东京→富士山→京都",
        "cities": ["东京", "富士山", "京都"],
        "departDate": "2026-10-01",
        "nights": 6,
        "totalAmount": "8500.00",
        "consultantId": "1001",
        "consultantName": "李四",
        "consultantRemark": "客户有特殊需求",
        "requirementNote": "希望升级酒店",
        "dispatchRemark": "已预留",
        "special": "客户晕车,安排靠窗座位",
        "requirementVersion": 1,
        "requirementStatus": "PROCESSING",
        "houseStatus": "PENDING_CLAIM",
        "houseStatusLabel": "待配房",
        "claimerId": null,
        "claimerName": null,
        "claimedAt": null,
        "isMine": false,
        "canStartAllocation": true,
        "manualUrgent": true,
        "manualUrgentAt": "2026-09-25T14:30:00",
        "urgencyLevel": "HIGH",
        "urgencyLabel": "高",
        "daysToDepart": 5,
        "isRework": false,
        "reworkPrevClaimerName": null,
        "exceptionCount": 0,
        "todoCount": 0,
        "primaryAction": null,
        "createTime": "2026-09-20T09:00:00"
      }
    ],
    "total": 12,
    "stats": {
      "pendingClaim": 12,
      "claiming": 5,
      "pendingConfirm": 3,
      "confirmed": 8,
      "exception": 1,
      "unfinished": 21,
      "all": 28
    }
  }
}

空数据 / 降级响应

  • 分页无结果时,list=[],total=0,stats 各字段为 0,code=200 不报错:
{
  "code": 200,
  "message": "成功",
  "success": true,
  "data": {
    "list": [],
    "total": 0,
    "stats": { "pendingClaim": 0, "claiming": 0, "pendingConfirm": 0, "confirmed": 0, "exception": 0, "unfinished": 0, "all": 0 }
  }
}
  • productNo 取不到时(product-v2 服务降级或响应缺字段),该字段为 null,其余字段正常返回,不报错。

  • 参数不合法时(status、productType、sortBy 等与规则不符),HTTP 200,code=400(全局 BindException 处理),message 是具体字段的校验文案。下面是传 productType=GROUP 的实测原文:

{"code":400,"message":"productType 只能是 CORE 或 CUSTOM","data":null,"traceId":null,"success":false}

错误响应

  • 未登录或无房务读权限(808090):
{
  "code": 808090,
  "message": "未登录或无该操作权限",
  "success": false,
  "data": null
}

业务边界

  • 查询条件 claimedAtFrom/claimedAtTo 同时传递时,等于隐含过滤 claimerId IS NOT NULL(只看已认领的行);与 status=pendingClaim 同传时查询结果为空、code=200、stats.pendingClaim=0,不报错。
  • 手动加急 manual_urgent=true 的行在任何 status 页签里都会被提前排列(加急 DESC,加急时间 DESC),无论选何种 sortBy。
  • 并发认领:前端的「开始配房」按钮直接调 POST /v3/admin/order/hotel-requirements/{id}/claim,若二人同时点同一行,先到者返回 200,后到者返回 808001 并附加新文案「该需求已被其他房务认领或状态已变化,请刷新后重试」,前端刷新列表即可看到当前认领人。
  • 异常数据(存量):列表里个别行的 orderNo 或 productName 可能为 null(对应主订单已软删除),前端需容忍空值、不做特殊提示,只显示已有字段。
  • 转单、释放等操作只在 isMine=true 的行显示(primaryAction 非 null);他人认领的行为只读。
  • requirementStatus 是订单对外状态,houseStatus 是该户配房阶段(两个维度独立)。

2. 房务配房列表·团期 GET /v3/admin/order/house-allocation/group-batches

VO: HouseAllocationGroupPageReqVO → HouseAllocationGroupPageRespVO

使用场景

订单列表的团期页签,整团一行。返回团期订单(order_group_batch),按待配房/已认领分行展示。前端的通知链接 ?groupBatchId=<团ID> 也以此端点定位落地。

入参字段表

字段 位置 类型 必填 约束 说明
scope Query String 否 all | mine 默认 all;mine 时只返回当前用户认领的团
status Query String 否 pendingClaim | claimed,或空 空或不传表示两者都要
groupBatchId Query Long 否 — 精确定位一个团(通知链接用);传了则 1 条或 0 条结果
keyword Query String 否 @Size(max=32) 模糊匹配:团期号 / 产品名(OR)
productId Query Long 否 — 产品 ID,精确匹配
batchStatus Query String 否 RECRUITING | RESOURCE_PREPARING | MATERIAL_PREPARING | PENDING_DEPARTURE | TRAVELLING | TRIP_FINISHED | REVIEWING | SETTLED | CANCELLED 团期阶段,精确匹配
departDateFrom Query LocalDate 否 yyyy-MM-dd 出发日期起
departDateTo Query LocalDate 否 yyyy-MM-dd 出发日期止
claimedAtFrom Query LocalDateTime 否 yyyy-MM-dd'T'HH:mm:ss 认领时间起
claimedAtTo Query LocalDateTime 否 yyyy-MM-dd'T'HH:mm:ss 认领时间止
page Query Integer 否 @Min(1) 默认 1
pageSize Query Integer 否 @Min(1) @Max(100) 默认 20
sortBy Query String 否 departDate,asc | claimedAt,desc | createTime,desc 默认 departDate,asc

出参字段表

字段 类型 说明
list List<HouseAllocationGroupRespVO> 分页结果行
total Long 满足条件的总行数
stats HouseAllocationGroupStatsVO 三个页签的计数:pendingClaim / claimed / all

行字段详情(HouseAllocationGroupRespVO):

字段 类型 说明
groupBatchId String 团期 ID,前端「开始配房」时用此值
batchNo String 团期号
batchName String 团期名称
batchLabel String 团期标签
productId String 产品 ID
productName String 产品名称
batchStatus String 团期阶段码(RECRUITING/RESOURCE_PREPARING/…)
batchStatusLabel String 中文显示名(「招募中」/「资源准备中」/…)
departDate LocalDate 出发日期
endDate LocalDate 结束日期
enrollDeadline LocalDate 报名截止日期
enrolledRooms Integer 已报名房间数
enrolledPeople Integer 已报名人数
activeOrderCount Integer 活跃订单数
hotelOrderCount Integer 需要配房的订单数
hotelReady Integer 已配房的订单数
daysToDepart Integer 距出发还有几天
urgencyLevel String 紧急度标签(LOW/MEDIUM/HIGH)
urgencyLabel String 紧急度中文名
requirementConfirmed Boolean 团期需求是否已整体确认(仅信息展示,不影响认领)
houseClaimerId String 团级认领人 ID;待配房时为 null
houseClaimerName String 团级认领人名字;待配房时为 null
houseClaimedAt LocalDateTime 认领时间;待配房时为 null
isMine Boolean 认领人是否当前用户
canStartAllocation Boolean 前端「开始配房」按钮的唯一依据;条件:houseClaimerId IS NULL 且当前用户有写权限
createTime LocalDateTime 创建时间

stats 分桶计数(HouseAllocationGroupStatsVO):

字段 类型 说明
pendingClaim Long 待配房团数(houseClaimerId IS NULL 且 requirementConfirmed=1 且 batchStatus=RESOURCE_PREPARING)
claimed Long 已认领团数(houseClaimerId IS NOT NULL,任意阶段)
all Long pendingClaim + claimed 的总数

请求示例

GET /v3/admin/order/house-allocation/group-batches?scope=all&status=pendingClaim&page=1&pageSize=20 HTTP/1.1
Host: api.test.1814.love:9443
Authorization: Bearer ***

无请求体。

响应示例

{
  "code": 200,
  "message": "成功",
  "success": true,
  "data": {
    "list": [
      {
        "groupBatchId": "2097250563497385985",
        "batchNo": "G20260926001",
        "batchName": "日本 10 月团·东京-京都-大阪",
        "batchLabel": "标准",
        "productId": "5001",
        "productName": "日本东京-京都-大阪 8 日游",
        "batchStatus": "RESOURCE_PREPARING",
        "batchStatusLabel": "资源准备中",
        "departDate": "2026-10-05",
        "endDate": "2026-10-12",
        "enrollDeadline": "2026-09-28",
        "enrolledRooms": 8,
        "enrolledPeople": 16,
        "activeOrderCount": 8,
        "hotelOrderCount": 8,
        "hotelReady": 0,
        "daysToDepart": 9,
        "urgencyLevel": "HIGH",
        "urgencyLabel": "高",
        "requirementConfirmed": false,
        "houseClaimerId": null,
        "houseClaimerName": null,
        "houseClaimedAt": null,
        "isMine": false,
        "canStartAllocation": true,
        "createTime": "2026-09-15T10:00:00"
      }
    ],
    "total": 5,
    "stats": {
      "pendingClaim": 5,
      "claimed": 12,
      "all": 17
    }
  }
}

空数据 / 降级响应

  • 分页无结果:list=[],total=0,stats 各字段为 0,code=200:
{
  "code": 200,
  "message": "成功",
  "success": true,
  "data": {
    "list": [],
    "total": 0,
    "stats": { "pendingClaim": 0, "claimed": 0, "all": 0 }
  }
}
  • 参数不合法时,HTTP 200,code=400,message 是具体字段的校验文案(结构同户级端点):
{"code":400,"message":"<该字段的校验文案>","data":null,"traceId":null,"success":false}

错误响应

  • 未登录或无房务读权限(808090):
{
  "code": 808090,
  "message": "未登录或无该操作权限",
  "success": false,
  "data": null
}

业务边界

  • 整团一行:团期阶段任意时刻只要被认领一次,就会在列表持续出现(claimed 页签或混合页签),不会因为进入后续阶段(待出发、出行中等)而消失。
  • 并发认领:前端的「开始配房」按钮直接调 POST /v3/admin/order/grab-pool/group-batches/{groupBatchId}/claim。并发场景下:
    • 团期 claim 端点挂了 @Idempotent(5 秒窗口)与 @Lock4j 两重防护
    • 同时提交会被幂等或锁层拦下,返回 100502(「整团认领处理中,请勿重复提交」,幂等窗口内),前端提示并刷新列表
    • 窗口过后别人已抢到会返回 808652(「该团期已被其他房务认领」)
  • 他人认领的团不提供看板入口:前端对 isMine=false 的行不显示「查看看板」入口(若用户直接访问详情页,会得到 808612 或 808613 拒绝);详情页权限不变。
  • 订单列表的通知参数 ?groupBatchId=<团ID> 须在团期页签按此参数定位(可配合 filter 或直接查询定位)。

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

场景 调用方法 说明
✅ 户级「开始配房」 POST /v3/admin/order/hotel-requirements/{id}/claim 直接调现有写口,行为不变;canStartAllocation=true 时显示按钮
✅ 团期「开始配房」 POST /v3/admin/order/grab-pool/group-batches/{groupBatchId}/claim 同上;路径保留 grab-pool,因为是现有写口
✅ 查看全员认领情况 GET /v3/admin/order/house-allocation/households?scope=all 或 /group-batches?scope=all 普通房务首次可见;旧端点 all-claims/ 仍返回 808092
✅ 刷新列表信号 监听 SSE 事件 grab-pool-changed 现有 SSE 通道保留,不新增事件
❌ 调旧端点继续写代码 GET /v3/admin/order/grab-pool/hotel-requirements @Deprecated,禁用
❌ 团期已被他人认领后再点「开始配房」 — 返回 808652「该团期已被其他房务认领」,刷新列表即可看到认领人,不要重试

配套变更说明

错误码文案更新

随 PR-1 部署,三个错误码文案改动(去掉对「抢单池」页面的引用):

码 旧文案 新文案 触发场景
808650 "团期订单须整团认领,不支持逐户认领。请到团期抢单池整团认领" "团期订单须整团认领后配房,不支持逐户认领 / 转单" 试图逐户认领 / 转单一个团期订单
808612 "该团期尚未被房务认领,请先到团期抢单池认领" "该团期尚未被房务整团认领" 进入他人未认领的团期看板,或操作不满足条件的团期
808001 "需求已被其他房务抢到" "该需求已被其他房务认领或状态已变化,请刷新后重试" 户级并发认领冲突,或状态变化后重复调用

房务抢单池菜单下线

随 PR-2 部署(Flyway V20260926_001):

  • 菜单 101(「抢单池·普通」,路径 /housekeeper/grab-pool)置为 INACTIVE
  • 菜单 102(「抢单池·团期」,路径 /housekeeper/grab-pool-group)置为 INACTIVE

菜单对所有角色同步生效(按 ACTIVE 状态过滤)。缓存于 user-service 启动完成时自动刷新;若启动日志出现"应用启动后刷新菜单缓存失败",需手工 Redis DEL 对应 key(1 小时 TTL 后自动过期)。

团期通知链接改向

随 PR-2 部署(SQL Flyway 更新通知配置),三条团期站内链接由抢单池改指订单列表:

通知事件 原链接 新链接 内容变化
GROUP_BATCH_HOUSE_CLAIMED /housekeeper/grab-pool-group?groupBatchId= /housekeeper/orders?groupBatchId= 链接改向;内容不再含「抢单池」词语
GROUP_BATCH_HOUSE_RELEASED /housekeeper/grab-pool-group?groupBatchId= /housekeeper/orders?groupBatchId= 同上
GROUP_BATCH_REQUIREMENT_CONFIRMED /housekeeper/grab-pool-group?groupBatchId= /housekeeper/orders?groupBatchId= 同上

旧读端点标废弃

五个旧端点的 Controller 方法加 @Deprecated 注解;Swagger 操作描述末尾补充「(已废弃,改用 /v3/admin/order/house-allocation/…)」。行为与字段完全不变,现有消费方在迁移完毕前仍可继续调用,但新代码禁止接入。

迁移完毕后(todos 与作废页签移至新端点或别处)方开工单删除。


五、数据库行为

无表结构变更,无 H2 迁移脚本改动。user-service Flyway V20260926_001 更新系统菜单与通知配置(非业务表)。


六、边界行为

  • 两个新端点都挂读门 HouseReadPermission,非房务角色(或未登录)返回 808090;普通房务、组长、超管均可调(不限 scope=all),这是与旧 all-claims/ 最大的权限差异。
  • 写口(认领、转单、释放)权限不变:写门只放行 ROOM_MANAGER 与 SUPER_ADMIN;房务组长(house_keeper_lead)调写口返回 808091,其他角色返回 808090。所以组长在两个新端点上所有行 canStartAllocation=false。
  • SSE 广播现有四类事件 ADDED / CLAIMED / RELEASED / URGENT 保留,团期认领、释放、接管不补新事件(现状事实:旧池亦不发,属既知设计)。
  • 他人认领的团期行只读:行操作(转单、释放等)只在 isMine=true 时展示;若直接访问团期看板详情,会得 808612/808613 拒绝。
  • 参数校验失败(如 status 值非法)走全局 BindException,HTTP 200,code=400(非 400 HTTP 状态)。

七、不影响范围

  • 认领、转单、释放、接管的写逻辑:完全不变,只改入口
  • 订单详情读权限:不变
  • 小程序端(/v3/mp/):无改动
  • 旧池的五个读端点在存量消费方(todos、作废页签)迁移完毕前仍可继续调用
  • SSE 通道与事件:保留现有四类,不新增
  • 子订单状态机、配房流程:不变
  • 身份权限种子与角色:不变(仅房务菜单下线,不涉及角色、权限位、权限码)
  • 网关配置:无改动;新路径在现有通配规则 Path=/v3/admin/** 下已生效

八、测试环境已验证

部署:hl-gateway / hl-user-service / hl-product-service-v2 / hl-order-service-v3 四个服务均为 dev-v3 12707c57c(deploy-status.sh 四行 ok,2026-09-26 15:47~16:06 滚完)。以下读数都是经网关 api.test.1814.love、用真实账号鉴权的实测结果(2026-09-26)。

# 场景 实测结果
1 户级「开始配房」:两个普通房务并发认领同一行 一个 200,另一个 808001「已被认领或状态已变化」。随后另一人在列表里看到该行:claimerName = 认领人,isMine=false,canStartAllocation=false
2 普通房务对他人已认领的户级行调认领 / 转交 / 释放 分别返回 808001 / 808010 / 808020,行状态不变
3 普通房务调户级列表 scope=all code=200;旧端点 GET /grab-pool/all-claims/hotel 仍返回 808092(旧权限策略不变)
4 团期「开始配房」:两个普通房务同时点击 5 秒幂等窗口内,后到者 100502;窗口外重试 808652。列表中该团 houseClaimerName = 先到者
5 房务主管(house_keeper_lead)调两个列表 均 code=200。全量翻页:户级 107 行、团期 109 行,canStartAllocation 全部为 false
6 房务主管调「开始配房」 808091「房务组长为只读监督角色,无权执行该操作」
7 非房务角色调两个列表 808090「未登录或非房务角色,无权操作」
8 户级列表传 productType=GROUP HTTP 200,{"code":400,"message":"productType 只能是 CORE 或 CUSTOM"}
9 团期订单不进户级列表 全量翻页户级 107 行,与团期的需求 ID、订单 ID 交集均为 0;阳性对照(已知户级行)在列
10 加急行排序 打标前第 1、2 页都没有加急行;把原在第 2 页第 10 行的样本标为加急后,它移到第 1 页第 1 行,第 2 页没有加急行(样本已还原)
11 stats 与列表同源 户级:不筛选 total=107,productType=CORE total=105,7 个状态分桶的 stats 与按该状态查询的 total 逐一相等。团期:不筛选 stats 为 45 / 64 / 109(pendingClaim / claimed / all),带关键字为 24 / 53 / 77,均与对应 total 相等
12 scope=mine 与 status=pendingClaim 同传 code=200,空页
13 整团认领后的站内信 6 条 CLAIMED 记录的链接为 /housekeeper/orders?groupBatchId=<团期ID>,正文不含「抢单池」;用该 groupBatchId 查团期列表,total=1
14 5 个旧端点 均 code=200,响应结构不变;Swagger 中 deprecated=true
15 菜单 普通房务 ×2、房务主管、超管共 4 个账号,当前菜单树里都没有菜单 101 / 102
16 户级列表 productNo 抽 3 行,与库中产品编号一致
17 关联订单已软删的存量需求行 该行 orderNo / productName / productNo 为 null,列表 code=200 照常返回

本次未在测试服触发、只按代码契约给出的:808612 / 808613(看他人认领的团期看板);productNo 取数失败时的降级(Feign fallback 置 null)。


十、相关文档

  • Issue: #8375
  • PR:
  • 涉及表结构: 无
  • 数据库变更: user-service Flyway V20260926_001(菜单下线 + 通知链接改向)

关联 / 联系人

链接

  • Issue: #8375
  • 合并提交:
    • product-v2: #8381 @ commit d7a98f13f
    • order-v3: #8382 @ commit 72d8fe310
    • user-service: #8379 @ commit 12707c57c

联系人

  • 后端负责人: @wx
  • 前端负责人(hl-ui): @mmg