# Admin Service API 文档 ## 目录 - [1. API 概述](#1-api-概述) - [2. 认证](#2-认证) - [3. 通用响应格式](#3-通用响应格式) - [4. 错误处理](#4-错误处理) - [5. API 端点](#5-api-端点) - [6. 数据模型](#6-数据模型) - [7. 使用示例](#7-使用示例) --- ## 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 认证。 **计划认证方案**: ```http Authorization: Bearer ``` **获取 Token** (待实现): ```http POST /api/v1/auth/login Content-Type: application/json { "username": "admin", "password": "password123" } ``` **响应**: ```json { "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "expiresIn": 7200 } ``` ### 2.2 权限级别 (待实现) | 角色 | 权限 | |-----|------| | **admin** | 完全权限:创建、启用、禁用、删除版本 | | **developer** | 创建、查询版本 | | **public** | 仅检查更新 (无需认证) | --- ## 3. 通用响应格式 ### 3.1 成功响应 **200 OK** - 查询成功: ```json { "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** - 创建成功: ```json { "id": "550e8400-e29b-41d4-a716-446655440000", "platform": "android", "versionCode": 101, ... } ``` **204 No Content** - 操作成功无返回内容 ### 3.2 分页响应 (待实现) ```json { "data": [...], "meta": { "total": 50, "page": 1, "pageSize": 10, "totalPages": 5 } } ``` --- ## 4. 错误处理 ### 4.1 错误响应格式 ```json { "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` **权限**: 需要认证 (待实现) **请求体**: ```json { "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` ```json { "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" } ``` **错误响应**: ```json // 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 示例**: ```bash 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` | **请求示例**: ```http GET /api/v1/version?platform=android&isEnabled=true ``` **响应**: `200 OK` ```json [ { "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 示例**: ```bash curl -X GET "http://localhost:3005/api/v1/version?platform=android&isEnabled=true" ``` --- ### 5.3 查询单个版本 **端点**: `GET /api/v1/version/:id` **权限**: 需要认证 (待实现) **路径参数**: | 参数 | 类型 | 说明 | |-----|------|------| | `id` | string (UUID) | 版本 ID | **请求示例**: ```http GET /api/v1/version/550e8400-e29b-41d4-a716-446655440000 ``` **响应**: `200 OK` ```json { "id": "550e8400-e29b-41d4-a716-446655440000", "platform": "android", "versionCode": 100, "versionName": "1.0.0", ... } ``` **错误响应**: ```json // 404 Not Found { "statusCode": 404, "message": "Version not found", "error": "Not Found" } ``` **cURL 示例**: ```bash 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 | **请求体**: ```json { "updatedBy": "admin" } ``` **请求示例**: ```http PATCH /api/v1/version/550e8400-e29b-41d4-a716-446655440000/enable Content-Type: application/json { "updatedBy": "admin" } ``` **响应**: `204 No Content` **错误响应**: ```json // 404 Not Found { "statusCode": 404, "message": "Version not found", "error": "Not Found" } ``` **cURL 示例**: ```bash 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 | **请求体**: ```json { "updatedBy": "admin" } ``` **请求示例**: ```http PATCH /api/v1/version/550e8400-e29b-41d4-a716-446655440000/disable Content-Type: application/json { "updatedBy": "admin" } ``` **响应**: `204 No Content` **业务逻辑**: - 禁用版本时,会自动将 `isForceUpdate` 设置为 `false` - 禁用后的版本不会出现在 "检查更新" 结果中 **cURL 示例**: ```bash 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` | **请求示例**: ```http GET /api/v1/version/check?platform=android&versionCode=100 ``` **响应 1**: `200 OK` - 有更新 ```json { "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` - 无更新 ```json { "hasUpdate": false } ``` **响应 3**: `200 OK` - 强制更新 ```json { "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!" } ``` **错误响应**: ```json // 400 Bad Request - 参数缺失 { "statusCode": 400, "message": ["platform should not be empty", "versionCode must be a number"], "error": "Bad Request" } ``` **业务逻辑**: 1. 查询指定平台的所有启用版本 (`isEnabled = true`) 2. 按 `versionCode` 降序排序,取第一个作为最新版本 3. 如果最新版本的 `versionCode` > 当前版本号,返回更新信息 4. 否则返回 `hasUpdate: false` **移动端处理逻辑**: ```typescript // 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 示例**: ```bash curl -X GET "http://localhost:3005/api/v1/version/check?platform=android&versionCode=100" ``` --- ## 6. 数据模型 ### 6.1 AppVersion (应用版本) ```typescript 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 (平台枚举) ```typescript enum Platform { ANDROID = 'android', IOS = 'ios', } ``` ### 6.3 VersionCheckResult (版本检查结果) ```typescript interface VersionCheckResult { hasUpdate: boolean; // 是否有更新 latestVersion?: string; // 最新版本名称 downloadUrl?: string; // 下载链接 isForceUpdate?: boolean; // 是否强制更新 changelog?: string; // 更新日志 } ``` --- ## 7. 使用示例 ### 7.1 完整发版流程 #### 步骤 1: 创建 Android 新版本 ```bash 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: 验证版本已创建 ```bash curl -X GET "http://localhost:3005/api/v1/version?platform=android&isEnabled=true" ``` #### 步骤 3: 移动端检查更新 ```bash # 用户当前版本号 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: 发现问题,紧急禁用版本 ```bash curl -X PATCH http://localhost:3005/api/v1/version/550e8400-e29b-41d4-a716-446655440001/disable \ -H "Content-Type: application/json" \ -d '{"updatedBy": "admin"}' ``` #### 步骤 5: 创建修复版本 ```bash 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 版本发布 ```bash 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 (部分示例) ```json { "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 文件托管建议 1. **使用 CDN**: 加速全球用户下载 2. **HTTPS**: 确保传输安全 3. **文件命名**: `app-{platform}-v{versionName}.{ext}` - Android: `app-android-v1.0.0.apk` - iOS: `app-ios-v1.0.0.ipa` ### 9.2 SHA256 校验流程 **服务端计算** (发版时): ```bash # Linux/macOS sha256sum app-android-v1.0.0.apk # Windows certutil -hashfile app-android-v1.0.0.apk SHA256 ``` **移动端校验** (下载后): ```dart // Flutter 示例 import 'package:crypto/crypto.dart'; import 'dart:io'; Future 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**: 禁用问题版本,启用旧版本 ```bash # 禁用 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 ```bash # 创建 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` 区分: ```bash # 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: 如何实现灰度发布? 当前版本不支持,未来可扩展: ```typescript // 计划实现 interface AppVersion { ... releaseType: 'full' | 'gray'; // 发布类型 grayRatio?: number; // 灰度比例 (0-100) grayUserIds?: string[]; // 灰度用户列表 } ``` --- **最后更新**: 2025-12-03 **版本**: 1.0.0 **维护者**: RWA Durian Team