34 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 | 7537 | 管理端展示订单号的响应体统一补团号(teamNo) | admin | jw(GIT) | 修改接口 | deployed | verified | verified | mmg | f7699455 | 2026-09-13 | 响应体纯增字段,向后兼容:未消费 teamNo 的页面行为完全不变。前端可按需在退款记录、支付流水、协同工单三块列表/详情补一列「团号」。 前端 2026-09-13 已交付(hl-admin f7699455):逐块 grep 实证退款走申请 VO 且列表/详情已显示团号、订单待办已读 teamNo、支付流水无前端页面,三块 no-op;仅协同工单列表 work-order/index.vue 与详情抽屉 WorkOrderDetailDrawer 原本无团号,按可选增强各补一列 teamNo(列表 null 显 -,详情 v-if 有值才显)。checkpoint 7 项全绿(含生产构建)。 | 2026-09-13 | dev-v3 |
order-v3: 管理端展示订单号的响应体统一补团号(teamNo)
服务: hl-order-service-v3 PR: #7564 Issue: #7537
⚠️ 关键变化
🔴 teamNo 是订单团号,不是运营团期号。 系统里有两个都被叫作「团号」的字段:
| 字段 | 来源 | 格式 | 生成时点 | 本单 |
|---|---|---|---|---|
teamNo |
order_main.team_no |
26-0001(4 位) |
订金支付成功 | ✅ 本单返的是这个 |
batchNo |
order_group_batch.batch_no |
GB-26-0001 |
建团期时 | ❌ 本单不返 |
🔴 teamNo 为 null 不代表「不是团期单」。 生成条件是订金支付成功,与订单是不是团期单完全无关:
- 已付订金的散客单 → 有团号
- 未付订金的团期单 → 没有团号
前端不要用 teamNo != null 去判断团期单,那会判错两个方向。
🔴 团号为空时一律是 null,不是空串、更不会回退成订单号。前端按 null 判空即可,不必再区分 ""。
🔴 同一团期下的每张子订单团号各不相同(团号是订单级的,不是团期级的)。别按「同团共用一个号」做归并。
一、背景
hl-ui 管理后台的退款记录、支付流水、协同工单三块列表/详情只显示订单号,
客服要知道团号得另开一个页面按订单号反查;订单待办的 teamNo 字段虽然早就在契约里,
但分页路径有值、单对象路径(新建/修改/完成/重开的回包)从来没赋过值,恒为 null,
前端拿到的数据前后不一致。
本单把这四处补齐:三个 VO 新增 teamNo 字段,一个 VO 补上从未执行的填充。
路径、方法、请求参数一律不变,只在响应体追加(或补填)一个字段,向后兼容纯增。
二、变更接口清单
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|---|---|---|---|---|---|
| 1 | 退款详情 | GET | /v3/admin/refund/{refundId} |
修改 | 响应体新增 teamNo |
| 2 | 按订单查退款 | GET | /v3/admin/refund/order/{orderId}/list |
修改 | 响应体新增 teamNo |
| 3 | 支付交易分页 | GET | /v3/admin/payment/list |
修改 | 响应体新增 teamNo |
| 4 | 交易详情 | GET | /v3/admin/payment/{transactionId} |
修改 | 响应体新增 teamNo |
| 5 | 按订单查交易 | GET | /v3/admin/payment/order/{orderId} |
修改 | 响应体新增 teamNo |
| 6 | 工单分页 | GET | /v3/admin/order/work-order/list |
修改 | 响应体新增 teamNo |
| 7 | 工单详情 | GET | /v3/admin/order/work-order/{workOrderId} |
修改 | 响应体新增 teamNo |
| 8 | 手动新建待办 | POST | /v3/admin/order-todos/manual |
修改 | teamNo 字段已存在,本单补上从未赋值的填充 |
| 9 | 修改手动待办 | PUT | /v3/admin/order-todos/{todoId} |
修改 | teamNo 字段已存在,本单补上从未赋值的填充 |
| 10 | 完成待办 | PUT | /v3/admin/order-todos/{todoId}/complete |
修改 | teamNo 字段已存在,本单补上从未赋值的填充 |
| 11 | 重开待办 | PUT | /v3/admin/order-todos/{todoId}/reopen |
修改 | teamNo 字段已存在,本单补上从未赋值的填充 |
三、接口详情
1. 退款详情 GET /v3/admin/refund/{refundId}
VO: RefundRecordVO
使用场景
hl-ui 管理后台查看单笔退款记录的完整信息。本单起响应体多出 teamNo,退款详情页可直接显示团号,不必再按订单号反查。
入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| refundId | Path | Long | ✅ | 退款记录 ID | 退款 ID |
出参字段表
| 字段 | 类型 | 说明 |
|---|---|---|
| teamNo | String | 本单新增。团号,4 位,形如 26-0001。订金支付成功后生成;未生成、订单不存在或 orderId 为空时为 null(不返空串、不回退订单号) |
| (其余字段) | — | 全部不变,本单不改动任何既有字段的名称、类型与语义 |
请求示例
GET /v3/admin/refund/{refundId}
Authorization: Bearer <admin token>
响应示例
{
"code": 200,
"message": "成功",
"data": {
"refundId": "2098380606701256706",
"orderId": "2098372746097348609",
"orderNo": "HL20260911192703129",
"teamNo": "26-4823",
"status": "SUCCESS"
},
"success": true
}
空数据 / 降级响应
订单已被删除、或订金尚未支付成功时,teamNo 为 null,其余字段照常返回,不降级、不报错。
错误响应
| 码 | 符号 | 触发 |
|---|---|---|
| 不变 | PAYMENT_REFUND_RECORD_NOT_FOUND |
refundId 查不到记录 |
{
"code": 520009,
"message": "退款记录不存在: 999999",
"data": null,
"traceId": null,
"success": false
}
业务边界
teamNo是订单团号(order_main.team_no),不是运营团期号batchNo(GB-26-0001),本单不返后者。- 同一张订单的多条退款记录
teamNo必然相同。
2. 按订单查退款 GET /v3/admin/refund/order/{orderId}/list
VO: List<RefundRecordVO>
使用场景
hl-ui 订单详情页的退款记录列表。本单起每行多出 teamNo。
入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| orderId | Path | Long | ✅ | 订单 ID | 订单 ID |
出参字段表
| 字段 | 类型 | 说明 |
|---|---|---|
| teamNo | String | 本单新增。团号,4 位,形如 26-0001。订金支付成功后生成;未生成、订单不存在或 orderId 为空时为 null(不返空串、不回退订单号) |
| (其余字段) | — | 全部不变,本单不改动任何既有字段的名称、类型与语义 |
请求示例
GET /v3/admin/refund/order/{orderId}/list
Authorization: Bearer <admin token>
响应示例
{
"code": 200,
"message": "成功",
"data": [
{
"refundId": "2098380606701256706",
"orderId": "2098372746097348609",
"orderNo": "HL20260911192703129",
"teamNo": "26-4823",
"status": "SUCCESS"
}
],
"success": true
}
空数据 / 降级响应
该订单无退款记录时返回空数组 [](HTTP 200),不抛错。空数组时后端不发订单查询。
错误响应
| 码 | 符号 | 触发 |
|---|---|---|
| 不变 | 无 | 本端点无新增错误码;无记录返空数组 |
{
"code": 401,
"message": "缺少有效的 Authorization 头",
"data": null,
"traceId": "b8ffe9e9e9f84abe",
"success": false
}
业务边界
- 本列表所有行同属一张订单,团号必然相同;后端仍走批量富化,整页只发 1 次订单查询,前端无需担心行数带来的耗时增长。
3. 支付交易分页 GET /v3/admin/payment/list
VO: PageResult<PaymentTransactionVO>
使用场景
hl-ui 支付管理的交易流水分页列表。本单起 records[] 每行多出 teamNo,可直接做「按团号归并」的展示。
入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| orderNo | Query | String | ❌ | 模糊匹配 | 订单号 |
| mchId | Query | String | ❌ | — | 商户号 |
| status | Query | String | ❌ | PENDING/SUCCESS/CLOSED/REFUNDED | 交易状态 |
| tradeType | Query | String | ❌ | JSAPI/H5 | 交易类型 |
| payType | Query | String | ❌ | FULL/DEPOSIT/BALANCE | 支付类型 |
| startDate | Query | String | ❌ | yyyy-MM-dd |
起始日期(含) |
| endDate | Query | String | ❌ | yyyy-MM-dd |
结束日期(含) |
| page | Query | Integer | ❌ | 默认 1 | 页码 |
| pageSize | Query | Integer | ❌ | 默认 20 | 每页条数 |
出参字段表
| 字段 | 类型 | 说明 |
|---|---|---|
| teamNo | String | 本单新增。团号,4 位,形如 26-0001。订金支付成功后生成;未生成、订单不存在或 orderId 为空时为 null(不返空串、不回退订单号) |
| (其余字段) | — | 全部不变,本单不改动任何既有字段的名称、类型与语义 |
请求示例
GET /v3/admin/payment/list
Authorization: Bearer <admin token>
响应示例
{
"code": 200,
"message": "成功",
"data": {
"records": [
{ "orderId": "2098381549387882497", "orderNo": "HL20260911200202015", "teamNo": "26-4684" },
{ "orderId": "2098381524394024962", "orderNo": "HL20260911200156046", "teamNo": "26-7561" }
],
"total": 128,
"page": 1,
"pageSize": 20
},
"success": true
}
空数据 / 降级响应
空页(records: [])时后端不发订单查询;单行订单已删或订金未付时该行 teamNo 为 null,整页照常返回,不会因一条脏数据整页 500。
错误响应
| 码 | 符号 | 触发 |
|---|---|---|
| 不变 | PAYMENT_START_DATE_FORMAT_INVALID / PAYMENT_END_DATE_FORMAT_INVALID |
日期格式非 yyyy-MM-dd |
{
"code": 520007,
"message": "开始日期格式错误,应为 yyyy-MM-dd",
"data": null,
"traceId": null,
"success": false
}
{
"code": 520008,
"message": "结束日期格式错误,应为 yyyy-MM-dd",
"data": null,
"traceId": null,
"success": false
}
业务边界
- 同一页里
teamNo有值与为null的行会并存,属正常:团号只在订金支付成功后生成。 - 整页只发 1 次订单批量查询(按 distinct
orderId),不随行数线性增长。
4. 交易详情 GET /v3/admin/payment/{transactionId}
VO: PaymentTransactionVO
使用场景
hl-ui 查看单笔支付交易详情。本单起响应体多出 teamNo。
入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| transactionId | Path | Long | ✅ | 交易 ID | 交易 ID |
出参字段表
| 字段 | 类型 | 说明 |
|---|---|---|
| teamNo | String | 本单新增。团号,4 位,形如 26-0001。订金支付成功后生成;未生成、订单不存在或 orderId 为空时为 null(不返空串、不回退订单号) |
| (其余字段) | — | 全部不变,本单不改动任何既有字段的名称、类型与语义 |
请求示例
GET /v3/admin/payment/{transactionId}
Authorization: Bearer <admin token>
响应示例
{
"code": 200,
"message": "成功",
"data": {
"transactionId": "2098382090226581506",
"orderId": "2098381549387882497",
"orderNo": "HL20260911200202015",
"teamNo": "26-4684",
"status": "SUCCESS"
},
"success": true
}
空数据 / 降级响应
订金未支付成功 / 订单已删时 teamNo 为 null,其余字段照常返回。
错误响应
| 码 | 符号 | 触发 |
|---|---|---|
| 不变 | PAYMENT_TRANSACTION_NOT_FOUND |
transactionId 查不到交易 |
{
"code": 520005,
"message": "交易记录不存在",
"data": null,
"traceId": null,
"success": false
}
业务边界
- 同 VO 的
POST /v3/admin/payment/{transactionId}/sync(同步支付状态)两个返回分支都已补富化,响应体同样多出teamNo。
5. 按订单查交易 GET /v3/admin/payment/order/{orderId}
VO: List<PaymentTransactionVO>
使用场景
hl-ui 订单详情页的支付流水列表。本单起每行多出 teamNo。
入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| orderId | Path | Long | ✅ | 订单 ID | 订单 ID |
出参字段表
| 字段 | 类型 | 说明 |
|---|---|---|
| teamNo | String | 本单新增。团号,4 位,形如 26-0001。订金支付成功后生成;未生成、订单不存在或 orderId 为空时为 null(不返空串、不回退订单号) |
| (其余字段) | — | 全部不变,本单不改动任何既有字段的名称、类型与语义 |
请求示例
GET /v3/admin/payment/order/{orderId}
Authorization: Bearer <admin token>
响应示例
{
"code": 200,
"message": "成功",
"data": [
{ "orderId": "2098381549387882497", "orderNo": "HL20260911200202015", "teamNo": "26-4684", "payType": "BALANCE" },
{ "orderId": "2098381549387882497", "orderNo": "HL20260911200202015", "teamNo": "26-4684", "payType": "DEPOSIT" }
],
"success": true
}
空数据 / 降级响应
该订单无交易记录时返回空数组 [](HTTP 200)。
错误响应
| 码 | 符号 | 触发 |
|---|---|---|
| 不变 | 无 | 本端点无新增错误码 |
{
"code": 401,
"message": "缺少有效的 Authorization 头",
"data": null,
"traceId": "b8ffe9e9e9f84abe",
"success": false
}
业务边界
- 本列表所有行同属一张订单,团号必然相同。
6. 工单分页 GET /v3/admin/order/work-order/list
VO: PageResult<WorkOrderRespVO>
使用场景
hl-ui 协同工单分页列表。本单起 records[] 每行多出 teamNo。
入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| status | Query | String | ❌ | PENDING/PROCESSING/RESOLVED/REJECTED | 工单状态 |
| type | Query | String | ❌ | CHANGE/COMPLAINT/SUPPLEMENT/OTHER,取值以字典 work_order_type 为准 |
工单类型 |
| priority | Query | String | ❌ | — | 优先级 |
| orderNo | Query | String | ❌ | — | 关联订单号 |
| assigneeAdminId | Query | Long | ❌ | — | 指派人 ID |
| page | Query | Integer | ❌ | 默认 1 | 页码 |
| pageSize | Query | Integer | ❌ | 默认 20 | 每页条数 |
出参字段表
| 字段 | 类型 | 说明 |
|---|---|---|
| teamNo | String | 本单新增。团号,4 位,形如 26-0001。订金支付成功后生成;未生成、订单不存在或 orderId 为空时为 null(不返空串、不回退订单号) |
| (其余字段) | — | 全部不变,本单不改动任何既有字段的名称、类型与语义 |
请求示例
GET /v3/admin/order/work-order/list
Authorization: Bearer <admin token>
响应示例
{
"code": 200,
"message": "成功",
"data": {
"records": [
{ "id": "2098579038820786177", "orderId": "2097500233448448002", "orderNo": "HL20260909093959906", "teamNo": "26-9208" },
{ "id": "2098579038493728770", "orderId": "2095549346731757569", "orderNo": "HL20260904002752146", "teamNo": null }
],
"total": 12,
"page": 1,
"pageSize": 20
},
"success": true
}
空数据 / 降级响应
空页时后端不发订单查询;单行订单已删或 orderId 为空时该行 teamNo 为 null,整页照常返回。
错误响应
| 码 | 符号 | 触发 |
|---|---|---|
| 不变 | 无 | 本端点无新增错误码 |
{
"code": 401,
"message": "缺少有效的 Authorization 头",
"data": null,
"traceId": "b8ffe9e9e9f84abe",
"success": false
}
业务边界
- 整页只发 1 次订单批量查询。
teamNo与typeName/statusName/priorityName三个字典展示名是两条独立填充链路,团号不走字典。
7. 工单详情 GET /v3/admin/order/work-order/{workOrderId}
VO: WorkOrderRespVO
使用场景
hl-ui 工单详情(含处理记录)。本单起响应体多出 teamNo。
入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| workOrderId | Path | Long | ✅ | 工单 ID | 工单 ID |
出参字段表
| 字段 | 类型 | 说明 |
|---|---|---|
| teamNo | String | 本单新增。团号,4 位,形如 26-0001。订金支付成功后生成;未生成、订单不存在或 orderId 为空时为 null(不返空串、不回退订单号) |
| (其余字段) | — | 全部不变,本单不改动任何既有字段的名称、类型与语义 |
请求示例
GET /v3/admin/order/work-order/{workOrderId}
Authorization: Bearer <admin token>
响应示例
{
"code": 200,
"message": "成功",
"data": {
"id": "2098579038820786177",
"workOrderNo": "WO202609120918017898",
"orderId": "2097500233448448002",
"orderNo": "HL20260909093959906",
"teamNo": "26-9208",
"status": "PENDING",
"logs": []
},
"success": true
}
空数据 / 降级响应
订金未支付成功 / 订单已删时 teamNo 为 null。
错误响应
| 码 | 符号 | 触发 |
|---|---|---|
| 不变 | WORK_ORDER_NOT_FOUND |
workOrderId 查不到工单 |
{
"code": 581440,
"message": "工单不存在",
"data": null,
"traceId": null,
"success": false
}
业务边界
- 同 VO 的 4 个写端点同步补了富化,响应体同样多出
teamNo:POST /v3/admin/order/work-order(创建)、PUT …/{workOrderId}/process(处理)、PUT …/{workOrderId}/assign(指派)、POST …/{workOrderId}/comment(备注)。
8. 手动新建待办 POST /v3/admin/order-todos/manual
VO: OrderTodoRespVO
使用场景
hl-ui 定制师手动给订单加一条待办。teamNo 字段早就在契约里,但此前单对象返回路径从未赋值、恒为 null;本单补上填充。
入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| orderId | Body | Long | ✅ | 必须是调用人自己的订单 | 订单 ID |
| todoLabel | Body | String | ✅ | 非空白 | 待办标题 |
| todoDate | Body | String | ✅ | yyyy-MM-dd |
待办日期 |
出参字段表
| 字段 | 类型 | 说明 |
|---|---|---|
| teamNo | String | 本单新增。团号,4 位,形如 26-0001。订金支付成功后生成;未生成、订单不存在或 orderId 为空时为 null(不返空串、不回退订单号) |
| (其余字段) | — | 全部不变,本单不改动任何既有字段的名称、类型与语义 |
请求示例
POST /v3/admin/order-todos/manual
Authorization: Bearer <admin token>
响应示例
{
"code": 200,
"message": "成功",
"data": {
"todoId": "2098579085771923457",
"orderId": "2097500233448448002",
"orderNo": "HL20260909093959906",
"teamNo": "26-9208",
"todoSource": "MANUAL",
"status": "PENDING"
},
"success": true
}
空数据 / 降级响应
订金未支付成功 / 订单已删时 teamNo 为 null(此前是恒 null,现在是真实值或 null)。
错误响应
| 码 | 符号 | 触发 |
|---|---|---|
| 不变 | TODO_ORDER_REQUIRED |
orderId 为空或订单不存在 |
| 不变 | TODO_TITLE_REQUIRED |
todoLabel 为空白 |
| 不变 | TODO_DATE_REQUIRED |
todoDate 为空 |
| 不变 | TODO_ORDER_CONSULTANT_MISMATCH |
订单不属于调用人 |
{
"code": 581702,
"message": "待办必须关联订单",
"data": null,
"traceId": null,
"success": false
}
{
"code": 581704,
"message": "待办标题不能为空",
"data": null,
"traceId": null,
"success": false
}
业务边界
- 分页列表
GET /v3/admin/order-todos的teamNo本来就有值(走 join 直接带出),本单只补齐单对象路径,两条路径自此一致。
9. 修改手动待办 PUT /v3/admin/order-todos/{todoId}
VO: OrderTodoRespVO
使用场景
hl-ui 修改手动待办的标题 / 日期。data.teamNo 由**恒 null**改为真实值。
入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| todoId | Path | Long | ✅ | 必须是调用人自己的手动待办 | 待办 ID |
| todoLabel | Body | String | ❌ | 两者都不传则原样返回 | 新标题 |
| todoDate | Body | String | ❌ | yyyy-MM-dd |
新日期 |
出参字段表
| 字段 | 类型 | 说明 |
|---|---|---|
| teamNo | String | 本单新增。团号,4 位,形如 26-0001。订金支付成功后生成;未生成、订单不存在或 orderId 为空时为 null(不返空串、不回退订单号) |
| (其余字段) | — | 全部不变,本单不改动任何既有字段的名称、类型与语义 |
请求示例
PUT /v3/admin/order-todos/{todoId}
Authorization: Bearer <admin token>
响应示例
{
"code": 200,
"message": "成功",
"data": {
"todoId": "2098579085771923457",
"orderId": "2097500233448448002",
"orderNo": "HL20260909093959906",
"teamNo": "26-9208",
"status": "PENDING"
},
"success": true
}
空数据 / 降级响应
订金未支付成功 / 订单已删时 teamNo 为 null。
错误响应
| 码 | 符号 | 触发 |
|---|---|---|
| 不变 | TODO_NOT_FOUND |
todoId 查不到 |
| 不变 | SYSTEM_TODO_MANUAL_OPERATION_FORBIDDEN |
系统生成的待办不允许手动改 |
| 不变 | TODO_FORBIDDEN |
待办不属于调用人 |
{
"code": 581700,
"message": "待办不存在",
"data": null,
"traceId": null,
"success": false
}
{
"code": 581701,
"message": "无权操作该待办",
"data": null,
"traceId": null,
"success": false
}
业务边界
- 两个 body 字段都不传时,后端原样返回当前待办——此路径同样会填
teamNo。
10. 完成待办 PUT /v3/admin/order-todos/{todoId}/complete
VO: OrderTodoRespVO
使用场景
hl-ui 把手动待办标记为已完成。data.teamNo 由**恒 null**改为真实值。
入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| todoId | Path | Long | ✅ | 必须是调用人自己的手动待办 | 待办 ID |
出参字段表
| 字段 | 类型 | 说明 |
|---|---|---|
| teamNo | String | 本单新增。团号,4 位,形如 26-0001。订金支付成功后生成;未生成、订单不存在或 orderId 为空时为 null(不返空串、不回退订单号) |
| (其余字段) | — | 全部不变,本单不改动任何既有字段的名称、类型与语义 |
请求示例
PUT /v3/admin/order-todos/{todoId}/complete
Authorization: Bearer <admin token>
响应示例
{
"code": 200,
"message": "成功",
"data": {
"todoId": "2098579085461446657",
"orderId": "2095549346731757569",
"orderNo": "HL20260904002752146",
"teamNo": null,
"status": "COMPLETED"
},
"success": true
}
空数据 / 降级响应
上面的响应示例就是订金未支付成功的真实回包:teamNo 为 null,不是空串、不是订单号。
错误响应
| 码 | 符号 | 触发 |
|---|---|---|
| 不变 | TODO_NOT_FOUND |
todoId 查不到 |
| 不变 | SYSTEM_TODO_MANUAL_OPERATION_FORBIDDEN |
系统生成的待办不允许手动操作 |
| 不变 | TODO_FORBIDDEN |
待办不属于调用人 |
{
"code": 581700,
"message": "待办不存在",
"data": null,
"traceId": null,
"success": false
}
{
"code": 581703,
"message": "系统待办不允许手动完成或重开",
"data": null,
"traceId": null,
"success": false
}
业务边界
- 待办已是非
PENDING态时后端不重复写库、原样返回,该短路分支同样会填teamNo。
11. 重开待办 PUT /v3/admin/order-todos/{todoId}/reopen
VO: OrderTodoRespVO
使用场景
hl-ui 把已完成的手动待办重新打开。data.teamNo 由**恒 null**改为真实值。
入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| todoId | Path | Long | ✅ | 必须是调用人自己的手动待办 | 待办 ID |
���参字段表
| 字段 | 类型 | 说明 |
|---|---|---|
| teamNo | String | 本单新增。团号,4 位,形如 26-0001。订金支付成功后生成;未生成、订单不存在或 orderId 为空时为 null(不返空串、不回退订单号) |
| (其余字段) | — | 全部不变,本单不改动任何既有字段的名称、类型与语义 |
请求示例
PUT /v3/admin/order-todos/{todoId}/reopen
Authorization: Bearer <admin token>
响应示例
{
"code": 200,
"message": "成功",
"data": {
"todoId": "2098579085771923457",
"orderId": "2097500233448448002",
"orderNo": "HL20260909093959906",
"teamNo": "26-9208",
"status": "PENDING"
},
"success": true
}
空数据 / 降级响应
订金未支付成功 / 订单已删时 teamNo 为 null。
错误响应
| 码 | 符号 | 触发 |
|---|---|---|
| 不变 | TODO_NOT_FOUND |
todoId 查不到 |
| 不变 | SYSTEM_TODO_MANUAL_OPERATION_FORBIDDEN |
系统生成的待办不允许手动操作 |
| 不变 | TODO_FORBIDDEN |
待办不属于调用人 |
{
"code": 581700,
"message": "待办不存在",
"data": null,
"traceId": null,
"success": false
}
{
"code": 581703,
"message": "系统待办不允许手动完成或重开",
"data": null,
"traceId": null,
"success": false
}
业务边界
- 待办已是
PENDING态时后端不重复写库、原样返回,该短路分支同样会填teamNo。
四、契约约束与正确调用方式
- 判空只判
null:teamNo为空时后端返null,不返空串。前端if (row.teamNo)即可,不必再写!== ''。 - 不要拿
teamNo判团期单:判团期请用团期相关字段(groupBatchId等),不是团号。 已付订金的散客单有团号、未付订金的团期单没有团号,用团号判会两个方向都判错。 - 不要按团号归并同团订单:同一团期下每张子订单的团号各不相同。要归团请用
groupBatchId。 - 不要期待本单返运营团期号:
batchNo(GB-26-0001)与从订单跳团期所需的groupBatchId不在本单范围,另有工单跟进。 - 格式:
26-0001—— 年份后两位 +-+ 4 位序号,VARCHAR(10)字符串,不是数字, 不要做数值解析、也不要按T开头做前缀判断(旧 Swaggerexample写的T2026…是错的,本单已一并订正)。 - 分页接口不会因为新增该字段变慢:整页只发 1 次订单批量查询,不随行数增长。
五、数据库行为
本单零数据库变更:无新增/修改表、无新增列、无新增索引、无 Flyway 迁移脚本、无 Mapper 改动。
teamNo 取的是既有列 order_main.team_no(DDL 注释:「团号(订金支付成功后生成,4位)」),
经既有服务契约 OrderService.selectBatchByIds(Collection<Long>) 批量读出,只读、不写。
清单里的写端点(8/9/10/11 待办写接口,以及工单的创建/处理/指派/备注)写库行为一行未改, 本单只是在它们返回前多填了一个展示字段。
六、边界行为
| 场景 | 行为 |
|---|---|
| 订金已支付成功 | teamNo 有值,形如 26-0001 |
| 订金未支付成功 | teamNo 为 null |
行的 orderId 为 null(历史脏数据) |
该行 teamNo 为 null,接口正常返回,不抛异常 |
| 订单已被删除 | 该行 teamNo 为 null,接口正常返回,不抛异常 |
| 分页里一条脏数据 | 只影响那一行,整页照常返回,不会整页 500 |
| 空列表 / 空页 | 后端不发订单查询 |
| 团期子订单 | 与散客单一视同仁,按订金是否付成功决定有无团号 |
六.6、修改前后对比
| 维度 | 改前 | 改后 |
|---|---|---|
| 接口 1~7(退款/支付/工单) | 响应体没有 teamNo 字段 |
响应体有 teamNo,位置紧随 orderNo |
| 接口 8~11(订单待办) | teamNo 字段存在但恒为 null |
teamNo 填真实值(无团号时才是 null) |
订单待办分页 GET /v3/admin/order-todos |
已有值 | 不变(本单未动该路径) |
| 路径 / 方法 / 请求参数 | — | 完全不变 |
| 既有字段的名称/类型/语义 | — | 完全不变 |
| 错误码 | — | 无新增、无调整 |
六.7、影响评估
- 兼容性:响应体纯增字段,未消费
teamNo的前端页面行为完全不变,无需任何改动即可继续工作。 - 需要前端动的:想显示团号的页面按上表加一列即可;接口 8~11 的调用方若此前把
teamNo恒为null当成「该字段没用」硬编码隐藏,现在可以打开。 - 性能:3 个列表/分页端点每页多一次主键
IN批量查询(整页 1 次,不是每行 1 次)。POST /v3/admin/payment/{transactionId}/sync的写事务内多一次同数据源本地读,该端点是管理员手动触发的低频操作。 - 连带生效(无需单独对接,响应体同样多出该字段):
POST /v3/admin/refund/orders/{orderId}、POST /v3/admin/payment/{transactionId}/sync、 工单的POST /v3/admin/order/work-order、PUT …/process、PUT …/assign、POST …/comment。 /v3/internal/侧连带多出该字段的 4 个端点(服务间调用,公网网关不放行,前端不对接):POST /v3/internal/payment/refund、GET /v3/internal/payment/status/{orderId}、GET /v3/internal/payment/transactions/{orderId}、GET /v3/internal/order/{orderId}/transactions。 它们复用同一批 VO,属向后兼容纯增。
七、不影响范围
GET /v3/internal/payment/pay-info/{orderId}(PayInfoVO)不追加任何字段 —— 非前端可见,本单明确不改。- 小程序端(mp 域)全部 VO 不动。
- 团期详情页的 5 个逐行 VO 不动(
GroupBatchOrderItemRespVO/GroupBatchChipItemRespVO/GroupBatchContractItemVO/GroupBatchFinanceItemVO/GroupBatchAdvanceItemVO),另有工单跟进。 RefundApplicationDetailRespVO.RecordItemVO刻意不加:同一响应体里的 record 行全属同一张订单, 团号与orderInfo.teamNo必然相同,逐行重复只会让前端猜哪个是权威值。- 8 个已有
teamNo的 VO 字段声明未被改动;只订正了 3 处 Swaggerexample字面量 (T2026…→26-0001),字段名与文案不动。 - 零改动:Controller 方法体、Mapper、Entity、Flyway、错误码、hl-gateway 配置、其他微服务。
八、测试环境已验证
部署:hl-order-service-v3 @ feature/7537-team-no-backfill / 6dcee7d4d(已合并 dev-v3 = c798fd5a6),
双实例滚动重启完成。全部实测经真实网关 api.test.1814.love:9443 + Bearer 鉴权。
| # | 端点 | 已付订金 | 未付订金 |
|---|---|---|---|
| 1 | GET /v3/admin/refund/{refundId} |
200,teamNo="26-4823" |
200,teamNo=null |
| 2 | GET /v3/admin/refund/order/{orderId}/list |
200,teamNo="26-4823" |
200,teamNo=null |
| 3 | GET /v3/admin/payment/list |
200,26-4684 / 26-7561 / 26-0438 三行各自正确 |
同页混合行含 null |
| 4 | GET /v3/admin/payment/{transactionId} |
200,teamNo="26-4684" |
200,teamNo=null |
| 5 | GET /v3/admin/payment/order/{orderId} |
200,两行均 26-4684 |
200,teamNo=null |
| 6 | GET /v3/admin/order/work-order/list |
200,26-6331/26-9208/26-1849 |
同页含 teamNo=null 行 |
| 7 | GET /v3/admin/order/work-order/{workOrderId} |
200,teamNo="26-9208" |
200,teamNo=null |
| 10 | PUT /v3/admin/order-todos/{todoId}/complete |
200,teamNo="26-9208" |
200,teamNo=null |
团期子订单也有团号(挡住「以为只有团期单才有团号」的反向误解):
GET /v3/admin/payment/order/2098372769329598466 → teamNo="26-9069",该单 group_batch_id 非空。
同团多户团号各不相同:同一 group_batch_id=2097500233511362561 下的两张子订单,
经 GET /v3/admin/order/work-order/{workOrderId} 分别返 26-9208 与 26-6331。
本地全量:mvn -o -pl hl-order-service-v3 -am test → 9925 例 / Failures 0;
其中新增 4 个测试类 35 例全绿,RedLineArchTest / LayerEnforcementTest / MapperBoundaryArchTest 均通过(非 Skipped)。
十、相关文档
- Issue:https://git.1814.love:8443/wx/HL/issues/7537
- PR:https://git.1814.love:8443/wx/HL/pulls/7564
- 字段来源 DDL:
hl-order-service-v3/src/main/resources/db/migration/V20260511_001__init_core_tables.sql:32 - 团号生成器:
hl-order-service-v3/src/main/java/com/hulalv/order/core/service/GroupCodeService.java:11-17,30-37
关联 / 联系人
- 后端:jw
- 前端(hl-ui 管理后台):mmg
- 需求定案:wx(2026-09-11 选项卡)