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 | 8446 | 订单列表与状态计数新增查询参数 productType(核心 / 定制 / 团期页签) | admin | wx(GIT) | 修改接口 | deployed | verified | verified | mmg | ab3b6be1268721e56ed809da9329b367d8b890e9 | v2.1 | 2026-09-28 | PR #8454 已合入 dev-v3(22145977d),order-v3 已部署测试服,经网关实测三个端点。新增查询参数 productType,与其他条件取 AND;只传 productType、不传 orderKind 时不按团属性过滤。前端改动见同日前端 changelog。前端已交付(ab3b6be1):列表与状态计数透传 productType、不再传 orderKind;「订单类型」下拉改核心/定制/团期三页签,团期关键词框只在团期页签显示、切出团期清残留关键词;productTypeTabs/groupBatchKeyword 等 spec 全绿。 | 2026-09-27 | dev-v3 |
订单服务(order-v3): 订单列表与状态计数新增查询参数 productType
服务: hl-order-service-v3(端口 8086/8186) PR: #8454(合并提交
22145977d) Issue: #8446 日期: 2026-09-27 影响范围: 管理后台「订单管理v2 › 订单列表」的列表与状态计数接口
⚠️ 关键变化
- 列表
GET /v3/admin/order(别名/v3/admin/order/list)与状态计数GET /v3/admin/order/status-group-counts新增查询参数productType:CORE/ROUTE/CUSTOM/GROUP,英文逗号多值,空串等同不传。 - 只传
productType、不传(或传空串)orderKind时,不再缺省orderKind=NORMAL,不按「是否挂团期」过滤。 页签「团期」因此能查到团期订单。 - 其余组合行为不变:显式传
orderKind与productType取 AND;传groupBatchId/groupBatchKeyword时仍强制按团期,再与productType取 AND。两个参数都不传时仍缺省 NORMAL。 - 非法值(如
productType=XYZ)返回 HTTP 200 +code=100001,与orderKind非法值同码。 - 响应结构不变。
一、背景
wx 2026-09-27 要求订单列表的「订单类型」下拉(散客 / 团单 / 全部)改成「核心 / 定制 / 团期」页签。页签按产品类型切分,而原 orderKind 按「订单有没有挂运营团期」切分,两者不是同一口径,所以新增 productType,orderKind 保留原语义不废弃。
二、变更接口清单
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|---|---|---|---|---|---|
| 1 | 订单列表 | GET | /v3/admin/order |
新增参数 | productType,别名路径 /v3/admin/order/list 同样生效 |
| 2 | 订单列表 Tab 分组计数 | GET | /v3/admin/order/status-group-counts |
新增参数 | productType,与列表同口径 |
三、接口详情
1. 订单列表 GET /v3/admin/order
VO: OrderListReqVO → Result<PageResult<OrderListItemRespVO>>
使用场景
订单列表页签「核心 / 定制 / 团期」切换时,按当前页签传 productType=CORE|CUSTOM|GROUP 取列表。
入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| productType | query | String | 否 | CORE/ROUTE/CUSTOM/GROUP,多值用英文逗号分隔(如 CORE,CUSTOM),空串等同不传 |
新增。按订单产品类型过滤,与其他条件取 AND |
| orderKind | query | String | 否 | ALL/GROUP/NORMAL,空串等同不传 |
原有。未传时缺省 NORMAL;例外:传了 productType 而本参数未传或为空串时不缺省、不按团属性过滤 |
其余参数(keyword、orderStatus、statusGroup、groupBatchId、groupBatchKeyword、page、pageSize 等)不变,pageSize 上限 100。
出参字段表
| 字段 | 类型 | 说明 |
|---|---|---|
| data.records[] | Array | 订单行(前端 request.js 拦截器会同步映射为 list) |
| data.records[].id | String | 订单 ID |
| data.records[].productType | String | 产品类型 CORE/ROUTE/CUSTOM/GROUP |
| data.total | Number | 符合条件的总条数 |
| data.page | Number | 当前页 |
| data.pageSize | Number | 每页条数 |
订单行其余字段不变。
请求示例
GET /v3/admin/order?productType=CORE&page=1&pageSize=100
响应示例
测试服 2026-09-27 实测,节选前 2 条、每条只保留关键字段:
{
"code": 200,
"message": "成功",
"success": true,
"data": {
"total": 71,
"page": 1,
"pageSize": 100,
"records": [
{
"id": "2104192144560553985",
"orderNo": "HL20260927205115753",
"productType": "CORE",
"groupBatchId": null,
"orderStatus": "CUSTOMIZING"
},
{
"id": "2104161383220457474",
"orderNo": "HL20260927184901765",
"productType": "CORE",
"groupBatchId": null,
"orderStatus": "CUSTOMIZING"
}
]
}
}
空数据 / 降级响应
没有符合条件的订单时 records 为空数组、total 为 0,例如 productType=CORE 加一个只挂了团期订单的团期关键词。
{
"code": 200,
"message": "成功",
"success": true,
"data": {
"total": 0,
"page": 1,
"pageSize": 20,
"records": []
}
}
错误响应
非法值返回 HTTP 200,code=100001(测试服实测原文):
{
"code": 100001,
"message": "productType 非法,可选值: CORE, ROUTE, CUSTOM, GROUP(多值用逗号分隔)",
"data": null,
"traceId": null,
"success": false
}
业务边界
- 多值用英文逗号,命中任一即返回;空串等同不传。
- 只传
productType时不按团属性过滤;默认仍排除已取消订单,传statusGroup=ALL才含已取消(与原口径一致)。 - 显式传
orderKind时与productType取 AND,例如productType=GROUP&orderKind=NORMAL恒为空。 - 传
groupBatchId/groupBatchKeyword时强制按团期,再与productType取 AND;在「核心 / 定制」页签下填团期关键词,只会查到挂了该团期、且产品类型是核心 / 定制的订单。 ROUTE(自驾路书)后端接受,本次前端不设页签。- 别名
/v3/admin/order/list入参出参完全相同。
2. 订单列表 Tab 分组计数 GET /v3/admin/order/status-group-counts
VO: OrderListReqVO → Result<List<StatusGroupCountVO>>
使用场景
页签切换时与列表一起请求,传同一个 productType,刷新顶部状态分组徽标。
入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| productType | query | String | 否 | CORE/ROUTE/CUSTOM/GROUP,多值用英文逗号分隔,空串等同不传 |
新增。与列表同口径 |
| orderKind | query | String | 否 | ALL/GROUP/NORMAL,空串等同不传 |
原有。与列表同口径,含上面的例外 |
其余参数与列表相同(不传 statusGroup / orderStatus / page / pageSize)。
出参字段表
| 字段 | 类型 | 说明 |
|---|---|---|
| data[].group | String | 分组标识,固定 6 项,顺序 ALL、BEFORE_TRIP、ON_TRIP、SETTLEMENT、ABNORMAL、AFTERSALE |
| data[].label | String | 分组中文名:全部 / 出行前 / 出行中 / 核单 / 异常/取消 / 售后 |
| data[].orderCount | Number | 该分组订单数 |
请求示例
GET /v3/admin/order/status-group-counts?productType=GROUP
响应示例
测试服 2026-09-27 实测原文:
{
"code": 200,
"message": "成功",
"data": [
{ "group": "ALL", "label": "全部", "orderCount": 14 },
{ "group": "BEFORE_TRIP", "label": "出行前", "orderCount": 14 },
{ "group": "ON_TRIP", "label": "出行中", "orderCount": 0 },
{ "group": "SETTLEMENT", "label": "核单", "orderCount": 0 },
{ "group": "ABNORMAL", "label": "异常/取消", "orderCount": 8 },
{ "group": "AFTERSALE", "label": "售后", "orderCount": 0 }
],
"traceId": null,
"success": true
}
空数据 / 降级响应
没有符合条件的订单时 6 项仍全部返回,orderCount 均为 0。
{
"code": 200,
"message": "成功",
"data": [
{ "group": "ALL", "label": "全部", "orderCount": 0 },
{ "group": "BEFORE_TRIP", "label": "出行前", "orderCount": 0 },
{ "group": "ON_TRIP", "label": "出行中", "orderCount": 0 },
{ "group": "SETTLEMENT", "label": "核单", "orderCount": 0 },
{ "group": "ABNORMAL", "label": "异常/取消", "orderCount": 0 },
{ "group": "AFTERSALE", "label": "售后", "orderCount": 0 }
],
"traceId": null,
"success": true
}
错误响应
与列表相同,非法值返回 HTTP 200 + code=100001(测试服实测原文):
{
"code": 100001,
"message": "productType 非法,可选值: CORE, ROUTE, CUSTOM, GROUP(多值用逗号分隔)",
"data": null,
"traceId": null,
"success": false
}
业务边界
- 与列表共用
OrderListReqVO和同一套过滤,页签徽标与列表条数同口径。 - 「全部」= 出行前 + 出行中 + 核单,不含「异常/取消」,只有显式
orderKind=ALL或cancelled=true时才计入。只传productType时不含,与两个参数都不传时一致。上例 14 = 14 + 0 + 0。 - 「售后」是横切计数,任何情况下都不计入「全部」。
四、契约约束与正确调用方式
- 页签「核心 / 定制 / 团期」→ 列表与计数都传
productType=CORE|CUSTOM|GROUP,不传orderKind。 - 如果仍带着旧的
orderKind=NORMAL,会与productType取 AND,「团期」页签恒为空。 - 旧调用方(只传
orderKind或都不传)行为不变。
| 组合 | 结果 |
|---|---|
productType=CORE |
核心产品订单,不看是否挂团期 |
productType=CORE,CUSTOM |
核心 + 定制 |
productType=GROUP&orderKind=NORMAL |
恒为空 |
| 两个都不传 | 缺省 NORMAL(未挂团期的订单),与改动前一致 |
productType=XYZ |
HTTP 200,code=100001 |
五、数据库行为
无数据库变更,只新增查询条件 product_type IN (...)。
六、边界行为
productType是独立追加的 AND 条件,不进团属性判断链,所以不会和groupBatchId/groupBatchKeyword互相吞掉(OrderListScopeFilter.java:44、:54-55)。- 只传
productType时 Service 把orderKind置 null 而不是ALL:置ALL会让「全部」徽标计入已取消(OrderService.java:529)。 ROUTE测试服当前产品与订单都是 0 条,后端已支持,将来加页签无需改后端。
六.5、枚举 / 数据字典
productType(产品类型)
所属字段: 入参 OrderListReqVO.productType、出参 records[].productType | 类型: String
| 值 | 中文 | 页签 |
|---|---|---|
CORE |
核心 | 核心 |
CUSTOM |
定制 | 定制 |
GROUP |
团期 | 团期 |
ROUTE |
自驾路书 | 本次不设 |
六.6、修改前后对比
| 场景 | 改前 | 改后 |
|---|---|---|
入参 productType |
无 | 新增,多值 |
只传 productType、不传 orderKind |
—(参数不存在) | 不缺省 NORMAL,不按团属性过滤 |
只传 orderKind 或都不传 |
都不传时缺省 NORMAL | 不变 |
六.7、影响评估
- 向后兼容:是。不传
productType的调用方行为不变。 - 前端是否必须同步:前端改页签时列表与计数都要改传
productType、删掉orderKind;不改前端时现有下拉照常可用。
七、不影响范围
- 订单详情、创建、编辑等其他接口不变。
- 定制师待办列表(
DesignerOrderListService)、财务订单查询(FinanceOrderQueryApiImpl)复用同一查询对象但不设productTypes,行为不变。 - 小程序(
MpOrderListReqVO)、H5 不涉及。
八、测试环境已验证
测试服 order-v3 22145977d,经网关、测试专用 ADMIN 账号,逐条与同条件 SQL(hl_order_service_v3.order_main,deleted_at IS NULL,默认排除已取消)比对,全部一致:
| 请求 | total / 计数 | SQL |
|---|---|---|
productType=CORE / CUSTOM / GROUP |
71 / 2 / 14,逐条 productType 全匹配 | 71 / 2 / 14 |
同上 + statusGroup=ALL |
86 / 2 / 22 | 86 / 2 / 22 |
/v3/admin/order/list?productType=GROUP |
14 | 与主路径相同 |
productType=CORE,CUSTOM |
73 | 71 + 2 |
productType=(空串)/ 都不传 |
73 / 73 | NORMAL 口径 73 |
orderKind=GROUP / orderKind=ALL |
14 / 87 | 14 / 87 |
计数 productType=GROUP |
全部 14、出行前 14、出行中 0、核单 0、异常/取消 8、售后 0 | 逐组一致 |
| 计数不传 productType | 全部 73、出行前 43、出行中 0、核单 30、异常/取消 15、售后 0 | 与上一行不同,参数生效 |
团期关键词 / + productType=GROUP / + productType=CORE |
12 / 12 / 0 | 该团期 CORE 订单 0 条 |
productType=XYZ(列表、计数) |
HTTP 200,code=100001 |
— |
单测:OrderServiceTest 323、OrderListScopeFilterTest 18、OrderListReqVOValidationTest 16、OrderGlobalExceptionHandlerTest 9、OrderControllerTest 56、OrderInfoMapperIT 30(Testcontainers 真库),全绿。
十、相关文档
- 接口文档:
docs/order-v3/api/API-SPEC.html(订单列表参数表、orderKind 例外、§1.11 计数口径) - 入参:
hl-order-service-v3/src/main/java/com/hulalv/order/core/controller/admin/vo/OrderListReqVO.java:91-104(productType)、:59-63(orderKind 例外说明) - 过滤:
hl-order-service-v3/src/main/java/com/hulalv/order/core/mapper/OrderListScopeFilter.java:54-55 - 错误码:
hl-order-service-v3/src/main/java/com/hulalv/shared/exception/OrderGlobalExceptionHandler.java:104-110