Files
verify/backend/scripts/translate_docs_i18n.go
admin 9b82fbef4e feat: 添加存储配置管理功能
- 添加存储配置管理页面(列表、创建、编辑)
- 支持本地存储、S3、WebDAV、FTP、SFTP 等存储类型
- 添加存储配置测试连接功能
- 本地存储自动初始化且禁止删除
- 修复 Switch 组件状态显示问题
- 添加更新存储配置时的 status 字段支持
2026-05-02 17:48:58 +08:00

179 lines
21 KiB
Go

package main
import (
"fmt"
"log"
"verification-platform-backend/internal/database"
"verification-platform-backend/internal/model"
)
func main() {
database.Init()
db := database.DB
categoryTranslations := map[string]struct {
NameEn string
DescriptionEn string
}{
"快速开始": {NameEn: "Quick Start", DescriptionEn: "Complete integration in 5 minutes"},
"API文档": {NameEn: "API Documentation", DescriptionEn: "Complete API reference"},
"示例代码": {NameEn: "Code Examples", DescriptionEn: "Common use case examples"},
"常见问题": {NameEn: "FAQ", DescriptionEn: "Frequently asked questions"},
}
var categories []model.DocCategory
if err := db.Find(&categories).Error; err != nil {
log.Fatal("Failed to get categories:", err)
}
for _, cat := range categories {
if trans, ok := categoryTranslations[cat.Name]; ok {
cat.NameEn = trans.NameEn
cat.DescriptionEn = trans.DescriptionEn
if err := db.Save(&cat).Error; err != nil {
log.Printf("Failed to update category %d: %v", cat.ID, err)
} else {
fmt.Printf("Translated category: %s -> %s\n", cat.Name, cat.NameEn)
}
}
}
docTranslations := map[string]struct {
TitleEn string
ContentEn string
}{
"用户注册": {
TitleEn: "User Registration",
ContentEn: "# User Registration\n\n### Endpoint\n```\nPOST /api/v1/app/:appKey/register\n```\n\n### Request Parameters\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| username | string | Yes | Username |\n| password | string | Yes | Password |\n| device_id | string | Yes | Device fingerprint, unique device identifier |\n| device_name | string | No | Device name, e.g. \"My Computer\", defaults to device_id |\n| email | string | Conditional | Email address, required when email verification is enabled |\n| email_code | string | Conditional | Email verification code, required when mandatory email verification is enabled |\n| device_type | string | No | Device type: android/ios/windows/mac/linux/web, auto-detected if not provided |\n| instance_id | string | No | Instance ID for multi-instance detection, defaults to device_id |\n\n### Request Example\n```json\n{\n \"username\": \"user123\",\n \"password\": \"password123\",\n \"device_id\": \"abc123def456\",\n \"device_name\": \"My Computer\",\n \"email\": \"user@example.com\",\n \"email_code\": \"123456\",\n \"device_type\": \"windows\"\n}\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"message\": \"Registration successful\",\n \"data\": {\n \"user_id\": 123\n }\n}\n```\n\n### Notes\n- device_id is the device fingerprint used to uniquely identify a device\n- device_name is a friendly name for the device for display purposes\n- device_type is auto-detected based on User-Agent if not provided\n- If mandatory email verification is enabled for the application, email and email_code are required",
},
"发送邮箱验证码": {
TitleEn: "Send Email Verification Code",
ContentEn: "# Send Email Verification Code\n\n### Endpoint\n```\nPOST /api/v1/app/:appKey/send-email-code\n```\n\n### Request Parameters\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| email | string | Yes | Email address |\n| purpose | string | No | Purpose: register, reset_password, change_email, defaults to register |\n\n### Request Example\n```json\n{\n \"email\": \"user@example.com\",\n \"purpose\": \"register\"\n}\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"message\": \"success\",\n \"data\": {\n \"message\": \"Verification code sent\"\n }\n}\n```\n\n### Notes\n- Verification code is valid for 15 minutes\n- Returns an error if email verification is not enabled for the application",
},
"用户登录": {
TitleEn: "User Login",
ContentEn: "# User Login\n\n### Endpoint\n```\nPOST /api/v1/app/:appKey/login\n```\n\n### Request Parameters\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| username | string | Yes | Username |\n| password | string | Yes | Password |\n| device_id | string | Yes | Device fingerprint, unique device identifier |\n| device_name | string | No | Device name, e.g. \"My Computer\", defaults to device_id |\n| device_type | string | No | Device type: android/ios/windows/mac/linux/web, auto-detected if not provided |\n| instance_id | string | No | Instance ID for multi-instance detection, defaults to device_id |\n\n### Request Example\n```json\n{\n \"username\": \"user123\",\n \"password\": \"password123\",\n \"device_id\": \"abc123def456\",\n \"device_name\": \"My Computer\",\n \"device_type\": \"windows\"\n}\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"message\": \"Login successful\",\n \"data\": {\n \"token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\",\n \"user_id\": 123\n }\n}\n```\n\n### Notes\n- device_id is the device fingerprint used to uniquely identify a device\n- device_name is a friendly name for the device for display purposes\n- device_type is auto-detected based on User-Agent if not provided\n- Returns an error with bound device list if device binding limit is reached",
},
"心跳验证": {
TitleEn: "Heartbeat Verification",
ContentEn: "# Heartbeat Verification\n\n### Endpoint\n```\nPOST /api/v1/app/:appKey/heartbeat\n```\n\n### Request Header\n```\nAuthorization: Bearer {token}\n```\n\n### Request Parameters\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| device_id | string | Yes | Device ID |\n\n### Request Example\n```json\n{\n \"device_id\": \"device_001\"\n}\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"message\": \"success\"\n}\n```\n\n### Notes\n- Keeps user online status\n- Recommended to call every 30 seconds\n- User will be considered offline if heartbeat is not called for a certain period\n- JWT token must be included in the request header",
},
"卡密充值": {
TitleEn: "Card Key Recharge",
ContentEn: "# Card Key Recharge\n\n### Endpoint\n```\nPOST /api/v1/app/:appKey/recharge\n```\n\n### Request Parameters\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| username | string | Yes | User account |\n| card_key | string | Yes | Card key |\n\n### Request Example\n```json\n{\n \"username\": \"user123\",\n \"card_key\": \"VIP123456\"\n}\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"message\": \"Recharge successful\",\n \"data\": {\n \"value\": 30\n }\n}\n```\n\n### Response Fields\n| Field | Type | Description |\n|-------|------|-------------|\n| value | number | Recharge value (meaning varies by card type) |",
},
"获取绑定设备列表": {
TitleEn: "Get Bound Devices List",
ContentEn: "# Get Bound Devices List\n\n### Endpoint\n```\nGET /api/v1/app/:appKey/devices\n```\n\n### Request Header\n```\nAuthorization: Bearer {token}\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"data\": {\n \"devices\": [\n {\n \"device_id\": \"device_001\",\n \"device_name\": \"My Computer\",\n \"bind_time\": \"2024-03-04T12:00:00Z\",\n \"last_active\": \"2024-03-04T13:00:00Z\"\n }\n ]\n }\n}\n```\n\n### Response Fields\n| Field | Type | Description |\n|-------|------|-------------|\n| device_id | string | Device ID |\n| device_name | string | Device name |\n| bind_time | string | Binding time |\n| last_active | string | Last active time |",
},
"解绑设备": {
TitleEn: "Unbind Device",
ContentEn: "# Unbind Device\n\n### Endpoint\n```\nPOST /api/v1/app/:appKey/unbind-device\n```\n\n### Request Header\n```\nAuthorization: Bearer {token}\n```\n\n### Request Parameters\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| device_id | string | Yes | Device ID |\n\n### Request Example\n```json\n{\n \"device_id\": \"device_001\"\n}\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"message\": \"Device unbound successfully\"\n}\n```",
},
"通过认证解绑设备": {
TitleEn: "Unbind Device with Authentication",
ContentEn: "# Unbind Device with Authentication\n\n### Endpoint\n```\nPOST /api/v1/app/:appKey/unbind-device-with-auth\n```\n\n### Request Header\n```\nAuthorization: Bearer {token}\n```\n\n### Request Parameters\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| device_id | string | Yes | Device ID to unbind |\n| password | string | Yes | User password for verification |\n\n### Request Example\n```json\n{\n \"device_id\": \"device_001\",\n \"password\": \"password123\"\n}\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"message\": \"Device unbound successfully\"\n}\n```",
},
"重置密码(邮箱验证码)": {
TitleEn: "Reset Password (Email Verification)",
ContentEn: "# Reset Password (Email Verification)\n\n### Endpoint\n```\nPOST /api/v1/app/:appKey/reset-password\n```\n\n### Request Parameters\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| email | string | Yes | Email address |\n| email_code | string | Yes | Email verification code |\n| new_password | string | Yes | New password |\n\n### Request Example\n```json\n{\n \"email\": \"user@example.com\",\n \"email_code\": \"123456\",\n \"new_password\": \"newpassword123\"\n}\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"message\": \"Password reset successful\"\n}\n```",
},
"修改密码": {
TitleEn: "Change Password",
ContentEn: "# Change Password\n\n### Endpoint\n```\nPOST /api/v1/app/:appKey/change-password\n```\n\n### Request Header\n```\nAuthorization: Bearer {token}\n```\n\n### Request Parameters\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| old_password | string | Yes | Current password |\n| new_password | string | Yes | New password |\n\n### Request Example\n```json\n{\n \"old_password\": \"oldpassword123\",\n \"new_password\": \"newpassword123\"\n}\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"message\": \"Password changed successfully\"\n}\n```",
},
"获取设备数量": {
TitleEn: "Get Device Count",
ContentEn: "# Get Device Count\n\n### Endpoint\n```\nGET /api/v1/app/:appKey/device-count\n```\n\n### Request Header\n```\nAuthorization: Bearer {token}\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"data\": {\n \"count\": 2,\n \"max_devices\": 3\n }\n}\n```",
},
"获取应用信息": {
TitleEn: "Get Application Info",
ContentEn: "# Get Application Info\n\n### Endpoint\n```\nGET /api/v1/app/:appKey/info\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"data\": {\n \"name\": \"My Application\",\n \"description\": \"Application description\",\n \"version\": \"1.0.0\",\n \"status\": \"active\"\n }\n}\n```",
},
"获取用户账户信息": {
TitleEn: "Get User Account Info",
ContentEn: "# Get User Account Info\n\n### Endpoint\n```\nGET /api/v1/app/:appKey/user/info\n```\n\n### Request Header\n```\nAuthorization: Bearer {token}\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"data\": {\n \"user_id\": 123,\n \"username\": \"user123\",\n \"email\": \"user@example.com\",\n \"balance\": 100,\n \"expiry_at\": \"2024-12-31T23:59:59Z\"\n }\n}\n```",
},
"获取应用常量": {
TitleEn: "Get Application Constants",
ContentEn: "# Get Application Constants\n\n### Endpoint\n```\nGET /api/v1/app/:appKey/constants\n```\n\n### Request Header\n```\nAuthorization: Bearer {token}\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"data\": {\n \"constants\": [\n {\n \"key\": \"APP_VERSION\",\n \"value\": \"1.0.0\"\n }\n ]\n }\n}\n```",
},
"获取指定常量": {
TitleEn: "Get Specific Constant",
ContentEn: "# Get Specific Constant\n\n### Endpoint\n```\nGET /api/v1/app/:appKey/constants/:key\n```\n\n### Request Header\n```\nAuthorization: Bearer {token}\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"data\": {\n \"key\": \"APP_VERSION\",\n \"value\": \"1.0.0\"\n }\n}\n```",
},
"获取应用变量": {
TitleEn: "Get Application Variables",
ContentEn: "# Get Application Variables\n\n### Endpoint\n```\nGET /api/v1/app/:appKey/variables\n```\n\n### Request Header\n```\nAuthorization: Bearer {token}\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"data\": {\n \"variables\": [\n {\n \"key\": \"user_setting\",\n \"value\": \"default\"\n }\n ]\n }\n}\n```",
},
"获取指定变量": {
TitleEn: "Get Specific Variable",
ContentEn: "# Get Specific Variable\n\n### Endpoint\n```\nGET /api/v1/app/:appKey/variables/:key\n```\n\n### Request Header\n```\nAuthorization: Bearer {token}\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"data\": {\n \"key\": \"user_setting\",\n \"value\": \"default\"\n }\n}\n```",
},
"更新用户变量": {
TitleEn: "Update User Variable",
ContentEn: "# Update User Variable\n\n### Endpoint\n```\nPOST /api/v1/app/:appKey/variables/:key\n```\n\n### Request Header\n```\nAuthorization: Bearer {token}\n```\n\n### Request Parameters\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| value | string | Yes | Variable value |\n\n### Request Example\n```json\n{\n \"value\": \"new_value\"\n}\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"message\": \"Variable updated successfully\"\n}\n```",
},
"调用云端函数": {
TitleEn: "Call Cloud Function",
ContentEn: "# Call Cloud Function\n\n### Endpoint\n```\nPOST /api/v1/app/:appKey/functions/:name\n```\n\n### Request Header\n```\nAuthorization: Bearer {token}\n```\n\n### Request Example\n```json\n{\n \"param1\": \"value1\",\n \"param2\": \"value2\"\n}\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"data\": {\n \"result\": \"function_result\"\n }\n}\n```",
},
"检查更新": {
TitleEn: "Check for Updates",
ContentEn: "# Check for Updates\n\n### Endpoint\n```\nGET /api/v1/app/:appKey/check-update\n```\n\n### Request Parameters\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| current_version | string | Yes | Current application version |\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"data\": {\n \"has_update\": true,\n \"latest_version\": \"2.0.0\",\n \"download_url\": \"https://example.com/download\",\n \"update_log\": \"Bug fixes and improvements\"\n }\n}\n```",
},
"获取公告": {
TitleEn: "Get Announcements",
ContentEn: "# Get Announcements\n\n### Endpoint\n```\nGET /api/v1/app/:appKey/announcements\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"data\": {\n \"announcements\": [\n {\n \"id\": 1,\n \"title\": \"System Maintenance\",\n \"content\": \"System maintenance scheduled for...\",\n \"type\": \"warning\",\n \"created_at\": \"2024-03-04T12:00:00Z\"\n }\n ]\n }\n}\n```",
},
"获取在线实例列表": {
TitleEn: "Get Online Instances",
ContentEn: "# Get Online Instances\n\n### Endpoint\n```\nGET /api/v1/app/:appKey/online-instances\n```\n\n### Request Header\n```\nAuthorization: Bearer {token}\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"data\": {\n \"instances\": [\n {\n \"device_id\": \"device_001\",\n \"device_name\": \"My Computer\",\n \"login_time\": \"2024-03-04T12:00:00Z\",\n \"last_heartbeat\": \"2024-03-04T13:00:00Z\"\n }\n ]\n }\n}\n```",
},
"强制离线实例": {
TitleEn: "Force Offline Instance",
ContentEn: "# Force Offline Instance\n\n### Endpoint\n```\nPOST /api/v1/app/:appKey/force-offline\n```\n\n### Request Header\n```\nAuthorization: Bearer {token}\n```\n\n### Request Parameters\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| device_id | string | Yes | Device ID to force offline |\n\n### Request Example\n```json\n{\n \"device_id\": \"device_001\"\n}\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"message\": \"Instance forced offline successfully\"\n}\n```",
},
"软件验证示例": {
TitleEn: "Software Verification Example",
ContentEn: "# Software Verification Example\n\n## Basic Verification Flow\n\n### 1. User Login\n```bash\ncurl -X POST https://api.example.com/api/v1/app/YOUR_APP_KEY/login \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"username\": \"user123\",\n \"password\": \"password123\",\n \"device_id\": \"unique_device_id\"\n }'\n```\n\n### 2. Save Token\nSave the returned token for subsequent API calls.\n\n### 3. Heartbeat\nCall heartbeat API periodically to maintain online status.\n\n## Complete Example (Python)\n```python\nimport requests\nimport time\n\nclass AppClient:\n def __init__(self, app_key):\n self.app_key = app_key\n self.base_url = \"https://api.example.com/api/v1/app\"\n self.token = None\n \n def login(self, username, password, device_id):\n url = f\"{self.base_url}/{self.app_key}/login\"\n response = requests.post(url, json={\n \"username\": username,\n \"password\": password,\n \"device_id\": device_id\n })\n data = response.json()\n if data[\"code\"] == 200:\n self.token = data[\"data\"][\"token\"]\n return True\n return False\n\n# Usage\nclient = AppClient(\"your_app_key\")\nif client.login(\"user123\", \"password\", \"device_001\"):\n while True:\n client.heartbeat(\"device_001\")\n time.sleep(30)\n```",
},
"游戏验证示例": {
TitleEn: "Game Verification Example",
ContentEn: "# Game Verification Example\n\n## Unity Integration\n\n### 1. Create API Client\n```csharp\nusing UnityEngine;\nusing UnityEngine.Networking;\nusing System.Collections;\n\npublic class VerificationClient : MonoBehaviour\n{\n private string appKey = \"your_app_key\";\n private string baseUrl = \"https://api.example.com/api/v1/app\";\n private string token;\n \n public IEnumerator Login(string username, string password, string deviceId)\n {\n string url = $\"{baseUrl}/{appKey}/login\";\n // ... implementation\n }\n}\n```\n\n### 2. Usage in Game\n```csharp\npublic class GameManager : MonoBehaviour\n{\n private VerificationClient client;\n private string deviceId;\n \n void Start()\n {\n deviceId = SystemInfo.deviceUniqueIdentifier;\n client = GetComponent<VerificationClient>();\n StartCoroutine(client.Login(\"user123\", \"password\", deviceId));\n }\n}\n```",
},
"如何获取API密钥?": {
TitleEn: "How to Get API Key?",
ContentEn: "# How to Get API Key?\n\n## Steps\n\n### 1. Register Account\nFirst, register a admin account on the platform.\n\n### 2. Create Application\n1. Go to Console > Applications\n2. Click \"Create Application\" button\n3. Fill in application name and description\n4. Click \"Create\"\n\n### 3. Get App Key\nAfter creating the application, you can find the App Key on the application details page.\n\n## App Key Format\nApp Key is a unique identifier in the format:\n```\napp_xxxxxxxxxxxxxxxx\n```\n\n## Security Notes\n- Do not share your App Key publicly\n- Regenerate App Key if it's compromised\n- Use environment variables to store App Key in production",
},
"卡密验证失败怎么办?": {
TitleEn: "What to Do When Card Key Verification Fails?",
ContentEn: "# What to Do When Card Key Verification Fails?\n\n## Common Issues\n\n### 1. Invalid Card Key\n**Symptom**: Returns \"Invalid or expired card key\"\n\n**Solutions**:\n- Check if the card key is entered correctly\n- Verify the card key hasn't been used\n- Confirm the card key hasn't expired\n\n### 2. Card Key Already Used\n**Symptom**: Returns \"Card key already used\"\n\n**Solutions**:\n- Each card key can only be used once\n- Purchase a new card key\n\n### 3. Card Key Expired\n**Symptom**: Returns \"Card key expired\"\n\n**Solutions**:\n- Check card key validity period\n- Contact support for assistance",
},
"如何实现代理授权?": {
TitleEn: "How to Implement Agent Authorization?",
ContentEn: "# How to Implement Agent Authorization?\n\n## Overview\nAgent authorization allows you to delegate application management to agents.\n\n## Setup Steps\n\n### 1. Create Agent Application\n1. Go to Console > Agent Applications\n2. Click \"Create Agent Application\"\n3. Select the application to authorize\n4. Set discount rate\n\n### 2. Generate Agent Link\nAfter creation, you'll get an agent link:\n```\nhttps://platform.com/agent/AGENT_CODE\n```\n\n### 3. Agent Dashboard\nAgents can access their dashboard to:\n- View sales statistics\n- Generate card keys\n- Manage users",
},
}
var docs []model.Doc
if err := db.Find(&docs).Error; err != nil {
log.Fatal("Failed to get docs:", err)
}
for _, doc := range docs {
if trans, ok := docTranslations[doc.Title]; ok {
doc.TitleEn = trans.TitleEn
doc.ContentEn = trans.ContentEn
if err := db.Save(&doc).Error; err != nil {
log.Printf("Failed to update doc %d: %v", doc.ID, err)
} else {
fmt.Printf("Translated doc: %s -> %s\n", doc.Title, doc.TitleEn)
}
}
}
fmt.Println("\nTranslation completed!")
}