Files
cn-rdms-web/10-产品动态时间线_前端API文档.md
hongawen 5b9c7e781b docs(api): 添加产品动态时间线前端API文档
- 新增产品动态时间线接口文档,明确前端调用规范
- 定义接口请求参数、响应结构和字段语义说明
- 提供请求示例和错误码说明
- 添加左侧筛选项映射规则和时间格式说明

feat(product): 实现产品首页动态时间线功能

- 重构产品首页布局结构,采用档案横幅型设计
- 新增对象基础概述横幅模块
- 实现产品动态时间线面板组件
- 集成需求池管理概览和最近变化区域
- 添加扩展信息区预留模块位

chore(docs): 更新代理工作说明和前端测试策略

- 添加前端任务测试策略说明
- 更新代理工作流程规范
- 明确git操作执行边界
- 优化组件类型声明更新
2026-04-24 16:38:43 +08:00

368 lines
9.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 10-产品动态时间线 前端 API 文档
## 0. 文档定位
本文档是给前端产品首页“产品动态展示区域”单独使用的接口文档。
目标:
- 明确前端当前应该调用哪个接口
- 明确左侧筛选项如何映射到后端参数
- 明确接口返回字段、时间格式、边界规则
- 避免继续混用设置页最近动态和首页正式时间线
说明:
- 设置页原最近动态接口 `GET /project/product/{id}/activities` 继续保留
- 产品首页正式动态时间线请统一使用本文档中的新接口
- 当前首页动态时间线不包含需求池变动,需求池由独立区域承载
---
## 1. 接口概览
### 1.1 接口信息
- 接口名称:获取产品动态时间线分页
- 请求方法:`GET`
- 请求路径:`/project/product/{id}/activities/page`
- 权限码:`project:product:query`
- 适用页面:产品首页动态时间线区域
### 1.2 接口用途
该接口用于返回产品首页动态展示区域的正式时间线数据,支持:
- 默认最近 30 天
- 左侧类型筛选
- 动作多选筛选
- 分页查询
- 创建初始化噪音去除
### 1.3 当前纳入首页时间线的事件范围
当前只包含以下 5 类:
- 产品创建
- 产品状态变更
- 产品经理变更
- 成员加入
- 成员移出
当前明确不包含:
- 需求池变动
- `update_member`
- 普通产品主数据编辑 `update`
- 删除产品动态
---
## 2. 请求定义
### 2.1 路径参数
| 参数名 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `id` | `integer(int64)` | 是 | 产品 ID |
### 2.2 查询参数
| 参数名 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `pageNo` | `integer` | 是 | 页码,从 `1` 开始 |
| `pageSize` | `integer` | 是 | 每页条数 |
| `activityType` | `string` | 否 | 分类,可选 `status` / `product` / `member` |
| `actionTypes` | `array<string>` | 否 | 动作编码数组,支持多选 |
| `startTime` | `string` | 否 | 开始时间,格式 `yyyy-MM-dd HH:mm:ss` |
| `endTime` | `string` | 否 | 结束时间,格式 `yyyy-MM-dd HH:mm:ss` |
### 2.3 参数规则
#### 2.3.1 时间参数规则
- `startTime``endTime` 必须同时传,或者同时不传
- 都不传时,后端默认查询最近 `30`
- 只传一个时,后端返回参数错误
- `startTime > endTime` 时,后端返回参数错误
#### 2.3.2 筛选参数规则
- `activityType` 是分类筛选
- `actionTypes` 是动作细筛选
- 两者同时传时,按交集处理
- 如果前端未来需要做跨类型多选,可以不传 `activityType`,只传 `actionTypes`
#### 2.3.3 `actionTypes` 传参方式
GET 场景请按重复参数方式传递,例如:
```text
/project/product/1024/activities/page?pageNo=1&pageSize=10&activityType=status&actionTypes=pause&actionTypes=resume&actionTypes=archive&actionTypes=abandon
```
---
## 3. 左侧筛选映射
首页左侧当前 5 个筛选项,前端请按下表映射到请求参数:
| 前端筛选项 | `activityType` | `actionTypes` |
| --- | --- | --- |
| 产品创建 | `product` | `create` |
| 产品状态变更 | `status` | `pause` / `resume` / `archive` / `abandon` |
| 产品经理变更 | `product` | `change_manager` |
| 成员加入 | `member` | `add_member` |
| 成员移出 | `member` | `remove_member` |
补充说明:
- 首页时间线当前不展示需求池变动
- 需求池的展示由独立模块负责,不要通过本接口混查
---
## 4. 响应定义
### 4.1 响应包装
接口统一返回 `CommonResult<PageResult<ProductActivityTimelineRespVO>>`
成功响应结构:
```json
{
"code": 0,
"msg": "",
"data": {
"total": 0,
"list": []
}
}
```
### 4.2 `data` 结构
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `total` | `integer(int64)` | 总条数 |
| `list` | `array<object>` | 当前页数据 |
### 4.3 单条动态结构
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `id` | `string` | 动态唯一标识,格式 `type:sourceId`,例如 `status:11` |
| `type` | `string` | 动态类型,取值 `status` / `product` / `member` |
| `actionType` | `string` | 动作编码 |
| `actionName` | `string` | 动作中文名称 |
| `operatorUserId` | `integer(int64)` | 操作人用户 ID可为 `null` |
| `operatorName` | `string` | 操作人名称,可为空字符串 |
| `occurredAt` | `integer(int64)` | 动态发生时间,毫秒时间戳 |
| `summary` | `string` | 可直接展示的摘要文案 |
| `reason` | `string` | 原因说明,可为 `null` |
| `fromStatus` | `string` | 原状态编码,可为 `null` |
| `toStatus` | `string` | 目标状态编码,可为 `null` |
| `details` | `string` | 补充明细,当前为 JSON 字符串 |
### 4.4 时间格式说明
这个接口当前有两个时间口径:
- 请求里的 `startTime``endTime`:字符串,格式 `yyyy-MM-dd HH:mm:ss`
- 响应里的 `occurredAt`:毫秒时间戳 `number`
前端需要按这个真实口径处理,不要把 `occurredAt` 当成格式化字符串读取。
---
## 5. 字段语义说明
### 5.1 `type` 取值说明
| 取值 | 说明 | 数据来源 |
| --- | --- | --- |
| `status` | 产品状态变更 | `rdms_product_status_log` |
| `product` | 产品对象动态 | `rdms_biz_audit_log``bizType=product` |
| `member` | 产品团队动态 | `rdms_biz_audit_log``bizType=rdms_user_object_role` |
### 5.2 `actionType` 取值范围
当前首页时间线只会出现以下动作:
| `type` | `actionType` | 说明 |
| --- | --- | --- |
| `product` | `create` | 产品创建 |
| `product` | `change_manager` | 产品经理变更 |
| `status` | `pause` | 暂停 |
| `status` | `resume` | 恢复 |
| `status` | `archive` | 归档 |
| `status` | `abandon` | 废弃 |
| `member` | `add_member` | 成员加入 |
| `member` | `remove_member` | 成员移出 |
### 5.3 `details` 当前口径
`details` 当前不做统一结构化建模,按来源原样返回字符串:
- `type=status`
- 返回状态日志补充信息
- 当前包含 `productCodeSnapshot``productNameSnapshot`
- `type=product`
- 返回产品审计 `fieldChanges`
- `type=member`
- 返回成员审计 `fieldChanges`
前端建议:
- 首版先不依赖 `details` 做复杂渲染
- 先以 `actionName + summary + operatorName + occurredAt` 跑通展示
---
## 6. 后端聚合规则
为了让前端看到的是“可直接展示的正式时间线”,后端已固定以下规则:
### 6.1 创建去噪
产品创建时通常会伴随初始化动作:
- 初始化 `change_manager`
- 初始化 `add_member`
这两类初始化动作不会单独出现在首页时间线里,最终只保留一条 `create`
### 6.2 状态日志优先
如果同一状态动作同时存在:
- 产品审计日志
- 状态日志
则首页时间线只取状态日志,不重复展示产品审计里的同类状态动作。
### 6.3 成员调整排除
`update_member` 当前不进入首页正式时间线。
原因:
- 首页当前只需要展示“加入”和“移出”
- 角色调整、备注调整等细节先不进入首页主时间线
---
## 7. 请求示例
### 7.1 默认查询首页动态
```http
GET /project/product/1024/activities/page?pageNo=1&pageSize=6
```
### 7.2 查询“产品状态变更”
```http
GET /project/product/1024/activities/page?pageNo=1&pageSize=10&activityType=status&actionTypes=pause&actionTypes=resume&actionTypes=archive&actionTypes=abandon
```
### 7.3 查询“成员移出”并限制时间范围
```http
GET /project/product/1024/activities/page?pageNo=1&pageSize=10&activityType=member&actionTypes=remove_member&startTime=2026-03-24 00:00:00&endTime=2026-04-23 23:59:59
```
---
## 8. 响应示例
```json
{
"code": 0,
"msg": "",
"data": {
"total": 2,
"list": [
{
"id": "product:22",
"type": "product",
"actionType": "change_manager",
"actionName": "切换产品经理",
"operatorUserId": 10002,
"operatorName": "李四",
"occurredAt": 1776812345000,
"summary": "李四执行了【切换产品经理】",
"reason": null,
"fromStatus": null,
"toStatus": null,
"details": "{\"managerUserId\":{\"before\":10001,\"after\":10002}}"
},
{
"id": "status:11",
"type": "status",
"actionType": "resume",
"actionName": "恢复",
"operatorUserId": 10001,
"operatorName": "张三",
"occurredAt": 1776812984000,
"summary": "张三执行了【恢复】:可以继续开展",
"reason": "可以继续开展",
"fromStatus": "paused",
"toStatus": "active",
"details": "{\"productCodeSnapshot\":\"CNPD2026001\",\"productNameSnapshot\":\"统一交付平台\"}"
}
]
}
}
```
---
## 9. 错误码
| `code` | 说明 |
| --- | --- |
| `0` | 成功 |
| `400` | 请求参数错误,例如只传了一侧时间,或开始时间晚于结束时间 |
| `401` | 未登录 |
| `403` | 没有该产品查询权限 |
| `1008001000` | 产品不存在 |
参数错误示例:
```json
{
"code": 400,
"msg": "开始时间和结束时间必须同时传入",
"data": null
}
```
---
## 10. 前端接入建议
首页动态区域首版建议直接消费以下字段:
- `actionName`
- `summary`
- `operatorName`
- `occurredAt`
左侧筛选建议直接使用:
- `activityType`
- `actionTypes`
当前不建议首版依赖:
- `details` 的深度结构化解析
- 需求池事件混入本接口
- 自行从 `actionType` 反推新的派生事件类型
一句话结论:
- 设置页最近动态继续调 `/activities`
- 产品首页正式动态时间线统一调 `/activities/page`