Files
wenzi/docs/api.md

21 KiB
Raw Permalink Blame History

API 文档

本文档详细说明了活动管理和API密钥管理相关的API端点。

统一响应封装

除图片/HTML/CSV等非 JSON 响应外,所有接口返回 ApiResponse

  • 成功响应:

    {
      "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"
    }
    
  • 错误响应:

    {
      "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

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

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

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

    {
      "name": "春季特惠活动",
      "startTime": "2025-03-01T10:00:00+08:00",
      "endTime": "2025-03-31T23:59:59+08:00"
    }
    
  • 成功响应 (201 Created):

    {
      "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

    {
      "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

    {
      "activityId": 1,
      "name": "我的第一个密钥"
    }
    
  • 成功响应 (201 Created):

    {
      "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: 如果请求数据无效(例如,activityIdname 为空)。
    • 404 Not Found: 如果 activityId 不存在。

2.2 吊销API密钥

  • Endpoint: DELETE /api/v1/api-keys/{id}
  • 描述: 吊销删除一个API密钥。
  • 路径参数: id (long) - API密钥的唯一标识符。
  • 成功响应 (200 OK): ApiResponse<Void>datanull
  • 失败响应:
    • 404 Not Found: 如果指定的 id 不存在。

2.3 使用/校验 API 密钥

  • Endpoint: POST /api/v1/api-keys/{id}/use

  • 描述: 校验提供的明文 API 密钥是否与 id 对应的密钥匹配;校验成功将更新 last_used_at

  • 请求体: application/json

    {
      "apiKey": "a1b2c3d4-e5f6-7890-1234-567890abcdef"
    }
    
  • 成功响应 (200 OK): ApiResponse<Void>datanull

  • 失败响应:

    • 401 Unauthorized + INVALID_API_KEY:密钥错误或已吊销。
    • 404 Not Foundid 不存在。

2.4 通过前缀校验 API 密钥(无需 ID

  • Endpoint: POST /api/v1/api-keys/validate

  • 描述: 仅凭明文 API 密钥进行校验(服务端使用前缀快速定位候选密钥,再进行哈希校验)。校验成功将更新 last_used_at

  • 请求体: application/json

    {
      "apiKey": "a1b2c3d4-e5f6-7890-1234-567890abcdef"
    }
    
  • 成功响应 (200 OK): ApiResponse<Void>datanull

  • 失败响应:

    • 401 Unauthorized + INVALID_API_KEY:密钥错误或已吊销。

3. 缓存管理 (Cache)

3.1 清空某类缓存

  • Endpoint: DELETE /api/v1/cache/{cacheName}
  • 描述: 清空指定缓存空间(如 leaderboardsactivitiesactivity_statsactivity_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):

    {
      "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-8Content-Disposition: attachment; filename="leaderboard_{id}.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):

    {
      "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):

    {
      "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.1 生成短链接(内部)

  • Endpoint: POST /api/v1/internal/shorten

  • 描述: 生成短链接记录,仅供内部服务或管理端调用。

  • 请求体:

    { "originalUrl": "https://example.com/landing?ref=abc" }
    
  • 成功响应 (201 Created):

    {
      "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):

    {
      "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):

    {
      "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
  • HTMLGET /api/v1/me/poster/html
  • 配置:GET /api/v1/me/poster/config
  • Query: activityId, userId, templatetemplate 可选)
  • 描述:图片/HTML 端点返回二进制或 HTML配置端点返回 ApiResponse<PosterConfigDto>data 包含 templateimageUrlhtmlUrl

7. 分享跟踪 (Share Tracking)

7.1 创建分享跟踪

  • Endpoint: POST /api/v1/share/track

  • 描述: 创建分享跟踪记录,用于追踪用户分享行为

  • 请求体: application/json

    {
      "activityId": 1,
      "inviterUserId": 123,
      "source": "wechat",
      "utm": "campaign-spring"
    }
    
  • 成功响应 (200 OK):

    {
      "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):

    {
      "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):

    {
      "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):

    {
      "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):

    {
      "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

    {
      "activityId": 1,
      "userId": 123,
      "channel": "wechat",
      "params": "utm_source=campaign1"
    }
    
  • 成功响应 (200 OK):

    {
      "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

    {
      "trackingId": "活动创建的追踪ID",
      "externalUserId": "外部用户ID可选",
      "timestamp": 1699999999999,
      "deviceFingerprint": "设备指纹(可选)",
      "ip": "客户端IP可选"
    }
    

    或使用下划线格式:

    {
      "tracking_id": "活动创建的追踪ID",
      "external_user_id": "外部用户ID可选",
      "timestamp": 1699999999999,
      "device_fingerprint": "设备指纹(可选)",
      "ip": "客户端IP可选"
    }
    
  • 成功响应 (200 OK):

    {
      "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):

    {
      "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):

    {
      "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 错误处理

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 分页处理

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 速率限制处理

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 维护者: 技术团队