22 KiB
Admin Service API 文档
目录
1. API 概述
1.1 基本信息
| 项目 | 值 |
|---|---|
| Base URL | http://localhost:3005/api/v1 |
| 协议 | HTTP/HTTPS |
| 数据格式 | JSON |
| 字符编码 | UTF-8 |
| API 版本 | v1 |
1.2 API 分类
| 分类 | 端点数 | 说明 |
|---|---|---|
| 版本管理 | 5 | 创建、启用、禁用、查询版本 |
| 版本检查 | 1 | 移动端检查更新 |
2. 认证
2.1 认证方式 (待实现)
当前版本 API 未实现认证机制,生产环境需要添加 JWT 认证。
计划认证方案:
Authorization: Bearer <JWT_TOKEN>
获取 Token (待实现):
POST /api/v1/auth/login
Content-Type: application/json
{
"username": "admin",
"password": "password123"
}
响应:
{
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expiresIn": 7200
}
2.2 权限级别 (待实现)
| 角色 | 权限 |
|---|---|
| admin | 完全权限:创建、启用、禁用、删除版本 |
| developer | 创建、查询版本 |
| public | 仅检查更新 (无需认证) |
3. 通用响应格式
3.1 成功响应
200 OK - 查询成功:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"platform": "android",
"versionCode": 100,
"versionName": "1.0.0",
"buildNumber": "1",
"downloadUrl": "https://cdn.example.com/app-v1.0.0.apk",
"fileSize": 52428800,
"fileSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"changelog": "Initial release",
"isEnabled": true,
"isForceUpdate": false,
"createdBy": "admin",
"createdAt": "2025-01-02T10:00:00.000Z",
"updatedBy": "admin",
"updatedAt": "2025-01-02T10:00:00.000Z"
}
201 Created - 创建成功:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"platform": "android",
"versionCode": 101,
...
}
204 No Content - 操作成功无返回内容
3.2 分页响应 (待实现)
{
"data": [...],
"meta": {
"total": 50,
"page": 1,
"pageSize": 10,
"totalPages": 5
}
}
4. 错误处理
4.1 错误响应格式
{
"statusCode": 400,
"message": "Invalid version code",
"error": "Bad Request",
"timestamp": "2025-01-02T10:00:00.000Z",
"path": "/api/v1/version"
}
4.2 HTTP 状态码
| 状态码 | 说明 | 常见场景 |
|---|---|---|
| 200 | 成功 | 查询成功 |
| 201 | 已创建 | 创建版本成功 |
| 204 | 无内容 | 启用/禁用成功 |
| 400 | 请求错误 | 参数验证失败 |
| 401 | 未认证 | Token 缺失或无效 |
| 403 | 禁止访问 | 权限不足 |
| 404 | 未找到 | 版本不存在 |
| 409 | 冲突 | 版本号重复 |
| 500 | 服务器错误 | 内部异常 |
4.3 业务错误码 (待实现)
| 错误码 | 说明 |
|---|---|
VERSION_ALREADY_EXISTS |
版本已存在 |
INVALID_VERSION_CODE |
版本号格式错误 |
INVALID_VERSION_NAME |
版本名称格式错误 |
INVALID_SHA256 |
SHA256 格式错误 |
VERSION_NOT_FOUND |
版本不存在 |
FILE_SIZE_INVALID |
文件大小无效 |
5. API 端点
5.1 创建版本
端点: POST /api/v1/version
权限: 需要认证 (待实现)
请求体:
{
"platform": "android",
"versionCode": 100,
"versionName": "1.0.0",
"buildNumber": "1",
"downloadUrl": "https://cdn.example.com/app-v1.0.0.apk",
"fileSize": 52428800,
"fileSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"changelog": "Initial release",
"isEnabled": true,
"isForceUpdate": false,
"createdBy": "admin"
}
字段说明:
| 字段 | 类型 | 必填 | 说明 | 验证规则 |
|---|---|---|---|---|
platform |
string | ✅ | 平台 | android 或 ios |
versionCode |
number | ✅ | 版本号 | 正整数 |
versionName |
string | ✅ | 版本名称 | 语义化版本 (x.y.z) |
buildNumber |
string | ✅ | 构建号 | 非空字符串 |
downloadUrl |
string | ✅ | 下载链接 | 有效 URL |
fileSize |
number | ✅ | 文件大小 (字节) | > 0 |
fileSha256 |
string | ✅ | SHA256 哈希 | 64 位十六进制 |
changelog |
string | ✅ | 更新日志 | 非空字符串 |
isEnabled |
boolean | ❌ | 是否启用 | 默认 true |
isForceUpdate |
boolean | ❌ | 是否强制更新 | 默认 false |
createdBy |
string | ✅ | 创建者 | 非空字符串 |
响应: 201 Created
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"platform": "android",
"versionCode": 100,
"versionName": "1.0.0",
"buildNumber": "1",
"downloadUrl": "https://cdn.example.com/app-v1.0.0.apk",
"fileSize": 52428800,
"fileSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"changelog": "Initial release",
"isEnabled": true,
"isForceUpdate": false,
"createdBy": "admin",
"createdAt": "2025-01-02T10:00:00.000Z",
"updatedBy": "admin",
"updatedAt": "2025-01-02T10:00:00.000Z"
}
错误响应:
// 400 Bad Request - 版本号无效
{
"statusCode": 400,
"message": "Version code must be a positive integer",
"error": "Bad Request"
}
// 409 Conflict - 版本已存在
{
"statusCode": 409,
"message": "Version already exists for this platform",
"error": "Conflict"
}
cURL 示例:
curl -X POST http://localhost:3005/api/v1/version \
-H "Content-Type: application/json" \
-d '{
"platform": "android",
"versionCode": 100,
"versionName": "1.0.0",
"buildNumber": "1",
"downloadUrl": "https://cdn.example.com/app-v1.0.0.apk",
"fileSize": 52428800,
"fileSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"changelog": "Initial release",
"isEnabled": true,
"isForceUpdate": false,
"createdBy": "admin"
}'
5.2 查询所有版本
端点: GET /api/v1/version
权限: 需要认证 (待实现)
查询参数:
| 参数 | 类型 | 必填 | 说明 | 示例 |
|---|---|---|---|---|
platform |
string | ❌ | 过滤平台 | android |
isEnabled |
boolean | ❌ | 过滤启用状态 | true |
page |
number | ❌ | 页码 (待实现) | 1 |
pageSize |
number | ❌ | 每页数量 (待实现) | 10 |
请求示例:
GET /api/v1/version?platform=android&isEnabled=true
响应: 200 OK
[
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"platform": "android",
"versionCode": 101,
"versionName": "1.0.1",
...
},
{
"id": "550e8400-e29b-41d4-a716-446655440001",
"platform": "android",
"versionCode": 100,
"versionName": "1.0.0",
...
}
]
cURL 示例:
curl -X GET "http://localhost:3005/api/v1/version?platform=android&isEnabled=true"
5.3 查询单个版本
端点: GET /api/v1/version/:id
权限: 需要认证 (待实现)
路径参数:
| 参数 | 类型 | 说明 |
|---|---|---|
id |
string (UUID) | 版本 ID |
请求示例:
GET /api/v1/version/550e8400-e29b-41d4-a716-446655440000
响应: 200 OK
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"platform": "android",
"versionCode": 100,
"versionName": "1.0.0",
...
}
错误响应:
// 404 Not Found
{
"statusCode": 404,
"message": "Version not found",
"error": "Not Found"
}
cURL 示例:
curl -X GET http://localhost:3005/api/v1/version/550e8400-e29b-41d4-a716-446655440000
5.4 启用版本
端点: PATCH /api/v1/version/:id/enable
权限: 需要认证 (待实现)
路径参数:
| 参数 | 类型 | 说明 |
|---|---|---|
id |
string (UUID) | 版本 ID |
请求体:
{
"updatedBy": "admin"
}
请求示例:
PATCH /api/v1/version/550e8400-e29b-41d4-a716-446655440000/enable
Content-Type: application/json
{
"updatedBy": "admin"
}
响应: 204 No Content
错误响应:
// 404 Not Found
{
"statusCode": 404,
"message": "Version not found",
"error": "Not Found"
}
cURL 示例:
curl -X PATCH http://localhost:3005/api/v1/version/550e8400-e29b-41d4-a716-446655440000/enable \
-H "Content-Type: application/json" \
-d '{"updatedBy": "admin"}'
5.5 禁用版本
端点: PATCH /api/v1/version/:id/disable
权限: 需要认证 (待实现)
路径参数:
| 参数 | 类型 | 说明 |
|---|---|---|
id |
string (UUID) | 版本 ID |
请求体:
{
"updatedBy": "admin"
}
请求示例:
PATCH /api/v1/version/550e8400-e29b-41d4-a716-446655440000/disable
Content-Type: application/json
{
"updatedBy": "admin"
}
响应: 204 No Content
业务逻辑:
- 禁用版本时,会自动将
isForceUpdate设置为false - 禁用后的版本不会出现在 "检查更新" 结果中
cURL 示例:
curl -X PATCH http://localhost:3005/api/v1/version/550e8400-e29b-41d4-a716-446655440000/disable \
-H "Content-Type: application/json" \
-d '{"updatedBy": "admin"}'
5.6 检查更新 (移动端)
端点: GET /api/v1/version/check
权限: 公开 (无需认证)
查询参数:
| 参数 | 类型 | 必填 | 说明 | 示例 |
|---|---|---|---|---|
platform |
string | ✅ | 平台 | android |
versionCode |
number | ✅ | 当前版本号 | 100 |
请求示例:
GET /api/v1/version/check?platform=android&versionCode=100
响应 1: 200 OK - 有更新
{
"hasUpdate": true,
"latestVersion": "1.0.1",
"downloadUrl": "https://cdn.example.com/app-v1.0.1.apk",
"isForceUpdate": false,
"changelog": "Bug fixes and performance improvements"
}
响应 2: 200 OK - 无更新
{
"hasUpdate": false
}
响应 3: 200 OK - 强制更新
{
"hasUpdate": true,
"latestVersion": "2.0.0",
"downloadUrl": "https://cdn.example.com/app-v2.0.0.apk",
"isForceUpdate": true,
"changelog": "Major security update. Please update immediately!"
}
错误响应:
// 400 Bad Request - 参数缺失
{
"statusCode": 400,
"message": ["platform should not be empty", "versionCode must be a number"],
"error": "Bad Request"
}
业务逻辑:
- 查询指定平台的所有启用版本 (
isEnabled = true) - 按
versionCode降序排序,取第一个作为最新版本 - 如果最新版本的
versionCode> 当前版本号,返回更新信息 - 否则返回
hasUpdate: false
移动端处理逻辑:
// Flutter 示例
async function checkForUpdate() {
const response = await fetch(
`${API_BASE}/version/check?platform=android&versionCode=100`
);
const data = await response.json();
if (data.hasUpdate) {
if (data.isForceUpdate) {
// 显示强制更新对话框(无法关闭)
showForceUpdateDialog({
version: data.latestVersion,
downloadUrl: data.downloadUrl,
changelog: data.changelog,
});
} else {
// 显示普通更新对话框(可以关闭)
showUpdateDialog({
version: data.latestVersion,
downloadUrl: data.downloadUrl,
changelog: data.changelog,
});
}
}
}
cURL 示例:
curl -X GET "http://localhost:3005/api/v1/version/check?platform=android&versionCode=100"
6. 数据模型
6.1 AppVersion (应用版本)
interface AppVersion {
id: string; // UUID
platform: 'android' | 'ios';// 平台
versionCode: number; // 版本号(整数)
versionName: string; // 版本名称(x.y.z)
buildNumber: string; // 构建号
downloadUrl: string; // 下载链接
fileSize: number; // 文件大小(字节)
fileSha256: string; // SHA256 哈希
changelog: string; // 更新日志
isEnabled: boolean; // 是否启用
isForceUpdate: boolean; // 是否强制更新
createdBy: string; // 创建者
createdAt: string; // 创建时间(ISO 8601)
updatedBy: string; // 更新者
updatedAt: string; // 更新时间(ISO 8601)
}
6.2 Platform (平台枚举)
enum Platform {
ANDROID = 'android',
IOS = 'ios',
}
6.3 VersionCheckResult (版本检查结果)
interface VersionCheckResult {
hasUpdate: boolean; // 是否有更新
latestVersion?: string; // 最新版本名称
downloadUrl?: string; // 下载链接
isForceUpdate?: boolean; // 是否强制更新
changelog?: string; // 更新日志
}
7. 使用示例
7.1 完整发版流程
步骤 1: 创建 Android 新版本
curl -X POST http://localhost:3005/api/v1/version \
-H "Content-Type: application/json" \
-d '{
"platform": "android",
"versionCode": 101,
"versionName": "1.0.1",
"buildNumber": "20250102001",
"downloadUrl": "https://cdn.rwadurian.com/android/app-v1.0.1.apk",
"fileSize": 54525952,
"fileSha256": "a3c5d7e9f1b2c4d6e8f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2",
"changelog": "1. Fixed mining reward calculation bug\n2. Improved UI performance\n3. Added dark mode support",
"isEnabled": true,
"isForceUpdate": false,
"createdBy": "admin"
}'
步骤 2: 验证版本已创建
curl -X GET "http://localhost:3005/api/v1/version?platform=android&isEnabled=true"
步骤 3: 移动端检查更新
# 用户当前版本号 100
curl -X GET "http://localhost:3005/api/v1/version/check?platform=android&versionCode=100"
# 响应:
{
"hasUpdate": true,
"latestVersion": "1.0.1",
"downloadUrl": "https://cdn.rwadurian.com/android/app-v1.0.1.apk",
"isForceUpdate": false,
"changelog": "1. Fixed mining reward calculation bug\n2. Improved UI performance\n3. Added dark mode support"
}
步骤 4: 发现问题,紧急禁用版本
curl -X PATCH http://localhost:3005/api/v1/version/550e8400-e29b-41d4-a716-446655440001/disable \
-H "Content-Type: application/json" \
-d '{"updatedBy": "admin"}'
步骤 5: 创建修复版本
curl -X POST http://localhost:3005/api/v1/version \
-H "Content-Type: application/json" \
-d '{
"platform": "android",
"versionCode": 102,
"versionName": "1.0.2",
"buildNumber": "20250102002",
"downloadUrl": "https://cdn.rwadurian.com/android/app-v1.0.2.apk",
"fileSize": 54530048,
"fileSha256": "b4d6e8f0a2c3d5e7f9a1b3c4d6e8f0a2b3c5d7e9f1a2b4c6d8e0f1a3b5c7d9e1",
"changelog": "Hotfix: Fixed critical security vulnerability",
"isEnabled": true,
"isForceUpdate": true,
"createdBy": "admin"
}'
7.2 iOS 版本发布
curl -X POST http://localhost:3005/api/v1/version \
-H "Content-Type: application/json" \
-d '{
"platform": "ios",
"versionCode": 1,
"versionName": "1.0.0",
"buildNumber": "1",
"downloadUrl": "https://apps.apple.com/app/rwa-durian/id123456789",
"fileSize": 67108864,
"fileSha256": "c5e7f9a1b3c4d6e8f0a2b3c5d7e9f1a2b4c6d8e0f1a3b5c7d9e1f2a4b6c8d0e2",
"changelog": "Initial iOS release",
"isEnabled": true,
"isForceUpdate": false,
"createdBy": "admin"
}'
7.3 Postman Collection (部分示例)
{
"info": {
"name": "Admin Service API",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"item": [
{
"name": "Create Android Version",
"request": {
"method": "POST",
"header": [{"key": "Content-Type", "value": "application/json"}],
"body": {
"mode": "raw",
"raw": "{\n \"platform\": \"android\",\n \"versionCode\": 100,\n \"versionName\": \"1.0.0\",\n \"buildNumber\": \"1\",\n \"downloadUrl\": \"https://cdn.example.com/app-v1.0.0.apk\",\n \"fileSize\": 52428800,\n \"fileSha256\": \"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\",\n \"changelog\": \"Initial release\",\n \"isEnabled\": true,\n \"isForceUpdate\": false,\n \"createdBy\": \"admin\"\n}"
},
"url": {
"raw": "http://localhost:3005/api/v1/version",
"protocol": "http",
"host": ["localhost"],
"port": "3005",
"path": ["api", "v1", "version"]
}
}
},
{
"name": "Check For Update",
"request": {
"method": "GET",
"url": {
"raw": "http://localhost:3005/api/v1/version/check?platform=android&versionCode=100",
"protocol": "http",
"host": ["localhost"],
"port": "3005",
"path": ["api", "v1", "version", "check"],
"query": [
{"key": "platform", "value": "android"},
{"key": "versionCode", "value": "100"}
]
}
}
}
]
}
8. 版本控制策略
8.1 版本号规则
VersionCode (数字版本号):
- 每次发布递增 1
- Android: 从 1 开始
- iOS: 从 1 开始
- 用于版本比较 (机器识别)
VersionName (语义化版本):
- 格式:
MAJOR.MINOR.PATCH(例如:1.2.3) - 用于用户展示 (人类可读)
BuildNumber (构建号):
- 格式: 自定义 (建议:
YYYYMMDDXXX) - 例如:
20250102001= 2025年1月2日第1次构建
8.2 更新策略
| 场景 | isForceUpdate | 说明 |
|---|---|---|
| 功能更新 | false |
用户可选择更新时机 |
| Bug 修复 | false |
建议更新,但不强制 |
| 安全漏洞 | true |
必须更新才能继续使用 |
| API 破坏性变更 | true |
旧版本无法正常工作 |
9. 最佳实践
9.1 文件托管建议
- 使用 CDN: 加速全球用户下载
- HTTPS: 确保传输安全
- 文件命名:
app-{platform}-v{versionName}.{ext}- Android:
app-android-v1.0.0.apk - iOS:
app-ios-v1.0.0.ipa
- Android:
9.2 SHA256 校验流程
服务端计算 (发版时):
# Linux/macOS
sha256sum app-android-v1.0.0.apk
# Windows
certutil -hashfile app-android-v1.0.0.apk SHA256
移动端校验 (下载后):
// Flutter 示例
import 'package:crypto/crypto.dart';
import 'dart:io';
Future<bool> verifyApkIntegrity(String filePath, String expectedSha256) async {
final file = File(filePath);
final bytes = await file.readAsBytes();
final digest = sha256.convert(bytes);
return digest.toString() == expectedSha256.toLowerCase();
}
// 使用
final isValid = await verifyApkIntegrity(
'/storage/emulated/0/Download/app.apk',
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
);
if (!isValid) {
throw Exception('File integrity check failed! Possible tampering detected.');
}
9.3 更新日志编写规范
推荐格式:
1. 新功能:添加暗黑模式支持
2. 优化:挖矿页面性能提升 30%
3. 修复:交易历史加载失败问题
4. 安全:修复账户导入漏洞
避免:
- ❌ "Bug fixes and improvements" (太笼统)
- ❌ 技术术语 (普通用户不理解)
- ✅ 简洁明了,面向用户
10. 常见问题
Q1: 如何回滚版本?
方案 1: 禁用问题版本,启用旧版本
# 禁用 v1.0.1
curl -X PATCH http://localhost:3005/api/v1/version/{v1.0.1-id}/disable \
-H "Content-Type: application/json" \
-d '{"updatedBy": "admin"}'
# 启用 v1.0.0
curl -X PATCH http://localhost:3005/api/v1/version/{v1.0.0-id}/enable \
-H "Content-Type: application/json" \
-d '{"updatedBy": "admin"}'
方案 2: 创建新版本,使用更高的 versionCode
# 创建 v1.0.0-hotfix (versionCode = 103)
curl -X POST http://localhost:3005/api/v1/version \
-H "Content-Type: application/json" \
-d '{
"platform": "android",
"versionCode": 103,
"versionName": "1.0.0",
"buildNumber": "20250102003",
...
}'
Q2: 如何处理多渠道包 (Google Play, 自建服务器)?
当前版本不支持,建议通过 buildNumber 区分:
# Google Play 渠道
{
"versionCode": 100,
"versionName": "1.0.0",
"buildNumber": "100-gplay",
"downloadUrl": "https://play.google.com/store/apps/details?id=com.rwa.durian",
...
}
# 自建渠道
{
"versionCode": 100,
"versionName": "1.0.0",
"buildNumber": "100-self",
"downloadUrl": "https://cdn.rwadurian.com/android/app-v1.0.0.apk",
...
}
Q3: 如何实现灰度发布?
当前版本不支持,未来可扩展:
// 计划实现
interface AppVersion {
...
releaseType: 'full' | 'gray'; // 发布类型
grayRatio?: number; // 灰度比例 (0-100)
grayUserIds?: string[]; // 灰度用户列表
}
最后更新: 2025-12-03 版本: 1.0.0 维护者: RWA Durian Team