Files
accounts-manager/docs/API文档.md
cloud370 3162cbfad0 feat: add export functionality for web API with demo script
- Add export API endpoint POST /web/v1/accounts/export
- Support two export modes: text (data strings) and object (full account objects)
- Automatically set account status to 'exported' during export
- Add comprehensive demo script that uploads, exports and verifies functionality
- Update API documentation with export endpoint details
- Add TypeScript types for export functionality

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-23 11:32:23 +08:00

20 KiB
Raw Blame History

账户管理系统 API 文档

概述

本文档描述了账户管理系统的API接口用于Web前端对接。系统提供了账户的获取、上传、更新、删除和统计等功能。

基础信息

  • 基础URL: {API_BASE_URL}
  • 数据格式: JSON
  • 字符编码: UTF-8

通用响应格式

所有API接口都使用统一的响应格式

interface ApiResponse<T> {
  code: BusinessCode;  // 业务状态码
  message: string;     // 响应消息
  data: T | null;      // 响应数据
}

业务状态码 (BusinessCode)

状态码 名称 说明
0 Success 请求成功
1001 NoResource 资源不存在
2001 InvalidParams 参数无效
3001 ResourceConflict 资源冲突
4001 PermissionDenied 权限不足
5001 BusinessError 业务错误

数据模型

账户 (Account)

账户是系统的核心数据模型,包含以下字段:

interface Account {
  id: number;        // 账户ID自增主键
  ownerId: string;  // 所有者ID
  platform: string; // 平台名称
  customId: string; // 自定义ID
  data: string;     // 账户数据JSON格式字符串
  status: string;   // 账户状态
  notes?: string;   // 备注,可选
  lockedAt?: Date;  // 锁定时间,可选
  createdAt: Date;  // 创建时间
  updatedAt: Date;  // 更新时间
}

账户状态

  • available: 可用
  • locked: 已锁定
  • 其他自定义状态

分页结果 (PaginationResult)

interface PaginationResult {
  page: number;      // 当前页码
  pageSize: number;  // 每页条数
  total: number;     // 总记录数
  totalPages: number; // 总页数
}

统计概览 (StatsOverview)

interface StatsOverview {
  totalAccounts: number; // 总账户数
  platformSummary: Record<string, number>; // 平台统计
  ownerSummary: Record<string, number>;    // 所有者统计
  statusSummary: Record<string, number>;    // 状态统计
  detailedBreakdown: {  // 详细统计
    platform: string;
    ownerId: string;
    status: string;
    count: number;
  }[];
}

API 接口

1. 账户获取接口

用于脚本端获取可用账户。

请求

GET /s/v1/{ownerId}/acquire?platform={platform}&count={count}

参数

参数名 位置 类型 必填 说明
ownerId 路径 string 所有者ID
platform 查询 string 平台名称
count 查询 number 获取数量默认1最大100

响应

成功响应:

{
  "code": 0,
  "message": "Successfully acquired 1 account.",
  "data": [
    {
      "id": 1,
      "customId": "custom123",
      "data": "{\"username\":\"test\",\"password\":\"123456\"}"
    }
  ]
}

无可用账户响应:

{
  "code": 1001,
  "message": "No available accounts found for platform 'example'.",
  "data": null
}

示例

// 使用fetch获取账户
async function acquireAccounts(ownerId, platform, count = 1) {
  const response = await fetch(`/s/v1/${ownerId}/acquire?platform=${platform}&count=${count}`, {
    method: 'GET',
    headers: {
      'Content-Type': 'application/json'
    }
  });
  
  const result = await response.json();
  return result;
}

// 调用示例
const result = await acquireAccounts('owner123', 'example', 2);
if (result.code === 0) {
  console.log('获取成功:', result.data);
} else {
  console.error('获取失败:', result.message);
}

2. 账户状态更新接口

用于脚本端更新账户状态。

请求

GET /s/v1/{ownerId}/update/{accountId}/{newStatus}?notes={notes}

参数

参数名 位置 类型 必填 说明
ownerId 路径 string 所有者ID
accountId 路径 number 账户ID
newStatus 路径 string 新状态
notes 查询 string 备注

响应

成功响应:

{
  "code": 0,
  "message": "Account status updated to 'used'.",
  "data": {
    "updatedId": 1
  }
}

权限不足响应:

{
  "code": 4001,
  "message": "Account not found or permission denied.",
  "data": null
}

示例

// 使用fetch更新账户状态
async function updateAccountStatus(ownerId, accountId, newStatus, notes) {
  const url = `/s/v1/${ownerId}/update/${accountId}/${newStatus}`;
  if (notes) {
    url += `?notes=${encodeURIComponent(notes)}`;
  }
  
  const response = await fetch(url, {
    method: 'GET',
    headers: {
      'Content-Type': 'application/json'
    }
  });
  
  const result = await response.json();
  return result;
}

// 调用示例
const result = await updateAccountStatus('owner123', 1, 'used', '测试使用');
if (result.code === 0) {
  console.log('更新成功:', result.data);
} else {
  console.error('更新失败:', result.message);
}

3. 账户上传接口

用于脚本端批量上传账户。

请求

POST /s/v1/{ownerId}/upload

请求体

[
  {
    "platform": "string",
    "customId": "string",
    "data": "string",
    "status": "string"
  }
]

参数

参数名 位置 类型 必填 说明
ownerId 路径 string 所有者ID
body 请求体 ScriptUploadItem[] 账户数据数组

ScriptUploadItem 类型

interface ScriptUploadItem {
  platform: string;  // 平台名称
  customId: string;  // 自定义ID
  data: string;      // 账户数据JSON格式字符串
  status?: string;   // 账户状态,可选,默认为"available"
}

响应

成功响应:

{
  "code": 0,
  "message": "Successfully processed 2 accounts (1 created, 1 updated).",
  "data": {
    "processedCount": 2,
    "createdCount": 1,
    "updatedCount": 1
  }
}

示例

// 使用fetch上传账户
async function uploadAccounts(ownerId, accounts) {
  const response = await fetch(`/s/v1/${ownerId}/upload`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(accounts)
  });
  
  const result = await response.json();
  return result;
}

// 调用示例
const accounts = [
  {
    platform: 'example',
    customId: 'user123',
    data: JSON.stringify({ username: 'user123', password: 'pass123' }),
    status: 'available'
  },
  {
    platform: 'example',
    customId: 'user456',
    data: JSON.stringify({ username: 'user456', password: 'pass456' })
  }
];

const result = await uploadAccounts('owner123', accounts);
if (result.code === 0) {
  console.log('上传成功:', result.data);
} else {
  console.error('上传失败:', result.message);
}

4. 账户列表接口

用于Web端获取账户列表支持筛选、分页和排序。

请求

POST /web/v1/accounts/list

请求体

{
  "filters": {
    "platform": "string",
    "status": ["string"],
    "ownerId": "string",
    "search": "string"
  },
  "pagination": {
    "page": 1,
    "pageSize": 10
  },
  "sort": {
    "field": "id",
    "order": "desc"
  }
}

参数

参数名 位置 类型 必填 说明
filters 请求体 ListAccountsFilters 筛选条件
pagination 请求体 object 分页参数
sort 请求体 object 排序参数

ListAccountsFilters 类型

interface ListAccountsFilters {
  platform?: string;   // 平台名称筛选
  status?: string[];   // 状态筛选,多选
  ownerId?: string;    // 所有者ID筛选
  search?: string;     // 搜索关键词搜索customId和notes
}

排序字段

支持以下字段排序:

  • id: 账户ID
  • ownerId: 所有者ID
  • platform: 平台名称
  • customId: 自定义ID
  • data: 账户数据
  • status: 账户状态
  • notes: 备注
  • lockedAt: 锁定时间
  • createdAt: 创建时间
  • updatedAt: 更新时间

响应

成功响应:

{
  "code": 0,
  "message": "Success",
  "data": {
    "list": [
      {
        "id": 1,
        "ownerId": "owner123",
        "platform": "example",
        "customId": "user123",
        "data": "{\"username\":\"user123\",\"password\":\"pass123\"}",
        "status": "available",
        "notes": "测试账户",
        "lockedAt": null,
        "createdAt": "2023-01-01T00:00:00.000Z",
        "updatedAt": "2023-01-01T00:00:00.000Z"
      }
    ],
    "pagination": {
      "page": 1,
      "pageSize": 10,
      "total": 1,
      "totalPages": 1
    }
  }
}

示例

// 使用fetch获取账户列表
async function getAccountsList(filters, pagination, sort) {
  const response = await fetch('/web/v1/accounts/list', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      filters,
      pagination,
      sort
    })
  });
  
  const result = await response.json();
  return result;
}

// 调用示例
const filters = {
  platform: 'example',
  status: ['available'],
  search: 'test'
};

const pagination = {
  page: 1,
  pageSize: 10
};

const sort = {
  field: 'createdAt',
  order: 'desc'
};

const result = await getAccountsList(filters, pagination, sort);
if (result.code === 0) {
  console.log('账户列表:', result.data.list);
  console.log('分页信息:', result.data.pagination);
} else {
  console.error('获取失败:', result.message);
}

5. 批量删除账户接口

用于Web端批量删除账户。

请求

POST /web/v1/accounts/delete-batch

请求体

{
  "ids": [1, 2, 3]
}

参数

参数名 位置 类型 必填 说明
ids 请求体 number[] 要删除的账户ID数组

响应

成功响应:

{
  "code": 0,
  "message": "Successfully deleted 3 accounts.",
  "data": {
    "deletedCount": 3
  }
}

示例

// 使用fetch批量删除账户
async function batchDeleteAccounts(ids) {
  const response = await fetch('/web/v1/accounts/delete-batch', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ ids })
  });
  
  const result = await response.json();
  return result;
}

// 调用示例
const result = await batchDeleteAccounts([1, 2, 3]);
if (result.code === 0) {
  console.log('删除成功:', result.data);
} else {
  console.error('删除失败:', result.message);
}

6. 批量更新账户接口

用于Web端批量更新账户。

请求

POST /web/v1/accounts/update-batch

请求体

{
  "ids": [1, 2, 3],
  "payload": {
    "status": "available",
    "ownerId": "newOwner",
    "notes": "批量更新备注"
  }
}

参数

参数名 位置 类型 必填 说明
ids 请求体 number[] 要更新的账户ID数组
payload 请求体 object 更新数据

payload 类型

interface UpdatePayload {
  status?: string;   // 新状态
  ownerId?: string;  // 新所有者ID
  notes?: string;    // 新备注
}

响应

成功响应:

{
  "code": 0,
  "message": "Successfully updated 3 accounts.",
  "data": {
    "updatedCount": 3
  }
}

示例

// 使用fetch批量更新账户
async function batchUpdateAccounts(ids, payload) {
  const response = await fetch('/web/v1/accounts/update-batch', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ ids, payload })
  });
  
  const result = await response.json();
  return result;
}

// 调用示例
const ids = [1, 2, 3];
const payload = {
  status: 'available',
  notes: '批量更新为可用状态'
};

const result = await batchUpdateAccounts(ids, payload);
if (result.code === 0) {
  console.log('更新成功:', result.data);
} else {
  console.error('更新失败:', result.message);
}

7. 账户导出接口

用于Web端批量导出账户并设置状态为已导出。

请求

POST /web/v1/accounts/export

请求体

{
  "ids": [1, 2, 3],
  "mode": "text"
}

参数

参数名 位置 类型 必填 说明
ids 请求体 number[] 要导出的账户ID数组
mode 请求体 string 导出模式:"text"或"object"

导出模式说明

  • text: 文本模式返回的data字段为字符串每行一个账户的data字段内容
  • object: 对象模式返回的data字段为完整的账户对象数组

响应

文本模式成功响应:

{
  "code": 0,
  "message": "Successfully exported 3 accounts.",
  "data": {
    "exportedCount": 3,
    "data": "{\"username\":\"user1\",\"password\":\"pass1\"}\n{\"username\":\"user2\",\"password\":\"pass2\"}\n{\"username\":\"user3\",\"password\":\"pass3\"}"
  }
}

对象模式成功响应:

{
  "code": 0,
  "message": "Successfully exported 3 accounts.",
  "data": {
    "exportedCount": 3,
    "data": [
      {
        "id": 1,
        "ownerId": "owner123",
        "platform": "example",
        "customId": "user1",
        "data": "{\"username\":\"user1\",\"password\":\"pass1\"}",
        "status": "exported",
        "notes": "测试账户1",
        "lockedAt": null,
        "createdAt": "2023-01-01T00:00:00.000Z",
        "updatedAt": "2023-01-01T12:00:00.000Z"
      },
      {
        "id": 2,
        "ownerId": "owner123",
        "platform": "example",
        "customId": "user2",
        "data": "{\"username\":\"user2\",\"password\":\"pass2\"}",
        "status": "exported",
        "notes": "测试账户2",
        "lockedAt": null,
        "createdAt": "2023-01-01T00:00:00.000Z",
        "updatedAt": "2023-01-01T12:00:00.000Z"
      }
    ]
  }
}

示例

// 使用fetch导出账户
async function exportAccounts(ids, mode) {
  const response = await fetch('/web/v1/accounts/export', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ ids, mode })
  });
  
  const result = await response.json();
  return result;
}

// 文本模式导出示例
const textResult = await exportAccounts([1, 2, 3], 'text');
if (textResult.code === 0) {
  console.log('导出成功:', textResult.data.exportedCount);
  console.log('文本数据:', textResult.data.data);
  // 可以直接保存为文件或复制到剪贴板
  const lines = textResult.data.data.split('\n');
  lines.forEach((line, index) => {
    console.log(`账户${index + 1}:`, line);
  });
} else {
  console.error('导出失败:', textResult.message);
}

// 对象模式导出示例
const objectResult = await exportAccounts([1, 2, 3], 'object');
if (objectResult.code === 0) {
  console.log('导出成功:', objectResult.data.exportedCount);
  const accounts = objectResult.data.data;
  accounts.forEach(account => {
    console.log(`账户ID: ${account.id}, 状态: ${account.status}`);
    console.log(`数据: ${account.data}`);
  });
} else {
  console.error('导出失败:', objectResult.message);
}

8. 统计概览接口

用于Web端获取账户统计信息。

请求

GET /web/v1/stats/overview

响应

成功响应:

{
  "code": 0,
  "message": "Success",
  "data": {
    "totalAccounts": 100,
    "platformSummary": {
      "example": 50,
      "test": 30,
      "demo": 20
    },
    "ownerSummary": {
      "owner1": 40,
      "owner2": 35,
      "owner3": 25
    },
    "statusSummary": {
      "available": 70,
      "locked": 20,
      "used": 10
    },
    "detailedBreakdown": [
      {
        "platform": "example",
        "ownerId": "owner1",
        "status": "available",
        "count": 20
      },
      {
        "platform": "example",
        "ownerId": "owner1",
        "status": "locked",
        "count": 10
      }
    ]
  }
}

示例

// 使用fetch获取统计概览
async function getStatsOverview() {
  const response = await fetch('/web/v1/stats/overview', {
    method: 'GET',
    headers: {
      'Content-Type': 'application/json'
    }
  });
  
  const result = await response.json();
  return result;
}

// 调用示例
const result = await getStatsOverview();
if (result.code === 0) {
  console.log('总账户数:', result.data.totalAccounts);
  console.log('平台统计:', result.data.platformSummary);
  console.log('所有者统计:', result.data.ownerSummary);
  console.log('状态统计:', result.data.statusSummary);
  console.log('详细统计:', result.data.detailedBreakdown);
} else {
  console.error('获取失败:', result.message);
}

错误处理

所有API接口在发生错误时都会返回统一的错误响应格式

{
  "code": "错误码",
  "message": "错误信息",
  "data": null
}

常见错误码

错误码 说明 处理建议
1001 资源不存在 检查请求的资源是否存在
2001 参数无效 检查请求参数是否符合要求
3001 资源冲突 检查是否有重复数据
5001 业务错误 检查业务逻辑是否正确

最佳实践

  1. 错误处理:前端应该根据返回的code值进行相应的错误处理,而不是依赖message字段。

  2. 分页在获取列表数据时合理设置分页大小建议不超过100条。

  3. 批量操作:批量操作时,建议限制单次操作的数量,避免服务器压力过大。

  4. 数据格式:账户数据字段data存储的是JSON格式字符串前端需要进行相应的序列化和反序列化操作。

类型定义

以下是完整的TypeScript类型定义可以直接在前端项目中使用

// 业务状态码
enum BusinessCode {
  Success = 0,
  NoResource = 1001,
  InvalidParams = 2001,
  ResourceConflict = 3001,
  PermissionDenied = 4001,
  BusinessError = 5001,
}

// 通用响应格式
interface ApiResponse<T> {
  code: BusinessCode;
  message: string;
  data: T | null;
}

// 账户类型
interface Account {
  id: number;
  ownerId: string;
  platform: string;
  customId: string;
  data: string;
  status: string;
  notes?: string;
  lockedAt?: Date | null;
  createdAt: Date;
  updatedAt: Date;
}

// 分页结果
interface PaginationResult {
  page: number;
  pageSize: number;
  total: number;
  totalPages: number;
}

// 脚本获取响应
type ScriptAcquireResponse = Pick<Account, 'id' | 'customId' | 'data'>[];

// 脚本上传项
interface ScriptUploadItem {
  platform: string;
  customId: string;
  data: string;
  status?: string;
}

// 账户列表筛选条件
interface ListAccountsFilters {
  platform?: string;
  status?: string[];
  ownerId?: string;
  search?: string;
}

// 账户列表请求体
interface ListAccountsBody {
  filters: ListAccountsFilters;
  pagination: {
    page: number;
    pageSize: number;
  };
  sort: {
    field: keyof Account;
    order: 'asc' | 'desc';
  };
}

// 账户列表响应
interface ListAccountsResponse {
  list: Account[];
  pagination: PaginationResult;
}

// 批量删除请求体
interface BatchDeleteBody {
  ids: number[];
}

// 批量更新请求体
interface BatchUpdateBody {
  ids: number[];
  payload: Partial<Pick<Account, 'status' | 'ownerId' | 'notes'>>;
}

// 账户导出请求体
interface ExportAccountsBody {
  ids: number[];
  mode: 'text' | 'object';
}

// 账户导出响应
interface ExportAccountsResponse {
  exportedCount: number;
  data: string | Account[];
}

// 统计概览
interface StatsOverview {
  totalAccounts: number;
  platformSummary: Record<string, number>;
  ownerSummary: Record<string, number>;
  statusSummary: Record<string, number>;
  detailedBreakdown: {
    platform: string;
    ownerId: string;
    status: string;
    count: number;
  }[];
}

版本历史

版本 日期 说明
1.0.0 2023-01-01 初始版本