816 lines
21 KiB
Markdown
816 lines
21 KiB
Markdown
# API 文档
|
||
|
||
本文档详细说明了活动管理和API密钥管理相关的API端点。
|
||
|
||
## 统一响应封装
|
||
|
||
除图片/HTML/CSV等非 JSON 响应外,所有接口返回 `ApiResponse`:
|
||
|
||
- 成功响应:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "success",
|
||
"data": {},
|
||
"meta": {
|
||
"pagination": {
|
||
"page": 0,
|
||
"size": 20,
|
||
"total": 100,
|
||
"totalPages": 5,
|
||
"hasNext": true,
|
||
"hasPrevious": false
|
||
}
|
||
},
|
||
"timestamp": "2025-09-30T12:34:56",
|
||
"traceId": "trace-id"
|
||
}
|
||
```
|
||
|
||
- 错误响应:
|
||
|
||
```json
|
||
{
|
||
"code": 400,
|
||
"message": "请求参数校验失败",
|
||
"error": {
|
||
"message": "activityId 不能为空",
|
||
"details": { "activityId": "must not be null" },
|
||
"code": "VALIDATION_ERROR"
|
||
},
|
||
"timestamp": "2025-09-30T12:34:56",
|
||
"traceId": "trace-id"
|
||
}
|
||
```
|
||
|
||
## 认证与鉴权
|
||
|
||
### 认证矩阵
|
||
|
||
| 路径模式 | 认证方式 | 说明 |
|
||
|----------|----------|------|
|
||
| `/r/**` | 无需认证 | 短链接跳转 |
|
||
| `/actuator/**` | 无需认证 | Spring Boot Actuator |
|
||
| `/api/v1/callback/**` | X-API-Key | 第三方回调接口 |
|
||
| `/api/v1/share/**` | X-API-Key + Bearer Token | 分享跟踪接口 |
|
||
| `/api/v1/me/**` | Bearer Token | 用户中心接口 |
|
||
| `/api/v1/activities/**` | Bearer Token | 用户端活动接口 |
|
||
| `/api/v1/activities/admin/**` | Bearer Token + 权限校验 | 管理后台活动接口 |
|
||
| `/api/v1/rewards/admin/**` | Bearer Token + 权限校验 | 管理后台奖励接口 |
|
||
| `/api/v1/roles/**` | Bearer Token + 权限校验 | 角色管理接口 |
|
||
| `/api/v1/departments/**` | Bearer Token + 权限校验 | 部门管理接口 |
|
||
| `/api/v1/approval/**` | Bearer Token + 权限校验 | 审批中心接口 |
|
||
| `/api/v1/users/**` | Bearer Token + 权限校验 | 用户管理接口 |
|
||
| `/api/v1/permissions/**` | Bearer Token + 权限校验 | 权限管理接口 |
|
||
| `/api/v1/invites/**` | Bearer Token + 权限校验 | 邀请管理接口 |
|
||
| `/api/v1/notifications/**` | Bearer Token + 权限校验 | 通知管理接口 |
|
||
| `/api/v1/risk/**` | Bearer Token + 权限校验 | 风险管理接口 |
|
||
| `/api/v1/audit/**` | Bearer Token + 权限校验 | 审计日志接口 |
|
||
| `/api/v1/system/**` | Bearer Token + 权限校验 | 系统管理接口 |
|
||
| `/api/v1/dashboard/**` | Bearer Token + 权限校验 | 仪表盘接口 |
|
||
| `/api/v1/api-keys/**` | Bearer Token + 权限校验 | API密钥管理接口 |
|
||
|
||
### 认证示例
|
||
|
||
**回调接口(仅需API Key):**
|
||
```http
|
||
POST /api/v1/callback/register
|
||
X-API-Key: a1b2c3d4-e5f6-7890-1234-567890abcdef
|
||
Content-Type: application/json
|
||
|
||
{"trackingId": "track-abc123", "externalUserId": "user456", "timestamp": 1699999999999}
|
||
```
|
||
|
||
**分享跟踪接口(需要API Key + Bearer Token):**
|
||
```http
|
||
POST /api/v1/share/track
|
||
X-API-Key: a1b2c3d4-e5f6-7890-1234-567890abcdef
|
||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||
Content-Type: application/json
|
||
|
||
{"activityId": 1, "inviterUserId": "user123", "source": "wechat"}
|
||
```
|
||
|
||
**管理后台接口(仅需Bearer Token):**
|
||
```http
|
||
GET /api/v1/activities/admin?page=0&size=20
|
||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||
```
|
||
|
||
## 错误码
|
||
|
||
- `VALIDATION_ERROR` → 400:请求参数校验失败(字段缺失/格式不符)。
|
||
- `BAD_REQUEST` → 400:业务数据不合法(如结束时间早于开始时间、上传文件不支持)。
|
||
- `FORBIDDEN` → 403:无权访问资源或操作。
|
||
- `NOT_FOUND` → 404:资源不存在(活动、API密钥等)。
|
||
- `INTERNAL_ERROR` → 500:服务器内部错误。
|
||
- `INVALID_API_KEY` → 401:提供的 API 密钥无效或已吊销。
|
||
|
||
## 1. 活动管理 (Activities)
|
||
|
||
### 1.1 创建活动
|
||
|
||
- **Endpoint**: `POST /api/v1/activities`
|
||
- **描述**: 创建一个新的营销活动。
|
||
- **请求体**: `application/json`
|
||
|
||
```json
|
||
{
|
||
"name": "春季特惠活动",
|
||
"startTime": "2025-03-01T10:00:00+08:00",
|
||
"endTime": "2025-03-31T23:59:59+08:00"
|
||
}
|
||
```
|
||
|
||
- **成功响应 (201 Created)**:
|
||
|
||
```json
|
||
{
|
||
"code": 201,
|
||
"message": "success",
|
||
"data": {
|
||
"id": 1,
|
||
"name": "春季特惠活动",
|
||
"startTime": "2025-03-01T10:00:00+08:00",
|
||
"endTime": "2025-03-31T23:59:59+08:00"
|
||
},
|
||
"timestamp": "2025-03-01T10:00:00"
|
||
}
|
||
```
|
||
|
||
- **失败响应**:
|
||
- `400 Bad Request`: 如果请求数据无效(例如,名称为空或结束时间早于开始时间)。
|
||
|
||
### 1.2 更新活动
|
||
|
||
- **Endpoint**: `PUT /api/v1/activities/{id}`
|
||
- **描述**: 更新一个已存在的活动。
|
||
- **路径参数**: `id` (long) - 活动的唯一标识符。
|
||
- **请求体**: `application/json`
|
||
|
||
```json
|
||
{
|
||
"name": "春季特惠活动(升级版)",
|
||
"startTime": "2025-03-01T10:00:00+08:00",
|
||
"endTime": "2025-04-15T23:59:59+08:00"
|
||
}
|
||
```
|
||
|
||
- **成功响应 (200 OK)**: `ApiResponse<Activity>`,`data` 为更新后的活动对象。
|
||
- **失败响应**:
|
||
- `400 Bad Request`: 如果请求数据无效。
|
||
- `404 Not Found`: 如果指定的 `id` 不存在。
|
||
|
||
### 1.3 获取活动详情
|
||
|
||
- **Endpoint**: `GET /api/v1/activities/{id}`
|
||
- **描述**: 获取指定ID的活动详情。
|
||
- **路径参数**: `id` (long) - 活动的唯一标识符。
|
||
- **成功响应 (200 OK)**: `ApiResponse<Activity>`,`data` 为活动对象。
|
||
- **失败响应**:
|
||
- `404 Not Found`: 如果指定的 `id` 不存在。
|
||
|
||
## 2. API密钥管理 (API Keys)
|
||
|
||
### 2.1 创建API密钥
|
||
|
||
- **Endpoint**: `POST /api/v1/api-keys`
|
||
- **描述**: 为指定的活动创建一个新的API密钥。该操作需要审批,密钥创建后会进入审批流程。返回 `pendingId` 用于查询审批状态,`recordId` 用于追踪审批记录。
|
||
- **请求体**: `application/json`
|
||
|
||
```json
|
||
{
|
||
"activityId": 1,
|
||
"name": "我的第一个密钥"
|
||
}
|
||
```
|
||
|
||
- **成功响应 (201 Created)**:
|
||
|
||
```json
|
||
{
|
||
"code": 201,
|
||
"message": "success",
|
||
"data": {
|
||
"pendingId": 123,
|
||
"recordId": 456,
|
||
"status": "PENDING",
|
||
"activityId": 1,
|
||
"name": "我的第一个密钥"
|
||
},
|
||
"timestamp": "2025-03-01T10:00:00"
|
||
}
|
||
```
|
||
|
||
- **响应字段说明**:
|
||
- `pendingId`: 待审批的API密钥ID
|
||
- `recordId`: 审批记录ID,可用于查询审批进度
|
||
- `status`: 审批状态 (`PENDING` = 待审批, `APPROVED` = 已通过, `REJECTED` = 已拒绝)
|
||
|
||
- **失败响应**:
|
||
- `400 Bad Request`: 如果请求数据无效(例如,`activityId` 或 `name` 为空)。
|
||
- `404 Not Found`: 如果 `activityId` 不存在。
|
||
|
||
### 2.2 吊销API密钥
|
||
|
||
- **Endpoint**: `DELETE /api/v1/api-keys/{id}`
|
||
- **描述**: 吊销(删除)一个API密钥。
|
||
- **路径参数**: `id` (long) - API密钥的唯一标识符。
|
||
- **成功响应 (200 OK)**: `ApiResponse<Void>`,`data` 为 `null`。
|
||
- **失败响应**:
|
||
- `404 Not Found`: 如果指定的 `id` 不存在。
|
||
|
||
### 2.3 使用/校验 API 密钥
|
||
|
||
- Endpoint: `POST /api/v1/api-keys/{id}/use`
|
||
- 描述: 校验提供的明文 API 密钥是否与 `id` 对应的密钥匹配;校验成功将更新 `last_used_at`。
|
||
- 请求体: `application/json`
|
||
|
||
```json
|
||
{
|
||
"apiKey": "a1b2c3d4-e5f6-7890-1234-567890abcdef"
|
||
}
|
||
```
|
||
|
||
- 成功响应 (200 OK): `ApiResponse<Void>`,`data` 为 `null`。
|
||
- 失败响应:
|
||
- `401 Unauthorized` + `INVALID_API_KEY`:密钥错误或已吊销。
|
||
- `404 Not Found`:`id` 不存在。
|
||
|
||
### 2.4 通过前缀校验 API 密钥(无需 ID)
|
||
|
||
- Endpoint: `POST /api/v1/api-keys/validate`
|
||
- 描述: 仅凭明文 API 密钥进行校验(服务端使用前缀快速定位候选密钥,再进行哈希校验)。校验成功将更新 `last_used_at`。
|
||
- 请求体: `application/json`
|
||
|
||
```json
|
||
{
|
||
"apiKey": "a1b2c3d4-e5f6-7890-1234-567890abcdef"
|
||
}
|
||
```
|
||
|
||
- 成功响应 (200 OK): `ApiResponse<Void>`,`data` 为 `null`。
|
||
- 失败响应:
|
||
- `401 Unauthorized` + `INVALID_API_KEY`:密钥错误或已吊销。
|
||
|
||
## 3. 缓存管理 (Cache)
|
||
|
||
### 3.1 清空某类缓存
|
||
|
||
- Endpoint: `DELETE /api/v1/cache/{cacheName}`
|
||
- 描述: 清空指定缓存空间(如 `leaderboards`、`activities`、`activity_stats`、`activity_graph`)。
|
||
- 成功响应 (204 No Content)
|
||
|
||
### 3.2 失效某个缓存键
|
||
|
||
- Endpoint: `DELETE /api/v1/cache/{cacheName}/{key}`
|
||
- 描述: 失效指定缓存空间下的某个键。
|
||
- 成功响应 (204 No Content)
|
||
|
||
## 4. 数据分析 (Analytics)
|
||
|
||
### 4.1 获取排行榜
|
||
|
||
- Endpoint: `GET /api/v1/activities/{id}/leaderboard`
|
||
- 描述: 返回指定活动的排行榜(已启用缓存 `leaderboards`)。支持分页与 TopN。
|
||
- 查询参数:
|
||
- `topN` 可选:只取前 N 名(先截断再分页)。
|
||
- `page` 可选,默认 `0`:页码(从 0 开始)。
|
||
- `size` 可选,默认 `20`:每页条数。
|
||
- 成功响应 (200 OK):
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "success",
|
||
"data": [
|
||
{ "userId": 1, "userName": "用户A", "score": 1500 },
|
||
{ "userId": 2, "userName": "用户B", "score": 1200 }
|
||
],
|
||
"meta": {
|
||
"pagination": {
|
||
"page": 0,
|
||
"size": 20,
|
||
"total": 2,
|
||
"totalPages": 1,
|
||
"hasNext": false,
|
||
"hasPrevious": false
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 4.2 导出排行榜CSV
|
||
|
||
- Endpoint: `GET /api/v1/activities/{id}/leaderboard/export`
|
||
- 描述: 导出排行榜为CSV文件并下载。支持 `topN` 仅导出前 N 名。
|
||
- 成功响应 (200 OK): 响应头 `Content-Type: text/csv;charset=UTF-8`,`Content-Disposition: attachment; filename="leaderboard_{id}.csv"`
|
||
- CSV示例:
|
||
|
||
```csv
|
||
userId,userName,score
|
||
1,用户A,1500
|
||
2,用户B,1200
|
||
```
|
||
|
||
### 4.3 获取裂变网络图
|
||
|
||
- Endpoint: `GET /api/v1/activities/{id}/graph`
|
||
- 描述: 返回指定活动的裂变网络图。支持以某个用户为根、限定层级与结果规模。
|
||
- 查询参数:
|
||
- `rootUserId` 可选:作为根节点的用户ID;为空则返回全量图(受 `limit` 限制)。
|
||
- `maxDepth` 可选,默认 `3`:最大层级深度(从根出发,`1` 表示仅直推)。
|
||
- `limit` 可选,默认 `1000`:返回的最大边数(超出将截断)。
|
||
- 成功响应 (200 OK):
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "success",
|
||
"data": {
|
||
"nodes": [ { "id": "1", "label": "用户1" } ],
|
||
"edges": [ { "from": "1", "to": "2" } ]
|
||
}
|
||
}
|
||
```
|
||
|
||
### 4.4 获取仪表盘统计
|
||
|
||
- Endpoint: `GET /api/v1/activities/{id}/stats`
|
||
- 描述: 汇总 `daily_activity_stats` 表的数据(已启用缓存 `activity_stats`)。`participants` 对应每日新增注册数聚合。
|
||
- 成功响应 (200 OK):
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "success",
|
||
"data": {
|
||
"totalParticipants": 220,
|
||
"totalShares": 110,
|
||
"dailyStats": [
|
||
{ "date": "2025-09-28", "participants": 100, "shares": 50 },
|
||
{ "date": "2025-09-29", "participants": 120, "shares": 60 }
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
## 5. 短链接 (Short Links)
|
||
|
||
### 5.1 生成短链接(内部)
|
||
|
||
- Endpoint: `POST /api/v1/internal/shorten`
|
||
- 描述: 生成短链接记录,仅供内部服务或管理端调用。
|
||
- 请求体:
|
||
|
||
```json
|
||
{ "originalUrl": "https://example.com/landing?ref=abc" }
|
||
```
|
||
|
||
- 成功响应 (201 Created):
|
||
|
||
```json
|
||
{
|
||
"code": 201,
|
||
"message": "success",
|
||
"data": { "code": "abc12345", "path": "/r/abc12345", "originalUrl": "https://example.com/landing?ref=abc" }
|
||
}
|
||
```
|
||
|
||
### 5.2 短链接重定向(公开)
|
||
|
||
- Endpoint: `GET /r/{code}`
|
||
- 描述: 302 跳转到短链对应的原始地址。
|
||
- 成功响应 (302 Found): 响应头 `Location: <originalUrl>`
|
||
|
||
## 6. 用户端体验 (User Experience)
|
||
|
||
### 6.1 获取用户专属邀请信息
|
||
|
||
- Endpoint: `GET /api/v1/me/invitation-info`
|
||
- 描述: 返回当前用户的专属短链接(示例以 query 参数的 `activityId`/`userId` 代替鉴权)。
|
||
- Query: `activityId`, `userId`
|
||
- 成功响应 (200 OK):
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "success",
|
||
"data": { "code": "inv12345", "path": "/r/inv12345", "originalUrl": "https://example.com/landing?activityId=1&inviter=2" }
|
||
}
|
||
```
|
||
|
||
### 6.2 获取邀请好友列表(分页)
|
||
|
||
- Endpoint: `GET /api/v1/me/invited-friends`
|
||
- Query: `activityId`, `userId`, `page`(默认0), `size`(默认20)
|
||
- 成功响应 (200 OK):
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "success",
|
||
"data": [ { "nickname": "用户10", "maskedPhone": "138****0010", "status": "registered" } ],
|
||
"meta": {
|
||
"pagination": {
|
||
"page": 0,
|
||
"size": 20,
|
||
"total": 1,
|
||
"totalPages": 1,
|
||
"hasNext": false,
|
||
"hasPrevious": false
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 6.3 生成海报
|
||
|
||
- 图片:`GET /api/v1/me/poster/image`
|
||
- HTML:`GET /api/v1/me/poster/html`
|
||
- 配置:`GET /api/v1/me/poster/config`
|
||
- Query: `activityId`, `userId`, `template`(`template` 可选)
|
||
- 描述:图片/HTML 端点返回二进制或 HTML;配置端点返回 `ApiResponse<PosterConfigDto>`,`data` 包含 `template`、`imageUrl`、`htmlUrl`。
|
||
|
||
## 7. 分享跟踪 (Share Tracking)
|
||
|
||
### 7.1 创建分享跟踪
|
||
|
||
- **Endpoint**: `POST /api/v1/share/track`
|
||
- **描述**: 创建分享跟踪记录,用于追踪用户分享行为
|
||
- **请求体**: `application/json`
|
||
|
||
```json
|
||
{
|
||
"activityId": 1,
|
||
"inviterUserId": 123,
|
||
"source": "wechat",
|
||
"utm": "campaign-spring"
|
||
}
|
||
```
|
||
|
||
- **成功响应 (200 OK)**:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "success",
|
||
"data": {
|
||
"trackingId": "track-abc123",
|
||
"shortCode": "xyz789",
|
||
"shareUrl": "https://example.com/r/xyz789",
|
||
"activityId": 1,
|
||
"inviterUserId": 123
|
||
}
|
||
}
|
||
```
|
||
|
||
### 7.2 获取分享指标
|
||
|
||
- **Endpoint**: `GET /api/v1/share/metrics`
|
||
- **描述**: 获取指定活动的分享统计指标
|
||
- **查询参数**:
|
||
- `activityId` (必需): 活动ID
|
||
- `startTime` (可选): 开始时间 (ISO 8601格式)
|
||
- `endTime` (可选): 结束时间 (ISO 8601格式)
|
||
|
||
- **成功响应 (200 OK)**:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "success",
|
||
"data": {
|
||
"activityId": 1,
|
||
"totalClicks": 1500,
|
||
"uniqueVisitors": 800,
|
||
"sourceDistribution": {
|
||
"wechat": 600,
|
||
"weibo": 400,
|
||
"direct": 200
|
||
},
|
||
"hourlyDistribution": {
|
||
"0": 50,
|
||
"1": 30,
|
||
"2": 20
|
||
},
|
||
"startTime": "2025-03-01T00:00:00Z",
|
||
"endTime": "2025-03-31T23:59:59Z"
|
||
}
|
||
}
|
||
```
|
||
|
||
### 7.3 获取顶级分享链接
|
||
|
||
- **Endpoint**: `GET /api/v1/share/top-links`
|
||
- **描述**: 获取分享次数最多的链接列表
|
||
- **查询参数**:
|
||
- `activityId` (必需): 活动ID
|
||
- `limit` (可选,默认10): 返回数量
|
||
|
||
- **成功响应 (200 OK)**:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "success",
|
||
"data": [
|
||
{
|
||
"shortCode": "abc123",
|
||
"clickCount": 500,
|
||
"inviterUserId": 123
|
||
},
|
||
{
|
||
"shortCode": "def456",
|
||
"clickCount": 300,
|
||
"inviterUserId": 456
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
### 7.4 获取转化漏斗
|
||
|
||
- **Endpoint**: `GET /api/v1/share/funnel`
|
||
- **描述**: 获取分享转化漏斗数据
|
||
- **查询参数**:
|
||
- `activityId` (必需): 活动ID
|
||
- `startTime` (可选): 开始时间
|
||
- `endTime` (可选): 结束时间
|
||
|
||
- **成功响应 (200 OK)**:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "success",
|
||
"data": {
|
||
"totalClicks": 1000,
|
||
"withReferer": 800,
|
||
"withUserAgent": 950,
|
||
"refererRate": 0.8,
|
||
"topReferers": {
|
||
"google.com": 300,
|
||
"facebook.com": 200,
|
||
"twitter.com": 150
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 7.5 获取分享元数据
|
||
|
||
- **Endpoint**: `GET /api/v1/share/share-meta`
|
||
- **描述**: 获取分享相关的元数据配置
|
||
- **查询参数**:
|
||
- `activityId` (必需): 活动ID
|
||
- `userId` (必需): 用户ID
|
||
- `template` (可选,默认"default"): 模板名称
|
||
|
||
- **成功响应 (200 OK)**:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "success",
|
||
"data": {
|
||
"title": "春季特惠活动",
|
||
"description": "邀请好友,赢取大奖",
|
||
"imageUrl": "https://example.com/poster.png",
|
||
"shareUrl": "https://example.com/r/abc123"
|
||
}
|
||
}
|
||
```
|
||
|
||
### 7.6 注册分享来源
|
||
|
||
- **Endpoint**: `POST /api/v1/share/register-source`
|
||
- **描述**: 注册用户的分享来源渠道
|
||
- **请求体**: `application/json`
|
||
|
||
```json
|
||
{
|
||
"activityId": 1,
|
||
"userId": 123,
|
||
"channel": "wechat",
|
||
"params": "utm_source=campaign1"
|
||
}
|
||
```
|
||
|
||
- **成功响应 (200 OK)**:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "success",
|
||
"data": {
|
||
"trackingId": "track-xyz",
|
||
"shortCode": "abc789",
|
||
"shareUrl": "https://example.com/r/abc789",
|
||
"activityId": 1,
|
||
"inviterUserId": 123
|
||
}
|
||
}
|
||
```
|
||
|
||
## 8. 回调管理 (Callbacks)
|
||
|
||
### 8.1 用户追踪注册
|
||
|
||
- **Endpoint**: `POST /api/v1/callback/register`
|
||
- **描述**: 用户参与活动时进行追踪注册上报,用于记录用户来源和设备信息
|
||
- **请求体**: `application/json`
|
||
|
||
```json
|
||
{
|
||
"trackingId": "活动创建的追踪ID",
|
||
"externalUserId": "外部用户ID(可选)",
|
||
"timestamp": 1699999999999,
|
||
"deviceFingerprint": "设备指纹(可选)",
|
||
"ip": "客户端IP(可选)"
|
||
}
|
||
```
|
||
|
||
或使用下划线格式:
|
||
|
||
```json
|
||
{
|
||
"tracking_id": "活动创建的追踪ID",
|
||
"external_user_id": "外部用户ID(可选)",
|
||
"timestamp": 1699999999999,
|
||
"device_fingerprint": "设备指纹(可选)",
|
||
"ip": "客户端IP(可选)"
|
||
}
|
||
```
|
||
|
||
- **成功响应 (200 OK)**:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "success",
|
||
"data": {
|
||
"registered": true,
|
||
"trackingId": "活动创建的追踪ID",
|
||
"activityId": 1,
|
||
"rewardStatus": "pending"
|
||
}
|
||
}
|
||
```
|
||
|
||
- **字段说明**:
|
||
- `trackingId` / `tracking_id`: 活动创建的追踪ID(必填)
|
||
- `externalUserId` / `external_user_id`: 外部系统用户ID(可选)
|
||
- `timestamp`: 时间戳(可选)
|
||
- `deviceFingerprint` / `device_fingerprint`: 设备指纹(可选,用于风控)
|
||
- `ip`: 客户端IP地址(可选,用于风控)
|
||
|
||
## 9. 用户奖励 (User Rewards)
|
||
|
||
### 9.1 获取用户奖励列表
|
||
|
||
- **Endpoint**: `GET /api/v1/me/rewards`
|
||
- **描述**: 获取当前用户的奖励记录(分页)
|
||
- **查询参数**:
|
||
- `activityId` (必需): 活动ID
|
||
- `userId` (必需): 用户ID
|
||
- `page` (可选,默认0): 页码
|
||
- `size` (可选,默认20): 每页数量
|
||
|
||
- **成功响应 (200 OK)**:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "success",
|
||
"data": [
|
||
{
|
||
"type": "invite_reward",
|
||
"points": 100,
|
||
"createdAt": "2025-03-01T10:00:00Z"
|
||
},
|
||
{
|
||
"type": "share_reward",
|
||
"points": 50,
|
||
"createdAt": "2025-03-02T15:30:00Z"
|
||
}
|
||
],
|
||
"meta": {
|
||
"pagination": {
|
||
"page": 0,
|
||
"size": 20,
|
||
"total": 2,
|
||
"totalPages": 1,
|
||
"hasNext": false,
|
||
"hasPrevious": false
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
## 10. 速率限制
|
||
|
||
所有API端点都受到速率限制保护:
|
||
|
||
- **默认限制**: 每分钟100次请求(基于API Key)
|
||
- **超出限制响应 (429 Too Many Requests)**:
|
||
|
||
```json
|
||
{
|
||
"code": 429,
|
||
"message": "Rate limit exceeded",
|
||
"error": {
|
||
"message": "Too many requests, please try again later",
|
||
"code": "RATE_LIMIT_EXCEEDED"
|
||
}
|
||
}
|
||
```
|
||
|
||
- **响应头**:
|
||
- `X-RateLimit-Limit`: 速率限制值
|
||
- `X-RateLimit-Remaining`: 剩余请求次数
|
||
- `Retry-After`: 重试等待秒数
|
||
|
||
## 11. API版本控制
|
||
|
||
- **当前版本**: v1
|
||
- **版本指定**: 通过URL路径 `/api/v1/...`
|
||
- **版本协商**: 可通过 `X-API-Version` 请求头指定版本(可选)
|
||
- **响应头**: `X-API-Version` 返回实际使用的API版本
|
||
|
||
## 12. 最佳实践
|
||
|
||
### 12.1 错误处理
|
||
|
||
```javascript
|
||
try {
|
||
const response = await fetch('/api/v1/activities/1', {
|
||
headers: {
|
||
'X-API-Key': 'your-api-key',
|
||
'Authorization': 'Bearer your-token'
|
||
}
|
||
});
|
||
|
||
const result = await response.json();
|
||
|
||
if (result.code !== 200) {
|
||
console.error('API Error:', result.error);
|
||
// 处理业务错误
|
||
}
|
||
} catch (error) {
|
||
console.error('Network Error:', error);
|
||
// 处理网络错误
|
||
}
|
||
```
|
||
|
||
### 12.2 分页处理
|
||
|
||
```javascript
|
||
async function fetchAllPages(activityId) {
|
||
let page = 0;
|
||
let allData = [];
|
||
let hasNext = true;
|
||
|
||
while (hasNext) {
|
||
const response = await fetch(
|
||
`/api/v1/activities/${activityId}/leaderboard?page=${page}&size=100`,
|
||
{ headers: { 'X-API-Key': 'your-key' } }
|
||
);
|
||
const result = await response.json();
|
||
|
||
allData = allData.concat(result.data);
|
||
hasNext = result.meta.pagination.hasNext;
|
||
page++;
|
||
}
|
||
|
||
return allData;
|
||
}
|
||
```
|
||
|
||
### 12.3 速率限制处理
|
||
|
||
```javascript
|
||
async function apiCallWithRetry(url, options, maxRetries = 3) {
|
||
for (let i = 0; i < maxRetries; i++) {
|
||
const response = await fetch(url, options);
|
||
|
||
if (response.status === 429) {
|
||
const retryAfter = response.headers.get('Retry-After') || 60;
|
||
await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
|
||
continue;
|
||
}
|
||
|
||
return response;
|
||
}
|
||
|
||
throw new Error('Max retries exceeded');
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
**文档版本**: 2.0
|
||
**最后更新**: 2026-03-04
|
||
**维护者**: 技术团队
|