文件
hl-api-changelog/changelogs-v2/2026-09/09_7304_团期时间线只读端点status-logs-新增接口-管理后台.md
T
2026-09-09 13:55:49 +08:00

9.6 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 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,与团期看板、芯片逐户明细一致。

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

  1. 中文名一律用后端返回的字段渲染,不要在前端自建 code→中文 映射表。 团期事件类型会持续新增(#7283 刚加过 BATCH_PRODUCT_CANCEL_FAILED),后端给名字前端就零改动;自建映射表会漏。
  2. 按 changeType 分叉渲染:STATUS 画 fromStatusName → toStatusName 箭头;DATA 的 fromStatus === toStatus,只渲染 content。
  3. operatorType 可能是 SYSTEM / MQ(AFTER_COMMIT 或异步链路写入),此时 operatorId 为 null,operatorName 是「系统」之类的固定文案,照常渲染即可,别按「一定有操作人」写死。
  4. extra 是对象或 null,不是字符串,不要再 JSON.parse。不同事件的 extra 结构不同,按需取键、缺键要兜住。
  5. 雪花 ID 一律按字符串处理(logId / groupBatchId / operatorId 都以字符串下发)。
  6. 名字字段可能为 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 的阻塞

关联 / 联系人