Files

797 lines
14 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package main
import (
"log"
"verification-platform-backend/internal/database"
"verification-platform-backend/internal/model"
)
func main() {
database.Init()
apiDocContent := `# 应用API
## 概述
本文档描述了应用对接平台所需的所有API。每个应用都有独立的API地址,通过应用的密钥(appKey)进行访问。
## 基础信息
- **基础URL**: http://your-domain.com/api/v1/app/{appKey}
- **请求方式**: GET/POST
- **数据格式**: JSON
- **字符编码**: UTF-8
## 通信加密
所有API支持加密通信,根据应用的安全设置进行加密解密。
### 加密方式
| 类型 | 说明 |
|------|------|
| none | 不加密,明文传输 |
| aes | AES-GCM加密 |
| rc4 | RC4流加密 |
### 加密请求格式
` + "```json" + `
{
"data": "加密后的数据(Base64编码)"
}
` + "```" + `
### 加密响应格式
` + "```json" + `
{
"data": "加密后的数据(Base64编码)"
}
` + "```" + `
---
## 公告管理
### 获取公告列表
获取应用的公告列表。
**请求**
` + "```" + `
GET /api/v1/app/{appKey}/announcements
` + "```" + `
**响应示例**
` + "```json" + `
{
"code": 200,
"message": "success",
"data": {
"announcements": [
{
"id": 1,
"title": "系统维护通知",
"content": "系统将于今晚进行维护",
"type": "warning",
"priority": "high",
"status": "active",
"created_at": "2024-01-01T00:00:00Z"
}
]
}
}
` + "```" + `
**字段说明**
| 字段 | 类型 | 说明 |
|------|------|------|
| type | string | 公告类型(info、warning、urgent |
| priority | string | 优先级(normal、medium、high |
| status | string | 状态(draft、active |
---
## 版本更新
### 检测更新
检查应用是否有新版本可用。
**请求**
` + "```" + `
GET /api/v1/app/{appKey}/check-update?version=1.0.0
` + "```" + `
**请求参数**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| version | string | 是 | 当前版本号 |
**响应示例**
` + "```json" + `
{
"code": 200,
"message": "success",
"data": {
"has_update": true,
"latest_version": "2.0.0",
"download_url": "http://example.com/download/app-v2.0.0.zip",
"file_size": 10240000,
"update_strategy": "optional",
"update_type": "full",
"update_method": "auto",
"description": "新版本修复了若干bug"
}
}
` + "```" + `
---
## 应用信息
### 获取应用配置
获取应用的基本配置信息。
**请求**
` + "```" + `
GET /api/v1/app/{appKey}/info
` + "```" + `
**响应示例**
` + "```json" + `
{
"code": 200,
"message": "success",
"data": {
"app_id": 1,
"app_name": "示例应用",
"description": "这是一个示例应用",
"billing_type": "subscription",
"encrypt_type": "aes",
"bind_type": "device",
"max_devices": 1,
"multi_open": false,
"enable_trial": true,
"trial_duration": 7
}
}
` + "```" + `
**字段说明**
| 字段 | 类型 | 说明 |
|------|------|------|
| billing_type | string | 计费类型(subscription订阅、time计时、point点数) |
| encrypt_type | string | 加密类型(none、aes、rc4 |
| bind_type | string | 绑定类型(none、device、ip |
| enable_trial | bool | 是否启用试用 |
| trial_duration | int | 试用天数 |
---
## 用户认证
### 用户注册
注册新用户账号。
**请求**
` + "```" + `
POST /api/v1/app/{appKey}/register
` + "```" + `
**请求体**
` + "```json" + `
{
"username": "testuser",
"password": "password123",
"email": "test@example.com",
"device_id": "DEVICE-001"
}
` + "```" + `
**响应示例**
` + "```json" + `
{
"code": 200,
"message": "success",
"data": {
"user_id": 1,
"username": "testuser",
"message": "注册成功"
}
}
` + "```" + `
---
### 用户登录
用户登录获取账号信息。
**请求**
` + "```" + `
POST /api/v1/app/{appKey}/login
` + "```" + `
**请求体**
` + "```json" + `
{
"username": "testuser",
"password": "password123",
"device_id": "DEVICE-001"
}
` + "```" + `
**响应示例**
` + "```json" + `
{
"code": 200,
"message": "success",
"data": {
"user_id": 1,
"username": "testuser",
"balance": 100,
"is_trial": false,
"expiry_at": "2024-12-31T23:59:59Z",
"message": "登录成功"
}
}
` + "```" + `
**错误响应**
| 错误信息 | 说明 |
|----------|------|
| 用户不存在 | 用户名未注册 |
| 密码错误 | 密码不正确 |
| 余额不足 | 账户余额为0且已过期 |
| 设备绑定数量已达上限 | 超过最大设备数限制 |
| 多开数量已达上限 | 同一设备登录用户数超限 |
---
## 卡密充值
### 使用卡密充值
使用卡密为当前用户充值。
**请求**
` + "```" + `
POST /api/v1/app/{appKey}/recharge
` + "```" + `
**请求体**
` + "```json" + `
{
"user_id": 1,
"card_key": "CARD-1234567890"
}
` + "```" + `
**响应示例**
` + "```json" + `
{
"code": 200,
"message": "success",
"data": {
"balance": 200,
"expiry_at": "2024-12-31T23:59:59Z",
"message": "充值成功"
}
}
` + "```" + `
---
## 试用功能
### 申请试用
申请新用户试用。
**请求**
` + "```" + `
POST /api/v1/app/{appKey}/trial
` + "```" + `
**请求体**
` + "```json" + `
{
"user_id": 1,
"device_id": "DEVICE-001"
}
` + "```" + `
**响应示例**
` + "```json" + `
{
"code": 200,
"message": "success",
"data": {
"trial_start": "2024-01-01T00:00:00Z",
"trial_end": "2024-01-08T00:00:00Z",
"expiry_at": "2024-01-08T00:00:00Z",
"message": "试用成功"
}
}
` + "```" + `
---
## 设备管理
### 获取设备列表
获取用户绑定的设备列表。
**请求**
` + "```" + `
GET /api/v1/app/{appKey}/devices?user_id=1
` + "```" + `
**请求参数**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| user_id | int | 是 | 用户ID |
**响应示例**
` + "```json" + `
{
"code": 200,
"message": "success",
"data": {
"devices": [
{
"device_id": "DEVICE-001",
"device_name": "默认设备",
"last_active": "2024-01-01T12:00:00Z"
}
]
}
}
` + "```" + `
---
### 解绑设备
解绑用户的设备。
**请求**
` + "```" + `
POST /api/v1/app/{appKey}/unbind-device
` + "```" + `
**请求体**
` + "```json" + `
{
"user_id": 1,
"device_id": "DEVICE-001"
}
` + "```" + `
**响应示例**
` + "```json" + `
{
"code": 200,
"message": "success",
"data": {
"message": "解绑成功"
}
}
` + "```" + `
---
## 账户管理
### 获取账户信息
获取用户的详细账户信息。
**请求**
` + "```" + `
GET /api/v1/app/{appKey}/account?user_id=1
` + "```" + `
**请求参数**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| user_id | int | 是 | 用户ID |
**响应示例**
` + "```json" + `
{
"code": 200,
"message": "success",
"data": {
"user_id": 1,
"username": "testuser",
"email": "test@example.com",
"balance": 100,
"is_trial": false,
"trial_start": null,
"trial_end": null,
"expiry_at": "2024-12-31T23:59:59Z",
"device_id": "DEVICE-001",
"created_at": "2024-01-01T00:00:00Z"
}
}
` + "```" + `
---
### 心跳检测
发送心跳以保持在线状态。
**请求**
` + "```" + `
POST /api/v1/app/{appKey}/heartbeat
` + "```" + `
**请求体**
` + "```json" + `
{
"user_id": 1,
"device_id": "DEVICE-001"
}
` + "```" + `
**响应示例**
` + "```json" + `
{
"code": 200,
"message": "success",
"data": {
"status": "active",
"message": "心跳成功"
}
}
` + "```" + `
---
## 云端数据
### 获取云端常量
获取全局的云端常量配置。
**请求**
` + "```" + `
GET /api/v1/app/{appKey}/constants
` + "```" + `
**响应示例**
` + "```json" + `
{
"code": 200,
"message": "success",
"data": {
"constants": {
"max_connections": "10",
"timeout": "30",
"retry_times": "3"
}
}
}
` + "```" + `
---
### 获取云端变量
获取用户的云端变量。
**请求**
` + "```" + `
GET /api/v1/app/{appKey}/variables?user_id=1
` + "```" + `
**请求参数**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| user_id | int | 是 | 用户ID |
**响应示例**
` + "```json" + `
{
"code": 200,
"message": "success",
"data": {
"variables": {
"setting1": "value1",
"setting2": "value2"
}
}
}
` + "```" + `
---
### 修改云端变量
更新用户的云端变量。
**请求**
` + "```" + `
POST /api/v1/app/{appKey}/variables
` + "```" + `
**请求体**
` + "```json" + `
{
"user_id": 1,
"variables": {
"setting1": "new_value1",
"setting2": "new_value2"
}
}
` + "```" + `
**响应示例**
` + "```json" + `
{
"code": 200,
"message": "success",
"data": {
"message": "更新成功"
}
}
` + "```" + `
---
### 调用云端函数
调用云端定义的动态函数。
**请求**
` + "```" + `
POST /api/v1/app/{appKey}/call-function
` + "```" + `
**请求体**
` + "```json" + `
{
"function_name": "custom_function",
"parameters": {
"param1": "value1",
"param2": "value2"
}
}
` + "```" + `
**响应示例**
` + "```json" + `
{
"code": 200,
"message": "success",
"data": {
"result": "动态函数调用成功",
"data": {
"param1": "value1",
"param2": "value2"
}
}
}
` + "```" + `
---
## 错误码说明
| 错误码 | 说明 |
|--------|------|
| 200 | 请求成功 |
| 400 | 请求参数错误 |
| 401 | 未授权或认证失败 |
| 403 | 禁止访问(账号被禁用、已过期等) |
| 404 | 资源不存在 |
| 500 | 服务器内部错误 |
---
## 试用和免费时段
### 试用功能
- 订阅模式应用可以启用试用功能
- 新用户可以申请试用,试用时长由应用配置决定
- 试用用户只能试用一次
- 试用期间可以正常使用应用的所有功能
### 免费时段功能
- 订阅模式应用可以设置免费时间段
- 在免费时间段内,所有用户可以免费使用应用
- 免费时间段按每天设置,例如:00:00-06:00
---
## 安全建议
1. **使用HTTPS**: 生产环境建议使用HTTPS协议
2. **启用加密**: 建议启用AES加密保护通信安全
3. **定期更换密钥**: 定期更换应用的通信密钥
4. **验证设备**: 启用设备绑定功能防止账号共享
5. **限制并发**: 根据需要限制最大设备数和并发数
---
## 代码示例
### JavaScript
` + "```javascript" + `
const appKey = 'your-app-key';
const baseUrl = 'http://your-domain.com/api/v1/app/' + appKey;
// 获取公告
async function getAnnouncements() {
const response = await fetch(baseUrl + '/announcements');
const result = await response.json();
if (result.code === 200) {
console.log('公告列表:', result.data.announcements);
}
}
// 用户登录
async function login(username, password, deviceId) {
const response = await fetch(baseUrl + '/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username, password, device_id: deviceId })
});
const result = await response.json();
if (result.code === 200) {
console.log('登录成功:', result.data);
return result.data;
}
}
// 心跳检测
async function heartbeat(userId, deviceId) {
const response = await fetch(baseUrl + '/heartbeat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ user_id: userId, device_id: deviceId })
});
const result = await response.json();
return result.code === 200;
}
` + "```" + `
### Python
` + "```python" + `
import requests
class AppClient:
def __init__(self, app_key, base_url='http://your-domain.com/api/v1/app'):
self.app_key = app_key
self.base_url = base_url + '/' + app_key
def get_announcements(self):
response = requests.get(self.base_url + '/announcements')
result = response.json()
if result['code'] == 200:
return result['data']['announcements']
return None
def login(self, username, password, device_id):
data = {'username': username, 'password': password, 'device_id': device_id}
response = requests.post(self.base_url + '/login', json=data)
result = response.json()
if result['code'] == 200:
return result['data']
return None
def heartbeat(self, user_id, device_id):
data = {'user_id': user_id, 'device_id': device_id}
response = requests.post(self.base_url + '/heartbeat', json=data)
result = response.json()
return result['code'] == 200
# 使用示例
client = AppClient('your-app-key')
announcements = client.get_announcements()
print('公告列表:', announcements)
` + "```" + `
`
var apiCategory model.DocCategory
if err := database.DB.Where("slug = ?", "api-docs").First(&apiCategory).Error; err != nil {
apiCategory = model.DocCategory{
Name: "API文档",
Slug: "api-docs",
Description: "应用对接API文档",
Sort: 100,
}
if err := database.DB.Create(&apiCategory).Error; err != nil {
log.Printf("创建API文档分类失败: %v", err)
return
}
}
var existingDoc model.Doc
if err := database.DB.Where("slug = ?", "app-api-docs").First(&existingDoc).Error; err == nil {
existingDoc.Title = "应用API"
existingDoc.Content = apiDocContent
existingDoc.Summary = "应用对接平台所需的所有API文档,包含用户认证、设备管理、云端数据等核心功能"
if err := database.DB.Save(&existingDoc).Error; err != nil {
log.Printf("更新API文档失败: %v", err)
return
}
log.Println("API文档更新成功")
return
}
apiDoc := model.Doc{
Title: "应用API",
CategoryID: &apiCategory.ID,
Slug: "app-api-docs",
Content: apiDocContent,
Summary: "应用对接平台所需的所有API文档,包含用户认证、设备管理、云端数据等核心功能",
Icon: "code",
Sort: 1,
Status: "published",
}
if err := database.DB.Create(&apiDoc).Error; err != nil {
log.Printf("创建API文档失败: %v", err)
return
}
log.Println("API文档创建成功")
}