9.6 KiB
9.6 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 | 7304 | 新增团期状态流水(时间线)只读端点 GB-ADM-096:GET /v3/admin/order/group-batch/:groupBatchId/status-logs | admin | jw(GIT) | 新增接口 | deployed | verified | verified | mmg | 51ca6946 | 2026-09-09 | 新增一个只读端点,把此前只写不可读的 group_batch_status_log 暴露给管理端。后端已部署 TEST 并经真实网关实测 AC-1~AC-6(含读回 #7283 的 BATCH_PRODUCT_CANCEL_FAILED 兜底留痕)。前端待接:团期详情加一个「操作记录/时间线」区块——STATUS 类画 fromStatusName→toStatusName 箭头,DATA 类只渲染 content;中文名一律用后端给的 eventTypeName/fromStatusName/toStatusName,不要自建映射表(枚举会继续新增);operatorType 可能是 SYSTEM/MQ,此时 operatorId 为 null、operatorName 是「系统」之类固定文案。权限与团期看板/芯片同码 group-batch:view。 | 2026-09-09 | dev-v3 |
团期状态流水(时间线)只读端点
一、给前端的一句话
团期的「操作记录 / 时间线」现在有接口了。一次 GET 拿到该团期从建团到当前的全部事件,按时间升序,中文名后端已经拼好,前端直接渲染即可。这是个纯新增端点,不动任何既有接口。
二、变更接口清单
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|---|---|---|---|---|---|
| 1 | 团期状态流水(时间线) | GET | /v3/admin/order/group-batch/:groupBatchId/status-logs |
新增 | 一次返回该团期全部状态流水,按时间升序;此前该表只写不可读 |
三、接口详情
1. 团期状态流水(时间线) GET /v3/admin/order/group-batch/:groupBatchId/status-logs
VO: GroupBatchStatusLogItemVO
使用场景
团期详情页的「操作记录 / 时间线」区块。此前这张表只写不读——建团、成团、取消成团、流团、退单审批、转期、导出、合同保险十余条链路都往里写,但页面上一条也看不到。
入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
groupBatchId |
path | Long | 是 | 雪花 ID,按字符串传 | 团期 ID |
无 query、无 body。不分页——单团期的流水条数由其生命周期事件数决定(量级几十条),不是无界列表。
出参
Result<List<GroupBatchStatusLogItemVO>>,按 changedAt 升序。
| 字段 | 类型 | 说明 |
|---|---|---|
logId |
String | 流水 ID(雪花) |
groupBatchId |
String | 团期 ID(雪花) |
changeType |
String | STATUS=状态流转 / DATA=状态内数据变更 |
eventType |
String | 事件类型值,如 BATCH_GROUP |
eventTypeName |
String | 事件类型中文名,如「成团」;枚举外的历史值为 null |
fromStatus |
String | 变更前团期状态;首次建团为 null |
fromStatusName |
String | 变更前状态中文名,如「招募中」 |
toStatus |
String | 变更后团期状态 |
toStatusName |
String | 变更后状态中文名,如「资源准备中」 |
content |
String | 展示文本,后端已拼好,前端直接渲染 |
reason |
String | 理由 / 备注,可为 null |
operatorType |
String | USER / ADMIN / SYSTEM / MQ |
operatorId |
String | 操作人 ID(雪花);SYSTEM / MQ 场景为 null |
operatorName |
String | 操作人姓名快照;系统场景为「系统」之类固定文案 |
extra |
Object | 附加快照,已解析成对象(不是转义 JSON 字符串);无附加数据时为 null |
changedAt |
String | yyyy-MM-dd HH:mm:ss |
请求示例
GET /v3/admin/order/group-batch/2097500233511362561/status-logs
Authorization: Bearer <admin token>
响应示例
{
"code": 200,
"message": "成功",
"data": [
{
"logId": "2097500233519751171",
"groupBatchId": "2097500233511362561",
"changeType": "STATUS",
"eventType": "BATCH_CREATE",
"eventTypeName": "建团",
"fromStatus": null,
"fromStatusName": null,
"toStatus": "RECRUITING",
"toStatusName": "招募中",
"content": "建团:秋日川西小环线",
"reason": null,
"operatorType": "ADMIN",
"operatorId": "1001",
"operatorName": "admin",
"extra": null,
"changedAt": "2026-09-09 09:40:00"
},
{
"logId": "2097501083860418561",
"groupBatchId": "2097500233511362561",
"changeType": "DATA",
"eventType": "BATCH_CONTRACT_ISSUE",
"eventTypeName": "手动开合同/保险",
"fromStatus": "RESOURCE_PREPARING",
"fromStatusName": "资源准备中",
"toStatus": "RESOURCE_PREPARING",
"toStatusName": "资源准备中",
"content": "手动开合同 · 张三(HL20260909094000073)",
"reason": null,
"operatorType": "ADMIN",
"operatorId": "1001",
"operatorName": "admin",
"extra": {
"orderId": "2097500234186702849",
"orderNo": "HL20260909094000073",
"kind": "合同",
"schemeName": "标准国内电子签约方案"
},
"changedAt": "2026-09-09 09:43:23"
}
]
}
空数据 / 降级响应
团期不存在、或该团期尚无任何流水,一律返回空列表,不报错:
{ "code": 200, "message": "成功", "data": [] }
注意这一点与团期详情不同:
GET /v3/admin/order/group-batch/:groupBatchId对不存在的团期抛589500,本端点回空数组。原因是这张表是 append-only 存证表,「查不到」在读语义上就等于「空时间线」。
单条记录的降级:extra 为空 / 空串 / 非法 JSON 时该条 extra 回 null,其余字段正常;事件类型或状态是枚举外的历史值时对应 *Name 回 null、code 原样返回。一条脏数据不会让整条时间线查不出来。
错误响应
当前角色没有 group-batch:view 权限(失败关闭,与团期看板 / 芯片明细同码):
{ "code": 589507, "message": "无操作权限(非团期管理员 / 非本定制师名下)", "data": null, "success": false }
缺少或无效的 token 由网关拦截,返回 401。本端点不产生其它业务错误码。
业务边界
- 只读端点,不改任何数据。
- 返回全量,不分页、不截断。
- 中文名由后端给:
eventTypeName/fromStatusName/toStatusName;枚举外的历史值为null。 - 团期不存在与无流水不区分,都回空数组。
- 权限码
group-batch:view,与团期看板、芯片逐户明细一致。
四、契约约束与正确调用方式
- 中文名一律用后端返回的字段渲染,不要在前端自建 code→中文 映射表。 团期事件类型会持续新增(#7283 刚加过
BATCH_PRODUCT_CANCEL_FAILED),后端给名字前端就零改动;自建映射表会漏。 - 按
changeType分叉渲染:STATUS画fromStatusName → toStatusName箭头;DATA的fromStatus === toStatus,只渲染content。 operatorType可能是SYSTEM/MQ(AFTER_COMMIT 或异步链路写入),此时operatorId为null,operatorName是「系统」之类的固定文案,照常渲染即可,别按「一定有操作人」写死。extra是对象或null,不是字符串,不要再JSON.parse。不同事件的extra结构不同,按需取键、缺键要兜住。- 雪花 ID 一律按字符串处理(
logId/groupBatchId/operatorId都以字符串下发)。 - 名字字段可能为
null(库里存的是当前枚举外的历史值),此时前端兜底显示对应的 code。
六、边界行为
| 场景 | 行为 |
|---|---|
| 团期不存在 | code=200,data=[] |
| 团期存在但无流水 | code=200,data=[] |
extra 为空 / 空串 / 非法 JSON |
该条 extra 回 null,其余字段正常,不影响整条时间线 |
| 事件类型 / 状态是枚举外的历史值 | 对应 *Name 回 null,eventType / fromStatus / toStatus 原样返回 |
无 group-batch:view 权限 |
589507 |
七、不影响范围
- 不改任何既有接口的路径、入参、出参、错误码。
- 不改团期状态流水的写入侧:十余条写入链路一行未动。
- 无表变更、无 Flyway、无数据迁移。
- 网关路由不新增(
/v3/admin/**已覆盖)。 - 只滚
hl-order-service-v3一个服务。
八、测试环境已验证
TEST(api.test.1814.love)真实网关逐条取证:
| 验收项 | 实测 |
|---|---|
全量返回、按 changedAt 升序、条数与 SELECT COUNT(*) 一致 |
✅ |
STATUS 与 DATA 两类各有实例,DATA 类 fromStatus == toStatus |
✅ |
能读回 #7283 的 BATCH_PRODUCT_CANCEL_FAILED,content 为「班期置不可售失败,请到产品后台手动取消该班期(班期 ID:…)」 |
✅ 本端点存在的直接理由 |
extra 为结构化对象;空值 / 脏值回 null 不报错 |
✅ |
团期不存在 → code=200, data=[](对照:团期详情同 id 抛 589500) |
✅ |
CUSTOMIZER 角色 → 589507,与 chips/contract 逐角色一致 |
✅ |
十、相关文档
- 实施单编号:GB-ADM-096(新增)
- 前序 #7283:本端点是它「同步失败只记时间线让运营看见」那条兜底的读回出口,解开其 AC-9 的阻塞