package main import ( "log" "verification-platform-backend/internal/database" "verification-platform-backend/internal/model" ) func main() { database.Init() log.Println("=== 查看当前所有文档 ===") var docs []model.Doc if err := database.DB.Find(&docs).Error; err != nil { log.Printf("查询文档失败: %v", err) return } for _, doc := range docs { log.Printf("ID: %d, Slug: %s, Title: %s", doc.ID, doc.Slug, doc.Title) } log.Println("\n=== 删除旧的云端函数文档 ===") if err := database.DB.Where("slug = ?", "dynamic-code").Delete(&model.Doc{}).Error; err != nil { log.Printf("删除文档失败: %v", err) } if err := database.DB.Where("slug = ?", "cloud-function").Delete(&model.Doc{}).Error; err != nil { log.Printf("删除文档失败: %v", err) } log.Println("\n=== 创建云端函数文档 ===") var apiCat model.DocCategory if err := database.DB.Where("slug = ?", "api").First(&apiCat).Error; err != nil { log.Printf("未找到API分类: %v", err) return } cloudFunctionContent := "# 云端函数接口\n\n" + "云端函数允许开发者为应用创建自定义的业务逻辑,通过JavaScript代码实现灵活的数据处理和业务规则。\n\n" + "---\n\n" + "## 概述\n\n" + "云端函数是基于JavaScript的自定义代码,可以在应用运行时动态执行。开发者可以通过云端函数实现:\n\n" + "- 动态定价计算\n" + "- 权限验证逻辑\n" + "- 业务规则判断\n" + "- 用户数据处理\n" + "- 自动化操作指令\n\n" + "---\n\n" + "## 获取云端函数列表\n\n" + "### 接口地址\n\n" + "`GET /api/v1/app/:appKey/cloud-function`\n\n" + "### 请求头\n\n" + "```\n" + "Authorization: Bearer {token}\n" + "```\n\n" + "### 路径参数\n\n" + "| 参数名 | 类型 | 必填 | 说明 |\n" + "|--------|------|------|------|\n" + "| appKey | string | 是 | 应用密钥 |\n\n" + "### 响应示例\n\n" + "```json\n" + "{\n" + " \"code\": 200,\n" + " \"message\": \"操作成功\",\n" + " \"data\": [\n" + " {\n" + " \"id\": 1,\n" + " \"name\": \"加法函数\",\n" + " \"key\": \"add\",\n" + " \"description\": \"实现数字加法运算\",\n" + " \"status\": \"active\",\n" + " \"created_at\": \"2024-01-01T00:00:00Z\"\n" + " }\n" + " ]\n" + "}\n" + "```\n\n" + "### 字段说明\n\n" + "| 字段名 | 类型 | 说明 |\n" + "|--------|------|------|\n" + "| id | number | 云端函数ID |\n" + "| name | string | 云端函数名称 |\n" + "| key | string | 云端函数唯一标识 |\n" + "| description | string | 描述 |\n" + "| status | string | 状态(active、inactive) |\n" + "| created_at | string | 创建时间 |\n\n" + "---\n\n" + "## 执行云端函数\n\n" + "### 接口地址\n\n" + "`POST /api/v1/app/:appKey/cloud-function/:key/execute`\n\n" + "### 请求头\n\n" + "```\n" + "Authorization: Bearer {token}\n" + "Content-Type: application/json\n" + "```\n\n" + "### 路径参数\n\n" + "| 参数名 | 类型 | 必填 | 说明 |\n" + "|--------|------|------|------|\n" + "| appKey | string | 是 | 应用密钥 |\n" + "| key | string | 是 | 云端函数标识 |\n\n" + "### 请求体\n\n" + "```json\n" + "{\n" + " \"params\": {\n" + " \"param1\": \"value1\",\n" + " \"param2\": \"value2\"\n" + " },\n" + " \"user_id\": 123\n" + "}\n" + "```\n\n" + "### 参数说明\n\n" + "| 参数名 | 类型 | 必填 | 说明 |\n" + "|--------|------|------|------|\n" + "| params | object | 否 | 自定义参数对象,键值对形式传递 |\n" + "| user_id | number | 否 | 用户ID,提供后会注入当前用户信息 |\n\n" + "### 响应示例\n\n" + "```json\n" + "{\n" + " \"code\": 200,\n" + " \"message\": \"操作成功\",\n" + " \"data\": {\n" + " \"result\": \"执行结果\",\n" + " \"execution_time\": 1\n" + " }\n" + "}\n" + "```\n\n" + "### 字段说明\n\n" + "| 字段名 | 类型 | 说明 |\n" + "|--------|------|------|\n" + "| result | any | 代码执行结果,可以是任意类型 |\n" + "| execution_time | number | 执行时间(毫秒) |\n\n" + "---\n\n" + "## 注入的数据\n\n" + "### 1. 应用配置数据 (app)\n\n" + "云端函数可以访问应用的完整配置信息:\n\n" + "```javascript\n" + "app.name\n" + "app.description\n" + "app.app_key\n" + "app.status\n" + "app.billing_type\n" + "app.point_price\n" + "app.points_per_cycle\n" + "app.point_deduction_cycle\n" + "app.enable_trial\n" + "app.trial_type\n" + "app.trial_duration\n" + "app.trial_points\n" + "app.enable_free_period\n" + "app.free_period_type\n" + "app.free_period_start\n" + "app.free_period_end\n" + "app.free_period_weekdays\n" + "app.free_period_start_time\n" + "app.free_period_end_time\n" + "app.max_devices\n" + "app.bind_type\n" + "app.multi_open\n" + "app.multi_open_mode\n" + "app.max_instances\n" + "app.login_policy\n" + "app.max_attempts\n" + "app.lock_duration\n" + "app.heartbeat_interval\n" + "app.heartbeat_timeout\n" + "app.change_limit\n" + "app.change_interval\n" + "app.change_exceed_action\n" + "app.change_deduct_amount\n" + "```\n\n" + "#### 应用配置字段说明\n\n" + "| 字段名 | 类型 | 说明 |\n" + "|--------|------|------|\n" + "| name | string | 应用名称 |\n" + "| description | string | 应用描述 |\n" + "| app_key | string | 应用密钥 |\n" + "| status | string | 应用状态 |\n" + "| billing_type | string | 计费方式 |\n" + "| point_price | number | 点数价格 |\n" + "| points_per_cycle | number | 每周期扣点数 |\n" + "| point_deduction_cycle | string | 扣点周期 |\n" + "| enable_trial | boolean | 是否启用试用 |\n" + "| trial_type | string | 试用类型 |\n" + "| trial_duration | number | 试用时长 |\n" + "| trial_points | number | 试用点数 |\n" + "| enable_free_period | boolean | 是否启用免费时段 |\n" + "| free_period_type | string | 免费时段类型 |\n" + "| free_period_start | string | 免费时段开始 |\n" + "| free_period_end | string | 免费时段结束 |\n" + "| free_period_weekdays | string | 免费时段星期 |\n" + "| free_period_start_time | string | 免费时段开始时间 |\n" + "| free_period_end_time | string | 免费时段结束时间 |\n" + "| max_devices | number | 最大设备数 |\n" + "| bind_type | string | 绑定方式 |\n" + "| multi_open | boolean | 是否允许多开 |\n" + "| multi_open_mode | string | 多开模式 |\n" + "| max_instances | number | 最大实例数 |\n" + "| login_policy | string | 登录策略 |\n" + "| max_attempts | number | 最大尝试次数 |\n" + "| lock_duration | number | 锁定时长 |\n" + "| heartbeat_interval | number | 心跳间隔 |\n" + "| heartbeat_timeout | number | 心跳超时 |\n" + "| change_limit | number | 变更限制 |\n" + "| change_interval | number | 变更间隔 |\n" + "| change_exceed_action | string | 超限操作 |\n" + "| change_deduct_amount | number | 超限扣点数 |\n\n" + "### 2. 用户信息 (user)\n\n" + "如果请求中提供了 `user_id`,会自动注入当前用户的信息:\n\n" + "```javascript\n" + "user.id\n" + "user.username\n" + "user.email\n" + "user.status\n" + "user.points\n" + "user.is_trial_user\n" + "user.expiry_at\n" + "user.last_login_at\n" + "```\n\n" + "#### 用户信息字段说明\n\n" + "| 字段名 | 类型 | 说明 |\n" + "|--------|------|------|\n" + "| id | number | 用户ID |\n" + "| username | string | 用户名 |\n" + "| email | string | 邮箱 |\n" + "| status | string | 用户状态 |\n" + "| points | number | 积分 |\n" + "| is_trial_user | boolean | 是否试用用户 |\n" + "| expiry_at | string | 到期时间 |\n" + "| last_login_at | string | 最后登录时间 |\n\n" + "### 3. 自定义参数\n\n" + "通过请求的 `params` 参数传递的自定义数据,可以直接在代码中使用:\n\n" + "```javascript\n" + "// 请求参数: {\"params\": {\"a\": 10, \"b\": 20, \"name\": \"张三\"}}\n\n" + "a + b\n" + "name.toUpperCase()\n" + "```\n\n" + "---\n\n" + "## JavaScript代码编写规范\n\n" + "### 1. 参数使用\n\n" + "云端函数可以直接使用请求参数中传递的变量,无需额外定义:\n\n" + "```javascript\n" + "a + b\n" + "```\n\n" + "**请求参数**:`{\"params\": {\"a\": 10, \"b\": 20}}`\n\n" + "**返回结果**:`30`\n\n" + "---\n\n" + "### 2. 函数定义与调用\n\n" + "可以定义函数并在最后一行调用:\n\n" + "```javascript\n" + "function calculate(x, y) {\n" + " return Math.sqrt(x * x + y * y);\n" + "}\n\n" + "calculate(x, y)\n" + "```\n\n" + "**请求参数**:`{\"params\": {\"x\": 3, \"y\": 4}}`\n\n" + "**返回结果**:`5`\n\n" + "---\n\n" + "### 3. 复杂逻辑\n\n" + "支持完整的JavaScript语法,包括控制流、循环、对象操作等:\n\n" + "```javascript\n" + "function processScore(score) {\n" + " if (score >= 90) {\n" + " return \"优秀\";\n" + " } else if (score >= 60) {\n" + " return \"及格\";\n" + " } else {\n" + " return \"不及格\";\n" + " }\n" + "}\n\n" + "processScore(score)\n" + "```\n\n" + "---\n\n" + "### 4. 返回值规则\n\n" + "- **最后一个表达式的值即为返回值**\n" + "- **不要在全局作用域使用return语句**\n" + "- 可以返回任意类型:数字、字符串、布尔值、对象、数组等\n\n" + "---\n\n" + "### 5. 使用注入数据\n\n" + "#### 使用应用配置\n\n" + "```javascript\n" + "function getAppInfo() {\n" + " return {\n" + " name: app.name,\n" + " status: app.status,\n" + " billing_type: app.billing_type,\n" + " max_devices: app.max_devices,\n" + " enable_trial: app.enable_trial\n" + " };\n" + "}\n\n" + "getAppInfo()\n" + "```\n\n" + "#### 使用用户信息\n\n" + "```javascript\n" + "function getUserInfo() {\n" + " if (!user) {\n" + " return { error: \"用户不存在\" };\n" + " }\n" + " \n" + " return {\n" + " username: user.username,\n" + " points: user.points,\n" + " is_trial_user: user.is_trial_user,\n" + " status: user.status\n" + " };\n" + "}\n\n" + "getUserInfo()\n" + "```\n\n" + "#### 组合使用\n\n" + "```javascript\n" + "function checkUserPermission() {\n" + " if (!user) {\n" + " return { error: \"用户不存在\" };\n" + " }\n" + " \n" + " if (user.status !== \"active\") {\n" + " return { error: \"用户状态异常\" };\n" + " }\n" + " \n" + " if (app.max_devices > 0) {\n" + " return {\n" + " allowed: true,\n" + " max_devices: app.max_devices,\n" + " user_status: user.status\n" + " };\n" + " }\n" + " \n" + " return { allowed: false, reason: \"应用未设置设备限制\" };\n" + "}\n\n" + "checkUserPermission()\n" + "```\n\n" + "---\n\n" + "### 6. 常见示例\n\n" + "#### 简单计算\n\n" + "```javascript\n" + "price * quantity\n" + "```\n\n" + "#### 字符串拼接\n\n" + "```javascript\n" + "name + \"的年龄是\" + age + \"岁\"\n" + "```\n\n" + "#### 条件判断\n\n" + "```javascript\n" + "score >= 60 ? \"及格\" : \"不及格\"\n" + "```\n\n" + "#### 对象返回\n\n" + "```javascript\n" + "{\n" + " sum: a + b,\n" + " product: a * b,\n" + " difference: a - b\n" + "}\n" + "```\n\n" + "#### 数组操作\n\n" + "```javascript\n" + "function sumArray(numbers) {\n" + " let total = 0;\n" + " for (let i = 0; i < numbers.length; i++) {\n" + " total += numbers[i];\n" + " }\n" + " return total;\n" + "}\n\n" + "sumArray([1, 2, 3, 4, 5])\n" + "```\n\n" + "---\n\n" + "### 7. 注意事项\n\n" + "1. **全局作用域不能使用return**:return只能在函数内部使用\n" + "2. **参数变量直接使用**:无需重新定义\n" + "3. **最后一行是返回值**:确保最后一行是需要返回的表达式\n" + "4. **支持ES6语法**:可以使用let、const、箭头函数等\n" + "5. **内置对象可用**:Math、Date、JSON等JavaScript内置对象都可以使用\n\n" + "---\n\n" + "## 操作指令\n\n" + "云端函数可以返回操作指令,后端会安全地执行这些指令。\n\n" + "### 1. 加时指令\n\n" + "为用户延长使用时间。\n\n" + "#### 指令格式\n\n" + "```javascript\n" + "{\n" + " action: \"extend_time\",\n" + " user_id: 123,\n" + " days: 7,\n" + " reason: \"用户申请延期\"\n" + "}\n" + "```\n\n" + "#### 字段说明\n\n" + "| 字段名 | 类型 | 必填 | 说明 |\n" + "|--------|------|------|------|\n" + "| action | string | 是 | 固定值:\"extend_time\" |\n" + "| user_id | number | 是 | 用户ID |\n" + "| days | number | 是 | 延长天数 |\n" + "| reason | string | 否 | 延长原因 |\n\n" + "#### 示例\n\n" + "```javascript\n" + "function autoExtendTime(userId, userLevel) {\n" + " let days = 0;\n" + " \n" + " if (userLevel === \"vip\") {\n" + " days = 30;\n" + " } else if (userLevel === \"premium\") {\n" + " days = 15;\n" + " } else if (userLevel === \"normal\") {\n" + " days = 7;\n" + " }\n" + " \n" + " return {\n" + " action: \"extend_time\",\n" + " user_id: userId,\n" + " days: days,\n" + " reason: \"根据用户等级自动加时\"\n" + " };\n" + "}\n\n" + "autoExtendTime(123, \"vip\")\n" + "```\n\n" + "---\n\n" + "### 2. 扣点指令\n\n" + "扣除用户积分。\n\n" + "#### 指令格式\n\n" + "```javascript\n" + "{\n" + " action: \"deduct_points\",\n" + " user_id: 123,\n" + " points: 100,\n" + " reason: \"使用功能扣点\"\n" + "}\n" + "```\n\n" + "#### 字段说明\n\n" + "| 字段名 | 类型 | 必填 | 说明 |\n" + "|--------|------|------|------|\n" + "| action | string | 是 | 固定值:\"deduct_points\" |\n" + "| user_id | number | 是 | 用户ID |\n" + "| points | number | 是 | 扣除点数 |\n" + "| reason | string | 否 | 扣点原因 |\n\n" + "#### 示例\n\n" + "```javascript\n" + "function autoDeductPoints(userId, usage) {\n" + " if (!user || user.points < usage) {\n" + " return { error: \"积分不足\" };\n" + " }\n" + " \n" + " return {\n" + " action: \"deduct_points\",\n" + " user_id: userId,\n" + " points: usage,\n" + " reason: \"功能使用扣点\"\n" + " };\n" + "}\n\n" + "autoDeductPoints(123, 50)\n" + "```\n\n" + "---\n\n" + "## 完整示例\n\n" + "### 示例1:动态定价\n\n" + "#### 场景\n" + "根据用户等级和应用设置,动态计算价格。\n\n" + "#### 请求\n\n" + "```json\n" + "POST /api/v1/app/your-app-key/cloud-function/calculate-price/execute\n" + "{\n" + " \"params\": {\n" + " \"basePrice\": 100,\n" + " \"userType\": \"new\"\n" + " }\n" + "}\n" + "```\n\n" + "#### 云端函数代码\n\n" + "```javascript\n" + "function calculatePrice(basePrice, userType) {\n" + " let finalPrice = basePrice;\n" + " \n" + " if (app.enable_trial && userType === \"new\") {\n" + " finalPrice = finalPrice * 0.5;\n" + " }\n" + " \n" + " if (userType === \"vip\") {\n" + " finalPrice = finalPrice * 0.8;\n" + " }\n" + " \n" + " return {\n" + " original_price: basePrice,\n" + " user_type: userType,\n" + " enable_trial: app.enable_trial,\n" + " final_price: finalPrice,\n" + " discount: basePrice - finalPrice\n" + " };\n" + "}\n\n" + "calculatePrice(basePrice, userType)\n" + "```\n\n" + "#### 响应\n\n" + "```json\n" + "{\n" + " \"code\": 200,\n" + " \"message\": \"操作成功\",\n" + " \"data\": {\n" + " \"result\": {\n" + " \"original_price\": 100,\n" + " \"user_type\": \"new\",\n" + " \"enable_trial\": true,\n" + " \"final_price\": 50,\n" + " \"discount\": 50\n" + " },\n" + " \"execution_time\": 1\n" + " }\n" + "}\n" + "```\n\n" + "---\n\n" + "### 示例2:权限验证\n\n" + "#### 场景\n" + "检查用户设备数量是否超过限制。\n\n" + "#### 请求\n\n" + "```json\n" + "POST /api/v1/app/your-app-key/cloud-function/check-permission/execute\n" + "{\n" + " \"params\": {\n" + " \"deviceCount\": 2\n" + " },\n" + " \"user_id\": 123\n" + "}\n" + "```\n\n" + "#### 云端函数代码\n\n" + "```javascript\n" + "function checkPermission(deviceCount) {\n" + " if (!user) {\n" + " return { allowed: false, reason: \"用户不存在\" };\n" + " }\n" + " \n" + " if (user.status !== \"active\") {\n" + " return { allowed: false, reason: \"用户状态异常\" };\n" + " }\n" + " \n" + " if (deviceCount > app.max_devices) {\n" + " return { \n" + " allowed: false, \n" + " reason: \"设备数量超过限制\",\n" + " current: deviceCount,\n" + " max: app.max_devices\n" + " };\n" + " }\n" + " \n" + " return { \n" + " allowed: true, \n" + " reason: \"权限验证通过\",\n" + " user: user.username\n" + " };\n" + "}\n\n" + "checkPermission(deviceCount)\n" + "```\n\n" + "#### 响应\n\n" + "```json\n" + "{\n" + " \"code\": 200,\n" + " \"message\": \"操作成功\",\n" + " \"data\": {\n" + " \"result\": {\n" + " \"allowed\": true,\n" + " \"reason\": \"权限验证通过\",\n" + " \"user\": \"testuser\"\n" + " },\n" + " \"execution_time\": 1\n" + " }\n" + "}\n" + "```\n\n" + "---\n\n" + "### 示例3:每日登录自动加时\n\n" + "#### 场景\n" + "试用用户每日登录自动延长1天。\n\n" + "#### 请求\n\n" + "```json\n" + "POST /api/v1/app/your-app-key/cloud-function/daily-login/execute\n" + "{\n" + " \"params\": {\n" + " \"userId\": 123\n" + " },\n" + " \"user_id\": 123\n" + "}\n" + "```\n\n" + "#### 云端函数代码\n\n" + "```javascript\n" + "function processDailyLogin(userId) {\n" + " if (!user) {\n" + " return { error: \"用户不存在\" };\n" + " }\n" + " \n" + " if (user.status !== \"active\") {\n" + " return { error: \"用户状态异常\" };\n" + " }\n" + " \n" + " if (user.is_trial_user) {\n" + " return {\n" + " action: \"extend_time\",\n" + " user_id: userId,\n" + " days: 1,\n" + " reason: \"试用用户每日登录加时\",\n" + " timestamp: new Date().toISOString()\n" + " };\n" + " }\n" + " \n" + " return {\n" + " message: \"登录成功\",\n" + " user_points: user.points,\n" + " app_name: app.name\n" + " };\n" + "}\n\n" + "processDailyLogin(userId)\n" + "```\n\n" + "#### 响应\n\n" + "```json\n" + "{\n" + " \"code\": 200,\n" + " \"message\": \"操作成功\",\n" + " \"data\": {\n" + " \"result\": {\n" + " \"action\": \"extend_time\",\n" + " \"user_id\": 123,\n" + " \"days\": 1,\n" + " \"reason\": \"试用用户每日登录加时\",\n" + " \"timestamp\": \"2026-03-11T00:57:55.123Z\"\n" + " },\n" + " \"execution_time\": 2\n" + " }\n" + "}\n" + "```\n\n" + "---\n\n" + "### 示例4:功能使用自动扣点\n\n" + "#### 场景\n" + "用户使用功能时自动扣除相应积分。\n\n" + "#### 请求\n\n" + "```json\n" + "POST /api/v1/app/your-app-key/cloud-function/use-feature/execute\n" + "{\n" + " \"params\": {\n" + " \"userId\": 123,\n" + " \"featureType\": \"advanced\"\n" + " },\n" + " \"user_id\": 123\n" + "}\n" + "```\n\n" + "#### 云端函数代码\n\n" + "```javascript\n" + "function processFeatureUsage(userId, featureType) {\n" + " if (!user) {\n" + " return { error: \"用户不存在\" };\n" + " }\n" + " \n" + " if (user.status !== \"active\") {\n" + " return { error: \"用户状态异常\" };\n" + " }\n" + " \n" + " let cost = app.points_per_cycle;\n" + " \n" + " if (featureType === \"advanced\") {\n" + " cost = cost * 2;\n" + " } else if (featureType === \"premium\") {\n" + " cost = cost * 5;\n" + " }\n" + " \n" + " if (user.points < cost) {\n" + " return { \n" + " error: \"积分不足\",\n" + " required: cost,\n" + " current: user.points\n" + " };\n" + " }\n" + " \n" + " return {\n" + " action: \"deduct_points\",\n" + " user_id: userId,\n" + " points: cost,\n" + " reason: \"使用功能扣点: \" + featureType,\n" + " feature_type: featureType\n" + " };\n" + "}\n\n" + "processFeatureUsage(userId, featureType)\n" + "```\n\n" + "#### 响应\n\n" + "```json\n" + "{\n" + " \"code\": 200,\n" + " \"message\": \"操作成功\",\n" + " \"data\": {\n" + " \"result\": {\n" + " \"action\": \"deduct_points\",\n" + " \"user_id\": 123,\n" + " \"points\": 2,\n" + " \"reason\": \"使用功能扣点: advanced\",\n" + " \"feature_type\": \"advanced\"\n" + " },\n" + " \"execution_time\": 1\n" + " }\n" + "}\n" + "```\n\n" + "---\n\n" + "### 示例5:业务规则获取\n\n" + "#### 场景\n" + "获取应用的所有业务规则,用于前端展示。\n\n" + "#### 请求\n\n" + "```json\n" + "POST /api/v1/app/your-app-key/cloud-function/get-rules/execute\n" + "{\n" + " \"params\": {}\n" + "}\n" + "```\n\n" + "#### 云端函数代码\n\n" + "```javascript\n" + "function getBusinessRules() {\n" + " const rules = [];\n" + " \n" + " if (app.enable_trial) {\n" + " rules.push({\n" + " type: \"trial\",\n" + " title: \"试用功能\",\n" + " description: \"支持试用,试用时长:\" + app.trial_duration + \"天\"\n" + " });\n" + " }\n" + " \n" + " if (app.max_devices > 1) {\n" + " rules.push({\n" + " type: \"multi_device\",\n" + " title: \"多设备支持\",\n" + " description: \"支持多设备,最多\" + app.max_devices + \"台\"\n" + " });\n" + " }\n" + " \n" + " if (app.enable_free_period) {\n" + " rules.push({\n" + " type: \"free_period\",\n" + " title: \"免费时段\",\n" + " description: \"支持免费时段:\" + app.free_period_start + \" - \" + app.free_period_end\n" + " });\n" + " }\n" + " \n" + " if (app.point_price > 0) {\n" + " rules.push({\n" + " type: \"points\",\n" + " title: \"积分系统\",\n" + " description: \"点数价格:\" + app.point_price + \",每周期扣点:\" + app.points_per_cycle\n" + " });\n" + " }\n" + " \n" + " return {\n" + " app_name: app.name,\n" + " total_rules: rules.length,\n" + " rules: rules\n" + " };\n" + "}\n\n" + "getBusinessRules()\n" + "```\n\n" + "#### 响应\n\n" + "```json\n" + "{\n" + " \"code\": 200,\n" + " \"message\": \"操作成功\",\n" + " \"data\": {\n" + " \"result\": {\n" + " \"app_name\": \"我的应用\",\n" + " \"total_rules\": 4,\n" + " \"rules\": [\n" + " {\n" + " \"type\": \"trial\",\n" + " \"title\": \"试用功能\",\n" + " \"description\": \"支持试用,试用时长:7天\"\n" + " },\n" + " {\n" + " \"type\": \"multi_device\",\n" + " \"title\": \"多设备支持\",\n" + " \"description\": \"支持多设备,最多3台\"\n" + " },\n" + " {\n" + " \"type\": \"free_period\",\n" + " \"title\": \"免费时段\",\n" + " \"description\": \"支持免费时段:20:00 - 08:00\"\n" + " },\n" + " {\n" + " \"type\": \"points\",\n" + " \"title\": \"积分系统\",\n" + " \"description\": \"点数价格:0.1,每周期扣点:1\"\n" + " }\n" + " ]\n" + " },\n" + " \"execution_time\": 1\n" + " }\n" + "}\n" + "```\n\n" + "---\n\n" + "## 错误处理\n\n" + "### 常见错误\n\n" + "#### 1. 语法错误\n\n" + "```json\n" + "{\n" + " \"code\": 400,\n" + " \"message\": \"代码执行错误: SyntaxError: Unexpected token\"\n" + "}\n" + "```\n\n" + "**原因**:JavaScript代码语法错误\n\n" + "**解决**:检查代码语法,确保括号、引号等匹配正确\n\n" + "---\n\n" + "#### 2. 运行时错误\n\n" + "```json\n" + "{\n" + " \"code\": 400,\n" + " \"message\": \"代码执行错误: ReferenceError: x is not defined\"\n" + "}\n" + "```\n\n" + "**原因**:使用了未定义的变量\n\n" + "**解决**:检查变量名是否正确,或确保已通过参数传入\n\n" + "---\n\n" + "#### 3. 全局return错误\n\n" + "```json\n" + "{\n" + " \"code\": 400,\n" + " \"message\": \"代码执行错误: SyntaxError: Illegal return statement\"\n" + "}\n" + "```\n\n" + "**原因**:在全局作用域使用了return语句\n\n" + "**解决**:将return语句放在函数内部,或直接返回表达式\n\n" + "---\n\n" + "#### 4. 操作执行失败\n\n" + "```json\n" + "{\n" + " \"code\": 500,\n" + " \"message\": \"执行加时操作失败: user not found\"\n" + "}\n" + "```\n\n" + "**原因**:操作指令中的用户不存在\n\n" + "**解决**:检查user_id是否正确,或用户是否属于当前应用\n\n" + "---\n\n" + "## 性能建议\n\n" + "1. **避免死循环**:确保循环有明确的退出条件\n" + "2. **合理使用缓存**:对于重复计算,可以考虑缓存结果\n" + "3. **控制代码复杂度**:过复杂的代码可能影响执行效率\n" + "4. **使用内置函数**:优先使用JavaScript内置函数,性能更好\n" + "5. **避免频繁操作**:操作指令会修改数据库,避免频繁调用\n\n" + "---\n\n" + "## 安全建议\n\n" + "1. **不要执行危险操作**:避免访问文件系统、网络请求等\n" + "2. **参数验证**:在代码中对参数进行必要的验证\n" + "3. **避免敏感信息**:不要在代码中硬编码密钥、密码等敏感信息\n" + "4. **限制执行时间**:设置合理的超时时间,防止长时间运行\n" + "5. **操作指令谨慎**:操作指令会修改数据库,确保逻辑正确\n" + "6. **用户数据保护**:不要在代码中泄露用户敏感信息\n\n" + "---\n\n" + "## 最佳实践\n\n" + "### 1. 代码组织\n\n" + "将复杂逻辑封装成函数,提高代码可读性:\n\n" + "```javascript\n" + "function validateUser() {\n" + " if (!user) {\n" + " return { valid: false, reason: \"用户不存在\" };\n" + " }\n" + " \n" + " if (user.status !== \"active\") {\n" + " return { valid: false, reason: \"用户状态异常\" };\n" + " }\n" + " \n" + " return { valid: true };\n" + "}\n\n" + "function calculatePrice(basePrice, discount) {\n" + " return basePrice * (1 - discount / 100);\n" + "}\n\n" + "function mainProcess() {\n" + " const validation = validateUser();\n" + " if (!validation.valid) {\n" + " return validation;\n" + " }\n" + " \n" + " const price = calculatePrice(100, 20);\n" + " return { success: true, price: price };\n" + "}\n\n" + "mainProcess()\n" + "```\n\n" + "---\n\n" + "### 2. 错误处理\n\n" + "在代码中添加适当的错误处理:\n\n" + "```javascript\n" + "function safeCalculate(a, b) {\n" + " if (typeof a !== \"number\" || typeof b !== \"number\") {\n" + " return { error: \"参数必须是数字\" };\n" + " }\n" + " \n" + " try {\n" + " return { result: a + b };\n" + " } catch (e) {\n" + " return { error: \"计算失败: \" + e.message };\n" + " }\n" + "}\n\n" + "safeCalculate(a, b)\n" + "```\n\n" + "---\n\n" + "### 3. 使用现代JavaScript\n\n" + "利用ES6+特性提高代码质量:\n\n" + "```javascript\n" + "// 使用箭头函数\n" + "const calculate = (x, y) => x + y;\n\n" + "// 使用解构赋值\n" + "const { name, age } = userInfo;\n\n" + "// 使用模板字符串\n" + "const message = `用户${name}的年龄是${age}岁`;\n\n" + "// 使用数组方法\n" + "const sum = numbers.reduce((a, b) => a + b, 0);\n\n" + "// 使用对象简写\n" + "const result = { name, age, status };\n" + "```\n\n" + "---\n\n" + "### 4. 日志记录\n\n" + "在返回结果中包含调试信息:\n\n" + "```javascript\n" + "function processWithLog(userId) {\n" + " const startTime = new Date();\n" + " \n" + " if (!user) {\n" + " return { \n" + " error: \"用户不存在\",\n" + " timestamp: startTime.toISOString(),\n" + " debug: { userId }\n" + " };\n" + " }\n" + " \n" + " const result = {\n" + " user_id: userId,\n" + " username: user.username,\n" + " status: user.status\n" + " };\n" + " \n" + " return {\n" + " success: true,\n" + " data: result,\n" + " timestamp: startTime.toISOString(),\n" + " execution_time: new Date() - startTime\n" + " };\n" + "}\n\n" + "processWithLog(userId)\n" + "```\n\n" + "---\n\n" + "## 常见问题\n\n" + "### Q1: 云端函数可以访问数据库吗?\n\n" + "**A**: 不能直接访问数据库。云端函数只能使用注入的数据(app、user)和请求参数。如果需要修改数据,应该返回操作指令(extend_time、deduct_points),由后端安全地执行。\n\n" + "---\n\n" + "### Q2: 云端函数可以调用外部API吗?\n\n" + "**A**: 不能。云端函数在沙箱环境中执行,不支持网络请求。如果需要调用外部API,应该通过后端接口实现。\n\n" + "---\n\n" + "### Q3: 云端函数的执行时间有限制吗?\n\n" + "**A**: 有。云端函数有执行时间限制,超时会被终止。建议避免死循环和长时间运行的操作。\n\n" + "---\n\n" + "### Q4: 如何调试云端函数?\n\n" + "**A**: 可以在返回结果中包含调试信息,或者使用简单的测试参数验证逻辑是否正确。\n\n" + "---\n\n" + "### Q5: 云端函数可以修改应用配置吗?\n\n" + "**A**: 不能。app对象是只读的,不能修改。如果需要修改应用配置,应该使用专门的管理接口。\n\n" + "---\n\n" + "## 更新日志\n\n" + "### v1.0.0 (2026-03-11)\n" + "- 初始版本发布\n" + "- 支持应用配置数据注入\n" + "- 支持用户信息注入\n" + "- 支持操作指令(加时、扣点)\n" + "- 支持完整的JavaScript语法\n" + "- 提供丰富的使用示例\n" cloudFunctionDoc := model.Doc{ Title: "云端函数接口", CategoryID: &apiCat.ID, Slug: "cloud-function", Content: cloudFunctionContent, Summary: "云端函数允许开发者为应用创建自定义的业务逻辑,通过JavaScript代码实现灵活的数据处理和业务规则", Icon: "⚡", Sort: 1, Status: "published", } if err := database.DB.Create(&cloudFunctionDoc).Error; err != nil { log.Printf("创建云端函数文档失败: %v", err) return } log.Println("云端函数文档创建成功") }