云梦镜像开放平台 - OpenAPI
版本: v2.0.0
基础URL: https://api.dreamreflex.com/api
协议: HTTP/HTTPS
数据格式: JSON
目标用户: 客户及二次开发者
目录
概述
这是云梦镜像客户服务系统(Customer Service Application - CSA)的API文档,面向客户和二次开发者。本API提供完整的客户服务功能,包括用户认证、工单管理、业务账号管理、合同查看、项目查看等功能。
功能模块
- 用户认证: 注册、登录、获取用户信息、更新个人资料、修改密码
- 工单管理: 创建、查询、更新、删除工单(仅限自己的工单)
- 业务账号管理: 申请、查看、更新业务账号信息
- 合同管理: 查看自己的合同列表和详情,更新合同的签署状态
- 项目管理: 查看自己的项目、文件、链接和任务
- 联系我们: 提交联系表单
技术特点
- RESTful API设计
- JWT Token认证
- OAuth2.0标准支持
- 完整的错误处理
- 分页查询支持
权限说明
- 普通用户: 可以管理自己的工单、业务账号、查看和管理自己的合同和项目
- 数据隔离: 用户只能访问自己创建或拥有的资源
- 管理员功能: 管理员专用接口不在本文档中,如需管理员功能请联系技术支持
认证方式
Token类型
使用 Bearer Token 方式进行身份认证。
如何获取Token
通过登录接口获取Token:
POST /api/auth/login
如何使用Token
在所有需要认证的接口中,添加以下请求头:
Authorization: Bearer <your_access_token>
Token有效期
- 访问令牌(Access Token): 30分钟
- Token过期后需要重新登录
- 建议在Token即将过期前提示用户重新登录
通用规范
HTTP方法
GET- 获取资源POST- 创建资源PUT- 更新资源PATCH- 部分更新资源DELETE- 删除资源
请求头
必需的请求头:
Content-Type: application/json
需要认证的接口额外添加:
Authorization: Bearer <token>
响应格式
成功响应
所有成功的响应都包含实际的数据对象。
示例:
{
"id": "507f1f77bcf86cd799439011",
"email": "user@example.com",
"role": "user"
}
错误响应
所有错误响应遵循统一格式:
{
"detail": "错误描述信息"
}
状态码
| 状态码 | 说明 | 场景 |
|---|---|---|
| 200 | 成功 | GET、PUT、PATCH请求成功 |
| 201 | 已创建 | POST创建资源成功 |
| 204 | 无内容 | DELETE删除成功 |
| 400 | 请求错误 | 参数验证失败或业务逻辑错误 |
| 401 | 未授权 | 未提供Token或Token无效 |
| 403 | 禁止访问 | 权限不足(如访问他人的资源) |
| 404 | 未找到 | 资源不存在 |
| 422 | 参数验证失败 | 请求数据格式错误 |
| 500 | 服务器错误 | 服务器内部错误 |
分页规范
所有列表接口支持分页,使用以下查询参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| skip | integer | 否 | 0 | 跳过的记录数(用于分页) |
| limit | integer | 否 | 10 | 返回的记录数(最大100) |
分页计算示例:
// 获取第2页(每页10条)
const page = 2;
const pageSize = 10;
const skip = (page - 1) * pageSize; // skip = 10
const limit = pageSize; // limit = 10
// 计算总页数
const totalPages = Math.ceil(total / limit);
接口列表
1. 认证模块
1.1 发送邮箱验证码
接口说明: 向指定邮箱发送6位数字验证码,用于注册。
接口地址: POST /api/auth/send-code
是否需要认证: 否
请求参数:
{
"email": "string" // 必填,邮箱地址,需符合邮箱格式
}
请求示例:
POST /api/auth/send-code
Content-Type: application/json
{
"email": "user@example.com"
}
成功响应: 200 OK
{
"message": "验证码已发送",
"email": "user@example.com"
}
错误响应:
| 状态码 | 说明 |
|---|---|
| 422 | 邮箱格式不正确 |
| 500 | 邮件发送失败 |
注意事项:
- 验证码有效期为10分钟
- 同一邮箱建议限制发送频率(前端控制,如60秒内只能发送一次)
- 开发环境下验证码会输出到服务器日志
1.2 用户注册
接口说明: 使用邮箱和验证码注册新用户。
接口地址: POST /api/auth/register
是否需要认证: 否
请求参数:
{
"email": "string", // 必填,邮箱地址
"password": "string", // 必填,密码(8-128位)
"verification_code": "string" // 必填,6位数字验证码
}
参数限制:
email: 必须是有效的邮箱格式password: 长度8-128位,支持字母、数字、特殊字符verification_code: 必须是6位数字
请求示例:
POST /api/auth/register
Content-Type: application/json
{
"email": "user@example.com",
"password": "mypassword123",
"verification_code": "123456"
}
成功响应: 201 Created
{
"id": "507f1f77bcf86cd799439011",
"email": "user@example.com",
"role": "user",
"is_active": true,
"created_at": "2024-01-01T00:00:00",
"updated_at": null,
"full_name": null,
"phone_number": null,
"avatar_url": null,
"bio": null
}
错误响应:
| 状态码 | 说明 | detail |
|---|---|---|
| 400 | 验证码无效 | "验证码无效或已过期" |
| 400 | 邮箱已注册 | "该邮箱已被注册" |
| 422 | 参数验证失败 | "密码长度至少为8位" 等 |
注意事项:
- 注册后默认角色为
user(普通用户) - 账号默认为激活状态
- 密码会经过安全加密存储(Argon2)
1.3 用户登录(JSON格式)
接口说明: 使用邮箱和密码登录,获取访问令牌。
接口地址: POST /api/auth/login
是否需要认证: 否
请求参数:
{
"email": "string", // 必填,邮箱地址
"password": "string" // 必填,密码
}
请求示例:
POST /api/auth/login
Content-Type: application/json
{
"email": "user@example.com",
"password": "mypassword123"
}
成功响应: 200 OK
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "bearer",
"expires_in": 1800
}
响应字段说明:
access_token: 访问令牌,用于后续API调用token_type: 令牌类型,固定为 "bearer"expires_in: 令牌有效期(秒),默认1800秒(30分钟)
错误响应:
| 状态码 | 说明 | detail |
|---|---|---|
| 401 | 登录失败 | "邮箱或密码错误" |
| 403 | 账号被禁用 | "账号已被禁用" |
注意事项:
- Token应该安全存储在前端(localStorage或sessionStorage)
- Token过期后需要重新登录
- 建议在Token即将过期前提示用户
1.4 用户登录(OAuth2标准)
接口说明: OAuth2标准登录接口,用于工具集成。
接口地址: POST /api/auth/token
是否需要认证: 否
请求格式: application/x-www-form-urlencoded
请求参数:
username=user@example.com&password=mypassword123
注意: 虽然参数名是 username,但请填写邮箱地址。
成功响应: 同 /api/auth/login
使用场景: 主要用于Swagger UI认证,前端建议使用 /api/auth/login
1.5 获取当前用户信息
接口说明: 获取当前登录用户的详细信息。
接口地址: GET /api/auth/me 或 GET /api/users/me
是否需要认证: 是
请求示例:
GET /api/auth/me
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
成功响应: 200 OK
{
"id": "507f1f77bcf86cd799439011",
"email": "user@example.com",
"role": "user",
"is_active": true,
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-02-01T12:34:56Z",
"full_name": "张三",
"phone_number": "+86-13800000000",
"avatar_url": "https://cdn.example.com/avatar.png",
"bio": "负责北区客户成功支持。"
}
响应字段说明:
id: 用户唯一标识email: 用户邮箱role: 用户角色("user" 或 "admin")is_active: 账号是否激活created_at: 账号创建时间(ISO 8601格式,UTC)updated_at: 账号最近更新时间(可能为null)full_name: 用户姓名(可选)phone_number: 联系方式(可选)avatar_url: 头像URL(可选)bio: 个人简介(可选)
错误响应:
| 状态码 | 说明 |
|---|---|
| 401 | Token无效或已过期 |
| 403 | 账号已被禁用 |
1.6 更新当前用户资料
接口说明: 修改当前登录用户的基础资料(姓名、联系方式、头像、个人简介)。
接口地址: PATCH /api/users/me
是否需要认证: 是
请求示例:
PATCH /api/users/me
Authorization: Bearer <token>
Content-Type: application/json
{
"full_name": "张三",
"phone_number": "+86-13800000000",
"bio": "负责北区客户成功支持。"
}
请求字段说明(全部可选,至少提供一个字段):
| 字段 | 类型 | 说明 |
|---|---|---|
full_name | string | 用户姓名,最长64字符 |
phone_number | string | 联系方式,最长32字符 |
avatar_url | string | 头像URL |
bio | string | 个人简介,最长256字符 |
成功响应: 200 OK,返回更新后的 User 对象(同 GET /api/auth/me)
错误响应:
| 状态码 | 说明 |
|---|---|
| 400 | 未提供任何需要更新的字段 |
| 401 | 用户未登录或Token无效 |
1.7 修改当前用户密码
接口说明: 用户自助修改登录密码。
接口地址: POST /api/users/me/change-password
是否需要认证: 是
请求示例:
POST /api/users/me/change-password
Authorization: Bearer <token>
Content-Type: application/json
{
"old_password": "OldPassw0rd!",
"new_password": "NewPassw0rd!"
}
请求字段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
old_password | string | 当前密码(必填) |
new_password | string | 新密码(必填,8-128字符) |
成功响应: 200 OK
{
"message": "密码修改成功"
}
错误响应:
| 状态码 | 说明 |
|---|---|
| 400 | 当前密码不正确或与新密码相同 |
| 401 | 用户未登录或Token无效 |
2. 工单模块
2.1 创建工单
接口说明: 创建新的工单。
接口地址: POST /api/tickets
是否需要认证: 是
权限要求: 所有登录用户
请求参数:
{
"title": "string", // 必填,工单标题(1-200字符)
"ticket_type": "string", // 必填,工单类型
"content": "string" // 必填,工单内容(至少1字符)
}
工单类型 (ticket_type):
| 值 | 说明 |
|---|---|
financial | 财务问题工单 |
technical | 技术问题工单 |
business | 业务问题工单 |
请求示例:
POST /api/tickets
Authorization: Bearer <token>
Content-Type: application/json
{
"title": "无法导出财务报表",
"ticket_type": "financial",
"content": "在尝试导出本月财务报表时,系统提示"导出失败",请帮忙处理。"
}
成功响应: 201 Created
{
"id": "507f1f77bcf86cd799439012",
"title": "无法导出财务报表",
"ticket_type": "financial",
"content": "在尝试导出本月财务报表时,系统提示"导出失败",请帮忙处理。",
"status": "pending",
"feedback": null,
"creator_email": "user@example.com",
"responder_email": null,
"created_at": "2024-01-01T10:00:00",
"updated_at": null,
"replied_at": null
}
错误响应:
| 状态码 | 说明 |
|---|---|
| 401 | 未登录或Token无效 |
| 422 | 参数验证失败(如标题过长、类型错误等) |
2.2 获取工单列表
接口说明: 获取工单列表,支持分页和筛选。普通用户只能看到自己创建的工单。
接口地址: GET /api/tickets
是否需要认证: 是
权限说明:
- 普通用户:只能看到自己创建的工单
- 支持分页和状态过滤
查询参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| skip | integer | 否 | 0 | 跳过的记录数(用于分页) |
| limit | integer | 否 | 10 | 返回的记录数(最大100) |
| status_filter | string | 否 | - | 按状态筛选 |
状态筛选 (status_filter):
| 值 | 说明 |
|---|---|
pending | 仅显示待回复的工单 |
replied | 仅显示已回复的工单 |
| 不传 | 显示所有状态 |
请求示例:
GET /api/tickets?skip=0&limit=10&status_filter=pending
Authorization: Bearer <token>
成功响应: 200 OK
{
"total": 25,
"items": [
{
"id": "507f1f77bcf86cd799439012",
"title": "无法导出财务报表",
"ticket_type": "financial",
"content": "在尝试导出本月财务报表时...",
"status": "pending",
"feedback": null,
"creator_email": "user@example.com",
"responder_email": null,
"created_at": "2024-01-01T10:00:00",
"updated_at": null,
"replied_at": null
},
{
"id": "507f1f77bcf86cd799439013",
"title": "系统登录缓慢",
"ticket_type": "technical",
"content": "最近几天登录系统非常慢...",
"status": "replied",
"feedback": "已优化服务器性能,请重试。",
"creator_email": "user@example.com",
"responder_email": "admin@example.com",
"created_at": "2024-01-01T09:00:00",
"updated_at": "2024-01-01T12:00:00",
"replied_at": "2024-01-01T12:00:00"
}
]
}
响应字段说明:
total: 符合条件的工单总数items: 当前页的工单列表
错误响应:
| 状态码 | 说明 |
|---|---|
| 401 | 未登录 |
| 422 | 参数验证失败(如limit超过100) |
2.3 获取工单详情
接口说明: 获取指定工单的详细信息。普通用户只能查看自己的工单。
接口地址: GET /api/tickets/{ticket_id}
是否需要认证: 是
权限说明:
- 普通用户:只能查看自己的工单
路径参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| ticket_id | string | 工单ID |
请求示例:
GET /api/tickets/507f1f77bcf86cd799439012
Authorization: Bearer <token>
成功响应: 200 OK
{
"id": "507f1f77bcf86cd799439012",
"title": "无法导出财务报表",
"ticket_type": "financial",
"content": "在尝试导出本月财务报表时,系统提示"导出失败",请帮忙处理。",
"status": "pending",
"feedback": null,
"creator_email": "user@example.com",
"responder_email": null,
"created_at": "2024-01-01T10:00:00",
"updated_at": null,
"replied_at": null
}
错误响应:
| 状态码 | 说明 |
|---|---|
| 401 | 未登录 |
| 403 | 无权访问此工单(不是创建者) |
| 404 | 工单不存在 |
2.4 更新工单
接口说明: 更新工单的标题和内容。只能更新自己创建的、状态为 pending(待回复)的工单。
接口地址: PUT /api/tickets/{ticket_id}
是否需要认证: 是
权限要求:
- 只能更新自己创建的工单
- 只能更新状态为
pending(待回复)的工单 - 已回复的工单不能再更新
路径参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| ticket_id | string | 工单ID |
请求参数:
{
"title": "string", // 可选,工单标题(1-200字符)
"content": "string" // 可选,工单内容(至少1字符)
}
注意: 至少提供一个字段,可以只更新标题或只更新内容。
请求示例:
PUT /api/tickets/507f1f77bcf86cd799439012
Authorization: Bearer <token>
Content-Type: application/json
{
"title": "无法导出财务报表(已重试)",
"content": "在尝试导出本月财务报表时,系统提示"导出失败"。我已经重试了多次,问题依然存在。"
}
成功响应: 200 OK
{
"id": "507f1f77bcf86cd799439012",
"title": "无法导出财务报表(已重试)",
"ticket_type": "financial",
"content": "在尝试导出本月财务报表时,系统提示"导出失败"。我已经重试了多次,问题依然存在。",
"status": "pending",
"feedback": null,
"creator_email": "user@example.com",
"responder_email": null,
"created_at": "2024-01-01T10:00:00",
"updated_at": "2024-01-01T10:30:00",
"replied_at": null
}
错误响应:
| 状态码 | 说明 |
|---|---|
| 400 | 工单已被回复,不能再更新 |
| 401 | 未登录 |
| 403 | 无权更新此工单(不是创建者) |
| 404 | 工单不存在 |
| 422 | 参数验证失败 |
2.5 删除工单
接口说明: 删除指定的工单。只能删除自己创建的工单。
接口地址: DELETE /api/tickets/{ticket_id}
是否需要认证: 是
权限说明:
- 普通用户:可以删除自己创建的工单
路径参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| ticket_id | string | 工单ID |
请求示例:
DELETE /api/tickets/507f1f77bcf86cd799439012
Authorization: Bearer <token>
成功响应: 204 No Content
(无响应体)
错误响应:
| 状态码 | 说明 |
|---|---|
| 401 | 未登录 |
| 403 | 无权删除此工单 |
| 404 | 工单不存在 |
3. 业务账号模块
3.1 获取当前用户的业务账号
接口说明: 获取当前登录用户的业务账号信息。
接口地址: GET /api/business-accounts/me
是否需要认证: 是
请求示例:
GET /api/business-accounts/me
Authorization: Bearer <token>
成功响应: 200 OK
{
"id": "507f1f77bcf86cd799439020",
"owner_email": "user@example.com",
"status": "active",
"assigned_email": "user@company.com",
"user_code": "USER001",
"company_name": "示例公司",
"tax_number": "91110000MA01234567",
"certification_info": "营业执照等认证信息",
"communication_address": "北京市朝阳区xxx",
"contact_person_name": "张三",
"contact_phone": "+86-13800000000",
"created_at": "2024-01-01T00:00:00",
"updated_at": "2024-01-15T10:30:00"
}
业务账号状态 (status):
| 值 | 说明 |
|---|---|
pending | 待审核(已申请,等待管理员审核) |
active | 已激活(已分配专属邮箱,可以正常使用) |
disabled | 已禁用 |
错误响应:
| 状态码 | 说明 |
|---|---|
| 401 | 未登录 |
| 404 | 业务账号不存在(未申请或未创建) |
3.2 申请创建业务账号
接口说明: 申请创建业务账号。如果当前用户尚无业务账号,则创建一条 pending 状态的记录。
接口地址: POST /api/business-accounts/me/apply
是否需要认证: 是
请求参数:
{
"company_name": "string", // 可选,公司抬头(最长128字符)
"tax_number": "string", // 可选,税号(最长64字符)
"certification_info": "string", // 可选,认证信息(最长512字符)
"communication_address": "string", // 可选,通信地址(最长256字符)
"contact_person_name": "string", // 可选,联系人姓名(最长64字符)
"contact_phone": "string" // 可选,联系方式(最长32字符)
}
注意: 所有字段都是可选的,但建议尽可能填写完整信息以便审核。
请求示例:
POST /api/business-accounts/me/apply
Authorization: Bearer <token>
Content-Type: application/json
{
"company_name": "示例公司",
"tax_number": "91110000MA01234567",
"certification_info": "营业执照等认证信息",
"communication_address": "北京市朝阳区xxx",
"contact_person_name": "张三",
"contact_phone": "+86-13800000000"
}
成功响应: 201 Created
{
"id": "507f1f77bcf86cd799439020",
"owner_email": "user@example.com",
"status": "pending",
"assigned_email": null,
"user_code": null,
"company_name": "示例公司",
"tax_number": "91110000MA01234567",
"certification_info": "营业执照等认证信息",
"communication_address": "北京市朝阳区xxx",
"contact_person_name": "张三",
"contact_phone": "+86-13800000000",
"created_at": "2024-01-01T00:00:00",
"updated_at": null
}
错误响应:
| 状态码 | 说明 |
|---|---|
| 400 | 已存在申请或已激活账号 |
| 401 | 未登录 |
| 422 | 参数验证失败 |
3.3 更新当前用户的业务账号资料
接口说明: 更新当前登录用户业务账号中可编辑字段。
接口地址: PATCH /api/business-accounts/me
是否需要认证: 是
可编辑字段:
- 公司抬头
- 税号
- 认证信息
- 通信地址
- 联系人姓名
- 联系方式
注意: 专属邮箱(assigned_email)和用户识别码(user_code)由管理员分配,用户无法修改。
请求参数:
{
"company_name": "string", // 可选,公司抬头
"tax_number": "string", // 可选,税号
"certification_info": "string", // 可选,认证信息
"communication_address": "string", // 可选,通信地址
"contact_person_name": "string", // 可选,联系人姓名
"contact_phone": "string" // 可选,联系方式
}
请求示例:
PATCH /api/business-accounts/me
Authorization: Bearer <token>
Content-Type: application/json
{
"company_name": "更新后的公司名称",
"contact_phone": "+86-13900000000"
}
成功响应: 200 OK,返回更新后的业务账号对象
错误响应:
| 状态码 | 说明 |
|---|---|
| 401 | 未登录 |
| 404 | 业务账号不存在 |
| 422 | 参数验证失败 |
3.4 获取业务账号详情
接口说明: 获取业务账号详情。普通用户只能查看自己的业务账号。
接口地址: GET /api/business-accounts/{account_id}
是否需要认证: 是
权限说明:
- 普通用户只能查看自己的业务账号
路径参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| account_id | string | 业务账号ID |
请求示例:
GET /api/business-accounts/507f1f77bcf86cd799439020
Authorization: Bearer <token>
成功响应: 200 OK,返回业务账号对象(同 GET /api/business-accounts/me)
错误响应:
| 状态码 | 说明 |
|---|---|
| 401 | 未登录 |
| 403 | 无权访问此业务账号 |
| 404 | 业务账号不存在 |
4. 合同模块
4.1 获取我的合同列表
接口说明: 获取当前登录用户自己的合同列表。
接口地址: GET /api/contracts/me
是否需要认证: 是
查询参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| skip | integer | 否 | 0 | 跳过的记录数(用于分页) |
| limit | integer | 否 | 10 | 返回的记录数(最大100) |
请求示例:
GET /api/contracts/me?skip=0&limit=10
Authorization: Bearer <token>
成功响应: 200 OK
{
"total": 5,
"items": [
{
"id": "507f1f77bcf86cd799439030",
"owner_email": "user@example.com",
"title": "云服务合同(2025版)",
"content_markdown": "# 合同正文\n\n这里是 Markdown 格式的合同内容……",
"is_signed": false,
"created_at": "2024-01-01T00:00:00",
"updated_at": "2024-01-15T10:30:00"
}
]
}
响应字段说明:
total: 符合条件的合同总数items: 当前页的合同列表is_signed: 签署状态,true表示已签署,false表示待签署content_markdown: 合同内容为 Markdown 格式,前端需要渲染
错误响应:
| 状态码 | 说明 |
|---|---|
| 401 | 未登录 |
| 422 | 参数验证失败 |
4.2 获取合同详情
接口说明: 获取指定合同的详细信息。普通用户只能查看自己的合同。
接口地址: GET /api/contracts/{contract_id}
是否需要认证: 是
权限说明:
- 普通用户只能查看自己的合同
路径参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| contract_id | string | 合同ID |
请求示例:
GET /api/contracts/507f1f77bcf86cd799439030
Authorization: Bearer <token>
成功响应: 200 OK
{
"id": "507f1f77bcf86cd799439030",
"owner_email": "user@example.com",
"title": "云服务合同(2025版)",
"content_markdown": "# 合同正文\n\n这里是 Markdown 格式的合同内容……",
"is_signed": false,
"created_at": "2024-01-01T00:00:00",
"updated_at": "2024-01-15T10:30:00"
}
错误响应:
| 状态码 | 说明 |
|---|---|
| 401 | 未登录 |
| 403 | 无权访问此合同 |
| 404 | 合同不存在 |
4.3 更新合同签署状态
接口说明: 更新指定合同的签署状态。普通用户只能更新自己的合同。
接口地址: PATCH /api/contracts/{contract_id}/sign-status
是否需要认证: 是
权限说明:
- 普通用户只能更新自己的合同
- 管理员可以更新任意合同
路径参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| contract_id | string | 合同ID |
请求体:
{
"is_signed": true
}
请求体字段说明:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| is_signed | boolean | 是 | 签署状态,true 表示已签署,false 表示待签署 |
请求示例:
PATCH /api/contracts/507f1f77bcf86cd799439030/sign-status
Authorization: Bearer <token>
Content-Type: application/json
{
"is_signed": true
}
成功响应: 200 OK
{
"id": "507f1f77bcf86cd799439030",
"owner_email": "user@example.com",
"title": "云服务合同(2025版)",
"content_markdown": "# 合同正文\n\n这里是 Markdown 格式的合同内容……",
"is_signed": true,
"created_at": "2024-01-01T00:00:00",
"updated_at": "2024-01-15T10:30:00"
}
错误响应:
| 状态码 | 说明 |
|---|---|
| 401 | 未登录 |
| 403 | 无权更新此合同的签署状态 |
| 404 | 合同不存在 |
| 422 | 参数验证失败 |
使用场景:
- 用户完成合同签署后,更新签署状态为已签署
- 需要修改签署状态时,可以随时更新
5. 项目模块
5.1 获取我的项目列表
接口说明: 获取当前登录用户自己的项目列表。
接口地址: GET /api/projects/me
是否需要认证: 是
查询参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| skip | integer | 否 | 0 | 跳过的记录数(用于分页) |
| limit | integer | 否 | 10 | 返回的记录数(最大100) |
请求示例:
GET /api/projects/me?skip=0&limit=10
Authorization: Bearer <token>
成功响应: 200 OK
{
"total": 3,
"items": [
{
"id": "507f1f77bcf86cd799439040",
"owner_email": "user@example.com",
"name": "示例项目",
"description": "这是一个示例项目",
"overview_markdown": "# 项目概述\n\n这里是项目概述内容...",
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-15T10:30:00Z"
}
]
}
响应字段说明:
total: 符合条件的项目总数items: 当前页的项目列表overview_markdown: 项目概述为 Markdown 格式,前端需要渲染
错误响应:
| 状态码 | 说明 |
|---|---|
| 401 | 未登录 |
| 422 | 参数验证失败 |
5.2 获取项目详情
接口说明: 获取指定项目的详细信息。普通用户只能查看自己的项目。
接口地址: GET /api/projects/{project_id}
是否需要认证: 是
权限说明:
- 普通用户只能查看自己的项目
路径参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| project_id | string | 项目ID |
请求示例:
GET /api/projects/507f1f77bcf86cd799439040
Authorization: Bearer <token>
成功响应: 200 OK
{
"id": "507f1f77bcf86cd799439040",
"owner_email": "user@example.com",
"name": "示例项目",
"description": "这是一个示例项目",
"overview_markdown": "# 项目概述\n\n这里是项目概述内容...",
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-15T10:30:00Z"
}
错误响应:
| 状态码 | 说明 |
|---|---|
| 401 | 未登录 |
| 403 | 无权访问此项目 |
| 404 | 项目不存在 |
5.3 获取项目文件列表
接口说明: 获取项目文件列表,支持按文件名和标签筛选。普通用户只能查看自己项目的文件。
接口地址: GET /api/projects/{project_id}/files
是否需要认证: 是
权限说明:
- 普通用户只能查看自己项目的文件
路径参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| project_id | string | 项目ID |
查询参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| skip | integer | 否 | 0 | 跳过的记录数 |
| limit | integer | 否 | 100 | 返回的记录数(最大500) |
| filename | string | 否 | - | 按文件名筛选(模糊匹配) |
| tag | string | 否 | - | 按标签筛选(精确匹配) |
请求示例:
GET /api/projects/507f1f77bcf86cd799439040/files?skip=0&limit=100&tag=文档
Authorization: Bearer <token>
成功响应: 200 OK
{
"total": 10,
"items": [
{
"id": "507f1f77bcf86cd799439050",
"project_id": "507f1f77bcf86cd799439040",
"filename": "项目文档.pdf",
"file_size": 1024000,
"content_type": "application/pdf",
"tag": "文档",
"oss_key": "projects/507f1f77bcf86cd799439040/files/项目文档.pdf",
"created_at": "2024-01-01T00:00:00Z",
"updated_at": null
}
]
}
错误响应:
| 状态码 | 说明 |
|---|---|
| 401 | 未登录 |
| 403 | 无权访问此项目 |
| 404 | 项目不存在 |
5.4 获取文件下载预签名URL
接口说明: 获取文件下载预签名URL。客户端使用此URL直接下载文件,避免文件流量经过服务器。普通用户只能下载自己项目的文件。
接口地址: POST /api/projects/files/{file_id}/download-url
是否需要认证: 是
权限说明:
- 普通用户只能下载自己项目的文件
路径参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| file_id | string | 文件ID |
请求示例:
POST /api/projects/files/507f1f77bcf86cd799439050/download-url
Authorization: Bearer <token>
成功响应: 200 OK
{
"download_url": "https://oss.example.com/projects/...?signature=...",
"expires_in": 3600
}
响应字段说明:
download_url: 预签名下载URL,可直接用于下载文件expires_in: URL有效期(秒),通常为3600秒(1小时)
使用示例:
// 获取下载URL
const response = await fetch('/api/projects/files/507f1f77bcf86cd799439050/download-url', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`
}
});
const { download_url } = await response.json();
// 直接使用URL下载文件
window.open(download_url);
// 或使用 fetch 下载
const fileResponse = await fetch(download_url);
const blob = await fileResponse.blob();
// 处理文件...
错误响应:
| 状态码 | 说明 |
|---|---|
| 401 | 未登录 |
| 403 | 无权访问此文件 |
| 404 | 文件不存在 |
5.5 获取项目链接列表
接口说明: 获取项目链接列表。普通用户只能查看自己项目的链接。
接口地址: GET /api/projects/{project_id}/links
是否需要认证: 是
权限说明:
- 普通用户只能查看自己项目的链接
路径参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| project_id | string | 项目ID |
查询参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| skip | integer | 否 | 0 | 跳过的记录数 |
| limit | integer | 否 | 100 | 返回的记录数(最大500) |
请求示例:
GET /api/projects/507f1f77bcf86cd799439040/links?skip=0&limit=100
Authorization: Bearer <token>
成功响应: 200 OK
{
"total": 5,
"items": [
{
"id": "507f1f77bcf86cd799439060",
"project_id": "507f1f77bcf86cd799439040",
"title": "项目文档链接",
"url": "https://docs.example.com/project",
"description": "项目相关文档",
"created_at": "2024-01-01T00:00:00Z",
"updated_at": null
}
]
}
错误响应:
| 状态码 | 说明 |
|---|---|
| 401 | 未登录 |
| 403 | 无权访问此项目 |
| 404 | 项目不存在 |
5.6 获取项目任务列表
接口说明: 获取项目任务列表,支持按状态筛选。普通用户只能查看自己项目的任务。
接口地址: GET /api/projects/{project_id}/tasks
是否需要认证: 是
权限说明:
- 普通用户只能查看自己项目的任务
路径参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| project_id | string | 项目ID |
查询参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| skip | integer | 否 | 0 | 跳过的记录数 |
| limit | integer | 否 | 100 | 返回的记录数(最大500) |
| status | string | 否 | - | 按状态筛选(pending=未完成, completed=已完成) |
请求示例:
GET /api/projects/507f1f77bcf86cd799439040/tasks?skip=0&limit=100&status=pending
Authorization: Bearer <token>
成功响应: 200 OK
{
"total": 8,
"items": [
{
"id": "507f1f77bcf86cd799439070",
"project_id": "507f1f77bcf86cd799439040",
"title": "完成项目文档",
"description": "编写项目相关文档",
"status": "pending",
"created_at": "2024-01-01T00:00:00Z",
"updated_at": null
}
]
}
任务状态 (status):
| 值 | 说明 |
|---|---|
pending | 未完成 |
completed | 已完成 |
错误响应:
| 状态码 | 说明 |
|---|---|
| 401 | 未登录 |
| 403 | 无权访问此项目 |
| 404 | 项目不存在 |
6. 联系我们模块
6.1 提交联系表单
接口说明: 提交联系我们表单(公开接口,需要 Cloudflare Turnstile 验证)。
接口地址: POST /api/owa/info
是否需要认证: 否
请求参数:
{
"name": "string", // 必填,称呼
"email": "string", // 必填,邮箱(不进行格式校验,允许任意字符串)
"message": "string", // 必填,消息内容
"turnstileToken": "string" // 必填,Cloudflare Turnstile 验证令牌
}
请求示例:
POST /api/owa/info
Content-Type: application/json
{
"name": "张三",
"email": "user@example.com",
"message": "我想咨询一下产品价格",
"turnstileToken": "0.xxx..."
}
成功响应: 201 Created
{
"id": "507f1f77bcf86cd799439080",
"name": "张三",
"email": "user@example.com",
"message": "我想咨询一下产品价格",
"is_processed": false,
"admin_notes": null,
"created_at": "2024-01-01T10:00:00"
}
错误响应:
| 状态码 | 说明 |
|---|---|
| 400 | Turnstile验证失败 |
| 422 | 参数验证失败 |
注意事项:
- 提交后会自动发送通知邮件给管理员
- 需要在前端集成 Cloudflare Turnstile 进行人机验证
- 验证令牌有效期为几分钟,请及时提交
数据模型
User(用户)
{
id: string; // 用户唯一标识
email: string; // 邮箱地址
role: "user" | "admin"; // 用户角色
is_active: boolean; // 账号是否激活
created_at: string; // 创建时间(ISO 8601,UTC)
updated_at: string | null; // 最后更新时间,可能为 null
full_name: string | null; // 姓名
phone_number: string | null; // 联系方式
avatar_url: string | null; // 头像链接
bio: string | null; // 个人简介
}
Ticket(工单)
{
id: string; // 工单唯一标识
title: string; // 工单标题
ticket_type: "financial" | "technical" | "business"; // 工单类型
content: string; // 工单内容
status: "pending" | "replied"; // 工单状态
feedback: string | null; // 反馈结果(管理员回复)
creator_email: string; // 创建者邮箱
responder_email: string | null; // 回复者邮箱(管理员)
created_at: string; // 创建时间(ISO 8601)
updated_at: string | null; // 更新时间(ISO 8601)
replied_at: string | null; // 回复时间(ISO 8601)
}
BusinessAccount(业务账号)
{
id: string; // 业务账号唯一标识
owner_email: string; // 所属用户邮箱
status: "pending" | "active" | "disabled"; // 业务账号状态
assigned_email: string | null; // 专属邮箱(管理员分配)
user_code: string | null; // 用户识别码(管理员分配)
company_name: string | null; // 公司抬头
tax_number: string | null; // 税号
certification_info: string | null; // 认证信息
communication_address: string | null; // 通信地址
contact_person_name: string | null; // 联系人姓名
contact_phone: string | null; // 联系方式
created_at: string; // 创建时间(ISO 8601)
updated_at: string | null; // 更新时间(ISO 8601)
}
Contract(合同)
{
id: string; // 合同唯一标识
owner_email: string; // 所属用户邮箱
title: string; // 合同标题
content_markdown: string; // 合同内容(Markdown格式)
is_signed: boolean; // 签署状态,true表示已签署,false表示待签署
created_at: string; // 创建时间(ISO 8601)
updated_at: string | null; // 更新时间(ISO 8601)
}
Project(项目)
{
id: string; // 项目唯一标识
owner_email: string; // 所属用户邮箱
name: string; // 项目名称
description: string | null; // 项目描述
overview_markdown: string; // 项目概述(Markdown格式)
created_at: string; // 创建时间(ISO 8601,UTC)
updated_at: string | null; // 更新时间(ISO 8601,UTC)
}
ProjectFile(项目文件)
{
id: string; // 文件唯一标识
project_id: string; // 所属项目ID
filename: string; // 文件名
file_size: number; // 文件大小(字节)
content_type: string; // 文件MIME类型
tag: string | null; // 文件标签
oss_key: string; // OSS存储键
created_at: string; // 创建时间(ISO 8601,UTC)
updated_at: string | null; // 更新时间(ISO 8601,UTC)
}
ProjectLink(项目链接)
{
id: string; // 链接唯一标识
project_id: string; // 所属项目ID
title: string; // 链接标题
url: string; // 链接URL
description: string | null; // 链接描述
created_at: string; // 创建时间(ISO 8601,UTC)
updated_at: string | null; // 更新时间(ISO 8601,UTC)
}
ProjectTask(项目任务)
{
id: string; // 任务唯一标识
project_id: string; // 所属项目ID
title: string; // 任务标题
description: string | null; // 任务描述
status: "pending" | "completed"; // 任务状态
created_at: string; // 创建时间(ISO 8601,UTC)
updated_at: string | null; // 更新时间(ISO 8601,UTC)
}
Token(令牌)
{
access_token: string; // 访问令牌
token_type: "bearer"; // 令牌类型
expires_in: number; // 有效期(秒)
}
错误码说明
错误响应格式
{
"detail": "错误描述信息"
}
常见错误
| 状态码 | 场景 | detail示例 | 前端处理建议 |
|---|---|---|---|
| 400 | 业务逻辑错误 | "验证码无效或已过期" | 提示用户重新操作 |
| 401 | 未认证 | "无效的认证凭据" | 跳转到登录页 |
| 403 | 权限不足 | "无权访问此资源" | 提示权限不足 |
| 404 | 资源不存在 | "工单不存在" | 提示资源不存在 |
| 422 | 参数验证失败 | "密码长度至少为8位" | 显示验证错误信息 |
| 500 | 服务器错误 | "Internal Server Error" | 提示稍后重试 |
错误处理示例
fetch('/api/tickets', {
method: 'GET',
headers: {
'Authorization': `Bearer ${token}`
}
})
.then(response => {
if (!response.ok) {
// 处理错误
if (response.status === 401) {
// Token无效,跳转登录
window.location.href = '/login';
} else if (response.status === 403) {
// 权限不足
alert('权限不足');
}
return response.json().then(err => {
throw new Error(err.detail);
});
}
return response.json();
})
.then(data => {
// 处理成功响应
console.log(data);
})
.catch(error => {
// 处理错误
console.error(error.message);
});
完整流程示例
场景1: 新用户注册并创建工单
// 步骤1: 发送验证码
fetch('http://localhost:8000/api/auth/send-code', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email: 'newuser@example.com'
})
})
.then(res => res.json())
.then(data => console.log('验证码已发送'));
// 步骤2: 用户输入收到的验证码,进行注册
fetch('http://localhost:8000/api/auth/register', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email: 'newuser@example.com',
password: 'mypassword123',
verification_code: '123456' // 用户输入的验证码
})
})
.then(res => res.json())
.then(user => console.log('注册成功:', user));
// 步骤3: 登录获取Token
fetch('http://localhost:8000/api/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email: 'newuser@example.com',
password: 'mypassword123'
})
})
.then(res => res.json())
.then(data => {
const token = data.access_token;
// 存储token
localStorage.setItem('token', token);
// 步骤4: 使用token创建工单
return fetch('http://localhost:8000/api/tickets', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({
title: '账单查询问题',
ticket_type: 'financial',
content: '无法查看本月账单明细'
})
});
})
.then(res => res.json())
.then(ticket => console.log('工单创建成功:', ticket));
场景2: 用户查看和更新工单
const token = localStorage.getItem('token');
// 步骤1: 获取工单列表
fetch('http://localhost:8000/api/tickets?skip=0&limit=10', {
headers: { 'Authorization': `Bearer ${token}` }
})
.then(res => res.json())
.then(data => {
console.log(`共有 ${data.total} 个工单`);
const firstTicket = data.items[0];
// 步骤2: 查看第一个工单详情
return fetch(`http://localhost:8000/api/tickets/${firstTicket.id}`, {
headers: { 'Authorization': `Bearer ${token}` }
});
})
.then(res => res.json())
.then(ticket => {
console.log('工单详情:', ticket);
// 步骤3: 如果工单状态是pending,可以更新
if (ticket.status === 'pending') {
return fetch(`http://localhost:8000/api/tickets/${ticket.id}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({
content: ticket.content + '\n\n补充:我已经尝试重新登录,问题依然存在。'
})
});
}
})
.then(res => res && res.json())
.then(updated => updated && console.log('工单已更新:', updated));
场景3: 查看业务账号和合同
const token = localStorage.getItem('token');
// 步骤1: 获取业务账号
fetch('http://localhost:8000/api/business-accounts/me', {
headers: { 'Authorization': `Bearer ${token}` }
})
.then(res => res.json())
.then(account => {
console.log('业务账号:', account);
// 步骤2: 获取合同列表
return fetch('http://localhost:8000/api/contracts/me?skip=0&limit=10', {
headers: { 'Authorization': `Bearer ${token}` }
});
})
.then(res => res.json())
.then(data => {
console.log(`共有 ${data.total} 个合同`);
if (data.items.length > 0) {
// 查看第一个合同详情
return fetch(`http://localhost:8000/api/contracts/${data.items[0].id}`, {
headers: { 'Authorization': `Bearer ${token}` }
});
}
})
.then(res => res && res.json())
.then(contract => {
console.log('合同详情:', contract);
// 步骤3: 更新合同签署状态(示例:标记为已签署)
if (contract && !contract.is_signed) {
return fetch(`http://localhost:8000/api/contracts/${contract.id}/sign-status`, {
method: 'PATCH',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ is_signed: true })
});
}
})
.then(res => res && res.json())
.then(updatedContract => updatedContract && console.log('签署状态已更新:', updatedContract));
场景4: 查看项目和下载文件
const token = localStorage.getItem('token');
// 步骤1: 获取项目列表
fetch('http://localhost:8000/api/projects/me?skip=0&limit=10', {
headers: { 'Authorization': `Bearer ${token}` }
})
.then(res => res.json())
.then(data => {
console.log(`共有 ${data.total} 个项目`);
if (data.items.length > 0) {
const project = data.items[0];
// 步骤2: 获取项目文件列表
return fetch(`http://localhost:8000/api/projects/${project.id}/files?skip=0&limit=100`, {
headers: { 'Authorization': `Bearer ${token}` }
});
}
})
.then(res => res && res.json())
.then(fileData => {
if (fileData && fileData.items.length > 0) {
const file = fileData.items[0];
// 步骤3: 获取文件下载URL
return fetch(`http://localhost:8000/api/projects/files/${file.id}/download-url`, {
method: 'POST',
headers: { 'Authorization': `Bearer ${token}` }
});
}
})
.then(res => res && res.json())
.then(downloadData => {
if (downloadData) {
console.log('下载URL:', downloadData.download_url);
// 使用下载URL下载文件
window.open(downloadData.download_url);
}
});
前端实现建议
1. Token管理
// Token存储
class AuthService {
setToken(token) {
localStorage.setItem('access_token', token);
}
getToken() {
return localStorage.getItem('access_token');
}
removeToken() {
localStorage.removeItem('access_token');
}
isLoggedIn() {
return !!this.getToken();
}
}
2. API请求封装
class ApiClient {
constructor(baseURL = 'http://localhost:8000/api') {
this.baseURL = baseURL;
}
async request(endpoint, options = {}) {
const url = `${this.baseURL}${endpoint}`;
const token = localStorage.getItem('access_token');
const headers = {
'Content-Type': 'application/json',
...options.headers
};
if (token) {
headers['Authorization'] = `Bearer ${token}`;
}
const response = await fetch(url, {
...options,
headers
});
if (!response.ok) {
if (response.status === 401) {
// Token过期,跳转登录
localStorage.removeItem('access_token');
window.location.href = '/login';
}
const error = await response.json();
throw new Error(error.detail || 'Request failed');
}
// 204 No Content
if (response.status === 204) {
return null;
}
return response.json();
}
get(endpoint, params = {}) {
const queryString = new URLSearchParams(params).toString();
const url = queryString ? `${endpoint}?${queryString}` : endpoint;
return this.request(url, { method: 'GET' });
}
post(endpoint, data) {
return this.request(endpoint, {
method: 'POST',
body: JSON.stringify(data)
});
}
put(endpoint, data) {
return this.request(endpoint, {
method: 'PUT',
body: JSON.stringify(data)
});
}
patch(endpoint, data) {
return this.request(endpoint, {
method: 'PATCH',
body: JSON.stringify(data)
});
}
delete(endpoint) {
return this.request(endpoint, { method: 'DELETE' });
}
}
// 使用示例
const api = new ApiClient();
// 登录
api.post('/auth/login', {
email: 'user@example.com',
password: 'password123'
}).then(data => {
localStorage.setItem('access_token', data.access_token);
});
// 获取工单列表
api.get('/tickets', { skip: 0, limit: 10 })
.then(data => console.log(data));
// 创建工单
api.post('/tickets', {
title: '问题标题',
ticket_type: 'technical',
content: '问题描述'
}).then(ticket => console.log(ticket));
3. 错误处理
// 统一错误处理
function handleApiError(error) {
// 根据错误类型显示不同提示
if (error.message.includes('验证码')) {
showNotification('验证码错误,请重新获取', 'error');
} else if (error.message.includes('权限')) {
showNotification('权限不足', 'error');
} else {
showNotification('操作失败,请稍后重试', 'error');
}
}
// 使用
api.post('/tickets', data)
.then(ticket => {
showNotification('工单创建成功', 'success');
})
.catch(handleApiError);
4. 分页组件数据
// 分页数据获取
async function fetchTickets(page = 1, pageSize = 10) {
const skip = (page - 1) * pageSize;
const data = await api.get('/tickets', { skip, limit: pageSize });
return {
items: data.items,
total: data.total,
currentPage: page,
totalPages: Math.ceil(data.total / pageSize)
};
}
// 使用
fetchTickets(1, 10).then(paginatedData => {
// 渲染列表
renderTicketList(paginatedData.items);
// 渲染分页器
renderPagination(paginatedData);
});
5. Markdown渲染
合同和项目的概述使用 Markdown 格式,前端需要渲染:
// 使用 marked 库渲染 Markdown
import { marked } from 'marked';
function renderMarkdown(markdown) {
return marked.parse(markdown);
}
// React 示例
function ContractDetail({ contract }) {
const html = renderMarkdown(contract.content_markdown);
return <div dangerouslySetInnerHTML={{ __html: html }} />;
}
6. 文件下载处理
// 获取并下载文件
async function downloadFile(fileId) {
try {
// 获取下载URL
const { download_url } = await api.post(`/projects/files/${fileId}/download-url`);
// 创建临时链接下载
const link = document.createElement('a');
link.href = download_url;
link.download = ''; // 让浏览器自动识别文件名
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
} catch (error) {
handleApiError(error);
}
}
开发环境说明
验证码获取
开发环境:
- 如果未配置邮件服务,验证码会输出到服务器控制台
- 可以从服务器日志中查看验证码
生产环境:
- 验证码会通过邮件发送到用户邮箱
- 有效期为10分钟
附录
时间格式
所有时间字段使用 ISO 8601 格式:
2024-01-01T10:30:00
2024-01-01T10:30:00Z // UTC时间
JavaScript解析示例:
const date = new Date('2024-01-01T10:30:00Z');
console.log(date.toLocaleString()); // 本地时间格式
工单类型中英文对照
| 英文 | 中文 | 说明 |
|---|---|---|
| financial | 财务问题 | 账单、付款、发票等 |
| technical | 技术问题 | 系统bug、功能异常等 |
| business | 业务问题 | 业务咨询、流程问题等 |
工单状态中英文对照
| 英文 | 中文 | 说明 |
|---|---|---|
| pending | 待回复 | 工单已创建,等待管理员处理 |
| replied | 已回复 | 管理员已回复,工单处理完成 |
业务账号状态中英文对照
| 英文 | 中文 | 说明 |
|---|---|---|
| pending | 待审核 | 已申请,等待管理员审核 |
| active | 已激活 | 已分配专属邮箱,可以正常使用 |
| disabled | 已禁用 | 账号已被禁用 |
联系支持
如有API使用问题,请:
- 查看 Swagger文档 - 可在线测试(仅限已登录用户)
- 查看服务器日志获取详细错误信息
- 联系技术支持团队
文档版本: v2.0.0
最后更新: 2025-11-25
维护者: Dreamreflex DevOps Team
目标用户: 客户及二次开发者