Files
verify/backend/cmd/scripts/init_extension_docs.go
T
2026-04-27 17:22:56 +08:00

937 lines
17 KiB
Go

package main
import (
"fmt"
"log"
"verification-platform-backend/internal/database"
"verification-platform-backend/internal/model"
"gorm.io/gorm"
)
func main() {
database.Init()
db := database.DB
log.Println("开始初始化扩展API文档...")
var category model.DocCategory
result := db.Where("slug = ?", "extension-api").First(&category)
if result.Error == gorm.ErrRecordNotFound {
category = model.DocCategory{
Name: "扩展API",
Slug: "extension-api",
Description: "开放API文档,供开发者在自己的服务器集成平台功能",
Icon: "code",
Status: "active",
Sort: 100,
}
if err := db.Create(&category).Error; err != nil {
log.Fatalf("创建文档分类失败: %v", err)
}
log.Println("创建文档分类成功")
} else {
log.Println("文档分类已存在")
}
docs := []struct {
Title string
Slug string
Content string
Sort int
}{
{
Title: "扩展API概述",
Slug: "extension-api-overview",
Content: `# 扩展API概述
扩展API允许开发者在自己的服务器上集成平台功能,实现自定义的业务逻辑。
## 功能特点
- **用户管理**: 查询用户信息、充值、扣费等操作
- **卡密管理**: 查询卡密、生成卡密
- **消息通知**: 向用户发送通知消息
- **应用管理**: 获取应用信息和统计数据
- **云端变量**: 读写用户和应用级别的云端变量
## 认证方式
所有API请求需要进行签名认证,请求头需要包含以下字段:
| 字段 | 说明 |
|------|------|
| X-Access-Key | API密钥的Access Key |
| X-Signature | 请求签名 |
| X-Timestamp | 请求时间戳(秒级) |
## 签名算法
签名生成步骤:
1. 拼接签名字符串: ` + "`METHOD + PATH + TIMESTAMP + BODY`" + `
2. 使用Secret Key对签名字符串进行HMAC-SHA256签名
3. 将签名结果转换为十六进制字符串
` + "```javascript" + `
// JavaScript示例
const crypto = require('crypto');
function generateSignature(method, path, timestamp, body, secretKey) {
const stringToSign = method + path + timestamp + body;
const hmac = crypto.createHmac('sha256', secretKey);
hmac.update(stringToSign);
return hmac.digest('hex');
}
` + "```" + `
## 请求限制
- 时间戳有效期:5分钟
- 请求频率:根据套餐限制
## 创建API密钥
1. 进入「扩展配置」页面
2. 切换到「API密钥」标签
3. 点击「创建密钥」按钮
4. 选择应用并配置权限
5. 保存Access Key和Secret Key
> ⚠️ **注意**: Secret Key只在创建时显示一次,请妥善保存!
`,
Sort: 1,
},
{
Title: "用户管理",
Slug: "extension-api-user",
Content: `# 用户管理
## 获取用户信息
获取指定用户的详细信息。
### 请求
` + "```" + `
GET /api/v1/ext/user/:userId
` + "```" + `
### 请求头
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| X-Access-Key | string | 是 | Access Key |
| X-Signature | string | 是 | 请求签名 |
| X-Timestamp | string | 是 | 时间戳 |
### 响应示例
` + "```json" + `
{
"code": 0,
"message": "success",
"data": {
"id": 1,
"username": "testuser",
"email": "test@example.com",
"status": "active",
"expiry_at": "2025-12-31T23:59:59Z",
"last_login_at": "2024-01-15T10:30:00Z",
"is_trial_user": false,
"created_at": "2024-01-01T00:00:00Z"
}
}
` + "```" + `
### 所需权限
- ` + "`user.read`" + `
---
## 获取用户列表
获取应用下的用户列表。
### 请求
` + "```" + `
GET /api/v1/ext/users
` + "```" + `
### 查询参数
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| page | int | 否 | 页码,默认1 |
| page_size | int | 否 | 每页数量,默认20 |
| status | string | 否 | 状态筛选 |
| search | string | 否 | 搜索关键词 |
### 响应示例
` + "```json" + `
{
"code": 0,
"message": "success",
"data": {
"users": [...],
"total": 100,
"page": 1,
"page_size": 20,
"total_page": 5
}
}
` + "```" + `
### 所需权限
- ` + "`user.list`" + `
---
## 用户充值
为用户充值时长。
### 请求
` + "```" + `
POST /api/v1/ext/user/:userId/recharge
` + "```" + `
### 请求体
` + "```json" + `
{
"amount": 30,
"type": "days",
"description": "在线充值"
}
` + "```" + `
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| amount | int | 是 | 充值数量 |
| type | string | 是 | 类型:days(天数) |
| description | string | 否 | 描述说明 |
### 响应示例
` + "```json" + `
{
"code": 0,
"message": "success",
"data": {
"message": "充值成功",
"user": {
"id": 1,
"expiry_at": "2025-12-31T23:59:59Z"
}
}
}
` + "```" + `
### 所需权限
- ` + "`user.recharge`" + `
---
## 用户扣费
扣除用户时长。
### 请求
` + "```" + `
POST /api/v1/ext/user/:userId/deduct
` + "```" + `
### 请求体
` + "```json" + `
{
"amount": 10,
"type": "days",
"description": "消费扣费"
}
` + "```" + `
### 响应示例
` + "```json" + `
{
"code": 0,
"message": "success",
"data": {
"message": "扣除成功",
"user": {
"id": 1,
"expiry_at": "2025-12-21T23:59:59Z"
}
}
}
` + "```" + `
### 所需权限
- ` + "`user.deduct`" + `
---
## 获取用户变量
获取用户的云端变量。
### 请求
` + "```" + `
GET /api/v1/ext/user/:userId/variables
` + "```" + `
### 响应示例
` + "```json" + `
{
"code": 0,
"message": "success",
"data": {
"vip_level": {
"value": "3",
"scope": "user"
},
"game_score": {
"value": "1000",
"scope": "user"
}
}
}
` + "```" + `
### 所需权限
- ` + "`user.variables`" + `
---
## 更新用户变量
更新用户的云端变量。
### 请求
` + "```" + `
POST /api/v1/ext/user/:userId/variables
` + "```" + `
### 请求体
` + "```json" + `
{
"variables": {
"vip_level": "5",
"game_score": "2000"
}
}
` + "```" + `
### 响应示例
` + "```json" + `
{
"code": 0,
"message": "success",
"data": {
"message": "更新成功"
}
}
` + "```" + `
### 所需权限
- ` + "`user.variables`" + `
`,
Sort: 2,
},
{
Title: "卡密管理",
Slug: "extension-api-card",
Content: `# 卡密管理
## 获取卡密列表
获取应用下的卡密列表。
### 请求
` + "```" + `
GET /api/v1/ext/cards
` + "```" + `
### 查询参数
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| page | int | 否 | 页码,默认1 |
| page_size | int | 否 | 每页数量,默认20 |
| status | string | 否 | 状态筛选:unused/used/disabled |
| card_type_id | int | 否 | 卡密类型ID |
### 响应示例
` + "```json" + `
{
"code": 0,
"message": "success",
"data": {
"cards": [
{
"id": 1,
"card_key": "ABCD1234EFGH5678",
"card_type_id": 1,
"status": "unused",
"created_at": "2024-01-01T00:00:00Z"
}
],
"total": 100,
"page": 1,
"page_size": 20,
"total_page": 5
}
}
` + "```" + `
### 所需权限
- ` + "`card.read`" + `
---
## 生成卡密
批量生成卡密。
### 请求
` + "```" + `
POST /api/v1/ext/cards/generate
` + "```" + `
### 请求体
` + "```json" + `
{
"card_type_id": 1,
"count": 10
}
` + "```" + `
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| card_type_id | int | 是 | 卡密类型ID |
| count | int | 是 | 生成数量 |
### 响应示例
` + "```json" + `
{
"code": 0,
"message": "success",
"data": {
"message": "生成成功",
"count": 10,
"cards": [
{
"id": 1,
"card_key": "ABCD1234EFGH5678",
"status": "unused"
}
]
}
}
` + "```" + `
### 所需权限
- ` + "`card.generate`" + `
---
## 获取卡密详情
获取单个卡密的详细信息。
### 请求
` + "```" + `
GET /api/v1/ext/card/:cardId
` + "```" + `
### 响应示例
` + "```json" + `
{
"code": 0,
"message": "success",
"data": {
"id": 1,
"card_key": "ABCD1234EFGH5678",
"card_type_id": 1,
"status": "unused",
"used_at": null,
"app_user_id": null,
"created_at": "2024-01-01T00:00:00Z"
}
}
` + "```" + `
### 所需权限
- ` + "`card.read`" + `
`,
Sort: 3,
},
{
Title: "消息通知",
Slug: "extension-api-notification",
Content: `# 消息通知
## 发送单个通知
向指定用户发送通知消息。
### 请求
` + "```" + `
POST /api/v1/ext/notification
` + "```" + `
### 请求体
` + "```json" + `
{
"user_id": 1,
"title": "系统通知",
"content": "您的账户已充值成功!",
"type": "info"
}
` + "```" + `
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| user_id | int | 是 | 用户ID |
| title | string | 是 | 通知标题 |
| content | string | 是 | 通知内容 |
| type | string | 否 | 类型:info/warning/error |
### 响应示例
` + "```json" + `
{
"code": 0,
"message": "success",
"data": {
"message": "发送成功",
"notification": {
"id": 1,
"title": "系统通知",
"content": "您的账户已充值成功!"
}
}
}
` + "```" + `
### 所需权限
- ` + "`notification.send`" + `
---
## 批量发送通知
向所有用户发送通知消息。
### 请求
` + "```" + `
POST /api/v1/ext/notification/batch
` + "```" + `
### 请求体
` + "```json" + `
{
"title": "系统公告",
"content": "系统将于今晚进行维护...",
"type": "warning"
}
` + "```" + `
### 响应示例
` + "```json" + `
{
"code": 0,
"message": "success",
"data": {
"message": "发送成功",
"notification": {
"id": 1,
"title": "系统公告",
"content": "系统将于今晚进行维护..."
}
}
}
` + "```" + `
### 所需权限
- ` + "`notification.send`" + `
`,
Sort: 4,
},
{
Title: "应用管理",
Slug: "extension-api-app",
Content: `# 应用管理
## 获取应用信息
获取当前应用的基本信息。
### 请求
` + "```" + `
GET /api/v1/ext/app/info
` + "```" + `
### 响应示例
` + "```json" + `
{
"code": 0,
"message": "success",
"data": {
"id": 1,
"name": "我的应用",
"description": "应用描述",
"billing_type": "subscription",
"encrypt_type": "aes",
"bind_type": "device",
"max_devices": 3,
"multi_open": false,
"enable_trial": true,
"trial_duration": 7,
"status": "active",
"created_at": "2024-01-01T00:00:00Z"
}
}
` + "```" + `
### 所需权限
- ` + "`app.info`" + `
---
## 获取应用统计
获取应用的统计数据。
### 请求
` + "```" + `
GET /api/v1/ext/app/stats
` + "```" + `
### 响应示例
` + "```json" + `
{
"code": 0,
"message": "success",
"data": {
"user_count": 1000,
"active_user_count": 500,
"card_count": 200,
"used_card_count": 150
}
}
` + "```" + `
### 所需权限
- ` + "`app.stats`" + `
---
## 获取应用变量
获取应用级别的云端变量。
### 请求
` + "```" + `
GET /api/v1/ext/app/variables
` + "```" + `
### 响应示例
` + "```json" + `
{
"code": 0,
"message": "success",
"data": {
"app_version": "1.0.0",
"maintenance_mode": "false",
"announcement": "欢迎使用本应用"
}
}
` + "```" + `
### 所需权限
- ` + "`app.variables`" + `
---
## 更新应用变量
更新应用级别的云端变量。
### 请求
` + "```" + `
POST /api/v1/ext/app/variables
` + "```" + `
### 请求体
` + "```json" + `
{
"variables": {
"app_version": "1.0.1",
"maintenance_mode": "true",
"announcement": "系统维护中,请稍后..."
}
}
` + "```" + `
### 响应示例
` + "```json" + `
{
"code": 0,
"message": "success",
"data": {
"message": "更新成功"
}
}
` + "```" + `
### 所需权限
- ` + "`app.variables`" + `
`,
Sort: 5,
},
{
Title: "代码示例",
Slug: "extension-api-examples",
Content: `# 代码示例
## JavaScript/Node.js
` + "```javascript" + `
const crypto = require('crypto');
const axios = require('axios');
const ACCESS_KEY = 'your_access_key';
const SECRET_KEY = 'your_secret_key';
const BASE_URL = 'https://your-domain.com/api/v1/ext';
// 生成签名
function generateSignature(method, path, timestamp, body) {
const bodyStr = body ? JSON.stringify(body) : '';
const stringToSign = method + path + timestamp + bodyStr;
const hmac = crypto.createHmac('sha256', SECRET_KEY);
hmac.update(stringToSign);
return hmac.digest('hex');
}
// 发送请求
async function request(method, path, body = null) {
const timestamp = Math.floor(Date.now() / 1000).toString();
const signature = generateSignature(method, path, timestamp, body);
const headers = {
'X-Access-Key': ACCESS_KEY,
'X-Signature': signature,
'X-Timestamp': timestamp,
'Content-Type': 'application/json'
};
const config = {
method,
url: BASE_URL + path,
headers
};
if (body) {
config.data = body;
}
const response = await axios(config);
return response.data;
}
// 使用示例
async function main() {
// 获取用户信息
const user = await request('GET', '/user/1');
console.log('用户信息:', user);
// 用户充值
const result = await request('POST', '/user/1/recharge', {
amount: 30,
type: 'days',
description: '在线充值'
});
console.log('充值结果:', result);
}
main().catch(console.error);
` + "```" + `
## Python
` + "```python" + `
import hmac
import hashlib
import time
import requests
import json
ACCESS_KEY = 'your_access_key'
SECRET_KEY = 'your_secret_key'
BASE_URL = 'https://your-domain.com/api/v1/ext'
def generate_signature(method, path, timestamp, body=''):
string_to_sign = method + path + timestamp + body
signature = hmac.new(
SECRET_KEY.encode('utf-8'),
string_to_sign.encode('utf-8'),
hashlib.sha256
).hexdigest()
return signature
def request(method, path, body=None):
timestamp = str(int(time.time()))
body_str = json.dumps(body) if body else ''
signature = generate_signature(method, path, timestamp, body_str)
headers = {
'X-Access-Key': ACCESS_KEY,
'X-Signature': signature,
'X-Timestamp': timestamp,
'Content-Type': 'application/json'
}
url = BASE_URL + path
response = requests.request(method, url, headers=headers, json=body)
return response.json()
# 使用示例
if __name__ == '__main__':
# 获取用户信息
user = request('GET', '/user/1')
print('用户信息:', user)
# 用户充值
result = request('POST', '/user/1/recharge', {
'amount': 30,
'type': 'days',
'description': '在线充值'
})
print('充值结果:', result)
` + "```" + `
## 在线充值集成示例
以下是一个完整的在线充值集成示例,展示如何实现用户在线支付后自动充值:
` + "```javascript" + `
// 支付回调处理
app.post('/payment/callback', async (req, res) => {
const { order_id, user_id, amount, status } = req.body;
// 验证支付状态
if (status !== 'success') {
return res.json({ code: -1, message: '支付失败' });
}
try {
// 调用扩展API为用户充值
const result = await request('POST', '/user/' + user_id + '/recharge', {
amount: Math.floor(amount), // 充值天数
type: 'days',
description: '在线支付充值 - 订单号: ' + order_id
});
if (result.code === 0) {
// 更新订单状态
await updateOrderStatus(order_id, 'completed');
res.json({ code: 0, message: '充值成功' });
} else {
res.json({ code: -1, message: result.message });
}
} catch (error) {
console.error('充值失败:', error);
res.json({ code: -1, message: '充值失败' });
}
});
` + "```" + `
`,
Sort: 6,
},
}
for _, docData := range docs {
var existingDoc model.Doc
result := db.Where("slug = ?", docData.Slug).First(&existingDoc)
if result.Error == gorm.ErrRecordNotFound {
doc := model.Doc{
CategoryID: &category.ID,
Title: docData.Title,
Slug: docData.Slug,
Content: docData.Content,
Status: "published",
Sort: docData.Sort,
}
if err := db.Create(&doc).Error; err != nil {
log.Printf("创建文档 %s 失败: %v", docData.Title, err)
} else {
log.Printf("创建文档 %s 成功", docData.Title)
}
} else {
existingDoc.Content = docData.Content
existingDoc.Title = docData.Title
db.Save(&existingDoc)
log.Printf("文档 %s 已存在,已更新", docData.Title)
}
}
log.Println("扩展API文档初始化完成!")
fmt.Println("\n文档列表:")
fmt.Println("1. 扩展API概述")
fmt.Println("2. 用户管理")
fmt.Println("3. 卡密管理")
fmt.Println("4. 消息通知")
fmt.Println("5. 应用管理")
fmt.Println("6. 代码示例")
fmt.Println("\n请访问管理后台的文档管理页面查看和编辑这些文档。")
}