[
  {
    "category": "CloudBase MCP,OpenClaw",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": 50,
    "hasTemplate": false,
    "content": [
      {
        "markdown": "可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我开发一个解忧信箱的 AI 网页应用。用户写下烦恼，AI 以温和的陌生人口吻回信\n```",
        "title": "和 AI 对话",
        "type": "tab",
        "content": []
      }
    ],
    "_id": "11f5119f69b3d35b0068a0eb38467a50",
    "_openid": "1524963278340493312",
    "createdAt": 1773392731017,
    "updatedAt": 1778664974534
  },
  {
    "category": "框架集成,移动端框架,Android Kotlin",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": 31,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/http-api/basic/overview",
    "content": [
      {
        "markdown": "通过 **HTTP 请求** 在 **Android Kotlin** 中调用各种云开发能力\n\n在 `build.gradle` (Module) 中添加依赖：\n\n```gradle\ndependencies {\n    implementation 'com.squareup.okhttp3:okhttp:4.12.0'\n    implementation 'com.google.code.gson:gson:2.10.1'\n    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3'\n}\n```",
        "index": 1,
        "title": "安装依赖",
        "content": []
      },
      {
        "markdown": "新增如下代码到您的 **Android Kotlin** 项目",
        "index": 2,
        "title": "初始化配置",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```kotlin\npackage com.example.cloudbase\n\nimport com.google.gson.Gson\nimport com.google.gson.reflect.TypeToken\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.withContext\nimport okhttp3.MediaType.Companion.toMediaType\nimport okhttp3.OkHttpClient\nimport okhttp3.Request\nimport okhttp3.RequestBody.Companion.toRequestBody\nimport java.util.concurrent.TimeUnit\n\nclass CloudBaseClient(\n    private val envId: String,\n    private var accessToken: String\n) {\n    private val baseUrl = \"https://$envId.api.tcloudbasegateway.com\"\n    private val gson = Gson()\n\n    private val client = OkHttpClient.Builder()\n        .connectTimeout(30, TimeUnit.SECONDS)\n        .readTimeout(30, TimeUnit.SECONDS)\n        .writeTimeout(30, TimeUnit.SECONDS)\n        .build()\n\n    /**\n     * 更新访问令牌\n     *\n     * @param newToken 新的访问令牌\n     */\n    fun updateAccessToken(newToken: String) {\n        this.accessToken = newToken\n        println(\"访问令牌已更新\")\n    }\n\n    /**\n     * 统一的HTTP请求方法\n     *\n     * @param method 请求方法 (GET, POST, PUT, PATCH, DELETE)\n     * @param path API路径 (如 /v1/rdb/rest/table_name)\n     * @param body 请求体数据\n     * @param customHeaders 自定义headers\n     *\n     * @return 响应数据或null\n     */\n    suspend fun <T> request(\n        method: String,\n        path: String,\n        body: Any? = null,\n        customHeaders: Map<String, String> = emptyMap(),\n        typeToken: TypeToken<T>? = null\n    ): T? = withContext(Dispatchers.IO) {\n        val url = \"$baseUrl$path\"\n\n        val requestBuilder = Request.Builder()\n            .url(url)\n            .header(\"Content-Type\", \"application/json\")\n            .header(\"Accept\", \"application/json\")\n            .header(\"Authorization\", \"Bearer $accessToken\")\n\n        // 添加自定义headers\n        customHeaders.forEach { (key, value) ->\n            requestBuilder.header(key, value)\n        }\n\n        // 设置请求方法和body\n        when (method.uppercase()) {\n            \"GET\" -> requestBuilder.get()\n            \"POST\", \"PUT\", \"PATCH\", \"DELETE\" -> {\n                val jsonBody = if (body != null) {\n                    gson.toJson(body).toRequestBody(\"application/json\".toMediaType())\n                } else {\n                    \"{}\".toRequestBody(\"application/json\".toMediaType())\n                }\n                when (method.uppercase()) {\n                    \"POST\" -> requestBuilder.post(jsonBody)\n                    \"PUT\" -> requestBuilder.put(jsonBody)\n                    \"PATCH\" -> requestBuilder.patch(jsonBody)\n                    \"DELETE\" -> requestBuilder.delete(jsonBody)\n                }\n            }\n        }\n\n        try {\n            val response = client.newCall(requestBuilder.build()).execute()\n\n            if (response.isSuccessful) {\n                val responseBody = response.body?.string()\n\n                // 如果响应为空，返回true表示成功\n                if (responseBody.isNullOrEmpty()) {\n                    @Suppress(\"UNCHECKED_CAST\")\n                    return@withContext true as? T\n                }\n\n                return@withContext if (typeToken != null) {\n                    gson.fromJson(responseBody, typeToken.type)\n                } else {\n                    @Suppress(\"UNCHECKED_CAST\")\n                    gson.fromJson(responseBody, Any::class.java) as? T\n                }\n            } else {\n                println(\"请求失败: ${response.code} ${response.body?.string()}\")\n                return@withContext null\n            }\n        } catch (e: Exception) {\n            println(\"请求失败: ${e.message}\")\n            e.printStackTrace()\n            return@withContext null\n        }\n    }\n}\n\n// 配置文件或初始化时创建实例\n// val cloudbase = CloudBaseClient(\n//     envId = \"your-env-id\",\n//     accessToken = \"your-access-token\"\n// )\n```",
            "index": 1,
            "title": "CloudBaseClient.kt"
          },
          {
            "markdown": "在 `local.properties` 或配置文件中添加：\n\n> 💡提示：用户权限请参考「身份认证」模块获取 access_token\n\n```properties\n# 环境ID\nCLOUDBASE_ENV_ID={%ENV_ID%}\n\n# 匿名访问令牌\nCLOUDBASE_ACCESS_TOKEN={%PUBLISHABLE_KEY%}\n```",
            "index": 2,
            "title": "配置文件"
          }
        ]
      },
      {
        "index": 3,
        "title": "调用云开发能力",
        "type": "codeTab",
        "content": [
          {
            "index": 1,
            "id": "mysql-db",
            "title": "MySQL数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```kotlin\nimport com.google.gson.reflect.TypeToken\n\nsuspend fun getMysqlData(cloudbase: CloudBaseClient, tableName: String): List<Map<String, Any>>? {\n    // 查询 MySQL 数据库数据\n    val data = cloudbase.request<List<Map<String, Any>>>(\n        method = \"GET\",\n        path = \"/v1/rdb/rest/$tableName?limit=10\",\n        typeToken = object : TypeToken<List<Map<String, Any>>>() {}\n    )\n\n    if (data != null) {\n        println(\"查询成功: $data\")\n    }\n    return data ?: emptyList()\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val result = getMysqlData(cloudbase, \"{%TABLE_NAME%}\")\n//     println(result)\n// }\n```",
                "index": 1,
                "title": "查询数据",
                "content": []
              },
              {
                "markdown": "```kotlin\nsuspend fun addMysqlData(cloudbase: CloudBaseClient, tableName: String, data: Map<String, Any>): Map<String, Any>? {\n    // 新增 MySQL 数据库数据\n    val result = cloudbase.request<Map<String, Any>>(\n        method = \"POST\",\n        path = \"/v1/rdb/rest/$tableName\",\n        body = data,\n        typeToken = object : TypeToken<Map<String, Any>>() {}\n    )\n\n    if (result != null) {\n        println(\"新增成功: $result\")\n    }\n    return result\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val result = addMysqlData(cloudbase, \"{%TABLE_NAME%}\", mapOf(\"title\" to \"示例标题\"))\n//     println(result)\n// }\n```",
                "index": 2,
                "title": "新增数据",
                "content": []
              },
              {
                "markdown": "```kotlin\nsuspend fun updateMysqlData(cloudbase: CloudBaseClient, tableName: String, dataId: String, data: Map<String, Any>): Any? {\n    // 更新 MySQL 数据库数据\n    val result = cloudbase.request<Any>(\n        method = \"PATCH\",\n        path = \"/v1/rdb/rest/$tableName?id=eq.$dataId\",\n        body = data\n    )\n\n    if (result != null) {\n        println(\"更新成功: $result\")\n    }\n    return result\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val result = updateMysqlData(cloudbase, \"{%TABLE_NAME%}\", \"<数据id>\", mapOf(\"title\" to \"新标题\"))\n//     println(result)\n// }\n```",
                "index": 3,
                "title": "更新数据",
                "content": []
              },
              {
                "markdown": "```kotlin\nsuspend fun deleteMysqlData(cloudbase: CloudBaseClient, tableName: String, dataId: String): Boolean {\n    // 删除 MySQL 数据库数据\n    val result = cloudbase.request<Any>(\n        method = \"DELETE\",\n        path = \"/v1/rdb/rest/$tableName?id=eq.$dataId\"\n    )\n\n    if (result != null) {\n        println(\"删除成功\")\n        return true\n    }\n    return false\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val result = deleteMysqlData(cloudbase, \"{%TABLE_NAME%}\", \"<数据id>\")\n//     println(result)\n// }\n```",
                "index": 4,
                "title": "删除数据",
                "content": []
              }
            ]
          },
          {
            "index": 2,
            "id": "data-model",
            "title": "数据模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```kotlin\nimport com.google.gson.reflect.TypeToken\n\nsuspend fun getModelData(cloudbase: CloudBaseClient, modelName: String, envType: String = \"prod\"): List<Map<String, Any>> {\n    // 查询数据模型数据\n    val payload = mapOf(\n        \"pageSize\" to 10,\n        \"pageNumber\" to 1,\n        \"getCount\" to true\n    )\n\n    val result = cloudbase.request<Map<String, Any>>(\n        method = \"POST\",\n        path = \"/v1/model/$envType/$modelName/list\",\n        body = payload,\n        typeToken = object : TypeToken<Map<String, Any>>() {}\n    )\n\n    if (result != null) {\n        val records = (result[\"data\"] as? Map<*, *>)?.get(\"records\") as? List<Map<String, Any>> ?: emptyList()\n        println(\"查询成功: $records\")\n        return records\n    }\n    return emptyList()\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val records = getModelData(cloudbase, \"{%TABLE_NAME%}\")\n//     println(records)\n// }\n```",
                "index": 1,
                "title": "查询数据",
                "content": []
              },
              {
                "markdown": "```kotlin\nsuspend fun addModelData(cloudbase: CloudBaseClient, modelName: String, data: Map<String, Any>, envType: String = \"prod\"): Map<String, Any>? {\n    // 新增数据模型数据\n    val result = cloudbase.request<Map<String, Any>>(\n        method = \"POST\",\n        path = \"/v1/model/$envType/$modelName/create\",\n        body = mapOf(\"data\" to data),\n        typeToken = object : TypeToken<Map<String, Any>>() {}\n    )\n\n    if (result != null) {\n        val docId = (result[\"data\"] as? Map<*, *>)?.get(\"id\")\n        println(\"新增成功! id: $docId\")\n    }\n    return result\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val result = addModelData(cloudbase, \"{%TABLE_NAME%}\", mapOf(\"title\" to \"示例标题\"))\n//     println(result)\n// }\n```",
                "index": 2,
                "title": "新增数据",
                "content": []
              },
              {
                "markdown": "```kotlin\nsuspend fun updateModelData(cloudbase: CloudBaseClient, modelName: String, dataId: String, data: Map<String, Any>, envType: String = \"prod\"): Boolean {\n    // 更新数据模型数据\n    val payload = mapOf(\n        \"data\" to data,\n        \"filter\" to mapOf(\n            \"where\" to mapOf(\n                \"_id\" to mapOf(\"\\$eq\" to dataId)\n            )\n        )\n    )\n\n    val result = cloudbase.request<Any>(\n        method = \"PUT\",\n        path = \"/v1/model/$envType/$modelName/update\",\n        body = payload\n    )\n\n    if (result != null) {\n        println(\"更新成功!\")\n        return true\n    }\n    return false\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val result = updateModelData(cloudbase, \"{%TABLE_NAME%}\", \"<数据id>\", mapOf(\"title\" to \"新标题\"))\n//     println(result)\n// }\n```",
                "index": 3,
                "title": "更新数据",
                "content": []
              },
              {
                "markdown": "```kotlin\nsuspend fun deleteModelData(cloudbase: CloudBaseClient, modelName: String, dataId: String, envType: String = \"prod\"): Boolean {\n    // 删除数据模型数据\n    val payload = mapOf(\n        \"filter\" to mapOf(\n            \"where\" to mapOf(\n                \"_id\" to mapOf(\"\\$eq\" to dataId)\n            )\n        )\n    )\n\n    val result = cloudbase.request<Any>(\n        method = \"POST\",\n        path = \"/v1/model/$envType/$modelName/delete\",\n        body = payload\n    )\n\n    if (result != null) {\n        println(\"删除成功!\")\n        return true\n    }\n    return false\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val result = deleteModelData(cloudbase, \"{%TABLE_NAME%}\", \"<数据id>\")\n//     println(result)\n// }\n```",
                "index": 4,
                "title": "删除数据",
                "content": []
              }
            ]
          },
          {
            "markdown": "```kotlin\nsuspend fun callFunction(cloudbase: CloudBaseClient, functionName: String, data: Map<String, Any>? = null): Map<String, Any>? {\n    // 调用云函数\n    val result = cloudbase.request<Map<String, Any>>(\n        method = \"POST\",\n        path = \"/v1/functions/$functionName\",\n        body = data ?: emptyMap<String, Any>(),\n        typeToken = object : TypeToken<Map<String, Any>>() {}\n    )\n\n    if (result != null) {\n        println(\"云函数调用结果: $result\")\n    }\n    return result\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val result = callFunction(cloudbase, \"{%FUNCTION_NAME%}\")\n//     println(result)\n// }\n```",
            "index": 3,
            "id": "scf",
            "title": "云函数"
          },
          {
            "markdown": "```kotlin\nsuspend fun callContainer(cloudbase: CloudBaseClient, serviceName: String, path: String = \"\", method: String = \"GET\", data: Map<String, Any>? = null): Any? {\n    // 调用云托管服务\n    val fullPath = \"/v1/cloudrun/$serviceName/$path\".trimEnd('/')\n    val result = cloudbase.request<Any>(\n        method = method.uppercase(),\n        path = fullPath,\n        body = data\n    )\n\n    if (result != null) {\n        println(\"云托管调用结果: $result\")\n    }\n    return result\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val result = callContainer(cloudbase, \"{%SERVICE_NAME%}\")\n//     println(result)\n// }\n```",
            "index": 4,
            "id": "run",
            "title": "云托管"
          },
          {
            "index": 5,
            "id": "storage",
            "title": "云存储",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```kotlin\nimport okhttp3.OkHttpClient\nimport okhttp3.Request\nimport okhttp3.RequestBody.Companion.toRequestBody\nimport java.io.File\n\nsuspend fun uploadFile(cloudbase: CloudBaseClient, filePath: String, objectId: String? = null): Map<String, String>? = withContext(Dispatchers.IO) {\n    // 上传文件到云存储\n    val file = File(filePath)\n\n    if (!file.exists()) {\n        println(\"文件不存在: $filePath\")\n        return@withContext null\n    }\n\n    val finalObjectId = objectId ?: \"uploads/${System.currentTimeMillis()}-${file.name}\"\n\n    // 1. 获取上传信息\n    val uploadInfo = cloudbase.request<List<Map<String, Any>>>(\n        method = \"POST\",\n        path = \"/v1/storages/get-objects-upload-info\",\n        body = listOf(mapOf(\"objectId\" to finalObjectId)),\n        typeToken = object : TypeToken<List<Map<String, Any>>>() {}\n    )\n\n    if (uploadInfo.isNullOrEmpty()) {\n        return@withContext null\n    }\n\n    val info = uploadInfo[0]\n    val uploadUrl = info[\"uploadUrl\"] as String\n\n    try {\n        // 2. 上传文件\n        val fileData = file.readBytes()\n        val uploadHeaders = mapOf(\n            \"Authorization\" to (info[\"authorization\"] as String),\n            \"X-Cos-Security-Token\" to (info[\"token\"] as String),\n            \"X-Cos-Meta-Fileid\" to (info[\"cloudObjectMeta\"] as String)\n        )\n\n        val requestBuilder = Request.Builder()\n            .url(uploadUrl)\n            .put(fileData.toRequestBody())\n\n        uploadHeaders.forEach { (key, value) ->\n            requestBuilder.header(key, value)\n        }\n\n        val client = OkHttpClient()\n        val uploadResponse = client.newCall(requestBuilder.build()).execute()\n\n        if (uploadResponse.isSuccessful) {\n            val result = mapOf(\n                \"cloudObjectId\" to (info[\"cloudObjectId\"] as String),\n                \"downloadUrl\" to (info[\"downloadUrl\"] as String),\n                \"objectId\" to finalObjectId\n            )\n\n            println(\"文件上传成功:\")\n            println(\"- 对象ID: ${result[\"objectId\"]}\")\n            println(\"- 下载URL: ${result[\"downloadUrl\"]}\")\n\n            return@withContext result\n        }\n\n        println(\"文件上传失败: ${uploadResponse.code}\")\n        return@withContext null\n    } catch (e: Exception) {\n        println(\"文件上传失败: ${e.message}\")\n        e.printStackTrace()\n        return@withContext null\n    }\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val result = uploadFile(cloudbase, \"/path/to/example.jpg\")\n//     println(result)\n// }\n```",
                "index": 1,
                "title": "上传文件",
                "content": []
              },
              {
                "markdown": "```kotlin\nsuspend fun getFileUrl(cloudbase: CloudBaseClient, cloudObjectId: String): String? {\n    // 获取云存储文件的临时访问链接\n    val result = cloudbase.request<List<Map<String, Any>>>(\n        method = \"POST\",\n        path = \"/v1/storages/get-objects-download-info\",\n        body = listOf(mapOf(\"cloudObjectId\" to cloudObjectId)),\n        typeToken = object : TypeToken<List<Map<String, Any>>>() {}\n    )\n\n    if (!result.isNullOrEmpty()) {\n        val downloadUrl = result[0][\"downloadUrl\"] as? String\n        println(\"文件链接: $downloadUrl\")\n        return downloadUrl\n    }\n    return null\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val fileUrl = getFileUrl(cloudbase, \"cloud://xxx.png\")\n//     println(fileUrl)\n// }\n```",
                "index": 2,
                "title": "获取文件链接",
                "content": []
              },
              {
                "markdown": "```kotlin\nimport okhttp3.OkHttpClient\nimport okhttp3.Request\nimport java.io.File\n\nsuspend fun downloadFile(cloudbase: CloudBaseClient, cloudObjectId: String, savePath: String = \"./\"): Boolean = withContext(Dispatchers.IO) {\n    // 下载云存储文件到本地\n    // 1. 获取下载链接\n    val result = cloudbase.request<List<Map<String, Any>>>(\n        method = \"POST\",\n        path = \"/v1/storages/get-objects-download-info\",\n        body = listOf(mapOf(\"cloudObjectId\" to cloudObjectId)),\n        typeToken = object : TypeToken<List<Map<String, Any>>>() {}\n    )\n\n    if (result.isNullOrEmpty()) {\n        return@withContext false\n    }\n\n    val downloadUrl = result[0][\"downloadUrl\"] as String\n\n    try {\n        // 2. 从URL中提取文件名\n        val filename = downloadUrl.split(\"/\").last().split(\"?\").first()\n\n        // 3. 确定完整路径\n        val fullPath = if (File(savePath).isDirectory || savePath.endsWith(\"/\")) {\n            \"$savePath/$filename\"\n        } else {\n            savePath\n        }\n\n        // 4. 下载文件\n        val client = OkHttpClient()\n        val request = Request.Builder().url(downloadUrl).build()\n        val fileResponse = client.newCall(request).execute()\n\n        if (fileResponse.isSuccessful) {\n            // 5. 保存到本地\n            val file = File(fullPath)\n            file.parentFile?.mkdirs()\n            file.writeBytes(fileResponse.body!!.bytes())\n\n            println(\"下载成功! 文件已保存到: $fullPath\")\n            return@withContext true\n        }\n\n        println(\"下载失败: ${fileResponse.code}\")\n        return@withContext false\n    } catch (e: Exception) {\n        println(\"下载失败: ${e.message}\")\n        e.printStackTrace()\n        return@withContext false\n    }\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     // 下载到指定目录\n//     downloadFile(cloudbase, \"cloud://xxx.png\", \"/sdcard/Download/\")\n//\n//     // 下载并重命名\n//     downloadFile(cloudbase, \"cloud://xxx.png\", \"/sdcard/Download/my-image.png\")\n// }\n```",
                "index": 3,
                "title": "下载文件",
                "content": []
              },
              {
                "markdown": "```kotlin\nsuspend fun deleteFile(cloudbase: CloudBaseClient, cloudObjectIds: Any): Boolean {\n    // 删除云存储文件\n    val ids = when (cloudObjectIds) {\n        is String -> listOf(cloudObjectIds)\n        is List<*> -> cloudObjectIds.filterIsInstance<String>()\n        else -> {\n            println(\"参数类型错误\")\n            return false\n        }\n    }\n\n    val data = ids.map { mapOf(\"cloudObjectId\" to it) }\n    val result = cloudbase.request<Any>(\n        method = \"POST\",\n        path = \"/v1/storages/delete-objects\",\n        body = data\n    )\n\n    if (result != null) {\n        println(\"删除成功!\")\n        return true\n    }\n    return false\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val result = deleteFile(cloudbase, \"cloud://xxx.png\")\n//     println(result)\n// }\n```",
                "index": 4,
                "title": "删除文件",
                "content": []
              }
            ]
          },
          {
            "index": 6,
            "id": "ai-model",
            "title": "大模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```kotlin\nimport okhttp3.OkHttpClient\nimport okhttp3.Request\nimport okhttp3.RequestBody.Companion.toRequestBody\nimport okhttp3.MediaType.Companion.toMediaType\nimport com.google.gson.Gson\n\nsuspend fun streamText(cloudbase: CloudBaseClient, model: String, subModel: String, messages: List<Map<String, String>>): String? = withContext(Dispatchers.IO) {\n    // 流式文本生成\n    val payload = mapOf(\n        \"model\" to subModel,\n        \"messages\" to messages,\n        \"stream\" to true\n    )\n\n    val url = \"${cloudbase.baseUrl}/v1/ai/$model/chat/completions\"\n    val gson = Gson()\n\n    val requestBody = gson.toJson(payload).toRequestBody(\"application/json\".toMediaType())\n\n    val request = Request.Builder()\n        .url(url)\n        .header(\"Content-Type\", \"application/json\")\n        .header(\"Accept\", \"text/event-stream\")\n        .header(\"Authorization\", \"Bearer ${cloudbase.accessToken}\")\n        .post(requestBody)\n        .build()\n\n    try {\n        val client = OkHttpClient()\n        val response = client.newCall(request).execute()\n\n        if (response.isSuccessful) {\n            println(\"AI 流式响应:\")\n            var fullContent = \"\"\n\n            response.body?.source()?.use { source ->\n                while (!source.exhausted()) {\n                    val line = source.readUtf8Line() ?: continue\n\n                    if (line.startsWith(\"data: \")) {\n                        val dataStr = line.substring(6)\n                        if (dataStr.trim() != \"[DONE]\") {\n                            try {\n                                val chunkData = gson.fromJson(dataStr, Map::class.java)\n                                val choices = chunkData[\"choices\"] as? List<*>\n                                val delta = (choices?.get(0) as? Map<*, *>)?.get(\"delta\") as? Map<*, *>\n                                val content = delta?.get(\"content\") as? String ?: \"\"\n\n                                if (content.isNotEmpty()) {\n                                    print(content)\n                                    fullContent += content\n                                }\n                            } catch (e: Exception) {\n                                // 忽略JSON解析错误\n                            }\n                        }\n                    }\n                }\n            }\n\n            println()\n            return@withContext fullContent\n        } else {\n            println(\"AI 调用失败: ${response.code}\")\n            return@withContext null\n        }\n    } catch (e: Exception) {\n        println(\"AI 调用失败: ${e.message}\")\n        e.printStackTrace()\n        return@withContext null\n    }\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val response = streamText(\n//         cloudbase,\n//         \"{%AI_MODEL_NAME%}\",\n//         \"{%AI_SUB_MODEL_NAME%}\",\n//         listOf(\n//             mapOf(\"role\" to \"system\", \"content\" to \"请严格按照七言绝句或七言律诗的格律要求创作\"),\n//             mapOf(\"role\" to \"user\", \"content\" to \"春天\")\n//         )\n//     )\n//     println(\"\\n完整回复: $response\")\n// }\n```",
                "index": 1,
                "id": "text-aiModel",
                "title": "生文模型",
                "content": []
              },
              {
                "markdown": "生图模型通过调用云函数来实现，在生图模型页面点击「一键创建云函数」，函数调用示例如下：\n\n```kotlin\nimport com.google.gson.Gson\n\nsuspend fun generateImage(cloudbase: CloudBaseClient, prompt: String): Map<String, Any>? = withContext(Dispatchers.IO) {\n    /// 调用生图云函数\n    val result = cloudbase.request(\n        \"POST\",\n        \"/v1/functions/<YOUR_FUNCTION_NAME>/invoke\",\n        mapOf(\"prompt\" to prompt)\n    )\n\n    if (result != null) {\n        val success = result[\"success\"] as? Boolean ?: false\n        \n        if (success) {\n            // 生成成功\n            println(\"生成成功!\")\n            println(\"图片URL: ${result[\"imageUrl\"]}\")\n            println(\"优化后的提示词: ${result[\"revised_prompt\"]}\")\n\n            // 使用图片\n            // 注意：图片URL有效期为24小时，请及时保存或转存\n            return@withContext result\n        } else {\n            // 生成失败\n            println(\"生成失败: ${result[\"code\"]} ${result[\"message\"]}\")\n            return@withContext null\n        }\n    }\n    return@withContext null\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val result = generateImage(cloudbase, \"一只可爱的猫咪在阳光下玩耍\")\n//     if (result != null) {\n//         println(\"图片URL: ${result[\"imageUrl\"]}\")\n//     }\n// }\n```",
                "index": 2,
                "id": "image-aiModel",
                "title": "生图模型",
                "content": []
              }
            ]
          },
          {
            "markdown": "",
            "index": 7,
            "id": "agent",
            "title": "Agent",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```kotlin\n/**\n * Android Kotlin 调用 Agent 示例（AG-UI 协议）\n * 协议文档：https://docs.cloudbase.net/ai/agent-development/protocol\n */\nimport okhttp3.OkHttpClient\nimport okhttp3.Request\nimport okhttp3.RequestBody.Companion.toRequestBody\nimport okhttp3.MediaType.Companion.toMediaType\nimport com.google.gson.Gson\n\nsuspend fun chatWithAgentStream(cloudbase: CloudBaseClient, botId: String, userMessage: String): String? = withContext(Dispatchers.IO) {\n    // 构建消息列表（AG-UI 协议格式）\n    val messages = listOf(\n        mapOf(\n            \"id\" to \"msg_001\",\n            \"role\" to \"user\",\n            \"content\" to userMessage\n        )\n    )\n\n    // AG-UI 协议请求参数\n    val payload = mapOf(\n        \"messages\" to messages,                                    // 必填：消息列表\n        \"threadId\" to \"550e8400-e29b-41d4-a716-446655440000\",     // 可选：会话ID，用于多轮对话\n        \"runId\" to \"run_001\",                                      // 可选：运行ID，用于追踪执行\n        \"tools\" to emptyList<Any>(),                               // 可选：前端工具定义\n        \"context\" to emptyList<Any>(),                             // 可选：上下文信息\n        \"forwardedProps\" to emptyMap<String, Any>()                // 可选：透传参数\n    )\n\n    val url = \"${cloudbase.baseUrl}/v1/aibot/bots/$botId/send-message\"\n    val gson = Gson()\n\n    val requestBody = gson.toJson(payload).toRequestBody(\"application/json\".toMediaType())\n\n    val request = Request.Builder()\n        .url(url)\n        .header(\"Content-Type\", \"application/json\")\n        .header(\"Accept\", \"text/event-stream\")\n        .header(\"Authorization\", \"Bearer ${cloudbase.accessToken}\")\n        .post(requestBody)\n        .build()\n\n    try {\n        val client = OkHttpClient()\n        val response = client.newCall(request).execute()\n\n        if (response.isSuccessful) {\n            println(\"AI 流式响应:\")\n            var fullContent = \"\"\n            var buffer = \"\"\n\n            response.body?.source()?.use { source ->\n                while (!source.exhausted()) {\n                    buffer += source.readUtf8Line() ?: \"\"\n                    buffer += \"\\n\"\n\n                    while (buffer.contains(\"\\n\")) {\n                        val newlineIndex = buffer.indexOf(\"\\n\")\n                        val line = buffer.substring(0, newlineIndex).trim()\n                        buffer = buffer.substring(newlineIndex + 1)\n\n                        if (line.startsWith(\"data: \")) {\n                            val dataStr = line.substring(6).trim()\n                            if (dataStr.isNotEmpty() && dataStr != \"[DONE]\") {\n                                try {\n                                    val chunkData = gson.fromJson(dataStr, Map::class.java)\n                                    val content = chunkData[\"content\"] as? String\n                                        ?: ((chunkData[\"choices\"] as? List<*>)?.get(0) as? Map<*, *>)?.let {\n                                            (it[\"delta\"] as? Map<*, *>)?.get(\"content\") as? String\n                                                ?: (it[\"message\"] as? Map<*, *>)?.get(\"content\") as? String\n                                        } ?: \"\"\n\n                                    if (content.isNotEmpty()) {\n                                        print(content)\n                                        fullContent += content\n                                    }\n                                } catch (e: Exception) {\n                                    // 忽略JSON解析错误\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n\n            println()\n            return@withContext fullContent\n        } else {\n            println(\"AI 调用失败: ${response.code}\")\n            return@withContext null\n        }\n    } catch (e: Exception) {\n        println(\"AI 调用失败: ${e.message}\")\n        e.printStackTrace()\n        return@withContext null\n    }\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val response = chatWithAgentStream(cloudbase, \"{%AGENT_ID%}\", \"你是谁\")\n//     println(\"\\n完整回复: $response\")\n// }\n\n```",
                "index": 0,
                "id": "scf",
                "title": "函数型"
              },
              {
                "markdown": "```kotlin\nimport okhttp3.OkHttpClient\nimport okhttp3.Request\nimport okhttp3.RequestBody.Companion.toRequestBody\nimport okhttp3.MediaType.Companion.toMediaType\nimport com.google.gson.Gson\n\nsuspend fun chatWithAgentStream(cloudbase: CloudBaseClient, botId: String, msg: String, history: List<Map<String, String>>? = null): String? = withContext(Dispatchers.IO) {\n    // 流式调用Agent\n    val payload = mapOf(\n        \"history\" to (history ?: emptyList<Map<String, String>>()),\n        \"msg\" to msg\n    )\n\n    val url = \"${cloudbase.baseUrl}/v1/aibot/bots/$botId/send-message\"\n    val gson = Gson()\n\n    val requestBody = gson.toJson(payload).toRequestBody(\"application/json\".toMediaType())\n\n    val request = Request.Builder()\n        .url(url)\n        .header(\"Content-Type\", \"application/json\")\n        .header(\"Accept\", \"text/event-stream\")\n        .header(\"Authorization\", \"Bearer ${cloudbase.accessToken}\")\n        .post(requestBody)\n        .build()\n\n    try {\n        val client = OkHttpClient()\n        val response = client.newCall(request).execute()\n\n        if (response.isSuccessful) {\n            println(\"AI 流式响应:\")\n            var fullContent = \"\"\n            var buffer = \"\"\n\n            response.body?.source()?.use { source ->\n                while (!source.exhausted()) {\n                    buffer += source.readUtf8Line() ?: \"\"\n                    buffer += \"\\n\"\n\n                    while (buffer.contains(\"\\n\")) {\n                        val newlineIndex = buffer.indexOf(\"\\n\")\n                        val line = buffer.substring(0, newlineIndex).trim()\n                        buffer = buffer.substring(newlineIndex + 1)\n\n                        if (line.startsWith(\"data: \")) {\n                            val dataStr = line.substring(6).trim()\n                            if (dataStr.isNotEmpty() && dataStr != \"[DONE]\") {\n                                try {\n                                    val chunkData = gson.fromJson(dataStr, Map::class.java)\n                                    val content = chunkData[\"content\"] as? String\n                                        ?: ((chunkData[\"choices\"] as? List<*>)?.get(0) as? Map<*, *>)?.let {\n                                            (it[\"delta\"] as? Map<*, *>)?.get(\"content\") as? String\n                                                ?: (it[\"message\"] as? Map<*, *>)?.get(\"content\") as? String\n                                        } ?: \"\"\n\n                                    if (content.isNotEmpty()) {\n                                        print(content)\n                                        fullContent += content\n                                    }\n                                } catch (e: Exception) {\n                                    // 忽略JSON解析错误\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n\n            println()\n            return@withContext fullContent\n        } else {\n            println(\"AI 调用失败: ${response.code}\")\n            return@withContext null\n        }\n    } catch (e: Exception) {\n        println(\"AI 调用失败: ${e.message}\")\n        e.printStackTrace()\n        return@withContext null\n    }\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val response = chatWithAgentStream(cloudbase, \"{%AGENT_ID%}\", \"你是谁\")\n//     println(\"\\n完整回复: $response\")\n// }\n```",
                "index": 1,
                "id": "baas",
                "title": "普通型"
              }
            ]
          },
          {
            "index": 8,
            "id": "identity",
            "title": "身份认证",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```kotlin\nsuspend fun signUpWithPhoneCode(cloudbase: CloudBaseClient, phoneNumber: String, verificationCode: String, username: String? = null, password: String? = null, captchaToken: String? = null): Map<String, Any>? {\n    // 步骤1: 发送短信验证码\n    val sendBody = mutableMapOf<String, Any>(\n        \"phone_number\" to if (phoneNumber.startsWith(\"+86\")) phoneNumber else \"+86$phoneNumber\",\n        \"target\" to \"NON_USER\"  // \"NON_USER\" - 账号不存在才发送; \"ANY\" - 不限制\n    )\n\n    val sendHeaders = captchaToken?.let { mapOf(\"x-captcha-token\" to it) } ?: emptyMap()\n\n    val sendResult = cloudbase.request<Map<String, Any>>(\n        method = \"POST\",\n        path = \"/auth/v1/verification\",\n        body = sendBody,\n        customHeaders = sendHeaders,\n        typeToken = object : TypeToken<Map<String, Any>>() {}\n    )\n\n    if (sendResult == null) {\n        println(\"发送验证码失败\")\n        return null\n    }\n\n    val verificationId = sendResult[\"verification_id\"] as? String ?: return null\n    println(\"验证码发送成功! ID: $verificationId\")\n\n    // 步骤2: 验证验证码\n    val verifyResult = cloudbase.request<Map<String, Any>>(\n        method = \"POST\",\n        path = \"/auth/v1/verification/verify\",\n        body = mapOf(\n            \"verification_id\" to verificationId,\n            \"verification_code\" to verificationCode\n        ),\n        typeToken = object : TypeToken<Map<String, Any>>() {}\n    )\n\n    if (verifyResult == null) {\n        println(\"验证码错误\")\n        return null\n    }\n\n    val verificationToken = verifyResult[\"verification_token\"] as? String ?: return null\n    println(\"验证成功!\")\n\n    // 步骤3: 使用验证令牌注册\n    val signUpBody = mutableMapOf<String, Any>(\n        \"phone_number\" to if (phoneNumber.startsWith(\"+86\")) phoneNumber else \"+86$phoneNumber\",\n        \"verification_token\" to verificationToken\n    )\n\n    // 可选：添加用户名和密码\n    username?.let { signUpBody[\"username\"] = it }\n    password?.let { signUpBody[\"password\"] = it }\n\n    val signUpResult = cloudbase.request<Map<String, Any>>(\n        method = \"POST\",\n        path = \"/auth/v1/signup\",\n        body = signUpBody,\n        typeToken = object : TypeToken<Map<String, Any>>() {}\n    )\n\n    if (signUpResult != null) {\n        val accessToken = signUpResult[\"access_token\"] as? String\n        val userId = signUpResult[\"sub\"] as? String\n\n        println(\"注册成功! 用户ID: $userId\")\n        println(\"访问令牌: ${accessToken?.take(20)}...\")\n\n        // 更新访问令牌\n        accessToken?.let { cloudbase.updateAccessToken(it) }\n        return signUpResult\n    }\n\n    println(\"注册失败\")\n    return null\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val result = signUpWithPhoneCode(cloudbase, \"13800138000\", \"123456\", \"myusername\", \"mypassword\")\n//     if (result != null) {\n//         println(\"手机号注册成功\")\n//     }\n// }\n```",
                "index": 1,
                "title": "短信验证码注册",
                "content": []
              },
              {
                "markdown": "```kotlin\nsuspend fun signUpWithEmailCode(cloudbase: CloudBaseClient, email: String, verificationCode: String, username: String? = null, password: String? = null, captchaToken: String? = null): Map<String, Any>? {\n    // 步骤1: 发送邮箱验证码\n    val sendBody = mutableMapOf<String, Any>(\n        \"email\" to email,\n        \"target\" to \"NON_USER\"  // \"NON_USER\" - 账号不存在才发送; \"ANY\" - 不限制\n    )\n\n    val sendHeaders = captchaToken?.let { mapOf(\"x-captcha-token\" to it) } ?: emptyMap()\n\n    val sendResult = cloudbase.request<Map<String, Any>>(\n        method = \"POST\",\n        path = \"/auth/v1/verification\",\n        body = sendBody,\n        customHeaders = sendHeaders,\n        typeToken = object : TypeToken<Map<String, Any>>() {}\n    )\n\n    if (sendResult == null) {\n        println(\"发送验证码失败\")\n        return null\n    }\n\n    val verificationId = sendResult[\"verification_id\"] as? String ?: return null\n    println(\"验证码发送成功! ID: $verificationId\")\n\n    // 步骤2: 验证验证码\n    val verifyResult = cloudbase.request<Map<String, Any>>(\n        method = \"POST\",\n        path = \"/auth/v1/verification/verify\",\n        body = mapOf(\n            \"verification_id\" to verificationId,\n            \"verification_code\" to verificationCode\n        ),\n        typeToken = object : TypeToken<Map<String, Any>>() {}\n    )\n\n    if (verifyResult == null) {\n        println(\"验证码错误\")\n        return null\n    }\n\n    val verificationToken = verifyResult[\"verification_token\"] as? String ?: return null\n    println(\"验证成功!\")\n\n    // 步骤3: 使用验证令牌注册\n    val signUpBody = mutableMapOf<String, Any>(\n        \"email\" to email,\n        \"verification_token\" to verificationToken\n    )\n\n    // 可选：添加用户名和密码\n    username?.let { signUpBody[\"username\"] = it }\n    password?.let { signUpBody[\"password\"] = it }\n\n    val signUpResult = cloudbase.request<Map<String, Any>>(\n        method = \"POST\",\n        path = \"/auth/v1/signup\",\n        body = signUpBody,\n        typeToken = object : TypeToken<Map<String, Any>>() {}\n    )\n\n    if (signUpResult != null) {\n        val accessToken = signUpResult[\"access_token\"] as? String\n        val userId = signUpResult[\"sub\"] as? String\n\n        println(\"注册成功! 用户ID: $userId\")\n        println(\"访问令牌: ${accessToken?.take(20)}...\")\n\n        // 更新访问令牌\n        accessToken?.let { cloudbase.updateAccessToken(it) }\n        return signUpResult\n    }\n\n    println(\"注册失败\")\n    return null\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val result = signUpWithEmailCode(cloudbase, \"user@example.com\", \"123456\", \"myusername\", \"mypassword\")\n//     if (result != null) {\n//         println(\"邮箱注册成功\")\n//     }\n// }\n```",
                "index": 2,
                "title": "邮箱验证码注册",
                "content": []
              },
              {
                "markdown": "```kotlin\nsuspend fun signIn(cloudbase: CloudBaseClient, username: String, password: String): Map<String, Any>? {\n    // 账号密码登录\n    val result = cloudbase.request<Map<String, Any>>(\n        method = \"POST\",\n        path = \"/auth/v1/signin\",\n        body = mapOf(\"username\" to username, \"password\" to password),\n        typeToken = object : TypeToken<Map<String, Any>>() {}\n    )\n\n    if (result != null) {\n        val accessToken = result[\"access_token\"] as? String\n        val refreshToken = result[\"refresh_token\"] as? String\n        val userId = result[\"sub\"] as? String\n\n        println(\"登录成功! 用户ID: $userId\")\n        println(\"访问令牌: ${accessToken?.take(20)}...\")\n\n        // 更新访问令牌\n        accessToken?.let { cloudbase.updateAccessToken(it) }\n        return result\n    }\n    return null\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val result = signIn(cloudbase, \"your_username\", \"your_password\")\n//     println(result)\n// }\n```",
                "index": 3,
                "id": "UserNameLogin",
                "title": "账号密码登录",
                "content": []
              },
              {
                "markdown": "```kotlin\nsuspend fun loginWithPhoneCode(cloudbase: CloudBaseClient, phoneNumber: String, verificationCode: String, captchaToken: String? = null): Boolean {\n    // 步骤1: 发送短信验证码\n    val sendBody = mutableMapOf<String, Any>(\n        \"phone_number\" to if (phoneNumber.startsWith(\"+86\")) phoneNumber else \"+86$phoneNumber\",\n        \"target\" to \"ANY\"  // \"ANY\" - 不限制，无论用户是否存在都发送; \"USER\" - 账号必须存在才发送\n    )\n\n    val sendHeaders = captchaToken?.let { mapOf(\"x-captcha-token\" to it) } ?: emptyMap()\n\n    val sendResult = cloudbase.request<Map<String, Any>>(\n        method = \"POST\",\n        path = \"/auth/v1/verification\",\n        body = sendBody,\n        customHeaders = sendHeaders,\n        typeToken = object : TypeToken<Map<String, Any>>() {}\n    )\n\n    if (sendResult == null) {\n        println(\"发送验证码失败\")\n        return false\n    }\n\n    val verificationId = sendResult[\"verification_id\"] as? String ?: return false\n    println(\"验证码发送成功! ID: $verificationId\")\n\n    // 步骤2: 验证验证码\n    val verifyResult = cloudbase.request<Map<String, Any>>(\n        method = \"POST\",\n        path = \"/auth/v1/verification/verify\",\n        body = mapOf(\n            \"verification_id\" to verificationId,\n            \"verification_code\" to verificationCode\n        ),\n        typeToken = object : TypeToken<Map<String, Any>>() {}\n    )\n\n    if (verifyResult == null) {\n        println(\"验证码错误\")\n        return false\n    }\n\n    val verificationToken = verifyResult[\"verification_token\"] as? String ?: return false\n    println(\"验证成功!\")\n\n    // 步骤3: 使用验证令牌登录\n    val loginResult = cloudbase.request<Map<String, Any>>(\n        method = \"POST\",\n        path = \"/auth/v1/signin\",\n        body = mapOf(\n            \"phone_number\" to if (phoneNumber.startsWith(\"+86\")) phoneNumber else \"+86$phoneNumber\",\n            \"verification_token\" to verificationToken\n        ),\n        typeToken = object : TypeToken<Map<String, Any>>() {}\n    )\n\n    if (loginResult != null) {\n        val accessToken = loginResult[\"access_token\"] as? String\n        println(\"登录成功!\")\n        accessToken?.let { cloudbase.updateAccessToken(it) }\n        return true\n    }\n\n    println(\"登录失败\")\n    return false\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val success = loginWithPhoneCode(cloudbase, \"13800138000\", \"123456\")\n//     if (success) {\n//         println(\"手机号登录成功\")\n//     }\n// }\n```",
                "index": 4,
                "id": "PhoneNumberLogin",
                "title": "短信验证码登录",
                "content": []
              },
              {
                "markdown": "```kotlin\nsuspend fun loginWithEmailCode(cloudbase: CloudBaseClient, email: String, verificationCode: String, captchaToken: String? = null): Boolean {\n    // 步骤1: 发送邮箱验证码\n    val sendBody = mutableMapOf<String, Any>(\n        \"email\" to email,\n        \"target\" to \"ANY\"  // \"ANY\" - 不限制，无论用户是否存在都发送; \"USER\" - 账号必须存在才发送\n    )\n\n    val sendHeaders = captchaToken?.let { mapOf(\"x-captcha-token\" to it) } ?: emptyMap()\n\n    val sendResult = cloudbase.request<Map<String, Any>>(\n        method = \"POST\",\n        path = \"/auth/v1/verification\",\n        body = sendBody,\n        customHeaders = sendHeaders,\n        typeToken = object : TypeToken<Map<String, Any>>() {}\n    )\n\n    if (sendResult == null) {\n        println(\"发送验证码失败\")\n        return false\n    }\n\n    val verificationId = sendResult[\"verification_id\"] as? String ?: return false\n    println(\"验证码发送成功! ID: $verificationId\")\n\n    // 步骤2: 验证验证码\n    val verifyResult = cloudbase.request<Map<String, Any>>(\n        method = \"POST\",\n        path = \"/auth/v1/verification/verify\",\n        body = mapOf(\n            \"verification_id\" to verificationId,\n            \"verification_code\" to verificationCode\n        ),\n        typeToken = object : TypeToken<Map<String, Any>>() {}\n    )\n\n    if (verifyResult == null) {\n        println(\"验证码错误\")\n        return false\n    }\n\n    val verificationToken = verifyResult[\"verification_token\"] as? String ?: return false\n    println(\"验证成功!\")\n\n    // 步骤3: 使用验证令牌登录\n    val loginResult = cloudbase.request<Map<String, Any>>(\n        method = \"POST\",\n        path = \"/auth/v1/signin\",\n        body = mapOf(\n            \"email\" to email,\n            \"verification_token\" to verificationToken\n        ),\n        typeToken = object : TypeToken<Map<String, Any>>() {}\n    )\n\n    if (loginResult != null) {\n        val accessToken = loginResult[\"access_token\"] as? String\n        println(\"登录成功!\")\n        accessToken?.let { cloudbase.updateAccessToken(it) }\n        return true\n    }\n\n    println(\"登录失败\")\n    return false\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val success = loginWithEmailCode(cloudbase, \"user@example.com\", \"123456\")\n//     if (success) {\n//         println(\"邮箱登录成功\")\n//     }\n// }\n```",
                "index": 5,
                "id": "email",
                "title": "邮箱验证码登录",
                "content": []
              }
            ]
          }
        ]
      }
    ],
    "_id": "14b1f540697c22ed003a162b5a2dd1b3",
    "_openid": "anon",
    "createdAt": 1769743085345,
    "updatedAt": 1770021222132
  },
  {
    "category": "CloudBase MCP,Cursor",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": 51,
    "hasTemplate": true,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/cursor",
    "content": [
      {
        "docsUrl": "",
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "将以下配置添加到 `.cursor/mcp.json`:\n```json\n{\n  \"mcpServers\": {\n    \"cloudbase\": {\n      \"command\": \"npx\",\n      \"args\": [\"@cloudbase/cloudbase-mcp@latest\"],\n      \"env\": {\n        \"INTEGRATION_IDE\": \"Cursor\"\n      }\n    }\n  }\n}\n```\n",
            "title": "手动配置"
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "22be1a426964a55f0bb8d12e3ef280ce",
    "_openid": "1524963278340493312",
    "createdAt": 1768203615153,
    "updatedAt": 1768203615153
  },
  {
    "category": "CloudBase MCP,CodeBuddy",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": 52,
    "hasTemplate": true,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/codebuddy",
    "content": [
      {
        "docsUrl": "",
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "CodeBuddy IDE 已内置集成 CloudBase MCP，建议优先使用配置集成方式，[查看 BaaS 集成文档](https://www.codebuddy.ai/docs/zh/ide/User-guide/Integration)",
            "title": "内置集成"
          },
          {
            "markdown": "手动配置 MCP 请查看 [CodeBuddy 文档](https://www.codebuddy.ai/docs/zh/ide/Config%20MCP) \n```json\n{\n  \"mcpServers\": {\n    \"cloudbase\": {\n      \"command\": \"npx\",\n      \"args\": [\"@cloudbase/cloudbase-mcp@latest\"],\n      \"env\": {\n        \"INTEGRATION_IDE\": \"CodeBuddyManual\"\n      }\n    }\n  }\n}\n```\n",
            "title": "手动配置"
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "22be1a426964a55f0bb8d12f3ea44e2d",
    "_openid": "1524963278340493312",
    "createdAt": 1768203615153,
    "updatedAt": 1770708687170
  },
  {
    "category": "CloudBase MCP,Claude Code",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": 53,
    "hasTemplate": true,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/claude-code",
    "content": [
      {
        "docsUrl": "",
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "将以下配置添加到 `.mcp.json`:\n```json\n{\n  \"mcpServers\": {\n    \"cloudbase\": {\n      \"command\": \"npx\",\n      \"args\": [\"@cloudbase/cloudbase-mcp@latest\"],\n      \"env\": {\n        \"INTEGRATION_IDE\": \"ClaudeCode\"\n      }\n    }\n  }\n}\n```\n",
            "title": "手动配置"
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "22be1a426964a55f0bb8d130511a01bb",
    "_openid": "1524963278340493312",
    "createdAt": 1768203615153,
    "updatedAt": 1768203615153
  },
  {
    "category": "CloudBase MCP,CodeBuddy Code",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": 54,
    "hasTemplate": true,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/codebuddy-code",
    "content": [
      {
        "docsUrl": "",
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "```bash\ncodebuddy mcp add --scope project cloudbase --env INTEGRATION_IDE=CodeBuddyCode -- npx @cloudbase/cloudbase-mcp@latest\n```",
            "title": "CLI 命令"
          },
          {
            "markdown": "将以下配置添加到 `.mcp.json`:\n```json\n{\n  \"mcpServers\": {\n    \"cloudbase\": {\n      \"command\": \"npx\",\n      \"args\": [\"@cloudbase/cloudbase-mcp@latest\"],\n      \"env\": {\n        \"INTEGRATION_IDE\": \"CodeBuddyCode\"\n      }\n    }\n  }\n}\n```\n",
            "title": "手动配置"
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "22be1a426964a55f0bb8d131522e6b45",
    "_openid": "1524963278340493312",
    "createdAt": 1768203615153,
    "updatedAt": 1768203615153
  },
  {
    "category": "CloudBase MCP,VSCode",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": 55,
    "hasTemplate": true,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/github-copilot",
    "content": [
      {
        "docsUrl": "",
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "将以下配置添加到 `.vscode/mcp.json`:\n```json\n{\n  \"mcpServers\": {\n    \"cloudbase\": {\n      \"command\": \"npx\",\n      \"args\": [\"@cloudbase/cloudbase-mcp@latest\"],\n      \"env\": {\n        \"INTEGRATION_IDE\": \"VSCode\"\n      }\n    }\n  }\n}\n```\n",
            "title": "手动配置"
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "22be1a426964a55f0bb8d1324213bff0",
    "_openid": "1524963278340493312",
    "createdAt": 1768203615153,
    "updatedAt": 1768203615153
  },
  {
    "category": "CloudBase MCP,Trae",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": 56,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/trae",
    "content": [
      {
        "docsUrl": "",
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "将以下配置添加到 `.trae/mcp.json`:\n```json\n{\n  \"mcpServers\": {\n    \"cloudbase\": {\n      \"command\": \"npx\",\n      \"args\": [\"@cloudbase/cloudbase-mcp@latest\"],\n      \"env\": {\n        \"INTEGRATION_IDE\": \"Trae\"\n      }\n    }\n  }\n}\n```\n",
            "title": "手动配置"
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "22be1a426964a55f0bb8d1331565794a",
    "_openid": "1524963278340493312",
    "createdAt": 1768203615153,
    "updatedAt": 1768203615153
  },
  {
    "category": "CloudBase MCP,通义灵码",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": 57,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/tongyi-lingma",
    "content": [
      {
        "docsUrl": "",
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "手动配置 MCP 请查看 [通义灵码文档](https://help.aliyun.com/zh/lingma/user-guide/guide-for-using-mcp) \n```json\n{\n  \"mcpServers\": {\n    \"cloudbase\": {\n      \"command\": \"npx\",\n      \"args\": [\"@cloudbase/cloudbase-mcp@latest\"],\n      \"env\": {\n        \"INTEGRATION_IDE\": \"LingMa\"\n      }\n    }\n  }\n}\n```\n",
            "title": "手动配置"
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "22be1a426964a55f0bb8d1341f5bfc09",
    "_openid": "1524963278340493312",
    "createdAt": 1768203615153,
    "updatedAt": 1768203615153
  },
  {
    "category": "CloudBase MCP,文心快码",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": 58,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/baidu-comate",
    "content": [
      {
        "docsUrl": "",
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "将以下配置添加到 `.baidu-comate/mcp.json`: \n```json\n{\n  \"mcpServers\": {\n    \"cloudbase\": {\n      \"command\": \"npx\",\n      \"args\": [\"@cloudbase/cloudbase-mcp@latest\"],\n      \"env\": {\n        \"INTEGRATION_IDE\": \"Comate\"\n      }\n    }\n  }\n}\n```\n",
            "title": "手动配置"
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "22be1a426964a55f0bb8d1351a7880cb",
    "_openid": "1524963278340493312",
    "createdAt": 1768203615153,
    "updatedAt": 1768203615153
  },
  {
    "category": "CloudBase MCP,Gemini CLI",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": 59,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/gemini-cli",
    "content": [
      {
        "docsUrl": "",
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "将以下配置添加到 `.gemini/settings.json`:\n```json\n{\n  \"mcpServers\": {\n    \"cloudbase\": {\n      \"command\": \"npx\",\n      \"args\": [\"@cloudbase/cloudbase-mcp@latest\"],\n      \"env\": {\n        \"INTEGRATION_IDE\": \"Gemini\"\n      }\n    }\n  }\n}\n```\n",
            "title": "手动配置"
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "22be1a426964a55f0bb8d136703529b9",
    "_openid": "1524963278340493312",
    "createdAt": 1768203615153,
    "updatedAt": 1768203615153
  },
  {
    "category": "CloudBase MCP,OpenAI Codex CLI",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": 60,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/openai-codex-cli",
    "content": [
      {
        "docsUrl": "",
        "markdown": "**前置步骤：** \n```bash\nnpm i @cloudbase/cloudbase-mcp -g\n```\n\n根据运行系统在终端中运行指令：\n\n**MacOS, Linux, WSL:**\n```bash\ncodex mcp add cloudbase --env INTEGRATION_IDE=CodeX -- cloudbase-mcp\n```\n\n**Windows Powershell:**\n```bash\ncodex mcp add cloudbase --env INTEGRATION_IDE=CodeX -- cmd /c cloudbase-mcp\n```",
        "title": "安装",
        "type": "",
        "content": []
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "22be1a426964a55f0bb8d1371c59129e",
    "_openid": "1524963278340493312",
    "createdAt": 1768203615153,
    "updatedAt": 1768203615153
  },
  {
    "category": "CloudBase MCP,Qwen Code",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": 61,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/qwen-code",
    "content": [
      {
        "docsUrl": "",
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "将以下配置添加到 `.qwen/settings.json`: \n```json\n{\n  \"mcpServers\": {\n    \"cloudbase\": {\n      \"command\": \"npx\",\n      \"args\": [\"@cloudbase/cloudbase-mcp@latest\"],\n      \"env\": {\n        \"INTEGRATION_IDE\": \"Qwen\"\n      }\n    }\n  }\n}\n```\n",
            "title": "手动配置"
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "22be1a426964a55f0bb8d1384c3a39a1",
    "_openid": "1524963278340493312",
    "createdAt": 1768203615153,
    "updatedAt": 1768203615153
  },
  {
    "category": "CloudBase MCP,RooCode",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": 62,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/roocode",
    "content": [
      {
        "docsUrl": "",
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "将以下配置添加到 `.roocode/mcp.json`: \n```json\n{\n  \"mcpServers\": {\n    \"cloudbase\": {\n      \"command\": \"npx\",\n      \"args\": [\"@cloudbase/cloudbase-mcp@latest\"],\n\t  \"disabled\": false,\n      \"env\": {\n        \"INTEGRATION_IDE\": \"RooCode\"\n      }\n    }\n  }\n}\n```\n",
            "title": "手动配置"
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "22be1a426964a55f0bb8d13924867803",
    "_openid": "1524963278340493312",
    "createdAt": 1768203615153,
    "updatedAt": 1768203615153
  },
  {
    "category": "CloudBase MCP,Augment Code",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": 63,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/augment-code",
    "content": [
      {
        "docsUrl": "",
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "将以下配置添加到 `.vscode/settings.json`: \n```json\n{\n  \"mcpServers\": {\n    \"cloudbase\": {\n      \"command\": \"npx\",\n      \"args\": [\"@cloudbase/cloudbase-mcp@latest\"],\n      \"env\": {\n        \"INTEGRATION_IDE\": \"Augment\"\n      }\n    }\n  }\n}\n```\n",
            "title": "手动配置"
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "22be1a426964a55f0bb8d13a126e66f6",
    "_openid": "1524963278340493312",
    "createdAt": 1768203615153,
    "updatedAt": 1768203615153
  },
  {
    "category": "CloudBase MCP,OpenCode",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": 64,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/opencode",
    "content": [
      {
        "docsUrl": "",
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "将以下配置添加到 `.opencode.json`: \n```json\n{\n  \"mcpServers\": {\n    \"cloudbase\": {\n      \"command\": \"npx\",\n      \"args\": [\"@cloudbase/cloudbase-mcp@latest\"],\n      \"env\": {\n        \"INTEGRATION_IDE\": \"OpenCode\"\n      }\n    }\n  }\n}\n```\n",
            "title": "手动配置"
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "22be1a426964a55f0bb8d13b61a91849",
    "_openid": "1524963278340493312",
    "createdAt": 1768203615153,
    "updatedAt": 1768203615153
  },
  {
    "category": "CloudBase MCP,Qoder",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": 65,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/qoder",
    "content": [
      {
        "docsUrl": "",
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "将以下配置添加到 `Qoder 设置 > MCP`: \n```json\n{\n  \"mcpServers\": {\n    \"cloudbase\": {\n      \"command\": \"npx\",\n      \"args\": [\"@cloudbase/cloudbase-mcp@latest\"],\n      \"env\": {\n        \"INTEGRATION_IDE\": \"Qorder\"\n      }\n    }\n  }\n}\n```\n",
            "title": "手动配置"
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "22be1a426964a55f0bb8d13c164b5905",
    "_openid": "1524963278340493312",
    "createdAt": 1768203615153,
    "updatedAt": 1768203615153
  },
  {
    "category": "CloudBase MCP,Google Antigravity",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": 66,
    "hasTemplate": true,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/antigravity",
    "content": [
      {
        "docsUrl": "",
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "将以下配置添加到 `.agent/rules/`: \n```json\n{\n  \"mcpServers\": {\n    \"cloudbase\": {\n      \"command\": \"npx\",\n      \"args\": [\"@cloudbase/cloudbase-mcp@latest\"],\n      \"env\": {\n        \"INTEGRATION_IDE\": \"Antigravity\"\n      }\n    }\n  }\n}\n```\n",
            "title": "手动配置"
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "22be1a426964a55f0bb8d13d68aaba00",
    "_openid": "1524963278340493312",
    "createdAt": 1768203615153,
    "updatedAt": 1768203615153
  },
  {
    "category": "CloudBase MCP,WindSurf",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": 67,
    "hasTemplate": true,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/windsurf",
    "content": [
      {
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "将以下配置添加到 `.windsurf/mcp.json`: \n```json\n{\n  \"mcpServers\": {\n    \"cloudbase\": {\n      \"command\": \"npx\",\n      \"args\": [\"@cloudbase/cloudbase-mcp@latest\"],\n      \"env\": {\n        \"INTEGRATION_IDE\": \"WindSurf\",\n        \"CLOUDBASE_MCP_PLUGINS_DISABLED\": \"interactive\"\n      }\n    }\n  }\n}\n```\n",
            "title": "手动配置",
            "content": []
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "22be1a426964a55f0bb8d13e088ef225",
    "_openid": "1524963278340493312",
    "createdAt": 1768203615153,
    "updatedAt": 1769757586231
  },
  {
    "category": "CloudBase MCP,Cline",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": 68,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/cline",
    "content": [
      {
        "docsUrl": "",
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "将以下配置添加到 `.cline/mcp.json`: \n```json\n{\n  \"mcpServers\": {\n    \"cloudbase\": {\n      \"autoApprove\": [],\n      \"timeout\": 60,\n      \"command\": \"npx\",\n      \"args\": [\"@cloudbase/cloudbase-mcp@latest\"],\n      \"env\": {\n        \"INTEGRATION_IDE\": \"Cline\"\n      },\n      \"transportType\": \"stdio\",\n      \"disabled\": false\n    }\n  }\n}\n```\n",
            "title": "手动配置"
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "22be1a426964a55f0bb8d13f2bb38389",
    "_openid": "1524963278340493312",
    "createdAt": 1768203615153,
    "updatedAt": 1768203615153
  },
  {
    "category": "CloudBase MCP,Kiro",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": 69,
    "hasTemplate": true,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/kiro",
    "content": [
      {
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "将以下配置添加到项目目录下的 `.kiro/settings/mcp.json`: \n```json\n{\n  \"mcpServers\": {\n    \"cloudbase\": {\n      \"command\": \"npx\",\n      \"args\": [\"@cloudbase/cloudbase-mcp@latest\"],\n      \"env\": {\n        \"INTEGRATION_IDE\": \"Kiro\"\n      }\n    }\n  }\n}\n```",
            "title": "手动配置"
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "tab",
        "content": []
      }
    ],
    "_id": "22be1a426964a55f0bb8d140138f8e03",
    "_openid": "1524963278340493312",
    "createdAt": 1768203615153,
    "updatedAt": 1768203615153
  },
  {
    "category": "框架集成,小程序 / 小游戏,微信小程序",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": -1,
    "hasTemplate": false,
    "docsUrl": "https://developers.weixin.qq.com/miniprogram/dev/wxcloudservice/wxcloud/guide/init.html",
    "content": [
      {
        "markdown": "在 `app.js` 中初始化云开发：",
        "index": 1,
        "title": "初始化 SDK",
        "type": "codeTab",
        "content": [
          {
            "markdown": "大部分云开发能力可通过 `小程序原生 API` 直接调用，无需安装 SDK，若 `原生API` 不支持请使用 `Client SDK` 进行调用\n\n```js\nApp({\n  onLaunch() {\n    wx.cloud.init({\n      env: \"{%ENV_ID%}\"\n    });\n  }\n});\n```",
            "index": 1,
            "title": "原生API 初始化",
            "content": []
          },
          {
            "markdown": "**安装**\n\n使用 Client SDK 前请先安装 SDK\n\n在小程序 `package.json` 所在目录（通常为 `miniprogram` 目录）执行：\n\n```bash\nnpm i @cloudbase/wx-cloud-client-sdk --save\n```\n\n安装完成后，在微信开发者工具点击 **工具 → 构建 npm**。\n\n**初始化**\n\n```js\nconst { init } = require(\"@cloudbase/wx-cloud-client-sdk\");\n\nApp({\n  onLaunch() {\n    wx.cloud.init({\n      env: \"{%ENV_ID%}\"\n    });\n    this.globalData.cloudbase = init(wx.cloud);\n  },\n  globalData: {}\n});\n```",
            "index": 2,
            "title": "Client SDK 初始化",
            "content": []
          }
        ]
      },
      {
        "index": 2,
        "title": "调用云开发能力",
        "type": "codeTab",
        "content": [
          {
            "markdown": "请使用 `Client SDK` 进行调用",
            "index": 1,
            "id": "mysql-db",
            "title": "MySQL数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\nconst cloudbase = getApp().globalData.cloudbase;\n\n// 查询 {%TABLE_NAME%} 表前10条数据\nconst { data, error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .select(\"*\")\n  .limit(10);\n\nconsole.log(\"查询结果:\", data);\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "```js\nconst cloudbase = getApp().globalData.cloudbase;\n\n// 新增 {%TABLE_NAME%} 表数据\nconst { data, error } = await cloudbase.rdb().from(\"{%TABLE_NAME%}\").insert({\n  title: \"示例标题\"\n});\n\nconsole.log(\"新增结果:\", error ? \"失败\" : \"成功\");\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "```js\nconst cloudbase = getApp().globalData.cloudbase;\n\n// 更新 {%TABLE_NAME%} 表中 id 为 <数据ID> 的数据\nconst { data, error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .update({\n    title: \"更新后的标题\"\n  })\n  .eq(\"id\", \"<数据ID>\");\n\nconsole.log(\"更新结果:\", error ? \"失败\" : \"成功\");\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "```js\nconst cloudbase = getApp().globalData.cloudbase;\n\n// 如果 {%TABLE_NAME%} 表中存在 id 为 1 的记录则更新 title 为\"示例标题\"，不存在则插入新记录\nconst { data, error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .upsert({ id: 1, title: \"示例标题\" });\n\nconsole.log(\"新增更新结果:\", error ? \"失败\" : \"成功\");\n```",
                "index": 4,
                "title": "更新或创建数据"
              },
              {
                "markdown": "```js\nconst cloudbase = getApp().globalData.cloudbase;\n\n// 删除 {%TABLE_NAME%} 表中 id 为 <数据ID> 的数据\nconst { data, error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .delete()\n  .eq(\"id\", \"<数据ID>\");\n\nconsole.log(\"删除结果:\", error ? \"失败\" : \"成功\");\n```",
                "index": 5,
                "title": "删除数据"
              }
            ]
          },
          {
            "index": 2,
            "id": "doc-db",
            "title": "文档型数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\nconst db = wx.cloud.database();\n\n// 查询 {%TABLE_NAME%} 表前10条数据\nconst res = await db.collection(\"{%TABLE_NAME%}\").limit(10).get();\n\nconsole.log(res.data);\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "```js\nconst db = wx.cloud.database();\n\n// 新增 {%TABLE_NAME%} 表数据\nconst res = await db.collection(\"{%TABLE_NAME%}\").add({\n  data: {\n    title: \"示例标题\",\n    content: \"示例内容\"\n  }\n});\n\nconsole.log(res);\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "```js\nconst db = wx.cloud.database();\n\n// 更新 {%TABLE_NAME%} 表中 id 为 <数据ID> 的数据\nconst res = await db\n  .collection(\"{%TABLE_NAME%}\")\n  .doc(\"<数据ID>\")\n  .update({\n    data: {\n      title: \"更新后的标题\"\n    }\n  });\n\nconsole.log(res.stats.updated);\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "```js\nconst db = wx.cloud.database();\n\n// 删除 {%TABLE_NAME%} 表中 id 为 <数据ID> 的数据\nconst res = await db.collection(\"{%TABLE_NAME%}\").doc(\"<数据ID>\").remove();\n\nconsole.log(res.stats.removed);\n```",
                "index": 4,
                "title": "删除数据"
              }
            ]
          },
          {
            "markdown": "请使用 `Client SDK` 进行调用",
            "index": 3,
            "id": "data-model",
            "title": "数据模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\nconst cloudbase = getApp().globalData.cloudbase;\n\n// 查询 {%TABLE_NAME%} 数据模型前10条数据\nconst res = await cloudbase.models[\"{%TABLE_NAME%}\"].list({\n  pageNumber: 1,\n  pagesize: 10\n});\n\nconsole.log(res.data.records);\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "```js\nconst cloudbase = getApp().globalData.cloudbase;\n\n// 新增 {%TABLE_NAME%} 数据模型数据\nconst res = await cloudbase.models[\"{%TABLE_NAME%}\"].create({\n  data: {\n    title: \"示例标题\",\n    content: \"示例内容\"\n  }\n});\n\nconsole.log(res.data);\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "```js\nconst cloudbase = getApp().globalData.cloudbase;\n\n// 更新 {%TABLE_NAME%} 数据模型中 _id 为 <数据ID> 的数据\nconst res = await cloudbase.models[\"{%TABLE_NAME%}\"].update({\n  data: {\n    title: \"更新后的标题\"\n  },\n  filter: {\n    where: {\n      _id: {\n        $eq: \"<数据ID>\"\n      }\n    }\n  }\n});\n\nconsole.log(res.data);\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "```js\nconst cloudbase = getApp().globalData.cloudbase;\n\n// 删除 {%TABLE_NAME%} 数据模型中 _id 为 <数据ID> 的数据\nconst res = await cloudbase.models[\"{%TABLE_NAME%}\"].delete({\n  filter: {\n    where: {\n      _id: {\n        $eq: \"<数据ID>\"\n      }\n    }\n  }\n});\n\nconsole.log(res.data);\n```",
                "index": 4,
                "title": "删除数据"
              }
            ]
          },
          {
            "markdown": "```js\n// 调用 {%FUNCTION_NAME%} 云函数\nconst res = await wx.cloud.callFunction({\n  name: \"{%FUNCTION_NAME%}\",\n  data: {} // 云函数入参\n});\n\nconsole.log(res.result);\n```",
            "index": 4,
            "id": "scf",
            "title": "云函数",
            "content": []
          },
          {
            "markdown": "```js\n// 调用 {%SERVICE_NAME%} 云托管服务\nconst res = await wx.cloud.callContainer({\n  config: {\n    env: \"{%ENV_ID%}\" // 与小程序已关联的云开发环境 ID\n  },\n  path: \"/\", // 业务自定义路径，根目录为 /\n  method: \"GET\", // 依业务选择\n  header: {\n    \"X-WX-SERVICE\": \"{%SERVICE_NAME%}\" // 云托管服务名称\n    // 其他 header\n  }\n  // dataType: 'text' // 默认为 JSON；如需自行解析可设为 'text'\n});\n\nconsole.log(res);\n```",
            "index": 5,
            "id": "run",
            "title": "云托管",
            "content": []
          },
          {
            "index": 1,
            "id": "storage",
            "title": "云存储",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\nwx.chooseMedia({\n  count: 1,\n  mediaType: [\"image\", \"video\"],\n  sourceType: [\"album\", \"camera\"],\n  success: async res => {\n    const res = await wx.cloud.uploadFile({\n      cloudPath: \"images/\" + Date.now() + \".png\", // 上传至云端的路径\n      filePath: res.tempFiles[0].tempFilePath // 小程序临时文件路径\n    });\n\n    console.log(res.fileID);\n  }\n});\n```",
                "index": 1,
                "title": "上传文件"
              },
              {
                "markdown": "```js\nconst res = await wx.cloud.getTempFileURL({\n  fileList: [\"cloud://xxx.png\"] // 文件 fileID 列表\n});\n\nconsole.log(res.fileList);\n// fileList示例\n// [{\n//    fileID: \"cloud://xxx.png\", // 文件 ID\n//    tempFileURL: \"https://xxx.png\", // 临时文件网络链接\n//    maxAge: 120 * 60 * 1000, // 有效期\n// }]\n```",
                "index": 2,
                "title": "获取文件链接"
              },
              {
                "markdown": "```js\nconst res = await wx.cloud.downloadFile({\n  fileID: \"cloud://xxx.png\" // 文件 fileID\n});\n\nconsole.log(res.tempFilePath); // 返回临时文件路径\n```",
                "index": 3,
                "title": "下载文件"
              },
              {
                "markdown": "```js\nconst res = await wx.cloud.deleteFile({\n  fileList: [\"cloud://xxx.png\"] // 文件 fileID 列表\n});\n\nconsole.log(res.fileList);\n```",
                "index": 4,
                "title": "删除文件"
              }
            ]
          },
          {
            "index": 7,
            "id": "ai-model",
            "title": "大模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\nconst res = await wx.cloud.extend.AI.createModel(\n  \"{%AI_MODEL_NAME%}\"\n).streamText({\n  data: {\n    model: \"{%AI_SUB_MODEL_NAME%}\",\n    messages: [\n      {\n        role: \"user\",\n        content: \"你好\"\n      }\n    ]\n  }\n});\n\nfor await (let event of res.eventStream) {\n  if (event.data === \"[DONE]\") {\n    break;\n  }\n  const data = JSON.parse(event.data);\n\n  // 当使用 deepseek-r1 时，模型会生成思维链内容\n  const think = data?.choices?.[0]?.delta?.reasoning_content;\n  if (think) {\n    console.log(think);\n  }\n\n  // 打印生成文本内容\n  const text = data?.choices?.[0]?.delta?.content;\n  if (text) {\n    console.log(text);\n  }\n}\n```",
                "index": 1,
                "id": "text-aiModel",
                "title": "生文模型"
              },
              {
                "markdown": "生图模型通过调用云函数来实现，在生图模型页面点击「一键创建云函数」，函数调用示例如下：\n\n```js\n// 调用生图云函数\nwx.cloud.callFunction({\n  name: \"<YOUR_FUNCTION_NAME>\",\n  data: {\n    prompt: \"一只可爱的猫咪在阳光下玩耍\"\n  },\n  success: res => {\n    const result = res.result;\n\n    if (result.success) {\n      // 生成成功\n      console.log(\"生成成功!\");\n      console.log(\"图片URL:\", result.imageUrl);\n      console.log(\"优化后的提示词:\", result.revised_prompt);\n\n      // 使用图片\n      // 注意：图片URL有效期为24小时，请及时保存或转存\n    } else {\n      // 生成失败\n      console.error(\"生成失败:\", result.code, result.message);\n    }\n  },\n  fail: err => {\n    console.error(\"调用失败:\", err);\n  }\n});\n```",
                "index": 2,
                "id": "image-aiModel",
                "title": "生图模型"
              }
            ]
          },
          {
            "markdown": "",
            "index": 8,
            "id": "agent",
            "title": "Agent",
            "type": "sideTab",
            "content": [
              {
                "markdown": "\n```js\nfunction generateId() {\n  const timestamp = Date.now().toString().slice(-4);\n  const random = Math.floor(Math.random() * 10000).toString().padStart(4, '0');\n  return timestamp + random;\n}\n\nasync function sendMessage(message) {\n  const res = await wx.cloud.extend.AI.bot.sendMessage({\n    data: {\n      // botId 必填，标识调用的 Agent\n      botId: '{%AGENT_ID%}',\n      // 入参结构参考前后端通信协议：\n      // https://docs.cloudbase.net/ai/agent/http-agent-protocol\n      threadId: 'thread_id_' + generateId(),\n      runId: 'run_id_' + generateId(),\n      messages: [\n        { id: String(Date.now()), role: 'user', content: message }\n      ],\n      tools: [],\n      context: [],\n      state: {},\n      forwardedProps: {},\n    }\n  });\n\n  // 流式接收响应\n  let response = '';\n  for await (const event of res.eventStream) {\n    // 需要手动解析 event.data\n    const data = JSON.parse(event.data);\n    // 根据事件类型输出，响应事件参考文档：\n    // https://docs.cloudbase.net/ai/agent/http-agent-protocol#%E5%93%8D%E5%BA%94%E4%BA%8B%E4%BB%B6\n    switch (data.type) {\n      case 'TEXT_MESSAGE_CONTENT':\n        response += data.delta;\n        console.log(data.delta);  // 实时输出\n        break;\n\n      case 'RUN_ERROR':\n        console.error('运行出错:', data.message);\n        break;\n\n      case 'RUN_FINISHED':\n        // 运行结束\n        break;\n    }\n  }\n\n  return response;\n}\n\nsendMessage('你好');\n```\n",
                "index": 0,
                "id": "scf",
                "title": "函数型"
              },
              {
                "markdown": "```js\nconst res = await wx.cloud.extend.AI.bot.sendMessage({\n  data: {\n    botId: \"{%AGENT_ID%}\",\n    msg: \"你好\"\n  }\n});\n\nfor await (const event of res.eventStream) {\n  if (event.data === \"[DONE]\") {\n    break;\n  }\n  const data = JSON.parse(event.data);\n\n  // 当使用 deepseek-r1 时，模型会生成思维链内容\n  const think = data.reasoning_content;\n  if (think) {\n    console.log(think);\n  }\n\n  // 打印输出正文\n  const content = data.content;\n  if (content) {\n    console.log(content);\n  }\n}\n```",
                "index": 1,
                "id": "baas",
                "title": "普通型"
              }
            ]
          }
        ]
      }
    ],
    "_id": "25cb905f697c83260042c1ff5f5202ba",
    "_openid": "anon",
    "createdAt": 1769767718025,
    "updatedAt": 1775129825841
  },
  {
    "category": "框架集成,后端框架,Python",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": 21,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/http-api/basic/overview",
    "content": [
      {
        "markdown": "通过 **HTTP 请求** 在 **python** 中调用各种云开发能力\n\n```bash\npip install requests python-dotenv\n```",
        "index": 1,
        "title": "安装依赖",
        "content": []
      },
      {
        "markdown": "新增如下代码到您的 **Python** 项目",
        "index": 2,
        "title": "初始化配置",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```python\nimport os\nimport requests\nfrom dotenv import load_dotenv\n\nload_dotenv()\n\nclass CloudBaseClient:\n\tdef __init__(self):\n\t\tself.env_id = os.getenv(\"CLOUDBASE_ENV_ID\")\n\t\tself.access_token = os.getenv(\"CLOUDBASE_ACCESS_TOKEN\")\n\t\tself.base_url = f\"https://{self.env_id}.api.tcloudbasegateway.com\"\n\t\tself.headers = {\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\"Accept\": \"application/json\",\n\t\t\t\"Authorization\": f\"Bearer {self.access_token}\"\n\t\t}\n\n\tdef request(self, method, path, **kwargs):\n\t\t\"\"\"\n\t\t统一的HTTP请求方法\n\n\t\tArgs:\n\t\t\tmethod: 请求方法 (GET, POST, PUT, PATCH, DELETE)\n\t\t\tpath: API路径 (如 /v1/rdb/rest/table_name)\n\t\t\t**kwargs: 其他请求参数 (json, params, headers等)\n\n\t\tReturns:\n\t\t\t响应数据或None\n\t\t\"\"\"\n\t\turl = f\"{self.base_url}{path}\"\n\t\theaders = self.headers.copy()\n\n\t\t# 允许自定义headers\n\t\tif \"headers\" in kwargs:\n\t\t\theaders.update(kwargs.pop(\"headers\"))\n\n\t\ttry:\n\t\t\tresponse = requests.request(method, url, headers=headers, **kwargs)\n\t\t\tresponse.raise_for_status()\n\n\t\t\t# 如果响应为空，返回True表示成功\n\t\t\tif not response.content:\n\t\t\t\treturn True\n\n\t\t\treturn response.json()\n\t\texcept requests.exceptions.RequestException as e:\n\t\t\tprint(f\"请求失败: {e}\")\n\t\t\treturn None\n\ncloudbase = CloudBaseClient()\n```",
            "index": 1,
            "title": "cloudbase_client.py"
          },
          {
            "markdown": "> 💡提示：如需管理员权限，请通过 [云开发平台/ApiKey管理页](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}&#/env/apikey) 获取 APIKey 替换 CLOUDBASE_ACCESS_TOKEN\n\n```properties\n# 环境ID\nCLOUDBASE_ENV_ID={%ENV_ID%}\n\n# 匿名访问令牌\nCLOUDBASE_ACCESS_TOKEN={%PUBLISHABLE_KEY%}\n```",
            "index": 2,
            "title": ".env"
          }
        ]
      },
      {
        "index": 3,
        "title": "调用云开发能力",
        "type": "codeTab",
        "content": [
          {
            "index": 1,
            "id": "mysql-db",
            "title": "MySQL数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```python\nfrom cloudbase_client import cloudbase\n\ndef get_mysql_data(table_name):\n\t\"\"\"查询 MySQL 数据库数据\"\"\"\n\tdata = cloudbase.request(\"GET\", f\"/v1/rdb/rest/{table_name}?limit=10\")\n\n\tif data:\n\t\tprint(\"查询成功:\", data)\n\treturn data or []\n\n# 使用示例\nif __name__ == \"__main__\":\n\tresult = get_mysql_data(\"{%TABLE_NAME%}\")\n```",
                "index": 1,
                "title": "查询数据",
                "content": []
              },
              {
                "markdown": "```python\nfrom cloudbase_client import cloudbase\n\ndef add_mysql_data(table_name, data):\n\t\"\"\"新增 MySQL 数据库数据\"\"\"\n\tresult = cloudbase.request(\"POST\", f\"/v1/rdb/rest/{table_name}\", json=data)\n\n\tif result:\n\t\tprint(\"新增成功:\", result)\n\treturn result\n\n# 使用示例\nif __name__ == \"__main__\":\n\tresult = add_mysql_data(\"{%TABLE_NAME%}\", {\"title\": \"示例标题\"})\n```",
                "index": 2,
                "title": "新增数据",
                "content": []
              },
              {
                "markdown": "```python\nfrom cloudbase_client import cloudbase\n\ndef update_mysql_data(table_name, data_id, data):\n\t\"\"\"更新 MySQL 数据库数据\"\"\"\n\tresult = cloudbase.request(\"PATCH\", f\"/v1/rdb/rest/{table_name}?id=eq.{data_id}\", json=data)\n\n\tif result:\n\t\tprint(\"更新成功:\", result)\n\treturn result\n\n# 使用示例\nif __name__ == \"__main__\":\n\tresult = update_mysql_data(\"{%TABLE_NAME%}\", \"<数据id>\", {\"title\": \"新标题\"})\n```",
                "index": 3,
                "title": "更新数据",
                "content": []
              },
              {
                "markdown": "```python\nfrom cloudbase_client import cloudbase\n\ndef delete_mysql_data(table_name, data_id):\n\t\"\"\"删除 MySQL 数据库数据\"\"\"\n\tresult = cloudbase.request(\"DELETE\", f\"/v1/rdb/rest/{table_name}?id=eq.{data_id}\")\n\n\tif result:\n\t\tprint(\"删除成功\")\n\t\treturn True\n\treturn False\n\n# 使用示例\nif __name__ == \"__main__\":\n\tresult = delete_mysql_data(\"{%TABLE_NAME%}\", \"<数据id>\")\n```",
                "index": 4,
                "title": "删除数据",
                "content": []
              }
            ]
          },
          {
            "index": 2,
            "id": "data-model",
            "title": "数据模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```python\nfrom cloudbase_client import cloudbase\n\ndef get_model_data(model_name, env_type=\"prod\"):\n\t\"\"\"查询数据模型数据\"\"\"\n\tpayload = {\n\t\t\"pageSize\": 10,\n\t\t\"pageNumber\": 1,\n\t\t\"getCount\": True\n\t}\n\n\tresult = cloudbase.request(\"POST\", f\"/v1/model/{env_type}/{model_name}/list\", json=payload)\n\n\tif result:\n\t\trecords = result.get(\"data\", {}).get(\"records\", [])\n\t\tprint(\"查询成功:\", records)\n\t\treturn records\n\treturn []\n\n# 使用示例\nif __name__ == \"__main__\":\n\trecords = get_model_data(\"{%TABLE_NAME%}\")\n```",
                "index": 1,
                "title": "查询数据",
                "content": []
              },
              {
                "markdown": "```python\nfrom cloudbase_client import cloudbase\n\ndef add_model_data(model_name, data, env_type=\"prod\"):\n\t\"\"\"新增数据模型数据\"\"\"\n\tresult = cloudbase.request(\"POST\", f\"/v1/model/{env_type}/{model_name}/create\", json={\"data\": data})\n\n\tif result:\n\t\tdoc_id = result.get(\"data\", {}).get(\"id\")\n\t\tprint(f\"新增成功! id: {doc_id}\")\n\treturn result\n\n# 使用示例\nif __name__ == \"__main__\":\n\tresult = add_model_data(\"{%TABLE_NAME%}\", {\"title\": \"示例标题\"})\n```",
                "index": 2,
                "title": "新增数据",
                "content": []
              },
              {
                "markdown": "```python\nfrom cloudbase_client import cloudbase\n\ndef update_model_data(model_name, data_id, data, env_type=\"prod\"):\n\t\"\"\"更新数据模型数据\"\"\"\n\tpayload = {\n\t\t\"data\": data,\n\t\t\"filter\": {\n\t\t\t\"where\": {\n\t\t\t\t\"_id\": {\"$eq\": data_id}\n\t\t\t}\n\t\t}\n\t}\n\n\tresult = cloudbase.request(\"PUT\", f\"/v1/model/{env_type}/{model_name}/update\", json=payload)\n\n\tif result:\n\t\tprint(\"更新成功!\")\n\t\treturn True\n\treturn False\n\n# 使用示例\nif __name__ == \"__main__\":\n\tresult = update_model_data(\"{%TABLE_NAME%}\", \"<数据id>\", {\"title\": \"新标题\"})\n```",
                "index": 3,
                "title": "更新数据",
                "content": []
              },
              {
                "markdown": "```python\nfrom cloudbase_client import cloudbase\n\ndef delete_model_data(model_name, data_id, env_type=\"prod\"):\n\t\"\"\"删除数据模型数据\"\"\"\n\tpayload = {\n\t\t\"filter\": {\n\t\t\t\"where\": {\n\t\t\t\t\"_id\": {\"$eq\": data_id}\n\t\t\t}\n\t\t}\n\t}\n\n\tresult = cloudbase.request(\"POST\", f\"/v1/model/{env_type}/{model_name}/delete\", json=payload)\n\n\tif result:\n\t\tprint(\"删除成功!\")\n\t\treturn True\n\treturn False\n\n# 使用示例\nif __name__ == \"__main__\":\n\tresult = delete_model_data(\"{%TABLE_NAME%}\", \"<数据id>\")\n```",
                "index": 4,
                "title": "删除数据",
                "content": []
              }
            ]
          },
          {
            "markdown": "```python\nfrom cloudbase_client import cloudbase\n\ndef call_function(function_name, data=None):\n\t\"\"\"调用云函数\"\"\"\n\tresult = cloudbase.request(\"POST\", f\"/v1/functions/{function_name}\", json=data or {})\n\n\tif result:\n\t\tprint(\"云函数调用结果:\", result)\n\treturn result\n\n# 使用示例\nif __name__ == \"__main__\":\n\tresult = call_function(\"{%FUNCTION_NAME%}\")\n```",
            "index": 3,
            "id": "scf",
            "title": "云函数"
          },
          {
            "markdown": "```python\nfrom cloudbase_client import cloudbase\n\ndef call_container(service_name, path=\"\", method=\"GET\", data=None):\n\t\"\"\"调用云托管服务\"\"\"\n\tfull_path = f\"/v1/cloudrun/{service_name}/{path}\".rstrip(\"/\")\n\tresult = cloudbase.request(method.upper(), full_path, json=data)\n\n\tif result:\n\t\tprint(\"云托管调用结果:\", result)\n\treturn result\n\n# 使用示例\nif __name__ == \"__main__\":\n\tresult = call_container(\"{%SERVICE_NAME%}\")\n```",
            "index": 4,
            "id": "run",
            "title": "云托管"
          },
          {
            "index": 5,
            "id": "storage",
            "title": "云存储",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```python\nimport os\nimport requests\nfrom datetime import datetime\nfrom cloudbase_client import cloudbase\n\ndef upload_file(file_path, object_id=None):\n\t\"\"\"上传文件到云存储\"\"\"\n\tif not object_id:\n\t\tfilename = os.path.basename(file_path)\n\t\ttimestamp = int(datetime.now().timestamp() * 1000)\n\t\tobject_id = f\"uploads/{timestamp}-{filename}\"\n\n\t# 1. 获取上传信息\n\tupload_info = cloudbase.request(\"POST\", \"/v1/storages/get-objects-upload-info\",\n\t\tjson=[{\"objectId\": object_id}])\n\n\tif not upload_info:\n\t\treturn None\n\n\tupload_info = upload_info[0]\n\tupload_url = upload_info[\"uploadUrl\"]\n\n\ttry:\n\t\t# 2. 上传文件\n\t\tupload_headers = {\n\t\t\t\"Authorization\": upload_info[\"authorization\"],\n\t\t\t\"X-Cos-Security-Token\": upload_info[\"token\"],\n\t\t\t\"X-Cos-Meta-Fileid\": upload_info[\"cloudObjectMeta\"]\n\t\t}\n\n\t\twith open(file_path, \"rb\") as f:\n\t\t\tfile_data = f.read()\n\n\t\tupload_response = requests.put(upload_url, headers=upload_headers, data=file_data)\n\t\tupload_response.raise_for_status()\n\n\t\tresult = {\n\t\t\t\"cloudObjectId\": upload_info[\"cloudObjectId\"],\n\t\t\t\"downloadUrl\": upload_info[\"downloadUrl\"],\n\t\t\t\"objectId\": object_id\n\t\t}\n\n\t\tprint(\"文件上传成功:\")\n\t\tprint(f\"- 对象ID: {result['objectId']}\")\n\t\tprint(f\"- 下载URL: {result['downloadUrl']}\")\n\n\t\treturn result\n\n\texcept FileNotFoundError:\n\t\tprint(f\"文件不存在: {file_path}\")\n\t\treturn None\n\texcept Exception as e:\n\t\tprint(f\"文件上传失败: {e}\")\n\t\treturn None\n\n# 使用示例\nif __name__ == \"__main__\":\n\tresult = upload_file(\"./example.jpg\")\n```",
                "index": 1,
                "title": "上传文件",
                "content": []
              },
              {
                "markdown": "```python\nfrom cloudbase_client import cloudbase\n\ndef get_file_url(cloud_object_id):\n\t\"\"\"获取云存储文件的临时访问链接\"\"\"\n\tresult = cloudbase.request(\"POST\", \"/v1/storages/get-objects-download-info\",\n\t\tjson=[{\"cloudObjectId\": cloud_object_id}])\n\n\tif result:\n\t\tdownload_url = result[0].get(\"downloadUrl\")\n\t\tprint(\"文件链接:\", download_url)\n\t\treturn download_url\n\treturn None\n\n# 使用示例\nif __name__ == \"__main__\":\n\tfile_url = get_file_url(\"cloud://xxx.png\")\n```",
                "index": 2,
                "title": "获取文件链接",
                "content": []
              },
              {
                "markdown": "```python\nimport os\nimport requests\nfrom cloudbase_client import cloudbase\n\ndef download_file(cloud_object_id, save_path=\"./\"):\n\t\"\"\"下载云存储文件到本地\"\"\"\n\t# 1. 获取下载链接\n\tresult = cloudbase.request(\"POST\", \"/v1/storages/get-objects-download-info\",\n\t\tjson=[{\"cloudObjectId\": cloud_object_id}])\n\n\tif not result:\n\t\treturn False\n\n\tdownload_url = result[0].get(\"downloadUrl\")\n\n\ttry:\n\t\t# 2. 从URL中提取文件名\n\t\tfilename = download_url.split(\"/\")[-1].split(\"?\")[0]\n\n\t\t# 3. 如果save_path是目录，则拼接文件名\n\t\tif os.path.isdir(save_path) or save_path.endswith(\"/\"):\n\t\t\tfull_path = os.path.join(save_path, filename)\n\t\telse:\n\t\t\tfull_path = save_path\n\n\t\t# 4. 下载文件\n\t\tfile_response = requests.get(download_url)\n\t\tfile_response.raise_for_status()\n\n\t\t# 5. 保存到本地\n\t\twith open(full_path, \"wb\") as f:\n\t\t\tf.write(file_response.content)\n\n\t\tprint(f\"下载成功! 文件已保存到: {full_path}\")\n\t\treturn True\n\texcept Exception as e:\n\t\tprint(f\"下载失败: {e}\")\n\t\treturn False\n\n# 使用示例\nif __name__ == \"__main__\":\n\t# 下载到当前目录，使用原文件名\n\tresult = download_file(\"cloud://xxx.png\")\n\n\t# 下载到指定目录\n\tresult = download_file(\"cloud://xxx.png\", \"./downloads/\")\n\n\t# 下载并重命名\n\tresult = download_file(\"cloud://xxx.png\", \"./my-image.png\")\n```",
                "index": 3,
                "title": "下载文件",
                "content": []
              },
              {
                "markdown": "```python\nfrom cloudbase_client import cloudbase\n\ndef delete_file(cloud_object_ids):\n\t\"\"\"删除云存储文件\"\"\"\n\t# 如果传入的是单个字符串，转换为列表\n\tif isinstance(cloud_object_ids, str):\n\t\tcloud_object_ids = [cloud_object_ids]\n\n\tdata = [{\"cloudObjectId\": obj_id} for obj_id in cloud_object_ids]\n\tresult = cloudbase.request(\"POST\", \"/v1/storages/delete-objects\", json=data)\n\n\tif result:\n\t\tprint(\"删除成功!\")\n\t\treturn True\n\treturn False\n\n# 使用示例\nif __name__ == \"__main__\":\n\tresult = delete_file(\"cloud://xxx.png\")\n```",
                "index": 4,
                "title": "删除文件",
                "content": []
              }
            ]
          },
          {
            "index": 6,
            "id": "ai-model",
            "title": "大模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```python\nimport requests\nimport json\nfrom cloudbase_client import cloudbase\n\ndef stream_text(model, sub_model, messages):\n\t\"\"\"流式文本生成\"\"\"\n\tpayload = {\n\t\t\"model\": sub_model,\n\t\t\"messages\": messages,\n\t\t\"stream\": True\n\t}\n\n\turl = f\"{cloudbase.base_url}/v1/ai/{model}/chat/completions\"\n\theaders = cloudbase.headers.copy()\n\theaders[\"Accept\"] = \"text/event-stream\"\n\n\ttry:\n\t\tresponse = requests.post(url, headers=headers, json=payload, stream=True)\n\t\tresponse.raise_for_status()\n\n\t\tprint(\"AI 流式响应:\")\n\t\tfull_content = \"\"\n\n\t\tfor line in response.iter_lines():\n\t\t\tif line:\n\t\t\t\tline_str = line.decode(\"utf-8\")\n\t\t\t\tif line_str.startswith(\"data: \"):\n\t\t\t\t\tdata_str = line_str[6:]\n\t\t\t\t\tif data_str.strip() != \"[DONE]\":\n\t\t\t\t\t\ttry:\n\t\t\t\t\t\t\tchunk_data = json.loads(data_str)\n\t\t\t\t\t\t\tcontent = chunk_data.get(\"choices\", [{}])[0].get(\"delta\", {}).get(\"content\", \"\")\n\t\t\t\t\t\t\tif content:\n\t\t\t\t\t\t\t\tprint(content, end=\"\", flush=True)\n\t\t\t\t\t\t\t\tfull_content += content\n\t\t\t\t\t\texcept json.JSONDecodeError:\n\t\t\t\t\t\t\tcontinue\n\n\t\tprint()  # 换行\n\t\treturn full_content\n\texcept Exception as e:\n\t\tprint(f\"AI 调用失败: {e}\")\n\t\treturn None\n\n# 使用示例\nif __name__ == \"__main__\":\n\tresponse = stream_text(\n\t\t\"{%AI_MODEL_NAME%}\",\n\t\t\"{%AI_SUB_MODEL_NAME%}\",\n\t\t[\n\t\t\t{\"role\": \"system\", \"content\": \"请严格按照七言绝句或七言律诗的格律要求创作，平仄需符合规则，押韵要和谐自然，韵脚字需在同一韵部。\"},\n\t\t\t{\"role\": \"user\", \"content\": \"春天\"}\n\t\t]\n\t)\n```",
                "index": 1,
                "id": "text-aiModel",
                "title": "生文模型",
                "content": []
              },
              {
                "markdown": "生图模型通过调用云函数来实现，在生图模型页面点击「一键创建云函数」，函数调用示例如下：\n\n```python\nimport requests\nfrom cloudbase_client import cloudbase\n\ndef generate_image(prompt):\n\t\"\"\"调用生图云函数\"\"\"\n\turl = f\"{cloudbase.base_url}/v1/functions/<YOUR_FUNCTION_NAME>/invoke\"\n\theaders = cloudbase.headers\n\tpayload = {\n\t\t\"prompt\": prompt\n\t}\n\n\ttry:\n\t\tresponse = requests.post(url, headers=headers, json=payload)\n\t\tresponse.raise_for_status()\n\t\tresult = response.json()\n\n\t\tif result.get(\"success\"):\n\t\t\t# 生成成功\n\t\t\tprint(\"生成成功!\")\n\t\t\tprint(f\"图片URL: {result.get('imageUrl')}\")\n\t\t\tprint(f\"优化后的提示词: {result.get('revised_prompt')}\")\n\n\t\t\t# 使用图片\n\t\t\t# 注意：图片URL有效期为24小时，请及时保存或转存\n\t\t\treturn result\n\t\telse:\n\t\t\t# 生成失败\n\t\t\tprint(f\"生成失败: {result.get('code')} {result.get('message')}\")\n\t\t\treturn None\n\texcept Exception as e:\n\t\tprint(f\"调用失败: {e}\")\n\t\treturn None\n\n# 使用示例\nif __name__ == \"__main__\":\n\tresult = generate_image(\"一只可爱的猫咪在阳光下玩耍\")\n\tif result:\n\t\tprint(f\"图片URL: {result.get('imageUrl')}\")\n```",
                "index": 2,
                "id": "image-aiModel",
                "title": "生图模型",
                "content": []
              }
            ]
          },
          {
            "markdown": "",
            "index": 7,
            "id": "agent",
            "title": "Agent",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```python\n\"\"\"\nPython 调用 Agent 示例（AG-UI 协议）\n协议文档：https://docs.cloudbase.net/ai/agent-development/protocol\n\"\"\"\nimport requests\nimport json\nimport uuid\nfrom cloudbase_client import cloudbase\n\ndef chat_with_agent_stream(bot_id, msg, history=None):\n    \"\"\"\n    流式调用Agent（AG-UI 协议）\n    \n    AG-UI 协议参数说明：\n    - messages: 必填，消息列表，包含 id/role/content\n    - threadId: 可选，会话ID，用于多轮对话管理\n    - runId: 可选，运行ID，用于追踪单次执行\n    - tools: 可选，前端工具定义\n    - context: 可选，上下文信息\n    - forwardedProps: 可选，透传参数\n    \"\"\"\n    if history is None:\n        history = []\n\n    url = f\"{cloudbase.base_url}/v1/aibot/bots/{bot_id}/send-message\"\n\n    # 构建消息列表（AG-UI 协议格式）\n    messages = []\n    \n    # 添加历史消息\n    for h in history:\n        messages.append({\n            \"id\": h.get(\"id\", f\"msg-{uuid.uuid4()}\"),\n            \"role\": h.get(\"role\", \"user\"),\n            \"content\": h.get(\"content\", \"\")\n        })\n    \n    # 添加当前用户消息\n    messages.append({\n        \"id\": f\"msg-{uuid.uuid4()}\",\n        \"role\": \"user\",\n        \"content\": msg\n    })\n\n    # AG-UI 协议请求体\n    payload = {\n        \"messages\": messages,                      # 必填：消息列表\n        \"threadId\": f\"thread-{uuid.uuid4()}\",     # 可选：会话ID\n        \"runId\": f\"run-{uuid.uuid4()}\",           # 可选：运行ID\n        \"tools\": [],                               # 可选：前端工具定义\n        \"context\": [],                             # 可选：上下文信息\n        \"forwardedProps\": {}                       # 可选：透传参数\n    }\n\n    headers = cloudbase.headers.copy()\n    headers[\"Accept\"] = \"text/event-stream\"\n\n    try:\n        response = requests.post(\n            url,\n            headers=headers,\n            json=payload,\n            stream=True,\n            timeout=30\n        )\n        response.raise_for_status()\n\n        print(\"AI 流式响应:\")\n        full_content = \"\"\n        buffer = \"\"\n\n        for chunk in response.iter_content(chunk_size=None, decode_unicode=False):\n            if chunk:\n                try:\n                    # 解码字节流\n                    buffer += chunk.decode('utf-8')\n\n                    # 处理完整的行\n                    while '\\n' in buffer:\n                        line, buffer = buffer.split('\\n', 1)\n                        line = line.strip()\n\n                        if line.startswith(\"data: \"):\n                            data_str = line[6:].strip()\n                            if data_str and data_str != \"[DONE]\":\n                                try:\n                                    chunk_data = json.loads(data_str)\n                                    # 支持多种响应格式\n                                    content = (\n                                        chunk_data.get(\"content\") or\n                                        chunk_data.get(\"choices\", [{}])[0].get(\"delta\", {}).get(\"content\", \"\") or\n                                        chunk_data.get(\"choices\", [{}])[0].get(\"message\", {}).get(\"content\", \"\")\n                                    )\n                                    if content:\n                                        print(content, end=\"\", flush=True)\n                                        full_content += content\n                                except json.JSONDecodeError:\n                                    pass\n                except UnicodeDecodeError:\n                    continue\n\n        print()  # 换行\n        return full_content\n\n    except requests.exceptions.Timeout:\n        print(\"请求超时，请检查网络连接或增加超时时间\")\n        return None\n    except requests.exceptions.RequestException as e:\n        print(f\"AI 调用失败: {e}\")\n        if hasattr(e.response, 'text'):\n            print(f\"响应内容: {e.response.text}\")\n        return None\n\n# 使用示例\nif __name__ == \"__main__\":\n    response = chat_with_agent_stream(\"{%AGENT_ID%}\", \"你是谁\")\n\n```",
                "index": 0,
                "id": "scf",
                "title": "函数型"
              },
              {
                "markdown": "```python\nimport requests\nimport json\nfrom cloudbase_client import cloudbase\n\ndef chat_with_agent_stream(bot_id, msg, history=None):\n\t\"\"\"流式调用Agent\"\"\"\n\tif history is None:\n\t\thistory = []\n\n\turl = f\"{cloudbase.base_url}/v1/aibot/bots/{bot_id}/send-message\"\n\n\tpayload = {\n\t\t\"history\": history,\n\t\t\"msg\": msg\n\t}\n\n\theaders = cloudbase.headers.copy()\n\theaders[\"Accept\"] = \"text/event-stream\"\n\n\ttry:\n\t\tresponse = requests.post(\n\t\t\turl,\n\t\t\theaders=headers,\n\t\t\tjson=payload,\n\t\t\tstream=True,\n\t\t\ttimeout=30\n\t\t)\n\t\tresponse.raise_for_status()\n\n\t\tprint(\"AI 流式响应:\")\n\t\tfull_content = \"\"\n\t\tbuffer = \"\"\n\n\t\tfor chunk in response.iter_content(chunk_size=None, decode_unicode=False):\n\t\t\tif chunk:\n\t\t\t\ttry:\n\t\t\t\t\t# 解码字节流\n\t\t\t\t\tbuffer += chunk.decode('utf-8')\n\n\t\t\t\t\t# 处理完整的行\n\t\t\t\t\twhile '\\n' in buffer:\n\t\t\t\t\t\tline, buffer = buffer.split('\\n', 1)\n\t\t\t\t\t\tline = line.strip()\n\n\t\t\t\t\t\tif line.startswith(\"data: \"):\n\t\t\t\t\t\t\tdata_str = line[6:].strip()\n\t\t\t\t\t\t\tif data_str and data_str != \"[DONE]\":\n\t\t\t\t\t\t\t\ttry:\n\t\t\t\t\t\t\t\t\tchunk_data = json.loads(data_str)\n\t\t\t\t\t\t\t\t\t# 支持多种响应格式\n\t\t\t\t\t\t\t\t\tcontent = (\n\t\t\t\t\t\t\t\t\t\tchunk_data.get(\"content\") or\n\t\t\t\t\t\t\t\t\t\tchunk_data.get(\"choices\", [{}])[0].get(\"delta\", {}).get(\"content\", \"\") or\n\t\t\t\t\t\t\t\t\t\tchunk_data.get(\"choices\", [{}])[0].get(\"message\", {}).get(\"content\", \"\")\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\tif content:\n\t\t\t\t\t\t\t\t\t\tprint(content, end=\"\", flush=True)\n\t\t\t\t\t\t\t\t\t\tfull_content += content\n\t\t\t\t\t\t\t\texcept json.JSONDecodeError:\n\t\t\t\t\t\t\t\t\tpass\n\t\t\t\texcept UnicodeDecodeError:\n\t\t\t\t\tcontinue\n\n\t\tprint()  # 换行\n\t\treturn full_content\n\n\texcept requests.exceptions.Timeout:\n\t\tprint(\"请求超时，请检查网络连接或增加超时时间\")\n\t\treturn None\n\texcept requests.exceptions.RequestException as e:\n\t\tprint(f\"AI 调用失败: {e}\")\n\t\tif hasattr(e.response, 'text'):\n\t\t\tprint(f\"响应内容: {e.response.text}\")\n\t\treturn None\n\n# 使用示例\nif __name__ == \"__main__\":\n\tresponse = chat_with_agent_stream(\"{%AGENT_ID%}\", \"你是谁\")\n```",
                "index": 1,
                "id": "baas",
                "title": "普通型"
              }
            ]
          },
          {
            "markdown": "```python\nfrom cloudbase_client import cloudbase\n\ndef sign_in(username, password):\n\t\"\"\"账号密码登录\"\"\"\n\tresult = cloudbase.request(\"POST\", \"/auth/v1/signin\",\n\t\tjson={\"username\": username, \"password\": password})\n\n\tif result:\n\t\taccess_token = result.get(\"access_token\")\n\t\trefresh_token = result.get(\"refresh_token\")\n\t\tuser_id = result.get(\"sub\")\n\n\t\tprint(f\"登录成功! 用户ID: {user_id}\")\n\t\tprint(f\"访问令牌: {access_token[:20]}...\")\n\t\treturn result\n\treturn None\n\n# 使用示例\nif __name__ == \"__main__\":\n\tresult = sign_in(\"your_username\", \"your_password\")\n```",
            "index": 8,
            "id": "identity",
            "title": "身份认证"
          }
        ]
      }
    ],
    "_id": "2cf12107697c22ef0034b361534aea63",
    "_openid": "anon",
    "createdAt": 1769743087954,
    "updatedAt": 1770021224769
  },
  {
    "category": "框架集成,前端框架,React(Vite)",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": 10,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/api-reference/webv2/initialization",
    "content": [
      {
        "markdown": "`@cloudbase/js-sdk` 可以让您在 Web 端（如 PC Web 页面、微信公众平台 H5 等）使用 JavaScript 访问 CloudBase 服务和资源。",
        "index": 1,
        "title": "安装 SDK",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```bash\nnpm i @cloudbase/js-sdk\n```",
            "index": 1,
            "title": "npm",
            "content": []
          },
          {
            "markdown": "```bash\nyarn add @cloudbase/js-sdk\n```",
            "index": 2,
            "title": "yarn",
            "content": []
          },
          {
            "markdown": "```bash\npnpm add @cloudbase/js-sdk\n```",
            "index": 3,
            "title": "pnpm",
            "content": []
          }
        ]
      },
      {
        "markdown": "新增如下代码到您的 React 项目",
        "index": 2,
        "title": "初始化 SDK",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```js\nimport cloudbaseSDK from \"@cloudbase/js-sdk\";\n\nexport const cloudbase = cloudbaseSDK.init({\n  env: import.meta.env.VITE_CLOUDBASE_ENV_ID,\n  region: import.meta.env.VITE_CLOUDBASE_REGION,\n  accessKey: import.meta.env.VITE_CLOUDBASE_ACCESS_KEY\n});\n```",
            "index": 1,
            "title": "src/utils/cloudbase.js",
            "content": []
          },
          {
            "markdown": "```properties\n# 环境ID\nVITE_CLOUDBASE_ENV_ID={%ENV_ID%}\n\n# 环境所在地域\nVITE_CLOUDBASE_REGION={%REGION%}\n\n# 匿名访问令牌\nVITE_CLOUDBASE_ACCESS_KEY={%PUBLISHABLE_KEY%}\n```",
            "index": 2,
            "title": ".env",
            "content": []
          }
        ]
      },
      {
        "index": 3,
        "title": "调用云开发能力",
        "type": "codeTab",
        "content": [
          {
            "index": 1,
            "id": "mysql-db",
            "title": "MySQL数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 查询 {%TABLE_NAME%} 表前10条数据\nconst { data, error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .select(\"*\")\n  .limit(10);\nif (!error) {\n  console.log(data);\n}\n```\n\n**完整示例：**\n\n```jsx\nimport { useState, useEffect } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [data, setData] = useState([]);\n\n  useEffect(() => {\n    getData();\n  }, []);\n\n  const getData = async () => {\n    // 查询 {%TABLE_NAME%} 表前10条数据\n    const { data, error } = await cloudbase\n      .rdb()\n      .from(\"{%TABLE_NAME%}\")\n      .select(\"*\")\n      .limit(10);\n    if (!error) setData(data || []);\n  };\n\n  return (\n    <ul>\n      {data.map(item => (\n        <li key={item.id}>{item.title}</li>\n      ))}\n    </ul>\n  );\n}\n\nexport default Page;\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 新增 {%TABLE_NAME%} 表数据\nconst { error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .insert({ title: \"示例标题\" });\nif (!error) {\n  console.log(\"新增成功\");\n}\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [title, setTitle] = useState(\"\");\n  const [message, setMessage] = useState(\"\");\n\n  const addData = async () => {\n    // 新增 {%TABLE_NAME%} 表数据\n    const { error } = await cloudbase\n      .rdb()\n      .from(\"{%TABLE_NAME%}\")\n      .insert({ title });\n    if (!error) {\n      setTitle(\"\");\n      setMessage(\"新增成功！\");\n    } else {\n      setMessage(\"新增失败：\" + error.message);\n    }\n  };\n\n  return (\n    <div>\n      <input value={title} onChange={e => setTitle(e.target.value)} />\n      <button onClick={addData}>新增</button>\n      {message && (\n        <p style={{ color: message.includes(\"成功\") ? \"green\" : \"red\" }}>\n          {message}\n        </p>\n      )}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 更新 {%TABLE_NAME%} 表中 id 为指定值的数据\nconst { error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .update({ title: \"新标题\" })\n  .eq(\"id\", \"<数据id>\");\nif (!error) {\n  console.log(\"更新成功\");\n}\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [message, setMessage] = useState(\"\");\n\n  const updateData = async () => {\n    // 更新 {%TABLE_NAME%} 表中 id 为指定值的数据\n    const { error } = await cloudbase\n      .rdb()\n      .from(\"{%TABLE_NAME%}\")\n      .update({ title: \"新标题\" })\n      .eq(\"id\", \"<数据id>\");\n    if (!error) {\n      setMessage(\"更新成功！\");\n    } else {\n      setMessage(\"更新失败：\" + error.message);\n    }\n  };\n\n  return (\n    <div>\n      <button onClick={updateData}>更新</button>\n      {message && (\n        <p style={{ color: message.includes(\"成功\") ? \"green\" : \"red\" }}>\n          {message}\n        </p>\n      )}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 如果 {%TABLE_NAME%} 表中存在 id 为 1 的记录则更新 title 为\"示例标题\"，不存在则插入新记录\nconst { error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .upsert({ id: 1, title: \"示例标题\" });\nif (!error) {\n  console.log(\"操作成功\");\n}\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [message, setMessage] = useState(\"\");\n\n  const upsertData = async () => {\n    // 如果 {%TABLE_NAME%} 表中存在 id 为 1 的记录则更新 title 为\"示例标题\"，不存在则插入新记录\n    const { error } = await cloudbase\n      .rdb()\n      .from(\"{%TABLE_NAME%}\")\n      .upsert({ id: 1, title: \"示例标题\" });\n    if (!error) {\n      setMessage(\"操作成功！\");\n    } else {\n      setMessage(\"操作失败：\" + error.message);\n    }\n  };\n\n  return (\n    <div>\n      <button onClick={upsertData}>更新或创建</button>\n      {message && (\n        <p style={{ color: message.includes(\"成功\") ? \"green\" : \"red\" }}>\n          {message}\n        </p>\n      )}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 4,
                "title": "更新或创建数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 删除 {%TABLE_NAME%} 表中 id 为指定值的数据\nconst { error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .delete()\n  .eq(\"id\", \"<数据id>\");\nif (!error) {\n  console.log(\"删除成功\");\n}\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [message, setMessage] = useState(\"\");\n\n  const deleteData = async () => {\n    // 删除 {%TABLE_NAME%} 表中 id 为指定值的数据\n    const { error } = await cloudbase\n      .rdb()\n      .from(\"{%TABLE_NAME%}\")\n      .delete()\n      .eq(\"id\", \"<数据id>\");\n    if (!error) {\n      setMessage(\"删除成功！\");\n    } else {\n      setMessage(\"删除失败：\" + error.message);\n    }\n  };\n\n  return (\n    <div>\n      <button onClick={deleteData}>删除</button>\n      {message && (\n        <p style={{ color: message.includes(\"成功\") ? \"green\" : \"red\" }}>\n          {message}\n        </p>\n      )}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 5,
                "title": "删除数据"
              }
            ]
          },
          {
            "index": 2,
            "id": "doc-db",
            "title": "文档型数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 查询 {%TABLE_NAME%} 表前10条数据\nconst db = cloudbase.database();\nconst res = await db.collection(\"{%TABLE_NAME%}\").limit(10).get();\nconsole.log(res.data);\n```\n\n**完整示例：**\n\n```jsx\nimport { useState, useEffect } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [data, setData] = useState([]);\n\n  useEffect(() => {\n    getData();\n  }, []);\n\n  const getData = async () => {\n    // 查询 {%TABLE_NAME%} 表前10条数据\n    const db = cloudbase.database();\n    const res = await db.collection(\"{%TABLE_NAME%}\").limit(10).get();\n    setData(res.data || []);\n  };\n\n  return (\n    <ul>\n      {data.map(item => (\n        <li key={item._id}>{item.title}</li>\n      ))}\n    </ul>\n  );\n}\n\nexport default Page;\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 新增 {%TABLE_NAME%} 表数据\nconst db = cloudbase.database();\nconst res = await db.collection(\"{%TABLE_NAME%}\").add({ title: \"示例标题\" });\nconsole.log(`新增成功! id: ${res.id}`);\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [message, setMessage] = useState(\"\");\n\n  const addData = async () => {\n    try {\n      // 新增 {%TABLE_NAME%} 表数据\n      const db = cloudbase.database();\n      const res = await db\n        .collection(\"{%TABLE_NAME%}\")\n        .add({ title: \"示例标题\" });\n      setMessage(`新增成功! id: ${res.id}`);\n    } catch (error) {\n      setMessage(\"新增失败：\" + error.message);\n    }\n  };\n\n  return (\n    <div>\n      <button onClick={addData}>新增</button>\n      {message && (\n        <p style={{ color: message.includes(\"成功\") ? \"green\" : \"red\" }}>\n          {message}\n        </p>\n      )}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 更新 {%TABLE_NAME%} 表中 id 为指定值的数据\nconst db = cloudbase.database();\nawait db\n  .collection(\"{%TABLE_NAME%}\")\n  .doc(\"<数据id>\")\n  .update({ title: \"新标题\" });\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [message, setMessage] = useState(\"\");\n\n  const updateData = async () => {\n    try {\n      // 更新 {%TABLE_NAME%} 表中 id 为指定值的数据\n      const db = cloudbase.database();\n      await db\n        .collection(\"{%TABLE_NAME%}\")\n        .doc(\"<数据id>\")\n        .update({ title: \"新标题\" });\n      setMessage(\"更新成功！\");\n    } catch (error) {\n      setMessage(\"更新失败：\" + error.message);\n    }\n  };\n\n  return (\n    <div>\n      <button onClick={updateData}>更新</button>\n      {message && (\n        <p style={{ color: message.includes(\"成功\") ? \"green\" : \"red\" }}>\n          {message}\n        </p>\n      )}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 删除 {%TABLE_NAME%} 表中 id 为指定值的数据\nconst db = cloudbase.database();\nawait db.collection(\"{%TABLE_NAME%}\").doc(\"<数据id>\").remove();\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [message, setMessage] = useState(\"\");\n\n  const deleteData = async () => {\n    try {\n      // 删除 {%TABLE_NAME%} 表中 id 为指定值的数据\n      const db = cloudbase.database();\n      await db.collection(\"{%TABLE_NAME%}\").doc(\"<数据id>\").remove();\n      setMessage(\"删除成功！\");\n    } catch (error) {\n      setMessage(\"删除失败：\" + error.message);\n    }\n  };\n\n  return (\n    <div>\n      <button onClick={deleteData}>删除</button>\n      {message && (\n        <p style={{ color: message.includes(\"成功\") ? \"green\" : \"red\" }}>\n          {message}\n        </p>\n      )}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 4,
                "title": "删除数据"
              }
            ]
          },
          {
            "index": 3,
            "id": "data-model",
            "title": "数据模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 查询 {%TABLE_NAME%} 数据模型前10条数据\nconst res = await cloudbase.models[\"{%TABLE_NAME%}\"].list({\n  pageNumber: 1,\n  pagesize: 10\n});\nconsole.log(res.data?.records);\n```\n\n**完整示例：**\n\n```jsx\nimport { useState, useEffect } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [data, setData] = useState([]);\n\n  useEffect(() => {\n    getData();\n  }, []);\n\n  const getData = async () => {\n    // 查询 {%TABLE_NAME%} 数据模型前10条数据\n    const res = await cloudbase.models[\"{%TABLE_NAME%}\"].list({\n      pageNumber: 1,\n      pagesize: 10\n    });\n    setData(res.data?.records || []);\n  };\n\n  return (\n    <ul>\n      {data.map(item => (\n        <li key={item._id}>{item.title}</li>\n      ))}\n    </ul>\n  );\n}\n\nexport default Page;\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 新增 {%TABLE_NAME%} 数据模型数据\nconst res = await cloudbase.models[\"{%TABLE_NAME%}\"].create({\n  data: { title: \"示例标题\" }\n});\nconsole.log(`新增成功! id: ${res.data.id}`);\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [message, setMessage] = useState(\"\");\n\n  const addData = async () => {\n    try {\n      // 新增 {%TABLE_NAME%} 数据模型数据\n      const res = await cloudbase.models[\"{%TABLE_NAME%}\"].create({\n        data: { title: \"示例标题\" }\n      });\n      setMessage(`新增成功! id: ${res.data.id}`);\n    } catch (error) {\n      setMessage(\"新增失败：\" + error.message);\n    }\n  };\n\n  return (\n    <div>\n      <button onClick={addData}>新增</button>\n      {message && (\n        <p style={{ color: message.includes(\"成功\") ? \"green\" : \"red\" }}>\n          {message}\n        </p>\n      )}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 更新 {%TABLE_NAME%} 数据模型中 _id 为指定值的数据\nawait cloudbase.models[\"{%TABLE_NAME%}\"].update({\n  data: { title: \"新标题\" },\n  filter: { where: { _id: { $eq: \"<数据id>\" } } }\n});\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [message, setMessage] = useState(\"\");\n\n  const updateData = async () => {\n    try {\n      // 更新 {%TABLE_NAME%} 数据模型中 _id 为指定值的数据\n      await cloudbase.models[\"{%TABLE_NAME%}\"].update({\n        data: { title: \"新标题\" },\n        filter: { where: { _id: { $eq: \"<数据id>\" } } }\n      });\n      setMessage(\"更新成功！\");\n    } catch (error) {\n      setMessage(\"更新失败：\" + error.message);\n    }\n  };\n\n  return (\n    <div>\n      <button onClick={updateData}>更新</button>\n      {message && (\n        <p style={{ color: message.includes(\"成功\") ? \"green\" : \"red\" }}>\n          {message}\n        </p>\n      )}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 删除 {%TABLE_NAME%} 数据模型中 _id 为指定值的数据\nawait cloudbase.models[\"{%TABLE_NAME%}\"].delete({\n  filter: { where: { _id: { $eq: \"<数据id>\" } } }\n});\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [message, setMessage] = useState(\"\");\n\n  const deleteData = async () => {\n    try {\n      // 删除 {%TABLE_NAME%} 数据模型中 _id 为指定值的数据\n      await cloudbase.models[\"{%TABLE_NAME%}\"].delete({\n        filter: { where: { _id: { $eq: \"<数据id>\" } } }\n      });\n      setMessage(\"删除成功！\");\n    } catch (error) {\n      setMessage(\"删除失败：\" + error.message);\n    }\n  };\n\n  return (\n    <div>\n      <button onClick={deleteData}>删除</button>\n      {message && (\n        <p style={{ color: message.includes(\"成功\") ? \"green\" : \"red\" }}>\n          {message}\n        </p>\n      )}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 4,
                "title": "删除数据"
              }
            ]
          },
          {
            "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 调用 {%FUNCTION_NAME%} 云函数\nconst res = await cloudbase.callFunction({\n  name: \"{%FUNCTION_NAME%}\",\n  data: {}\n});\nconsole.log(res.result);\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [data, setData] = useState(null);\n\n  const getData = async () => {\n    // 调用 {%FUNCTION_NAME%} 云函数\n    const res = await cloudbase.callFunction({\n      name: \"{%FUNCTION_NAME%}\",\n      data: {}\n    });\n    setData(res.result);\n  };\n\n  return (\n    <div>\n      <button onClick={getData}>调用云函数</button>\n      {data && <pre>{JSON.stringify(data, null, 2)}</pre>}\n    </div>\n  );\n}\n\nexport default Page;\n```",
            "index": 4,
            "id": "scf",
            "title": "云函数",
            "content": []
          },
          {
            "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 调用 {%SERVICE_NAME%} 云托管服务\nconst res = await cloudbase.callContainer({\n  name: \"{%SERVICE_NAME%}\"\n  method: 'POST',\n  path: '/',\n  header:{\n    'Content-Type': 'application/json; charset=utf-8'\n  },\n  data: {},\n});\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [data, setData] = useState(null);\n\n  const getData = async () => {\n    // 调用 {%SERVICE_NAME%} 云托管服务\n    const res = await cloudbase.callContainer({\n      name: \"{%SERVICE_NAME%}\"\n      method: 'POST',\n      path: '/',\n      header:{\n        'Content-Type': 'application/json; charset=utf-8'\n      },\n      data: {},\n    });\n    setData(res);\n  };\n\n  return (\n    <div>\n      <button onClick={getData}>调用云托管</button>\n      {data && <pre>{JSON.stringify(data, null, 2)}</pre>}\n    </div>\n  );\n}\n\nexport default Page;\n```",
            "index": 5,
            "id": "run",
            "title": "云托管",
            "content": []
          },
          {
            "index": 6,
            "id": "storage",
            "title": "云存储",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst res = await cloudbase.uploadFile({\n  cloudPath: `images/${Date.now()}-${file.name}`, // 上传至云端的路径\n  filePath: file\n});\nconsole.log(res.fileID);\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [fileID, setFileID] = useState(\"\");\n\n  const uploadFile = async e => {\n    const file = e.target.files[0];\n    const res = await cloudbase.uploadFile({\n      cloudPath: `images/${Date.now()}-${file.name}`, // 上传至云端的路径\n      filePath: file\n    });\n    setFileID(res.fileID);\n  };\n\n  return (\n    <div>\n      <input type=\"file\" onChange={uploadFile} />\n      {fileID && <p>上传成功: {fileID}</p>}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 1,
                "title": "上传文件"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst res = await cloudbase.getTempFileURL({\n  fileList: [\"cloud://xxx.png\"] // 文件 fileID 列表\n});\nconsole.log(res.fileList[0].tempFileURL);\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [fileUrl, setFileUrl] = useState(\"\");\n\n  const getData = async () => {\n    const res = await cloudbase.getTempFileURL({\n      fileList: [\"cloud://xxx.png\"] // 文件 fileID 列表\n    });\n    setFileUrl(res.fileList[0].tempFileURL);\n  };\n\n  return (\n    <div>\n      <button onClick={getData}>获取链接</button>\n      {fileUrl && <p>链接: {fileUrl}</p>}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 2,
                "title": "获取文件链接"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nawait cloudbase.downloadFile({\n  fileID: \"cloud://xxx.png\" // 文件 fileID\n});\n```\n\n**完整示例：**\n\n```jsx\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const downloadFile = async () => {\n    await cloudbase.downloadFile({\n      fileID: \"cloud://xxx.png\" // 文件 fileID\n    });\n  };\n\n  return <button onClick={downloadFile}>下载文件</button>;\n}\n\nexport default Page;\n```",
                "index": 3,
                "title": "下载文件"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst res = await cloudbase.deleteFile({\n  fileList: [\"cloud://xxx.png\"] // 文件 fileID 列表\n});\nif (res.fileList[0].code === \"SUCCESS\") {\n  console.log(\"删除成功\");\n}\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [message, setMessage] = useState(\"\");\n\n  const deleteFile = async () => {\n    const res = await cloudbase.deleteFile({\n      fileList: [\"cloud://xxx.png\"] // 文件 fileID 列表\n    });\n    if (res.fileList[0].code === \"SUCCESS\") {\n      setMessage(\"删除成功！\");\n    } else {\n      setMessage(\"删除失败！\", res.fileList);\n    }\n  };\n\n  return (\n    <div>\n      <button onClick={deleteFile}>删除文件</button>\n      {message && <p>{message}</p>}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 4,
                "title": "删除文件"
              }
            ]
          },
          {
            "index": 7,
            "id": "ai-model",
            "title": "大模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst res = await cloudbase\n  .ai()\n  .createModel(\"{%AI_MODEL_NAME%}\")\n  .streamText({\n    model: \"{%AI_SUB_MODEL_NAME%}\",\n    messages: [{ role: \"user\", content: \"你好\" }]\n  });\n\nfor await (let data of res.dataStream) {\n  // 如果有则打印思维链内容\n  const think = data?.choices?.[0]?.delta?.reasoning_content;\n  if (think) console.log(think);\n\n  // 打印生成文本内容\n  const text = data?.choices?.[0]?.delta?.content;\n  if (text) console.log(text);\n}\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [data, setData] = useState(\"\");\n  const [input, setInput] = useState(\"\");\n\n  const getData = async () => {\n    const res = await cloudbase\n      .ai()\n      .createModel(\"{%AI_MODEL_NAME%}\")\n      .streamText({\n        model: \"{%AI_SUB_MODEL_NAME%}\",\n        messages: [{ role: \"user\", content: input }]\n      });\n\n    let result = \"\";\n    for await (let data of res.dataStream) {\n      // 如果有则打印思维链内容\n      const think = data?.choices?.[0]?.delta?.reasoning_content;\n      if (think) {\n        result += think;\n      }\n\n      // 打印生成文本内容\n      const text = data?.choices?.[0]?.delta?.content;\n      if (text) result += text;\n\n      setData(result);\n    }\n  };\n\n  return (\n    <div>\n      <input\n        value={input}\n        placeholder=\"请输入大模型对话内容\"\n        onChange={e => setInput(e.target.value)}\n      />\n      <button onClick={getData}>发送</button>\n      <p>{data}</p>\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 1,
                "id": "text-aiModel",
                "title": "生文模型"
              },
              {
                "markdown": "生图模型通过调用云函数来实现，在生图模型页面点击「一键创建云函数」，函数调用示例如下：\n\n**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 调用生图云函数\nconst res = await cloudbase.callFunction({\n  name: \"<YOUR_FUNCTION_NAME>\",\n  data: {\n    prompt: \"一只可爱的猫咪在阳光下玩耍\"\n  }\n});\n\nconst result = res.result;\n\nif (result.success) {\n  // 生成成功\n  console.log(\"生成成功!\");\n  console.log(\"图片URL:\", result.imageUrl);\n  console.log(\"优化后的提示词:\", result.revised_prompt);\n\n  // 使用图片\n  // 注意：图片URL有效期为24小时，请及时保存或转存\n} else {\n  // 生成失败\n  console.error(\"生成失败:\", result.code, result.message);\n}\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [prompt, setPrompt] = useState(\"\");\n  const [imageUrl, setImageUrl] = useState(\"\");\n  const [message, setMessage] = useState(\"\");\n  const [loading, setLoading] = useState(false);\n\n  const generateImage = async () => {\n    setLoading(true);\n    setMessage(\"\");\n    setImageUrl(\"\");\n\n    try {\n      // 调用生图云函数\n      const res = await cloudbase.callFunction({\n        name: \"<YOUR_FUNCTION_NAME>\",\n        data: {\n          prompt: prompt\n        }\n      });\n\n      const result = res.result;\n\n      if (result.success) {\n        setImageUrl(result.imageUrl);\n        setMessage(\"生成成功！\");\n      } else {\n        setMessage(`生成失败：${result.message}`);\n      }\n    } catch (error) {\n      setMessage(\"调用失败：\" + error.message);\n    } finally {\n      setLoading(false);\n    }\n  };\n\n  return (\n    <div>\n      <input\n        value={prompt}\n        placeholder=\"请输入图片描述\"\n        onChange={e => setPrompt(e.target.value)}\n      />\n      <button onClick={generateImage} disabled={!prompt || loading}>\n        {loading ? \"生成中...\" : \"生成图片\"}\n      </button>\n      {message && (\n        <p style={{ color: message.includes(\"成功\") ? \"green\" : \"red\" }}>\n          {message}\n        </p>\n      )}\n      {imageUrl && (\n        <div>\n          <img src={imageUrl} alt=\"生成的图片\" style={{ maxWidth: \"100%\" }} />\n          <p style={{ fontSize: \"12px\", color: \"#666\" }}>\n            注意：图片URL有效期为24小时，请及时保存\n          </p>\n        </div>\n      )}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 2,
                "id": "image-aiModel",
                "title": "生图模型"
              }
            ]
          },
          {
            "markdown": "",
            "index": 8,
            "id": "agent",
            "title": "Agent",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from './utils/cloudbase';\n\nconst res = await cloudbase.ai().bot.sendMessage({\n  botId: '{%AGENT_ID%}',\n  // 入参结构参考前后端通信协议：\n  //  https://docs.cloudbase.net/ai/agent/http-agent-protocol\n  threadId: '550e8400-e29b-41d4-a716-446655440000',\n  runId: 'run_001',\n  messages: [\n    {\n      id: 'msg_001',\n      role: 'user',\n      content: '你好',\n    },\n  ],\n  tools: [],\n  context: [],\n  state: {},\n  forwardedProps: {},\n});\n\nfor await (const data of res.dataStream) {\n  // 如果有则打印思维链内容\n  const think = data.reasoning_content;\n  if (think) console.log(think);\n\n  // 打印输出正文\n  const content = data.content;\n  if (content) console.log(content);\n}\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from 'react';\nimport { cloudbase } from './utils/cloudbase';\n\nfunction Page() {\n  const [data, setData] = useState('');\n  const [input, setInput] = useState('');\n\n  const getData = async () => {\n    const res = await cloudbase.ai().bot.sendMessage({\n      botId: '{%AGENT_ID%}',\n      // 入参结构参考前后端通信协议：\n      //  https://docs.cloudbase.net/ai/agent/http-agent-protocol\n      threadId: '550e8400-e29b-41d4-a716-446655440000',\n      runId: 'run_001',\n      messages: [\n        {\n          id: 'msg_001',\n          role: 'user',\n          content: input,\n        },\n      ],\n      tools: [],\n      context: [],\n      state: {},\n      forwardedProps: {},\n    });\n\n    let result = '';\n    for await (const data of res.dataStream) {\n      // 如果有则打印思维链内容\n      const think = data.reasoning_content;\n      if (think) {\n        result += think;\n      }\n\n      // 打印输出正文\n      const content = data.content;\n      if (content) result += content;\n\n      setData(result);\n    }\n  };\n\n  return (\n    <div>\n      <input value={input} placeholder=\"请输入Agent对话内容\" onChange={(e) => setInput(e.target.value)} />\n      <button onClick={getData}>发送</button>\n      <p>{data}</p>\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 0,
                "id": "scf",
                "title": "函数型"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst res = await cloudbase.ai().bot.sendMessage({\n  botId: \"{%AGENT_ID%}\",\n  msg: \"你好\"\n});\n\nfor await (const data of res.dataStream) {\n  // 如果有则打印思维链内容\n  const think = data.reasoning_content;\n  if (think) console.log(think);\n\n  // 打印输出正文\n  const content = data.content;\n  if (content) console.log(content);\n}\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [data, setData] = useState(\"\");\n  const [input, setInput] = useState(\"\");\n\n  const getData = async () => {\n    const res = await cloudbase.ai().bot.sendMessage({\n      botId: \"{%AGENT_ID%}\",\n      msg: input\n    });\n\n    let result = \"\";\n    for await (const data of res.dataStream) {\n      // 如果有则打印思维链内容\n      const think = data.reasoning_content;\n      if (think) {\n        result += think;\n      }\n\n      // 打印输出正文\n      const content = data.content;\n      if (content) result += content;\n\n      setData(result);\n    }\n  };\n\n  return (\n    <div>\n      <input\n        value={input}\n        placeholder=\"请输入Agent对话内容\"\n        onChange={e => setInput(e.target.value)}\n      />\n      <button onClick={getData}>发送</button>\n      <p>{data}</p>\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 1,
                "id": "baas",
                "title": "普通型"
              }
            ]
          },
          {
            "index": 9,
            "id": "identity",
            "title": "身份认证",
            "type": "sideTab",
            "content": [
              {
                "markdown": "使用 **短信验证码注册** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **短信验证码**\n\n**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ phone_number: phone });\n\n// 验证验证码\nconst verifyRes = await auth.verify({\n  verification_id: verificationId,\n  verification_code: code\n});\n\n// 注册（如用户已存在则自动登录）\nawait auth.signUp({\n  phone_number: `+86 ${phone}`,\n  verification_code: code,\n  verification_token: verifyRes.verification_token,\n  name: `user_${phone.slice(-4)}`,\n  password: \"admin@123\"\n});\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [phone, setPhone] = useState(\"\");\n  const [code, setCode] = useState(\"\");\n  const [verificationId, setVerificationId] = useState(\"\");\n  const [message, setMessage] = useState(\"\");\n\n  // 发送验证码\n  const sendCode = async () => {\n    try {\n      const auth = cloudbase.auth();\n      const res = await auth.getVerification({ phone_number: phone });\n      setVerificationId(res.verification_id);\n      setMessage(\"验证码已发送！\");\n    } catch (error) {\n      setMessage(\"发送失败：\" + error.message);\n    }\n  };\n\n  // 注册\n  const register = async () => {\n    try {\n      const auth = cloudbase.auth();\n      // 验证验证码\n      const verifyRes = await auth.verify({\n        verification_id: verificationId,\n        verification_code: code\n      });\n      // 注册（如用户已存在则自动登录）\n      await auth.signUp({\n        phone_number: `+86 ${phone}`,\n        verification_code: code,\n        verification_token: verifyRes.verification_token,\n        name: `user_${phone.slice(-4)}`,\n        password: \"admin@123\"\n      });\n      setMessage(\"注册成功！\");\n    } catch (error) {\n      setMessage(\"注册失败：\" + error.message);\n    }\n  };\n\n  return (\n    <div>\n      <label>手机号：</label>\n      <input\n        value={phone}\n        onChange={e => setPhone(e.target.value)}\n        placeholder=\"13800000000\"\n      />\n      <div>\n        <label>验证码：</label>\n        <input\n          value={code}\n          onChange={e => setCode(e.target.value)}\n          placeholder=\"验证码\"\n        />\n        <button disabled={!phone} onClick={sendCode}>\n          发送验证码\n        </button>\n      </div>\n      <button disabled={!verificationId || !code} onClick={register}>\n        注册\n      </button>\n      {message && (\n        <p style={{ color: message.includes(\"成功\") ? \"green\" : \"red\" }}>\n          {message}\n        </p>\n      )}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 1,
                "title": "短信验证码注册"
              },
              {
                "markdown": "使用 **邮箱验证码注册** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **邮箱验证码**\n\n**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ email });\n\n// 验证验证码\nconst verifyRes = await auth.verify({\n  verification_id: verificationId,\n  verification_code: code\n});\n\n// 注册（如用户已存在则自动登录）\nawait auth.signUp({\n  email,\n  verification_code: code,\n  verification_token: verifyRes.verification_token,\n  name: `user_${email.slice(-4)}`,\n  password: \"admin@123\"\n});\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [email, setEmail] = useState(\"\");\n  const [code, setCode] = useState(\"\");\n  const [verificationId, setVerificationId] = useState(\"\");\n  const [message, setMessage] = useState(\"\");\n\n  // 发送验证码\n  const sendCode = async () => {\n    try {\n      const auth = cloudbase.auth();\n      const res = await auth.getVerification({ email });\n      setVerificationId(res.verification_id);\n      setMessage(\"验证码已发送！\");\n    } catch (error) {\n      setMessage(\"发送失败：\" + error.message);\n    }\n  };\n\n  // 注册\n  const register = async () => {\n    try {\n      const auth = cloudbase.auth();\n      // 验证验证码\n      const verifyRes = await auth.verify({\n        verification_id: verificationId,\n        verification_code: code\n      });\n      // 注册（如用户已存在则自动登录）\n      await auth.signUp({\n        email,\n        verification_code: code,\n        verification_token: verifyRes.verification_token,\n        name: `user_${email.slice(-4)}`,\n        password: \"admin@123\"\n      });\n      setMessage(\"注册成功！\");\n    } catch (error) {\n      setMessage(\"注册失败：\" + error.message);\n    }\n  };\n\n  return (\n    <div>\n      <label>邮箱：</label>\n      <input\n        value={email}\n        onChange={e => setEmail(e.target.value)}\n        placeholder=\"example@email.com\"\n      />\n      <div>\n        <label>验证码：</label>\n        <input\n          value={code}\n          onChange={e => setCode(e.target.value)}\n          placeholder=\"验证码\"\n        />\n        <button disabled={!email} onClick={sendCode}>\n          发送验证码\n        </button>\n      </div>\n      <button disabled={!verificationId || !code} onClick={register}>\n        注册\n      </button>\n      {message && (\n        <p style={{ color: message.includes(\"成功\") ? \"green\" : \"red\" }}>\n          {message}\n        </p>\n      )}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 2,
                "title": "邮箱验证码注册"
              },
              {
                "markdown": "使用 **账号密码登录** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **用户名密码登录**\n\n**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\nawait auth.signIn({\n  username, // 可以是用户名、手机号或邮箱\n  password\n});\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [username, setUsername] = useState(\"\");\n  const [password, setPassword] = useState(\"\");\n  const [message, setMessage] = useState(\"\");\n\n  // 登录\n  const login = async () => {\n    try {\n      const auth = cloudbase.auth();\n      await auth.signIn({\n        username: username, // 可以是用户名、手机号或邮箱\n        password: password\n      });\n      setMessage(\"登录成功！\");\n    } catch (error) {\n      setMessage(\"登录失败：\" + error.message);\n    }\n  };\n\n  return (\n    <div>\n      <label>账号：</label>\n      <input\n        value={username}\n        onChange={e => setUsername(e.target.value)}\n        placeholder=\"用户名/手机号/邮箱\"\n      />\n      注：手机号登录请添加区号 +86\n      <br />\n      <label>密码：</label>\n      <input\n        type=\"password\"\n        value={password}\n        onChange={e => setPassword(e.target.value)}\n        placeholder=\"请输入密码\"\n      />\n      <br />\n      <button disabled={!username || !password} onClick={login}>\n        登录\n      </button>\n      {message && (\n        <p style={{ color: message.includes(\"成功\") ? \"green\" : \"red\" }}>\n          {message}\n        </p>\n      )}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 3,
                "id": "UserNameLogin",
                "title": "账号密码登录"
              },
              {
                "markdown": "使用 **短信验证码登录** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **短信验证码登录**\n\n**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ phone_number: `+86 ${phone}` });\n\n// 登录\nawait auth.signInWithSms({\n  verificationInfo: res,\n  verificationCode: code,\n  phoneNum: `+86 ${phone}`\n});\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [phone, setPhone] = useState(\"\");\n  const [code, setCode] = useState(\"\");\n  const [verificationInfo, setVerificationInfo] = useState(null);\n  const [message, setMessage] = useState(\"\");\n\n  // 发送验证码\n  const sendCode = async () => {\n    try {\n      const auth = cloudbase.auth();\n      const res = await auth.getVerification({ phone_number: `+86 ${phone}` });\n      setVerificationInfo(res);\n      setMessage(\"验证码已发送！\");\n    } catch (error) {\n      setMessage(\"发送失败：\" + error.message);\n    }\n  };\n\n  // 登录\n  const login = async () => {\n    try {\n      const auth = cloudbase.auth();\n      await auth.signInWithSms({\n        verificationInfo,\n        verificationCode: code,\n        phoneNum: `+86 ${phone}`\n      });\n      setMessage(\"登录成功！\");\n    } catch (error) {\n      setMessage(\"登录失败：\" + error.message);\n    }\n  };\n\n  return (\n    <div>\n      <label>手机号：</label>\n      <input\n        value={phone}\n        onChange={e => setPhone(e.target.value)}\n        placeholder=\"13800000000\"\n      />\n      <div>\n        <label>验证码：</label>\n        <input\n          value={code}\n          onChange={e => setCode(e.target.value)}\n          placeholder=\"验证码\"\n        />\n        <button onClick={sendCode} disabled={!phone}>\n          发送验证码\n        </button>\n      </div>\n      <button onClick={login} disabled={!verificationInfo || !code}>\n        登录\n      </button>\n      {message && (\n        <p style={{ color: message.includes(\"成功\") ? \"green\" : \"red\" }}>\n          {message}\n        </p>\n      )}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 4,
                "id": "PhoneNumberLogin",
                "title": "短信验证码登录"
              },
              {
                "markdown": "使用 **邮箱验证码登录** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **邮箱验证码**\n\n**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ email });\n\n// 登录\nawait auth.signInWithEmail({\n  verificationInfo: res,\n  verificationCode: code,\n  email\n});\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [email, setEmail] = useState(\"\");\n  const [code, setCode] = useState(\"\");\n  const [verificationInfo, setVerificationInfo] = useState(null);\n  const [message, setMessage] = useState(\"\");\n\n  // 发送验证码\n  const sendCode = async () => {\n    try {\n      const auth = cloudbase.auth();\n      const res = await auth.getVerification({ email });\n      setVerificationInfo(res);\n      setMessage(\"验证码已发送！\");\n    } catch (error) {\n      setMessage(\"发送失败：\" + error.message);\n    }\n  };\n\n  // 登录\n  const login = async () => {\n    try {\n      const auth = cloudbase.auth();\n      await auth.signInWithEmail({\n        verificationInfo,\n        verificationCode: code,\n        email\n      });\n      setMessage(\"登录成功！\");\n    } catch (error) {\n      setMessage(\"登录失败：\" + error.message);\n    }\n  };\n\n  return (\n    <div>\n      <label>邮箱：</label>\n      <input\n        value={email}\n        onChange={e => setEmail(e.target.value)}\n        placeholder=\"example@email.com\"\n      />\n      <div>\n        <label>验证码：</label>\n        <input\n          value={code}\n          onChange={e => setCode(e.target.value)}\n          placeholder=\"验证码\"\n        />\n        <button onClick={sendCode} disabled={!email}>\n          发送验证码\n        </button>\n      </div>\n      <button onClick={login} disabled={!verificationInfo || !code}>\n        登录\n      </button>\n      {message && (\n        <p style={{ color: message.includes(\"成功\") ? \"green\" : \"red\" }}>\n          {message}\n        </p>\n      )}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 5,
                "id": "email",
                "title": "邮箱验证码登录"
              },
              {
                "markdown": "使用 **Google 授权登录** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **Google 授权登录**\n\n**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 步骤1：生成Google授权URL并跳转\nconst state = Date.now().toString();\nlocalStorage.setItem(\"google_login_state\", state);\nconst { uri } = await auth.genProviderRedirectUri({\n  provider_id: \"google\",\n  provider_redirect_uri: window.location.href,\n  state: state\n});\nwindow.location.href = uri;\n\n// 步骤2：使用code换取provider_token\nconst { provider_token } = await auth.grantProviderToken({\n  provider_id: \"google\",\n  provider_redirect_uri: window.location.origin + window.location.pathname,\n  provider_code: code\n});\n\n// 步骤3：使用provider_token登录\nawait auth.signInWithProvider({\n  provider_token: provider_token\n});\n```\n\n**完整示例：**\n\n```jsx\nimport { useState, useEffect } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [message, setMessage] = useState(\"\");\n  const [isCallback, setIsCallback] = useState(false);\n\n  useEffect(() => {\n    // 检查是否是Google回调页面\n    const urlParams = new URLSearchParams(window.location.search);\n    const code = urlParams.get(\"code\");\n    const state = urlParams.get(\"state\");\n\n    if (code && state) {\n      setIsCallback(true);\n      handleGoogleCallback(code, state);\n    }\n  }, []);\n\n  // 步骤1：跳转到Google授权页\n  const startGoogleLogin = async () => {\n    try {\n      const auth = cloudbase.auth();\n      const state = Date.now().toString(); // 生成唯一标识，防止CSRF攻击\n\n      // 保存state到本地，用于回调时验证\n      localStorage.setItem(\"google_login_state\", state);\n\n      // 生成Google授权URL\n      const { uri } = await auth.genProviderRedirectUri({\n        provider_id: \"google\", // 固定值，代表Google开放平台\n        provider_redirect_uri: window.location.href, // 授权后回调当前页面\n        state: state\n      });\n\n      // 跳转到Google授权页\n      window.location.href = uri;\n    } catch (error) {\n      setMessage(\"跳转失败：\" + error.message);\n    }\n  };\n\n  // 步骤2和3：处理Google回调并完成登录\n  const handleGoogleCallback = async (code, state) => {\n    try {\n      // 验证state是否匹配，防止CSRF攻击\n      const savedState = localStorage.getItem(\"google_login_state\");\n      if (savedState !== state) {\n        setMessage(\"登录失败：状态验证失败\");\n        return;\n      }\n\n      const auth = cloudbase.auth();\n\n      // 使用code换取provider_token\n      const { provider_token } = await auth.grantProviderToken({\n        provider_id: \"google\",\n        provider_redirect_uri:\n          window.location.origin + window.location.pathname,\n        provider_code: code\n      });\n\n      try {\n        // 尝试直接登录\n        await auth.signInWithProvider({\n          provider_token: provider_token\n        });\n\n        setMessage(\"登录成功！\");\n\n        // 清除URL参数并清除本地存储\n        localStorage.removeItem(\"google_login_state\");\n        window.history.replaceState(\n          {},\n          document.title,\n          window.location.pathname\n        );\n      } catch (loginError) {\n        // 如果是首次Google登录，需要先注册并绑定\n        if (loginError.error === \"not_found\") {\n          setMessage(\"检测到首次Google登录，需要绑定账号...\");\n\n          // 这里需要引导用户完成注册流程\n          // 例如：收集手机号验证码进行注册\n          // 注册成功后调用 bindWithProvider 绑定Google身份\n\n          // 示例：假设已有其他方式注册的账号，直接绑定\n          await auth.bindWithProvider({\n            provider_token: provider_token\n          });\n\n          // 绑定成功后重新登录\n          await auth.signInWithProvider({\n            provider_token: provider_token\n          });\n\n          setMessage(\"绑定并登录成功！\");\n\n          // 清除URL参数和本地存储\n          localStorage.removeItem(\"google_login_state\");\n          window.history.replaceState(\n            {},\n            document.title,\n            window.location.pathname\n          );\n        } else {\n          throw loginError;\n        }\n      }\n    } catch (error) {\n      setMessage(\"登录失败：\" + error.message);\n      localStorage.removeItem(\"google_login_state\");\n    }\n  };\n\n  return (\n    <div>\n      {!isCallback && <button onClick={startGoogleLogin}>Google登录</button>}\n      {isCallback && <p>正在处理Google登录...</p>}\n      {message && (\n        <p style={{ color: message.includes(\"成功\") ? \"green\" : \"red\" }}>\n          {message}\n        </p>\n      )}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 6,
                "id": "google",
                "title": "Google 授权登录"
              }
            ]
          }
        ]
      }
    ],
    "_id": "2f6f1f4b698062900099ddb66d817ab6",
    "_openid": "anon",
    "createdAt": 1770021519969,
    "updatedAt": 1770021519969
  },
  {
    "category": "框架集成,移动端框架,Flutter",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": 30,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/http-api/basic/overview",
    "content": [
      {
        "markdown": "通过 **HTTP 请求** 在 **Flutter** 中调用各种云开发能力\n\n在 `pubspec.yaml` 中添加依赖：\n\n```yaml\ndependencies:\n  http: ^1.1.0\n  flutter_dotenv: ^5.1.0\n```\n\n然后运行：\n\n```bash\nflutter pub get\n```",
        "index": 1,
        "title": "安装依赖",
        "content": []
      },
      {
        "markdown": "新增如下代码到您的 **Flutter** 项目",
        "index": 2,
        "title": "初始化配置",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```dart\nimport 'dart:convert';\nimport 'package:http/http.dart' as http;\nimport 'package:flutter_dotenv/flutter_dotenv.dart';\n\nclass CloudBaseClient {\n  late String envId;\n  late String accessToken;\n  late String baseUrl;\n  late Map<String, String> headers;\n\n  CloudBaseClient() {\n    envId = dotenv.env['CLOUDBASE_ENV_ID'] ?? '';\n    accessToken = dotenv.env['CLOUDBASE_ACCESS_TOKEN'] ?? '';\n    baseUrl = 'https://$envId.api.tcloudbasegateway.com';\n    headers = {\n      'Content-Type': 'application/json',\n      'Accept': 'application/json',\n      'Authorization': 'Bearer $accessToken',\n    };\n  }\n\n  /// 更新访问令牌\n  ///\n  /// [newToken] 新的访问令牌\n  void updateAccessToken(String newToken) {\n    accessToken = newToken;\n    headers['Authorization'] = 'Bearer $newToken';\n    print('访问令牌已更新');\n  }\n\n  /// 统一的HTTP请求方法\n  ///\n  /// [method] 请求方法 (GET, POST, PUT, PATCH, DELETE)\n  /// [path] API路径 (如 /v1/rdb/rest/table_name)\n  /// [body] 请求体数据\n  /// [customHeaders] 自定义headers\n  ///\n  /// 返回响应数据或null\n  Future<dynamic> request(\n    String method,\n    String path, {\n    dynamic body,\n    Map<String, String>? customHeaders,\n  }) async {\n    final url = Uri.parse('$baseUrl$path');\n    final requestHeaders = Map<String, String>.from(headers);\n\n    if (customHeaders != null) {\n      requestHeaders.addAll(customHeaders);\n    }\n\n    try {\n      http.Response response;\n\n      switch (method.toUpperCase()) {\n        case 'GET':\n          response = await http.get(url, headers: requestHeaders);\n          break;\n        case 'POST':\n          response = await http.post(\n            url,\n            headers: requestHeaders,\n            body: body != null ? jsonEncode(body) : null,\n          );\n          break;\n        case 'PUT':\n          response = await http.put(\n            url,\n            headers: requestHeaders,\n            body: body != null ? jsonEncode(body) : null,\n          );\n          break;\n        case 'PATCH':\n          response = await http.patch(\n            url,\n            headers: requestHeaders,\n            body: body != null ? jsonEncode(body) : null,\n          );\n          break;\n        case 'DELETE':\n          response = await http.delete(url, headers: requestHeaders);\n          break;\n        default:\n          throw Exception('不支持的HTTP方法: $method');\n      }\n\n      if (response.statusCode >= 200 && response.statusCode < 300) {\n        if (response.body.isEmpty) {\n          return true;\n        }\n        return jsonDecode(response.body);\n      } else {\n        print('请求失败: ${response.statusCode} ${response.body}');\n        return null;\n      }\n    } catch (e) {\n      print('请求失败: $e');\n      return null;\n    }\n  }\n}\n\nfinal cloudbase = CloudBaseClient();\n```",
            "index": 1,
            "title": "cloudbase_client.dart"
          },
          {
            "markdown": "> 💡提示：用户权限请参考「身份认证」模块获取 access_token\n\n```properties\n# 环境ID\nCLOUDBASE_ENV_ID={%ENV_ID%}\n\n# 匿名访问令牌\nCLOUDBASE_ACCESS_TOKEN={%PUBLISHABLE_KEY%}\n```",
            "index": 2,
            "title": ".env"
          }
        ]
      },
      {
        "index": 3,
        "title": "调用云开发能力",
        "type": "codeTab",
        "content": [
          {
            "index": 1,
            "id": "mysql-db",
            "title": "MySQL数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<List<dynamic>> getMysqlData(String tableName) async {\n  /// 查询 MySQL 数据库数据\n  final data = await cloudbase.request('GET', '/v1/rdb/rest/$tableName?limit=10');\n\n  if (data != null) {\n    print('查询成功: $data');\n    return data as List<dynamic>;\n  }\n  return [];\n}\n\n// 使用示例\nvoid main() async {\n  final result = await getMysqlData('{%TABLE_NAME%}');\n  print(result);\n}\n```",
                "index": 1,
                "title": "查询数据",
                "content": []
              },
              {
                "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<dynamic> addMysqlData(String tableName, Map<String, dynamic> data) async {\n  /// 新增 MySQL 数据库数据\n  final result = await cloudbase.request('POST', '/v1/rdb/rest/$tableName', body: data);\n\n  if (result != null) {\n    print('新增成功: $result');\n  }\n  return result;\n}\n\n// 使用示例\nvoid main() async {\n  final result = await addMysqlData('{%TABLE_NAME%}', {'title': '示例标题'});\n  print(result);\n}\n```",
                "index": 2,
                "title": "新增数据",
                "content": []
              },
              {
                "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<dynamic> updateMysqlData(String tableName, String dataId, Map<String, dynamic> data) async {\n  /// 更新 MySQL 数据库数据\n  final result = await cloudbase.request(\n    'PATCH',\n    '/v1/rdb/rest/$tableName?id=eq.$dataId',\n    body: data,\n  );\n\n  if (result != null) {\n    print('更新成功: $result');\n  }\n  return result;\n}\n\n// 使用示例\nvoid main() async {\n  final result = await updateMysqlData('{%TABLE_NAME%}', '<数据id>', {'title': '新标题'});\n  print(result);\n}\n```",
                "index": 3,
                "title": "更新数据",
                "content": []
              },
              {
                "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<bool> deleteMysqlData(String tableName, String dataId) async {\n  /// 删除 MySQL 数据库数据\n  final result = await cloudbase.request('DELETE', '/v1/rdb/rest/$tableName?id=eq.$dataId');\n\n  if (result != null) {\n    print('删除成功');\n    return true;\n  }\n  return false;\n}\n\n// 使用示例\nvoid main() async {\n  final result = await deleteMysqlData('{%TABLE_NAME%}', '<数据id>');\n  print(result);\n}\n```",
                "index": 4,
                "title": "删除数据",
                "content": []
              }
            ]
          },
          {
            "index": 2,
            "id": "data-model",
            "title": "数据模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<List<dynamic>> getModelData(String modelName, {String envType = 'prod'}) async {\n  /// 查询数据模型数据\n  final payload = {\n    'pageSize': 10,\n    'pageNumber': 1,\n    'getCount': true,\n  };\n\n  final result = await cloudbase.request('POST', '/v1/model/$envType/$modelName/list', body: payload);\n\n  if (result != null) {\n    final records = result['data']?['records'] ?? [];\n    print('查询成功: $records');\n    return records;\n  }\n  return [];\n}\n\n// 使用示例\nvoid main() async {\n  final records = await getModelData('{%TABLE_NAME%}');\n  print(records);\n}\n```",
                "index": 1,
                "title": "查询数据",
                "content": []
              },
              {
                "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<dynamic> addModelData(String modelName, Map<String, dynamic> data, {String envType = 'prod'}) async {\n  /// 新增数据模型数据\n  final result = await cloudbase.request(\n    'POST',\n    '/v1/model/$envType/$modelName/create',\n    body: {'data': data},\n  );\n\n  if (result != null) {\n    final docId = result['data']?['id'];\n    print('新增成功! id: $docId');\n  }\n  return result;\n}\n\n// 使用示例\nvoid main() async {\n  final result = await addModelData('{%TABLE_NAME%}', {'title': '示例标题'});\n  print(result);\n}\n```",
                "index": 2,
                "title": "新增数据",
                "content": []
              },
              {
                "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<bool> updateModelData(String modelName, String dataId, Map<String, dynamic> data, {String envType = 'prod'}) async {\n  /// 更新数据模型数据\n  final payload = {\n    'data': data,\n    'filter': {\n      'where': {\n        '_id': {'\\$eq': dataId}\n      }\n    }\n  };\n\n  final result = await cloudbase.request('PUT', '/v1/model/$envType/$modelName/update', body: payload);\n\n  if (result != null) {\n    print('更新成功!');\n    return true;\n  }\n  return false;\n}\n\n// 使用示例\nvoid main() async {\n  final result = await updateModelData('{%TABLE_NAME%}', '<数据id>', {'title': '新标题'});\n  print(result);\n}\n```",
                "index": 3,
                "title": "更新数据",
                "content": []
              },
              {
                "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<bool> deleteModelData(String modelName, String dataId, {String envType = 'prod'}) async {\n  /// 删除数据模型数据\n  final payload = {\n    'filter': {\n      'where': {\n        '_id': {'\\$eq': dataId}\n      }\n    }\n  };\n\n  final result = await cloudbase.request('POST', '/v1/model/$envType/$modelName/delete', body: payload);\n\n  if (result != null) {\n    print('删除成功!');\n    return true;\n  }\n  return false;\n}\n\n// 使用示例\nvoid main() async {\n  final result = await deleteModelData('{%TABLE_NAME%}', '<数据id>');\n  print(result);\n}\n```",
                "index": 4,
                "title": "删除数据",
                "content": []
              }
            ]
          },
          {
            "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<dynamic> callFunction(String functionName, {Map<String, dynamic>? data}) async {\n  /// 调用云函数\n  final result = await cloudbase.request('POST', '/v1/functions/$functionName', body: data ?? {});\n\n  if (result != null) {\n    print('云函数调用结果: $result');\n  }\n  return result;\n}\n\n// 使用示例\nvoid main() async {\n  final result = await callFunction('{%FUNCTION_NAME%}');\n  print(result);\n}\n```",
            "index": 3,
            "id": "scf",
            "title": "云函数"
          },
          {
            "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<dynamic> callContainer(String serviceName, {String path = '', String method = 'GET', Map<String, dynamic>? data}) async {\n  /// 调用云托管服务\n  final fullPath = '/v1/cloudrun/$serviceName/$path'.replaceAll(RegExp(r'/+$'), '');\n  final result = await cloudbase.request(method.toUpperCase(), fullPath, body: data);\n\n  if (result != null) {\n    print('云托管调用结果: $result');\n  }\n  return result;\n}\n\n// 使用示例\nvoid main() async {\n  final result = await callContainer('{%SERVICE_NAME%}');\n  print(result);\n}\n```",
            "index": 4,
            "id": "run",
            "title": "云托管"
          },
          {
            "index": 5,
            "id": "storage",
            "title": "云存储",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```dart\nimport 'dart:io';\nimport 'package:http/http.dart' as http;\nimport 'cloudbase_client.dart';\n\nFuture<Map<String, dynamic>?> uploadFile(String filePath, {String? objectId}) async {\n  /// 上传文件到云存储\n  final file = File(filePath);\n\n  if (!await file.exists()) {\n    print('文件不存在: $filePath');\n    return null;\n  }\n\n  if (objectId == null) {\n    final filename = filePath.split('/').last;\n    final timestamp = DateTime.now().millisecondsSinceEpoch;\n    objectId = 'uploads/$timestamp-$filename';\n  }\n\n  // 1. 获取上传信息\n  final uploadInfo = await cloudbase.request(\n    'POST',\n    '/v1/storages/get-objects-upload-info',\n    body: [{'objectId': objectId}],\n  );\n\n  if (uploadInfo == null || uploadInfo.isEmpty) {\n    return null;\n  }\n\n  final info = uploadInfo[0];\n  final uploadUrl = info['uploadUrl'];\n\n  try {\n    // 2. 上传文件\n    final fileData = await file.readAsBytes();\n    final uploadHeaders = {\n      'Authorization': info['authorization'],\n      'X-Cos-Security-Token': info['token'],\n      'X-Cos-Meta-Fileid': info['cloudObjectMeta'],\n    };\n\n    final uploadResponse = await http.put(\n      Uri.parse(uploadUrl),\n      headers: uploadHeaders,\n      body: fileData,\n    );\n\n    if (uploadResponse.statusCode >= 200 && uploadResponse.statusCode < 300) {\n      final result = {\n        'cloudObjectId': info['cloudObjectId'],\n        'downloadUrl': info['downloadUrl'],\n        'objectId': objectId,\n      };\n\n      print('文件上传成功:');\n      print('- 对象ID: ${result['objectId']}');\n      print('- 下载URL: ${result['downloadUrl']}');\n\n      return result;\n    }\n\n    print('文件上传失败: ${uploadResponse.statusCode}');\n    return null;\n  } catch (e) {\n    print('文件上传失败: $e');\n    return null;\n  }\n}\n\n// 使用示例\nvoid main() async {\n  final result = await uploadFile('./example.jpg');\n  print(result);\n}\n```",
                "index": 1,
                "title": "上传文件",
                "content": []
              },
              {
                "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<String?> getFileUrl(String cloudObjectId) async {\n  /// 获取云存储文件的临时访问链接\n  final result = await cloudbase.request(\n    'POST',\n    '/v1/storages/get-objects-download-info',\n    body: [{'cloudObjectId': cloudObjectId}],\n  );\n\n  if (result != null && result.isNotEmpty) {\n    final downloadUrl = result[0]['downloadUrl'];\n    print('文件链接: $downloadUrl');\n    return downloadUrl;\n  }\n  return null;\n}\n\n// 使用示例\nvoid main() async {\n  final fileUrl = await getFileUrl('cloud://xxx.png');\n  print(fileUrl);\n}\n```",
                "index": 2,
                "title": "获取文件链接",
                "content": []
              },
              {
                "markdown": "```dart\nimport 'dart:io';\nimport 'package:http/http.dart' as http;\nimport 'cloudbase_client.dart';\n\nFuture<bool> downloadFile(String cloudObjectId, {String savePath = './'}) async {\n  /// 下载云存储文件到本地\n  // 1. 获取下载链接\n  final result = await cloudbase.request(\n    'POST',\n    '/v1/storages/get-objects-download-info',\n    body: [{'cloudObjectId': cloudObjectId}],\n  );\n\n  if (result == null || result.isEmpty) {\n    return false;\n  }\n\n  final downloadUrl = result[0]['downloadUrl'];\n\n  try {\n    // 2. 从URL中提取文件名\n    final uri = Uri.parse(downloadUrl);\n    final filename = uri.pathSegments.last.split('?').first;\n\n    // 3. 确定完整路径\n    String fullPath;\n    final saveDir = Directory(savePath);\n    if (await saveDir.exists() || savePath.endsWith('/')) {\n      fullPath = '$savePath/$filename';\n    } else {\n      fullPath = savePath;\n    }\n\n    // 4. 下载文件\n    final fileResponse = await http.get(Uri.parse(downloadUrl));\n\n    if (fileResponse.statusCode >= 200 && fileResponse.statusCode < 300) {\n      // 5. 保存到本地\n      final file = File(fullPath);\n      await file.writeAsBytes(fileResponse.bodyBytes);\n\n      print('下载成功! 文件已保存到: $fullPath');\n      return true;\n    }\n\n    print('下载失败: ${fileResponse.statusCode}');\n    return false;\n  } catch (e) {\n    print('下载失败: $e');\n    return false;\n  }\n}\n\n// 使用示例\nvoid main() async {\n  // 下载到当前目录，使用原文件名\n  await downloadFile('cloud://xxx.png');\n\n  // 下载到指定目录\n  await downloadFile('cloud://xxx.png', savePath: './downloads/');\n\n  // 下载并重命名\n  await downloadFile('cloud://xxx.png', savePath: './my-image.png');\n}\n```",
                "index": 3,
                "title": "下载文件",
                "content": []
              },
              {
                "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<bool> deleteFile(dynamic cloudObjectIds) async {\n  /// 删除云存储文件\n  List<String> ids;\n  if (cloudObjectIds is String) {\n    ids = [cloudObjectIds];\n  } else if (cloudObjectIds is List<String>) {\n    ids = cloudObjectIds;\n  } else {\n    print('参数类型错误');\n    return false;\n  }\n\n  final data = ids.map((id) => {'cloudObjectId': id}).toList();\n  final result = await cloudbase.request('POST', '/v1/storages/delete-objects', body: data);\n\n  if (result != null) {\n    print('删除成功!');\n    return true;\n  }\n  return false;\n}\n\n// 使用示例\nvoid main() async {\n  final result = await deleteFile('cloud://xxx.png');\n  print(result);\n}\n```",
                "index": 4,
                "title": "删除文件",
                "content": []
              }
            ]
          },
          {
            "index": 6,
            "id": "ai-model",
            "title": "大模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```dart\nimport 'dart:convert';\nimport 'package:http/http.dart' as http;\nimport 'cloudbase_client.dart';\n\nFuture<String?> streamText(String model, String subModel, List<Map<String, String>> messages) async {\n  /// 流式文本生成\n  final payload = {\n    'model': subModel,\n    'messages': messages,\n    'stream': true,\n  };\n\n  final url = '${cloudbase.baseUrl}/v1/ai/$model/chat/completions';\n  final headers = Map<String, String>.from(cloudbase.headers);\n  headers['Accept'] = 'text/event-stream';\n\n  try {\n    final request = http.Request('POST', Uri.parse(url));\n    request.headers.addAll(headers);\n    request.body = jsonEncode(payload);\n\n    final streamedResponse = await request.send();\n\n    if (streamedResponse.statusCode >= 200 && streamedResponse.statusCode < 300) {\n      print('AI 流式响应:');\n      String fullContent = '';\n\n      await for (var chunk in streamedResponse.stream.transform(utf8.decoder)) {\n        final lines = chunk.split('\\n');\n        for (var line in lines) {\n          if (line.startsWith('data: ')) {\n            final dataStr = line.substring(6);\n            if (dataStr.trim() != '[DONE]') {\n              try {\n                final chunkData = jsonDecode(dataStr);\n                final content = chunkData['choices']?[0]?['delta']?['content'] ?? '';\n                if (content.isNotEmpty) {\n                  print(content);\n                  fullContent += content;\n                }\n              } catch (e) {\n                // 忽略JSON解析错误\n              }\n            }\n          }\n        }\n      }\n\n      return fullContent;\n    } else {\n      print('AI 调用失败: ${streamedResponse.statusCode}');\n      return null;\n    }\n  } catch (e) {\n    print('AI 调用失败: $e');\n    return null;\n  }\n}\n\n// 使用示例\nvoid main() async {\n  final response = await streamText(\n    '{%AI_MODEL_NAME%}',\n    '{%AI_SUB_MODEL_NAME%}',\n    [\n      {'role': 'system', 'content': '请严格按照七言绝句或七言律诗的格律要求创作'},\n      {'role': 'user', 'content': '春天'}\n    ],\n  );\n  print('\\n完整回复: $response');\n}\n```",
                "index": 1,
                "id": "text-aiModel",
                "title": "生文模型",
                "content": []
              },
              {
                "markdown": "生图模型通过调用云函数来实现，在生图模型页面点击「一键创建云函数」，函数调用示例如下：\n\n```dart\nimport 'cloudbase_client.dart';\n\nFuture<Map<String, dynamic>?> generateImage(String prompt) async {\n  /// 调用生图云函数\n  final result = await cloudbase.request(\n    'POST',\n    '/v1/functions/<YOUR_FUNCTION_NAME>/invoke',\n    body: {\n      'prompt': prompt,\n    },\n  );\n\n  if (result != null) {\n    final success = result['success'] ?? false;\n    \n    if (success) {\n      // 生成成功\n      print('生成成功!');\n      print('图片URL: ${result['imageUrl']}');\n      print('优化后的提示词: ${result['revised_prompt']}');\n\n      // 使用图片\n      // 注意：图片URL有效期为24小时，请及时保存或转存\n      return result;\n    } else {\n      // 生成失败\n      print('生成失败: ${result['code']} ${result['message']}');\n      return null;\n    }\n  }\n  return null;\n}\n\n// 使用示例\nvoid main() async {\n  final result = await generateImage('一只可爱的猫咪在阳光下玩耍');\n  if (result != null) {\n    print('图片URL: ${result['imageUrl']}');\n  }\n}\n```",
                "index": 2,
                "id": "image-aiModel",
                "title": "生图模型",
                "content": []
              }
            ]
          },
          {
            "markdown": "",
            "index": 7,
            "id": "agent",
            "title": "Agent",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```dart\n/**\n * Flutter 调用 Agent 示例（AG-UI 协议）\n * 协议文档：https://docs.cloudbase.net/ai/agent-development/protocol\n */\nimport 'dart:convert';\nimport 'package:http/http.dart' as http;\nimport 'cloudbase_client.dart';\n\nFuture<String?> chatWithAgentStream(String botId, String userMessage) async {\n  // 构建消息列表（AG-UI 协议格式）\n  final messages = [\n    {\n      'id': 'msg_001',\n      'role': 'user',\n      'content': userMessage,\n    }\n  ];\n\n  // AG-UI 协议请求参数\n  final payload = {\n    'messages': messages,                                    // 必填：消息列表\n    'threadId': '550e8400-e29b-41d4-a716-446655440000',      // 可选：会话ID，用于多轮对话\n    'runId': 'run_001',                                       // 可选：运行ID，用于追踪执行\n    'tools': [],                                              // 可选：前端工具定义\n    'context': [],                                            // 可选：上下文信息\n    'forwardedProps': {},                                     // 可选：透传参数\n  };\n\n  final url = '${cloudbase.baseUrl}/v1/aibot/bots/$botId/send-message';\n  final headers = Map<String, String>.from(cloudbase.headers);\n  headers['Accept'] = 'text/event-stream';\n\n  try {\n    final request = http.Request('POST', Uri.parse(url));\n    request.headers.addAll(headers);\n    request.body = jsonEncode(payload);\n\n    final streamedResponse = await request.send();\n\n    if (streamedResponse.statusCode >= 200 && streamedResponse.statusCode < 300) {\n      print('AI 流式响应:');\n      String fullContent = '';\n      String buffer = '';\n\n      await for (var chunk in streamedResponse.stream.transform(utf8.decoder)) {\n        buffer += chunk;\n\n        while (buffer.contains('\\n')) {\n          final newlineIndex = buffer.indexOf('\\n');\n          final line = buffer.substring(0, newlineIndex).trim();\n          buffer = buffer.substring(newlineIndex + 1);\n\n          if (line.startsWith('data: ')) {\n            final dataStr = line.substring(6).trim();\n            if (dataStr.isNotEmpty && dataStr != '[DONE]') {\n              try {\n                final chunkData = jsonDecode(dataStr);\n                final content = chunkData['content'] ??\n                    chunkData['choices']?[0]?['delta']?['content'] ??\n                    chunkData['choices']?[0]?['message']?['content'] ??\n                    '';\n                if (content.isNotEmpty) {\n                  print(content);\n                  fullContent += content;\n                }\n              } catch (e) {\n                // 忽略JSON解析错误\n              }\n            }\n          }\n        }\n      }\n\n      print('');\n      return fullContent;\n    } else {\n      print('AI 调用失败: ${streamedResponse.statusCode}');\n      return null;\n    }\n  } catch (e) {\n    print('AI 调用失败: $e');\n    return null;\n  }\n}\n\n// 使用示例\nvoid main() async {\n  final response = await chatWithAgentStream('{%AGENT_ID%}', '你是谁');\n  print('\\n完整回复: $response');\n}\n\n```",
                "index": 0,
                "id": "scf",
                "title": "函数型"
              },
              {
                "markdown": "```dart\nimport 'dart:convert';\nimport 'package:http/http.dart' as http;\nimport 'cloudbase_client.dart';\n\nFuture<String?> chatWithAgentStream(String botId, String msg, {List<Map<String, String>>? history}) async {\n  /// 流式调用Agent\n  final payload = {\n    'history': history ?? [],\n    'msg': msg,\n  };\n\n  final url = '${cloudbase.baseUrl}/v1/aibot/bots/$botId/send-message';\n  final headers = Map<String, String>.from(cloudbase.headers);\n  headers['Accept'] = 'text/event-stream';\n\n  try {\n    final request = http.Request('POST', Uri.parse(url));\n    request.headers.addAll(headers);\n    request.body = jsonEncode(payload);\n\n    final streamedResponse = await request.send();\n\n    if (streamedResponse.statusCode >= 200 && streamedResponse.statusCode < 300) {\n      print('AI 流式响应:');\n      String fullContent = '';\n      String buffer = '';\n\n      await for (var chunk in streamedResponse.stream.transform(utf8.decoder)) {\n        buffer += chunk;\n\n        while (buffer.contains('\\n')) {\n          final newlineIndex = buffer.indexOf('\\n');\n          final line = buffer.substring(0, newlineIndex).trim();\n          buffer = buffer.substring(newlineIndex + 1);\n\n          if (line.startsWith('data: ')) {\n            final dataStr = line.substring(6).trim();\n            if (dataStr.isNotEmpty && dataStr != '[DONE]') {\n              try {\n                final chunkData = jsonDecode(dataStr);\n                final content = chunkData['content'] ??\n                    chunkData['choices']?[0]?['delta']?['content'] ??\n                    chunkData['choices']?[0]?['message']?['content'] ??\n                    '';\n                if (content.isNotEmpty) {\n                  print(content);\n                  fullContent += content;\n                }\n              } catch (e) {\n                // 忽略JSON解析错误\n              }\n            }\n          }\n        }\n      }\n\n      print('');\n      return fullContent;\n    } else {\n      print('AI 调用失败: ${streamedResponse.statusCode}');\n      return null;\n    }\n  } catch (e) {\n    print('AI 调用失败: $e');\n    return null;\n  }\n}\n\n// 使用示例\nvoid main() async {\n  final response = await chatWithAgentStream('{%AGENT_ID%}', '你是谁');\n  print('\\n完整回复: $response');\n}\n```",
                "index": 1,
                "id": "baas",
                "title": "普通型"
              }
            ]
          },
          {
            "index": 8,
            "id": "identity",
            "title": "身份认证",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<Map<String, dynamic>?> signUpWithPhoneCode(String phoneNumber, String verificationCode, {String? username, String? password, String? captchaToken}) async {\n  try {\n    // 步骤1: 发送短信验证码\n    final sendBody = {\n      'phone_number': phoneNumber.startsWith('+86') ? phoneNumber : '+86$phoneNumber',\n      'target': 'NON_USER',  // \"NON_USER\" - 账号不存在才发送; \"ANY\" - 不限制\n    };\n\n    final sendHeaders = captchaToken != null ? {'x-captcha-token': captchaToken} : null;\n\n    final sendResult = await cloudbase.request(\n      'POST',\n      '/auth/v1/verification',\n      body: sendBody,\n      customHeaders: sendHeaders,\n    );\n\n    if (sendResult == null) {\n      print('发送验证码失败');\n      return null;\n    }\n\n    final verificationId = sendResult['verification_id'];\n    print('验证码发送成功! ID: $verificationId');\n\n    // 步骤2: 验证验证码\n    final verifyResult = await cloudbase.request(\n      'POST',\n      '/auth/v1/verification/verify',\n      body: {\n        'verification_id': verificationId,\n        'verification_code': verificationCode,\n      },\n    );\n\n    if (verifyResult == null) {\n      print('验证码错误');\n      return null;\n    }\n\n    final verificationToken = verifyResult['verification_token'];\n    print('验证成功!');\n\n    // 步骤3: 使用验证令牌注册\n    final signUpBody = {\n      'phone_number': phoneNumber.startsWith('+86') ? phoneNumber : '+86$phoneNumber',\n      'verification_token': verificationToken,\n    };\n\n    // 可选：添加用户名和密码\n    if (username != null) signUpBody['username'] = username;\n    if (password != null) signUpBody['password'] = password;\n\n    final signUpResult = await cloudbase.request(\n      'POST',\n      '/auth/v1/signup',\n      body: signUpBody,\n    );\n\n    if (signUpResult != null) {\n      final accessToken = signUpResult['access_token'];\n      final userId = signUpResult['sub'];\n\n      print('注册成功! 用户ID: $userId');\n      print('访问令牌: ${accessToken.substring(0, 20)}...');\n\n      // 更新访问令牌\n      cloudbase.updateAccessToken(accessToken);\n      return signUpResult;\n    }\n\n    print('注册失败');\n    return null;\n  } catch (e) {\n    print('注册失败: $e');\n    return null;\n  }\n}\n\n// 使用示例\nvoid main() async {\n  final result = await signUpWithPhoneCode('13800138000', '123456', username: 'myusername', password: 'mypassword');\n  if (result != null) {\n    print('手机号注册成功');\n  }\n}\n```",
                "index": 1,
                "title": "短信验证码注册",
                "content": []
              },
              {
                "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<Map<String, dynamic>?> signUpWithEmailCode(String email, String verificationCode, {String? username, String? password, String? captchaToken}) async {\n  try {\n    // 步骤1: 发送邮箱验证码\n    final sendBody = {\n      'email': email,\n      'target': 'NON_USER',  // \"NON_USER\" - 账号不存在才发送; \"ANY\" - 不限制\n    };\n\n    final sendHeaders = captchaToken != null ? {'x-captcha-token': captchaToken} : null;\n\n    final sendResult = await cloudbase.request(\n      'POST',\n      '/auth/v1/verification',\n      body: sendBody,\n      customHeaders: sendHeaders,\n    );\n\n    if (sendResult == null) {\n      print('发送验证码失败');\n      return null;\n    }\n\n    final verificationId = sendResult['verification_id'];\n    print('验证码发送成功! ID: $verificationId');\n\n    // 步骤2: 验证验证码\n    final verifyResult = await cloudbase.request(\n      'POST',\n      '/auth/v1/verification/verify',\n      body: {\n        'verification_id': verificationId,\n        'verification_code': verificationCode,\n      },\n    );\n\n    if (verifyResult == null) {\n      print('验证码错误');\n      return null;\n    }\n\n    final verificationToken = verifyResult['verification_token'];\n    print('验证成功!');\n\n    // 步骤3: 使用验证令牌注册\n    final signUpBody = {\n      'email': email,\n      'verification_token': verificationToken,\n    };\n\n    // 可选：添加用户名和密码\n    if (username != null) signUpBody['username'] = username;\n    if (password != null) signUpBody['password'] = password;\n\n    final signUpResult = await cloudbase.request(\n      'POST',\n      '/auth/v1/signup',\n      body: signUpBody,\n    );\n\n    if (signUpResult != null) {\n      final accessToken = signUpResult['access_token'];\n      final userId = signUpResult['sub'];\n\n      print('注册成功! 用户ID: $userId');\n      print('访问令牌: ${accessToken.substring(0, 20)}...');\n\n      // 更新访问令牌\n      cloudbase.updateAccessToken(accessToken);\n      return signUpResult;\n    }\n\n    print('注册失败');\n    return null;\n  } catch (e) {\n    print('注册失败: $e');\n    return null;\n  }\n}\n\n// 使用示例\nvoid main() async {\n  final result = await signUpWithEmailCode('user@example.com', '123456', username: 'myusername', password: 'mypassword');\n  if (result != null) {\n    print('邮箱注册成功');\n  }\n}\n```",
                "index": 2,
                "title": "邮箱验证码注册",
                "content": []
              },
              {
                "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<Map<String, dynamic>?> signIn(String username, String password) async {\n  /// 账号密码登录\n  final result = await cloudbase.request(\n    'POST',\n    '/auth/v1/signin',\n    body: {'username': username, 'password': password},\n  );\n\n  if (result != null) {\n    final accessToken = result['access_token'];\n    final refreshToken = result['refresh_token'];\n    final userId = result['sub'];\n\n    print('登录成功! 用户ID: $userId');\n    print('访问令牌: ${accessToken.substring(0, 20)}...');\n\n    // 更新访问令牌\n    cloudbase.updateAccessToken(accessToken);\n    return result;\n  }\n  return null;\n}\n\n// 使用示例\nvoid main() async {\n  final result = await signIn('your_username', 'your_password');\n  print(result);\n}\n```",
                "index": 3,
                "id": "UserNameLogin",
                "title": "账号密码登录",
                "content": []
              },
              {
                "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<bool> loginWithPhoneCode(String phoneNumber, String verificationCode, {String? captchaToken}) async {\n  try {\n    // 步骤1: 发送短信验证码\n    final sendBody = {\n      'phone_number': phoneNumber.startsWith('+86') ? phoneNumber : '+86$phoneNumber',\n      'target': 'ANY',  // \"ANY\" - 不限制，无论用户是否存在都发送; \"USER\" - 账号必须存在才发送\n    };\n\n    final sendHeaders = captchaToken != null ? {'x-captcha-token': captchaToken} : null;\n\n    final sendResult = await cloudbase.request(\n      'POST',\n      '/auth/v1/verification',\n      body: sendBody,\n      customHeaders: sendHeaders,\n    );\n\n    if (sendResult == null) {\n      print('发送验证码失败');\n      return false;\n    }\n\n    final verificationId = sendResult['verification_id'];\n    print('验证码发送成功! ID: $verificationId');\n\n    // 步骤2: 验证验证码\n    final verifyResult = await cloudbase.request(\n      'POST',\n      '/auth/v1/verification/verify',\n      body: {\n        'verification_id': verificationId,\n        'verification_code': verificationCode,\n      },\n    );\n\n    if (verifyResult == null) {\n      print('验证码错误');\n      return false;\n    }\n\n    final verificationToken = verifyResult['verification_token'];\n    print('验证成功!');\n\n    // 步骤3: 使用验证令牌登录\n    final loginResult = await cloudbase.request(\n      'POST',\n      '/auth/v1/signin',\n      body: {\n        'phone_number': phoneNumber.startsWith('+86') ? phoneNumber : '+86$phoneNumber',\n        'verification_token': verificationToken,\n      },\n    );\n\n    if (loginResult != null) {\n      final accessToken = loginResult['access_token'];\n      print('登录成功!');\n      cloudbase.updateAccessToken(accessToken);\n      return true;\n    }\n\n    print('登录失败');\n    return false;\n  } catch (e) {\n    print('登录失败: $e');\n    return false;\n  }\n}\n\n// 使用示例\nvoid main() async {\n  final success = await loginWithPhoneCode('13800138000', '123456');\n  if (success) {\n    print('手机号登录成功');\n  }\n}\n```",
                "index": 4,
                "id": "PhoneNumberLogin",
                "title": "短信验证码登录",
                "content": []
              },
              {
                "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<bool> loginWithEmailCode(String email, String verificationCode, {String? captchaToken}) async {\n  try {\n    // 步骤1: 发送邮箱验证码\n    final sendBody = {\n      'email': email,\n      'target': 'ANY',  // \"ANY\" - 不限制，无论用户是否存在都发送; \"USER\" - 账号必须存在才发送\n    };\n\n    final sendHeaders = captchaToken != null ? {'x-captcha-token': captchaToken} : null;\n\n    final sendResult = await cloudbase.request(\n      'POST',\n      '/auth/v1/verification',\n      body: sendBody,\n      customHeaders: sendHeaders,\n    );\n\n    if (sendResult == null) {\n      print('发送验证码失败');\n      return false;\n    }\n\n    final verificationId = sendResult['verification_id'];\n    print('验证码发送成功! ID: $verificationId');\n\n    // 步骤2: 验证验证码\n    final verifyResult = await cloudbase.request(\n      'POST',\n      '/auth/v1/verification/verify',\n      body: {\n        'verification_id': verificationId,\n        'verification_code': verificationCode,\n      },\n    );\n\n    if (verifyResult == null) {\n      print('验证码错误');\n      return false;\n    }\n\n    final verificationToken = verifyResult['verification_token'];\n    print('验证成功!');\n\n    // 步骤3: 使用验证令牌登录\n    final loginResult = await cloudbase.request(\n      'POST',\n      '/auth/v1/signin',\n      body: {\n        'email': email,\n        'verification_token': verificationToken,\n      },\n    );\n\n    if (loginResult != null) {\n      final accessToken = loginResult['access_token'];\n      print('登录成功!');\n      cloudbase.updateAccessToken(accessToken);\n      return true;\n    }\n\n    print('登录失败');\n    return false;\n  } catch (e) {\n    print('登录失败: $e');\n    return false;\n  }\n}\n\n// 使用示例\nvoid main() async {\n  final success = await loginWithEmailCode('user@example.com', '123456');\n  if (success) {\n    print('邮箱登录成功');\n  }\n}\n```",
                "index": 5,
                "id": "email",
                "title": "邮箱验证码登录",
                "content": []
              }
            ]
          }
        ]
      }
    ],
    "_id": "36e9b7bb697c22eb0038131064a37d20",
    "_openid": "anon",
    "createdAt": 1769743083159,
    "updatedAt": 1770021219878
  },
  {
    "category": "框架集成,ORMs,SQLAlchemy",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": 43,
    "hasTemplate": false,
    "docsUrl": "https://docs.sqlalchemy.org/en/20/orm/quickstart.html",
    "content": [
      {
        "docsUrl": "",
        "markdown": "使用 `SQLAlchemy` 操作 **MySQL数据库**\n```bash\npip install sqlalchemy pymysql\n```",
        "title": "安装依赖",
        "type": "",
        "content": []
      },
      {
        "markdown": "新增如下代码到您的 **SQLAlchemy** 项目",
        "title": "使用示例",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```python\nimport os\nfrom sqlalchemy import create_engine, text\nfrom sqlalchemy.orm import sessionmaker\nfrom models import Base, Todo\n\ndef main():\n    engine = create_engine(os.getenv('DATABASE_URL'))\n\n    Session = sessionmaker(bind=engine)\n    with Session() as session:\n        todos = session.query(Todo).all()\n        print(f\"Found {len(todos)} todos\")\n\nif __name__ == '__main__':\n    main()\n```",
            "title": "main.py"
          },
          {
            "markdown": "```python\nfrom sqlalchemy import Column, Integer, String\nfrom sqlalchemy.orm import declarative_base\n\nBase = declarative_base()\n\nclass Todo(Base):\n    __tablename__ = 'todos'\n\n    _id = Column(String(255), primary_key=True)\n    title = Column(String(255))\n```",
            "title": "models.py"
          },
          {
            "markdown": "```\nDATABASE_URL=mysql+pymysql://{%DATABASE_URL%}\n```",
            "id": "mysqlString",
            "title": ".env"
          }
        ]
      }
    ],
    "_id": "5d26109469649b720bb275df69e84fde",
    "_openid": "anon",
    "createdAt": 1768201074306,
    "updatedAt": 1770105728741
  },
  {
    "category": "框架集成,前端框架,UniApp",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": 12,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/api-reference/webv2/adapter/uniapp-adapter",
    "content": [
      {
        "markdown": "`@cloudbase/js-sdk` 配合 `@cloudbase/adapter-uni-app` 可以让您在 uni-app 项目中使用 JavaScript 访问 CloudBase 服务和资源。",
        "index": 1,
        "title": "安装 SDK",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```bash\nnpm i @cloudbase/js-sdk @cloudbase/adapter-uni-app\n```",
            "index": 1,
            "title": "npm",
            "content": []
          },
          {
            "markdown": "```bash\nyarn add @cloudbase/js-sdk @cloudbase/adapter-uni-app\n```",
            "index": 2,
            "title": "yarn",
            "content": []
          },
          {
            "markdown": "```bash\npnpm add @cloudbase/js-sdk @cloudbase/adapter-uni-app\n```",
            "index": 3,
            "title": "pnpm",
            "content": []
          }
        ]
      },
      {
        "markdown": "新增如下代码到您的 uni-app 项目",
        "index": 2,
        "title": "初始化 SDK",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```js\nimport cloudbaseSDK from \"@cloudbase/js-sdk\";\nimport adapter from \"@cloudbase/adapter-uni-app\";\n\n// 传入配置选项\nconst options = {\n  uni: uni // 传入 uni 对象，用于图形验证码功能\n};\n\ncloudbaseSDK.useAdapters(adapter, options);\n\nconst cloudbase = cloudbaseSDK.init({\n  // 环境 ID\n  env: \"{%ENV_ID%}\",\n  // 地域\n  region: \"{%REGION%}\",\n  // 匿名访问令牌\n  accessKey: \"{%PUBLISHABLE_KEY%}\"\n});\n\nexport default cloudbase;\n```",
            "index": 1,
            "title": "./utils/cloudbase.js",
            "content": []
          }
        ]
      },
      {
        "sideTabs": [
          {
            "id": "pg-db",
            "title": "PostgreSQL 数据库"
          }
        ],
        "index": 3,
        "title": "调用云开发能力",
        "type": "codeTab",
        "content": [
          {
            "index": 1,
            "id": "pg-db",
            "title": "PostgreSQL 数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\nimport { cloudbase } from \"@/utils/cloudbase\";\n\n// 查询 {%TABLE_NAME%} 表前 10 条数据\nconst { data, error } = await cloudbase.rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .select(\"*\")\n  .limit(10);\n\nconsole.log(\"查询结果:\", data);\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "```js\nimport { cloudbase } from \"@/utils/cloudbase\";\n\n// 向 {%TABLE_NAME%} 表插入一条数据\n// 注意：anon 令牌（publishable key）仅有读权限，写操作需用户登录态或配置 RLS 写策略\nconst { data, error } = await cloudbase.rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .insert({ title: \"新文章\", status: \"draft\" })\n  .select();\n\nconsole.log(\"新增结果:\", data);\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "```js\nimport { cloudbase } from \"@/utils/cloudbase\";\n\n// 更新 {%TABLE_NAME%} 表中 id=1 的记录\n// 注意：anon 令牌（publishable key）仅有读权限，写操作需用户登录态或配置 RLS 写策略\nconst { data, error } = await cloudbase.rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .update({ status: \"published\" })\n  .eq(\"id\", 1)\n  .select();\n\nconsole.log(\"更新结果:\", data);\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "```js\nimport { cloudbase } from \"@/utils/cloudbase\";\n\n// 当 id 冲突时更新，否则插入\n// 注意：anon 令牌（publishable key）仅有读权限，写操作需用户登录态或配置 RLS 写策略\nconst { data, error } = await cloudbase.rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .upsert({ id: 1, title: \"标题\", status: \"published\" }, { onConflict: \"id\" })\n  .select();\n\nconsole.log(\"更新或创建结果:\", data);\n```",
                "index": 4,
                "title": "更新或创建数据"
              },
              {
                "markdown": "```js\nimport { cloudbase } from \"@/utils/cloudbase\";\n\n// 删除 {%TABLE_NAME%} 表中 id=1 的记录\n// 注意：anon 令牌（publishable key）仅有读权限，写操作需用户登录态或配置 RLS 写策略\nconst { data, error } = await cloudbase.rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .delete()\n  .eq(\"id\", 1);\n\nconsole.log(\"删除完成:\", error);\n```",
                "index": 5,
                "title": "删除数据"
              }
            ]
          },
          {
            "index": 1,
            "id": "mysql-db",
            "title": "MySQL数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\n// 查询 {%TABLE_NAME%} 表前10条数据\nconst db = cloudbase.database();\nconst res = await db.collection(\"{%TABLE_NAME%}\").limit(10).get();\nconsole.log(res.data);\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <button @click=\"getData\">查询数据</button>\n    <view v-if=\"dataList.length > 0\">\n      <view v-for=\"(item, index) in dataList\" :key=\"index\" class=\"data-item\">\n        <text>{{ JSON.stringify(item) }}</text>\n      </view>\n    </view>\n    <text v-else>暂无数据</text>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      dataList: []\n    };\n  },\n  methods: {\n    // 查询数据\n    async getData() {\n      try {\n        const { data, error } = await cloudbase\n          .database()\n          .from(\"{%TABLE_NAME%}\")\n          .select(\"*\")\n          .limit(10);\n\n        if (!error) {\n          this.dataList = data;\n          uni.showToast({\n            title: \"查询成功\",\n            icon: \"success\"\n          });\n        } else {\n          uni.showToast({\n            title: \"查询失败\",\n            icon: \"none\"\n          });\n        }\n      } catch (error) {\n        uni.showToast({\n          title: \"查询失败：\" + error.message,\n          icon: \"none\"\n        });\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\n// 新增 {%TABLE_NAME%} 表数据\nconst db = cloudbase.database();\nconst res = await db.collection(\"{%TABLE_NAME%}\").add({ title: \"示例标题\" });\nconsole.log(`新增成功! id: ${res.id}`);\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>标题：</text>\n      <input v-model=\"title\" placeholder=\"请输入标题\" />\n    </view>\n    <button :disabled=\"!title\" @click=\"addData\">新增数据</button>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      title: \"\"\n    };\n  },\n  methods: {\n    // 新增数据\n    async addData() {\n      try {\n        const { data, error } = await cloudbase\n          .database()\n          .from(\"{%TABLE_NAME%}\")\n          .insert({ title: this.title });\n\n        if (!error) {\n          uni.showToast({\n            title: \"新增成功\",\n            icon: \"success\"\n          });\n          this.title = \"\";\n        } else {\n          uni.showToast({\n            title: \"新增失败\",\n            icon: \"none\"\n          });\n        }\n      } catch (error) {\n        uni.showToast({\n          title: \"新增失败：\" + error.message,\n          icon: \"none\"\n        });\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 更新 {%TABLE_NAME%} 表中 id 为指定值的数据\nconst { error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .update({ title: \"新标题\" })\n  .eq(\"id\", \"<数据id>\");\nif (!error) {\n  console.log(\"更新成功\");\n}\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>数据ID：</text>\n      <input v-model=\"dataId\" placeholder=\"请输入数据ID\" />\n    </view>\n    <view>\n      <text>新标题：</text>\n      <input v-model=\"newTitle\" placeholder=\"请输入新标题\" />\n    </view>\n    <button :disabled=\"!dataId || !newTitle\" @click=\"updateData\">\n      更新数据\n    </button>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      dataId: \"\",\n      newTitle: \"\"\n    };\n  },\n  methods: {\n    // 更新数据\n    async updateData() {\n      try {\n        const { data, error } = await cloudbase\n          .database()\n          .from(\"{%TABLE_NAME%}\")\n          .update({ title: this.newTitle })\n          .eq(\"id\", this.dataId);\n\n        if (!error) {\n          uni.showToast({\n            title: \"更新成功\",\n            icon: \"success\"\n          });\n          this.dataId = \"\";\n          this.newTitle = \"\";\n        } else {\n          uni.showToast({\n            title: \"更新失败\",\n            icon: \"none\"\n          });\n        }\n      } catch (error) {\n        uni.showToast({\n          title: \"更新失败：\" + error.message,\n          icon: \"none\"\n        });\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 如果 {%TABLE_NAME%} 表中存在 id 为 1 的记录则更新 title 为\"示例标题\"，不存在则插入新记录\nconst { error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .upsert({ id: 1, title: \"示例标题\" });\nif (!error) {\n  console.log(\"操作成功\");\n}\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>ID：</text>\n      <input v-model=\"id\" type=\"number\" placeholder=\"请输入ID\" />\n    </view>\n    <view>\n      <text>标题：</text>\n      <input v-model=\"title\" placeholder=\"请输入标题\" />\n    </view>\n    <button :disabled=\"!id || !title\" @click=\"upsertData\">更新或创建</button>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      id: \"\",\n      title: \"\"\n    };\n  },\n  methods: {\n    // 更新或创建数据\n    async upsertData() {\n      try {\n        const { data, error } = await cloudbase\n          .database()\n          .from(\"{%TABLE_NAME%}\")\n          .upsert({ id: parseInt(this.id), title: this.title });\n\n        if (!error) {\n          uni.showToast({\n            title: \"操作成功\",\n            icon: \"success\"\n          });\n          this.id = \"\";\n          this.title = \"\";\n        } else {\n          uni.showToast({\n            title: \"操作失败\",\n            icon: \"none\"\n          });\n        }\n      } catch (error) {\n        uni.showToast({\n          title: \"操作失败：\" + error.message,\n          icon: \"none\"\n        });\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 4,
                "title": "更新或创建数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 删除 {%TABLE_NAME%} 表中 id 为指定值的数据\nconst { error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .delete()\n  .eq(\"id\", \"<数据id>\");\nif (!error) {\n  console.log(\"删除成功\");\n}\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>数据ID：</text>\n      <input v-model=\"dataId\" placeholder=\"请输入要删除的数据ID\" />\n    </view>\n    <button :disabled=\"!dataId\" @click=\"deleteData\">删除数据</button>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      dataId: \"\"\n    };\n  },\n  methods: {\n    // 删除数据\n    async deleteData() {\n      try {\n        const { data, error } = await cloudbase\n          .database()\n          .from(\"{%TABLE_NAME%}\")\n          .delete()\n          .eq(\"id\", this.dataId);\n\n        if (!error) {\n          uni.showToast({\n            title: \"删除成功\",\n            icon: \"success\"\n          });\n          this.dataId = \"\";\n        } else {\n          uni.showToast({\n            title: \"删除失败\",\n            icon: \"none\"\n          });\n        }\n      } catch (error) {\n        uni.showToast({\n          title: \"删除失败：\" + error.message,\n          icon: \"none\"\n        });\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 5,
                "title": "删除数据"
              }
            ]
          },
          {
            "index": 2,
            "id": "doc-db",
            "title": "文档型数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\n// 查询 {%TABLE_NAME%} 表前10条数据\nconst db = cloudbase.database();\nconst res = await db.collection(\"{%TABLE_NAME%}\").limit(10).get();\nconsole.log(res.data);\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <button @click=\"getData\">查询数据</button>\n    <view v-if=\"dataList.length > 0\">\n      <view v-for=\"(item, index) in dataList\" :key=\"index\" class=\"data-item\">\n        <text>{{ JSON.stringify(item) }}</text>\n      </view>\n    </view>\n    <text v-else>暂无数据</text>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      dataList: []\n    };\n  },\n  methods: {\n    // 查询数据\n    async getData() {\n      try {\n        const db = cloudbase.database();\n        const res = await db.collection(\"{%TABLE_NAME%}\").limit(10).get();\n\n        this.dataList = res.data;\n        uni.showToast({\n          title: \"查询成功\",\n          icon: \"success\"\n        });\n      } catch (error) {\n        uni.showToast({\n          title: \"查询失败：\" + error.message,\n          icon: \"none\"\n        });\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\n// 新增 {%TABLE_NAME%} 表数据\nconst db = cloudbase.database();\nconst res = await db.collection(\"{%TABLE_NAME%}\").add({ title: \"示例标题\" });\nconsole.log(`新增成功! id: ${res.id}`);\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>标题：</text>\n      <input v-model=\"title\" placeholder=\"请输入标题\" />\n    </view>\n    <button :disabled=\"!title\" @click=\"addData\">新增数据</button>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      title: \"\"\n    };\n  },\n  methods: {\n    // 新增数据\n    async addData() {\n      try {\n        const db = cloudbase.database();\n        const res = await db\n          .collection(\"{%TABLE_NAME%}\")\n          .add({ title: this.title });\n\n        uni.showToast({\n          title: `新增成功! id: ${res.id}`,\n          icon: \"success\"\n        });\n        this.title = \"\";\n      } catch (error) {\n        uni.showToast({\n          title: \"新增失败：\" + error.message,\n          icon: \"none\"\n        });\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\n// 更新 {%TABLE_NAME%} 表中 id 为指定值的数据\nconst db = cloudbase.database();\nawait db\n  .collection(\"{%TABLE_NAME%}\")\n  .doc(\"<数据id>\")\n  .update({ title: \"新标题\" });\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>数据ID：</text>\n      <input v-model=\"dataId\" placeholder=\"请输入数据ID\" />\n    </view>\n    <view>\n      <text>新标题：</text>\n      <input v-model=\"newTitle\" placeholder=\"请输入新标题\" />\n    </view>\n    <button :disabled=\"!dataId || !newTitle\" @click=\"updateData\">\n      更新数据\n    </button>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      dataId: \"\",\n      newTitle: \"\"\n    };\n  },\n  methods: {\n    // 更新数据\n    async updateData() {\n      try {\n        const db = cloudbase.database();\n        await db\n          .collection(\"{%TABLE_NAME%}\")\n          .doc(this.dataId)\n          .update({ title: this.newTitle });\n\n        uni.showToast({\n          title: \"更新成功\",\n          icon: \"success\"\n        });\n        this.dataId = \"\";\n        this.newTitle = \"\";\n      } catch (error) {\n        uni.showToast({\n          title: \"更新失败：\" + error.message,\n          icon: \"none\"\n        });\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\n// 删除 {%TABLE_NAME%} 表中 id 为指定值的数据\nconst db = cloudbase.database();\nawait db.collection(\"{%TABLE_NAME%}\").doc(\"<数据id>\").remove();\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>数据ID：</text>\n      <input v-model=\"dataId\" placeholder=\"请输入要删除的数据ID\" />\n    </view>\n    <button :disabled=\"!dataId\" @click=\"deleteData\">删除数据</button>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      dataId: \"\"\n    };\n  },\n  methods: {\n    // 删除数据\n    async deleteData() {\n      try {\n        const db = cloudbase.database();\n        await db.collection(\"{%TABLE_NAME%}\").doc(this.dataId).remove();\n\n        uni.showToast({\n          title: \"删除成功\",\n          icon: \"success\"\n        });\n        this.dataId = \"\";\n      } catch (error) {\n        uni.showToast({\n          title: \"删除失败：\" + error.message,\n          icon: \"none\"\n        });\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 4,
                "title": "删除数据"
              }
            ]
          },
          {
            "index": 3,
            "id": "data-model",
            "title": "数据模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 查询 {%TABLE_NAME%} 数据模型前10条数据\nconst res = await cloudbase.models[\"{%TABLE_NAME%}\"].list({\n  pageNumber: 1,\n  pagesize: 10\n});\nconsole.log(res.data?.records);\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <button @click=\"getData\">查询数据</button>\n    <view v-if=\"dataList.length > 0\">\n      <view v-for=\"(item, index) in dataList\" :key=\"index\" class=\"data-item\">\n        <text>{{ JSON.stringify(item) }}</text>\n      </view>\n    </view>\n    <text v-else>暂无数据</text>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      dataList: []\n    };\n  },\n  methods: {\n    // 查询数据\n    async getData() {\n      try {\n        const res = await cloudbase.models[\"{%TABLE_NAME%}\"].list({\n          pageNumber: 1,\n          pagesize: 10\n        });\n\n        this.dataList = res.data?.records || [];\n        uni.showToast({\n          title: \"查询成功\",\n          icon: \"success\"\n        });\n      } catch (error) {\n        uni.showToast({\n          title: \"查询失败：\" + error.message,\n          icon: \"none\"\n        });\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 新增 {%TABLE_NAME%} 数据模型数据\nconst res = await cloudbase.models[\"{%TABLE_NAME%}\"].create({\n  data: { title: \"示例标题\" }\n});\nconsole.log(`新增成功! id: ${res.data.id}`);\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>标题：</text>\n      <input v-model=\"title\" placeholder=\"请输入标题\" />\n    </view>\n    <button :disabled=\"!title\" @click=\"addData\">新增数据</button>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      title: \"\"\n    };\n  },\n  methods: {\n    // 新增数据\n    async addData() {\n      try {\n        const res = await cloudbase.models[\"{%TABLE_NAME%}\"].create({\n          data: { title: this.title }\n        });\n\n        uni.showToast({\n          title: `新增成功! id: ${res.data.id}`,\n          icon: \"success\"\n        });\n        this.title = \"\";\n      } catch (error) {\n        uni.showToast({\n          title: \"新增失败：\" + error.message,\n          icon: \"none\"\n        });\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 更新 {%TABLE_NAME%} 数据模型中 _id 为指定值的数据\nawait cloudbase.models[\"{%TABLE_NAME%}\"].update({\n  data: { title: \"新标题\" },\n  filter: { where: { _id: { $eq: \"<数据id>\" } } }\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>数据ID：</text>\n      <input v-model=\"dataId\" placeholder=\"请输入数据ID\" />\n    </view>\n    <view>\n      <text>新标题：</text>\n      <input v-model=\"newTitle\" placeholder=\"请输入新标题\" />\n    </view>\n    <button :disabled=\"!dataId || !newTitle\" @click=\"updateData\">\n      更新数据\n    </button>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      dataId: \"\",\n      newTitle: \"\"\n    };\n  },\n  methods: {\n    // 更新数据\n    async updateData() {\n      try {\n        await cloudbase.models[\"{%TABLE_NAME%}\"].update({\n          data: { title: this.newTitle },\n          filter: { where: { _id: { $eq: this.dataId } } }\n        });\n\n        uni.showToast({\n          title: \"更新成功\",\n          icon: \"success\"\n        });\n        this.dataId = \"\";\n        this.newTitle = \"\";\n      } catch (error) {\n        uni.showToast({\n          title: \"更新失败：\" + error.message,\n          icon: \"none\"\n        });\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 删除 {%TABLE_NAME%} 数据模型中 _id 为指定值的数据\nawait cloudbase.models[\"{%TABLE_NAME%}\"].delete({\n  filter: { where: { _id: { $eq: \"<数据id>\" } } }\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>数据ID：</text>\n      <input v-model=\"dataId\" placeholder=\"请输入要删除的数据ID\" />\n    </view>\n    <button :disabled=\"!dataId\" @click=\"deleteData\">删除数据</button>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      dataId: \"\"\n    };\n  },\n  methods: {\n    // 删除数据\n    async deleteData() {\n      try {\n        await cloudbase.models[\"{%TABLE_NAME%}\"].delete({\n          filter: { where: { _id: { $eq: this.dataId } } }\n        });\n\n        uni.showToast({\n          title: \"删除成功\",\n          icon: \"success\"\n        });\n        this.dataId = \"\";\n      } catch (error) {\n        uni.showToast({\n          title: \"删除失败：\" + error.message,\n          icon: \"none\"\n        });\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 4,
                "title": "删除数据"
              }
            ]
          },
          {
            "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\n// 调用 {%FUNCTION_NAME%} 云函数\nconst res = await cloudbase.callFunction({\n  name: \"{%FUNCTION_NAME%}\",\n  data: {}\n});\nconsole.log(res.result);\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <button @click=\"callFunction\">调用云函数</button>\n    <view v-if=\"result\">\n      <text>返回结果：</text>\n      <text>{{ JSON.stringify(result) }}</text>\n    </view>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      result: null\n    };\n  },\n  methods: {\n    // 调用云函数\n    async callFunction() {\n      try {\n        const res = await cloudbase.callFunction({\n          name: \"{%FUNCTION_NAME%}\",\n          data: {}\n        });\n\n        this.result = res.result;\n        uni.showToast({\n          title: \"调用成功\",\n          icon: \"success\"\n        });\n      } catch (error) {\n        uni.showToast({\n          title: \"调用失败：\" + error.message,\n          icon: \"none\"\n        });\n      }\n    }\n  }\n};\n</script>\n```",
            "index": 4,
            "id": "scf",
            "title": "云函数",
            "content": []
          },
          {
            "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 调用 {%SERVICE_NAME%} 云托管服务\nconst res = await cloudbase.callContainer({\n  name: \"{%SERVICE_NAME%}\"\n  method: 'POST',\n  path: '/',\n  header:{\n    'Content-Type': 'application/json; charset=utf-8'\n  },\n  data: {},\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <button @click=\"callRun\">调用云托管</button>\n    <view v-if=\"result\">\n      <text>返回结果：</text>\n      <text>{{ JSON.stringify(result) }}</text>\n    </view>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      result: null\n    };\n  },\n  methods: {\n    // 调用云托管\n    async callRun() {\n      try {\n        // 调用 {%SERVICE_NAME%} 云托管服务\n        const res = await cloudbase.callContainer({\n          name: \"{%SERVICE_NAME%}\"\n          method: 'POST',\n          path: '/',\n          header:{\n            'Content-Type': 'application/json; charset=utf-8'\n          },\n          data: {},\n        });\n\n        this.result = res;\n        uni.showToast({\n          title: \"调用成功\",\n          icon: \"success\"\n        });\n      } catch (error) {\n        uni.showToast({\n          title: \"调用失败：\" + error.message,\n          icon: \"none\"\n        });\n      }\n    }\n  }\n};\n</script>\n```",
            "index": 5,
            "id": "run",
            "title": "云托管",
            "content": []
          },
          {
            "index": 6,
            "id": "storage",
            "title": "云存储",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst res = await cloudbase.uploadFile({\n  cloudPath: `images/${Date.now()}-${file.name}`, // 上传至云端的路径\n  filePath: file\n});\nconsole.log(res.fileID);\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <button @click=\"uploadFile\">选择并上传图片</button>\n    <view v-if=\"fileId\">\n      <text>上传成功！</text>\n      <text>文件ID: {{ fileId }}</text>\n    </view>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      fileId: \"\"\n    };\n  },\n  methods: {\n    // 上传文件\n    async uploadFile() {\n      uni.chooseImage({\n        count: 1,\n        success: async chooseImageRes => {\n          try {\n            uni.showLoading({\n              title: \"上传中...\"\n            });\n\n            const tempFilePath = chooseImageRes.tempFilePaths[0];\n            const cloudPath = `images/${Date.now()}-${Math.random()}.png`;\n\n            const res = await cloudbase.uploadFile({\n              cloudPath: cloudPath,\n              filePath: tempFilePath\n            });\n\n            this.fileId = res.fileID;\n            uni.hideLoading();\n            uni.showToast({\n              title: \"上传成功\",\n              icon: \"success\"\n            });\n          } catch (error) {\n            uni.hideLoading();\n            uni.showToast({\n              title: \"上传失败：\" + error.message,\n              icon: \"none\"\n            });\n          }\n        }\n      });\n    }\n  }\n};\n</script>\n```",
                "index": 1,
                "title": "上传文件"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst res = await cloudbase.getTempFileURL({\n  fileList: [\"cloud://xxx.png\"] // 文件 fileID 列表\n});\nconsole.log(res.fileList[0].tempFileURL);\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>文件ID：</text>\n      <input v-model=\"fileId\" placeholder=\"请输入文件ID (cloud://xxx.png)\" />\n    </view>\n    <button :disabled=\"!fileId\" @click=\"getFileUrl\">获取文件链接</button>\n    <view v-if=\"fileUrl\">\n      <text>文件链接：</text>\n      <text>{{ fileUrl }}</text>\n      <image :src=\"fileUrl\" mode=\"aspectFit\"></image>\n    </view>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      fileId: \"\",\n      fileUrl: \"\"\n    };\n  },\n  methods: {\n    // 获取文件链接\n    async getFileUrl() {\n      try {\n        const res = await cloudbase.getTempFileURL({\n          fileList: [this.fileId]\n        });\n\n        this.fileUrl = res.fileList[0].tempFileURL;\n        uni.showToast({\n          title: \"获取成功\",\n          icon: \"success\"\n        });\n      } catch (error) {\n        uni.showToast({\n          title: \"获取失败：\" + error.message,\n          icon: \"none\"\n        });\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 2,
                "title": "获取文件链接"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nawait cloudbase.downloadFile({\n  fileID: \"cloud://xxx.png\" // 文件 fileID\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>文件ID：</text>\n      <input v-model=\"fileId\" placeholder=\"请输入文件ID (cloud://xxx.png)\" />\n    </view>\n    <button :disabled=\"!fileId\" @click=\"downloadFile\">下载文件</button>\n    <view v-if=\"localPath\">\n      <text>下载成功！</text>\n      <text>本地路径: {{ localPath }}</text>\n    </view>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      fileId: \"\",\n      localPath: \"\"\n    };\n  },\n  methods: {\n    // 下载文件\n    async downloadFile() {\n      try {\n        uni.showLoading({\n          title: \"下载中...\"\n        });\n\n        const res = await cloudbase.downloadFile({\n          fileID: this.fileId\n        });\n\n        this.localPath = res.tempFilePath;\n        uni.hideLoading();\n        uni.showToast({\n          title: \"下载成功\",\n          icon: \"success\"\n        });\n      } catch (error) {\n        uni.hideLoading();\n        uni.showToast({\n          title: \"下载失败：\" + error.message,\n          icon: \"none\"\n        });\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 3,
                "title": "下载文件"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst res = await cloudbase.deleteFile({\n  fileList: [\"cloud://xxx.png\"] // 文件 fileID 列表\n});\nif (res.fileList[0].code === \"SUCCESS\") {\n  console.log(\"删除成功\");\n}\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>文件ID：</text>\n      <input v-model=\"fileId\" placeholder=\"请输入文件ID (cloud://xxx.png)\" />\n    </view>\n    <button :disabled=\"!fileId\" @click=\"deleteFile\">删除文件</button>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      fileId: \"\"\n    };\n  },\n  methods: {\n    // 删除文件\n    async deleteFile() {\n      try {\n        const res = await cloudbase.deleteFile({\n          fileList: [this.fileId]\n        });\n\n        if (res.fileList[0].code === \"SUCCESS\") {\n          uni.showToast({\n            title: \"删除成功\",\n            icon: \"success\"\n          });\n          this.fileId = \"\";\n        } else {\n          uni.showToast({\n            title: \"删除失败\",\n            icon: \"none\"\n          });\n        }\n      } catch (error) {\n        uni.showToast({\n          title: \"删除失败：\" + error.message,\n          icon: \"none\"\n        });\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 4,
                "title": "删除文件"
              }
            ]
          },
          {
            "index": 7,
            "id": "ai-model",
            "title": "大模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst res = await cloudbase\n  .ai()\n  .createModel(\"{%AI_MODEL_NAME%}\")\n  .streamText({\n    model: \"{%AI_SUB_MODEL_NAME%}\",\n    messages: [{ role: \"user\", content: \"你好\" }]\n  });\n\nfor await (let data of res.dataStream) {\n  // 如果有则打印思维链内容\n  const think = data?.choices?.[0]?.delta?.reasoning_content;\n  if (think) console.log(think);\n\n  // 打印生成文本内容\n  const text = data?.choices?.[0]?.delta?.content;\n  if (text) console.log(text);\n}\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>输入主题：</text>\n      <input v-model=\"input\" placeholder=\"请输入主题，如：春天\" />\n    </view>\n    <button :disabled=\"!input || isGenerating\" @click=\"callAIModel\">\n      生成内容\n    </button>\n    <view v-if=\"response\">\n      <text>生成结果：</text>\n      <text>{{ response }}</text>\n    </view>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      input: \"\",\n      response: \"\",\n      isGenerating: false\n    };\n  },\n  methods: {\n    // 调用大模型\n    async callAIModel() {\n      this.isGenerating = true;\n      this.response = \"\";\n\n      try {\n        // 确保已登录\n        const loginState = await cloudbase.auth().getLoginState();\n        if (!loginState) {\n          await cloudbase.auth().signInAnonymously();\n        }\n\n        uni.showLoading({\n          title: \"生成中...\"\n        });\n\n        const res = await cloudbase\n          .ai()\n          .createModel(\"<YOUR_AI_MODEL_NAME>\")\n          .streamText({\n            model: \"<YOUR_AI_SUB_MODEL_NAME>\",\n            messages: [{ role: \"user\", content: this.input }]\n          });\n\n        for await (let str of res.textStream) {\n          this.response += str;\n        }\n\n        uni.hideLoading();\n        uni.showToast({\n          title: \"生成完成\",\n          icon: \"success\"\n        });\n      } catch (err) {\n        uni.hideLoading();\n        uni.showToast({\n          title: \"生成失败：\" + err.message,\n          icon: \"none\"\n        });\n      } finally {\n        this.isGenerating = false;\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 1,
                "id": "text-aiModel",
                "title": "生文模型"
              },
              {
                "markdown": "生图模型通过调用云函数来实现，在生图模型页面点击「一键创建云函数」，函数调用示例如下：\n\n**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 调用生图云函数\nconst res = await cloudbase.callFunction({\n  name: \"<YOUR_FUNCTION_NAME>\",\n  data: {\n    prompt: \"一只可爱的猫咪在阳光下玩耍\"\n  }\n});\n\nconst result = res.result;\n\nif (result.success) {\n  // 生成成功\n  console.log(\"生成成功!\");\n  console.log(\"图片URL:\", result.imageUrl);\n  console.log(\"优化后的提示词:\", result.revised_prompt);\n\n  // 使用图片\n  // 注意：图片URL有效期为24小时，请及时保存或转存\n} else {\n  // 生成失败\n  console.error(\"生成失败:\", result.code, result.message);\n}\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>图片描述：</text>\n      <input v-model=\"prompt\" placeholder=\"请输入图片描述\" />\n    </view>\n    <button :disabled=\"!prompt || loading\" @click=\"generateImage\">\n      {{ loading ? \"生成中...\" : \"生成图片\" }}\n    </button>\n    <view v-if=\"message\">\n      <text :style=\"{ color: message.includes('成功') ? 'green' : 'red' }\">\n        {{ message }}\n      </text>\n    </view>\n    <view v-if=\"imageUrl\">\n      <image :src=\"imageUrl\" mode=\"aspectFit\" style=\"width: 100%\"></image>\n      <text style=\"font-size: 12px; color: #666\">\n        注意：图片URL有效期为24小时，请及时保存\n      </text>\n    </view>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      prompt: \"\",\n      imageUrl: \"\",\n      message: \"\",\n      loading: false\n    };\n  },\n  methods: {\n    // 生成图片\n    async generateImage() {\n      this.loading = true;\n      this.message = \"\";\n      this.imageUrl = \"\";\n\n      try {\n        uni.showLoading({\n          title: \"生成中...\"\n        });\n\n        // 调用生图云函数\n        const res = await cloudbase.callFunction({\n          name: \"<YOUR_FUNCTION_NAME>\",\n          data: {\n            prompt: this.prompt\n          }\n        });\n\n        const result = res.result;\n\n        if (result.success) {\n          this.imageUrl = result.imageUrl;\n          this.message = \"生成成功！\";\n          uni.hideLoading();\n          uni.showToast({\n            title: \"生成成功\",\n            icon: \"success\"\n          });\n        } else {\n          this.message = `生成失败：${result.message}`;\n          uni.hideLoading();\n          uni.showToast({\n            title: \"生成失败\",\n            icon: \"none\"\n          });\n        }\n      } catch (error) {\n        this.message = \"调用失败：\" + error.message;\n        uni.hideLoading();\n        uni.showToast({\n          title: \"调用失败\",\n          icon: \"none\"\n        });\n      } finally {\n        this.loading = false;\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 2,
                "id": "image-aiModel",
                "title": "生图模型"
              }
            ]
          },
          {
            "markdown": "",
            "index": 8,
            "id": "agent",
            "title": "Agent",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from './utils/cloudbase';\n\nconst res = await cloudbase.ai().bot.sendMessage({\n  botId: '{%AGENT_ID%}',\n  // 入参结构参考前后端通信协议：\n  //  https://docs.cloudbase.net/ai/agent/http-agent-protocol\n  threadId: '550e8400-e29b-41d4-a716-446655440000',\n  runId: 'run_001',\n  messages: [\n    {\n      id: 'msg_001',\n      role: 'user',\n      content: '你好',\n    },\n  ],\n  tools: [],\n  context: [],\n  state: {},\n  forwardedProps: {},\n});\n\nfor await (const data of res.dataStream) {\n  // 如果有则打印思维链内容\n  const think = data.reasoning_content;\n  if (think) console.log(think);\n\n  // 打印输出正文\n  const content = data.content;\n  if (content) console.log(content);\n}\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>输入问题：</text>\n      <input v-model=\"input\" placeholder=\"请输入问题，如：你是谁\" />\n    </view>\n    <button :disabled=\"!input || isGenerating\" @click=\"callAgent\">\n      发送消息\n    </button>\n    <view v-if=\"response\">\n      <text>回答：</text>\n      <text>{{ response }}</text>\n    </view>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      input: \"\",\n      response: \"\",\n      isGenerating: false\n    };\n  },\n  methods: {\n    // 调用Agent\n    async callAgent() {\n      this.isGenerating = true;\n      this.response = \"\";\n\n      try {\n        // 确保已登录\n        const loginState = await cloudbase.auth().getLoginState();\n        if (!loginState) {\n          await cloudbase.auth().signInAnonymously();\n        }\n\n        uni.showLoading({\n          title: \"生成中...\"\n        });\n\n        const res = await cloudbase.ai().bot.sendMessage({\n          botId: \"{%AGENT_ID%}\",\n          // 入参结构参考前后端通信协议：\n          //  https://docs.cloudbase.net/ai/agent/http-agent-protocol\n          threadId: '550e8400-e29b-41d4-a716-446655440000',\n          runId: 'run_001',\n          messages: [\n            {\n              id: 'msg_001',\n              role: 'user',\n              content: '你好',\n            },\n          ],\n          tools: [],\n          context: [],\n          state: {},\n          forwardedProps: {},\n        });\n\n        for await (const data of res.dataStream) {\n          // 如果有则打印思维链内容\n          const think = data.reasoning_content;\n          if (think) this.response += think;\n\n          // 打印输出正文\n          const content = data.content;\n          if (content) this.response += content;\n        }\n\n        uni.hideLoading();\n        uni.showToast({\n          title: \"生成完成\",\n          icon: \"success\"\n        });\n      } catch (err) {\n        uni.hideLoading();\n        uni.showToast({\n          title: \"生成失败：\" + err.message,\n          icon: \"none\"\n        });\n      } finally {\n        this.isGenerating = false;\n      }\n    }\n  }\n};\n</script>\n\n```",
                "index": 0,
                "id": "scf",
                "title": "函数型"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst res = await cloudbase.ai().bot.sendMessage({\n  botId: \"{%AGENT_ID%}\",\n  msg: \"你好\"\n});\n\nfor await (const data of res.dataStream) {\n  // 如果有则打印思维链内容\n  const think = data.reasoning_content;\n  if (think) console.log(think);\n\n  // 打印输出正文\n  const content = data.content;\n  if (content) console.log(content);\n}\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>输入问题：</text>\n      <input v-model=\"input\" placeholder=\"请输入问题，如：你是谁\" />\n    </view>\n    <button :disabled=\"!input || isGenerating\" @click=\"callAgent\">\n      发送消息\n    </button>\n    <view v-if=\"response\">\n      <text>回答：</text>\n      <text>{{ response }}</text>\n    </view>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      input: \"\",\n      response: \"\",\n      isGenerating: false\n    };\n  },\n  methods: {\n    // 调用Agent\n    async callAgent() {\n      this.isGenerating = true;\n      this.response = \"\";\n\n      try {\n        // 确保已登录\n        const loginState = await cloudbase.auth().getLoginState();\n        if (!loginState) {\n          await cloudbase.auth().signInAnonymously();\n        }\n\n        uni.showLoading({\n          title: \"生成中...\"\n        });\n\n        const res = await cloudbase.ai().bot.sendMessage({\n          botId: \"{%AGENT_ID%}\",\n          msg: \"你好\"\n        });\n\n        for await (const data of res.dataStream) {\n          // 如果有则打印思维链内容\n          const think = data.reasoning_content;\n          if (think) this.response += think;\n\n          // 打印输出正文\n          const content = data.content;\n          if (content) this.response += content;\n        }\n\n        uni.hideLoading();\n        uni.showToast({\n          title: \"生成完成\",\n          icon: \"success\"\n        });\n      } catch (err) {\n        uni.hideLoading();\n        uni.showToast({\n          title: \"生成失败：\" + err.message,\n          icon: \"none\"\n        });\n      } finally {\n        this.isGenerating = false;\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 1,
                "id": "baas",
                "title": "普通型"
              }
            ]
          },
          {
            "index": 9,
            "id": "identity",
            "title": "身份认证",
            "type": "sideTab",
            "content": [
              {
                "markdown": "使用 **短信验证码注册** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **短信验证码**\n\n**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ phone_number: phone });\n\n// 验证验证码\nconst verifyRes = await auth.verify({\n  verification_id: verificationId,\n  verification_code: code\n});\n\n// 注册（如用户已存在则自动登录）\nawait auth.signUp({\n  phone_number: `+86 ${phone}`,\n  verification_code: code,\n  verification_token: verifyRes.verification_token,\n  name: `user_${phone.slice(-4)}`,\n  password: \"admin@123\"\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>手机号：</text>\n      <input v-model=\"phone\" placeholder=\"13800000000\" />\n    </view>\n    <view>\n      <text>验证码：</text>\n      <input v-model=\"code\" placeholder=\"验证码\" />\n      <button :disabled=\"!phone\" @click=\"sendCode\">发送验证码</button>\n    </view>\n    <button :disabled=\"!verificationId || !code\" @click=\"register\">注册</button>\n    <text\n      v-if=\"message\"\n      :style=\"{ color: message.includes('成功') ? 'green' : 'red' }\"\n      >{{ message }}</text\n    >\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      phone: \"\",\n      code: \"\",\n      verificationId: \"\",\n      message: \"\"\n    };\n  },\n  methods: {\n    // 发送验证码\n    async sendCode() {\n      try {\n        const auth = cloudbase.auth();\n        const res = await auth.getVerification({ phone_number: this.phone });\n        this.verificationId = res.verification_id;\n        this.message = \"验证码已发送！\";\n      } catch (error) {\n        this.message = \"发送失败：\" + error.message;\n      }\n    },\n\n    // 注册\n    async register() {\n      try {\n        const auth = cloudbase.auth();\n        // 验证验证码\n        const verifyRes = await auth.verify({\n          verification_id: this.verificationId,\n          verification_code: this.code\n        });\n        // 注册（如用户已存在则自动登录）\n        await auth.signUp({\n          phone_number: `+86 ${this.phone}`,\n          verification_code: this.code,\n          verification_token: verifyRes.verification_token,\n          name: `user_${this.phone.slice(-4)}`,\n          password: \"admin@123\"\n        });\n        this.message = \"注册成功！\";\n      } catch (error) {\n        this.message = \"注册失败：\" + error.message;\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 1,
                "title": "短信验证码注册"
              },
              {
                "markdown": "使用 **邮箱验证码注册** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **邮箱验证码**\n\n**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ email });\n\n// 验证验证码\nconst verifyRes = await auth.verify({\n  verification_id: verificationId,\n  verification_code: code\n});\n\n// 注册（如用户已存在则自动登录）\nawait auth.signUp({\n  email,\n  verification_code: code,\n  verification_token: verifyRes.verification_token,\n  name: `user_${email.slice(-4)}`,\n  password: \"admin@123\"\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>邮箱：</text>\n      <input v-model=\"email\" placeholder=\"example@email.com\" />\n    </view>\n    <view>\n      <text>验证码：</text>\n      <input v-model=\"code\" placeholder=\"验证码\" />\n      <button :disabled=\"!email\" @click=\"sendCode\">发送验证码</button>\n    </view>\n    <button :disabled=\"!verificationId || !code\" @click=\"register\">注册</button>\n    <text\n      v-if=\"message\"\n      :style=\"{ color: message.includes('成功') ? 'green' : 'red' }\"\n      >{{ message }}</text\n    >\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      email: \"\",\n      code: \"\",\n      verificationId: \"\",\n      message: \"\"\n    };\n  },\n  methods: {\n    // 发送验证码\n    async sendCode() {\n      try {\n        const auth = cloudbase.auth();\n        const res = await auth.getVerification({ email: this.email });\n        this.verificationId = res.verification_id;\n        this.message = \"验证码已发送！\";\n      } catch (error) {\n        this.message = \"发送失败：\" + error.message;\n      }\n    },\n\n    // 注册\n    async register() {\n      try {\n        const auth = cloudbase.auth();\n        // 验证验证码\n        const verifyRes = await auth.verify({\n          verification_id: this.verificationId,\n          verification_code: this.code\n        });\n        // 注册（如用户已存在则自动登录）\n        await auth.signUp({\n          email: this.email,\n          verification_code: this.code,\n          verification_token: verifyRes.verification_token,\n          name: `user_${this.email.slice(-4)}`,\n          password: \"admin@123\"\n        });\n        this.message = \"注册成功！\";\n      } catch (error) {\n        this.message = \"注册失败：\" + error.message;\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 2,
                "title": "邮箱验证码注册"
              },
              {
                "markdown": "使用 **账号密码登录** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **用户名密码登录**\n\n**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\nawait auth.signIn({\n  username, // 可以是用户名、手机号或邮箱\n  password\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>账号：</text>\n      <input v-model=\"username\" placeholder=\"用户名/手机号/邮箱\" />\n      <text>注：手机号登录请添加区号 +86</text>\n    </view>\n    <view>\n      <text>密码：</text>\n      <input type=\"password\" v-model=\"password\" placeholder=\"请输入密码\" />\n    </view>\n    <button :disabled=\"!username || !password\" @click=\"login\">登录</button>\n    <text\n      v-if=\"message\"\n      :style=\"{ color: message.includes('成功') ? 'green' : 'red' }\"\n      >{{ message }}</text\n    >\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      username: \"\",\n      password: \"\",\n      message: \"\"\n    };\n  },\n  methods: {\n    // 登录\n    async login() {\n      try {\n        const auth = cloudbase.auth();\n        await auth.signIn({\n          username: this.username, // 可以是用户名、手机号或邮箱\n          password: this.password\n        });\n        this.message = \"登录成功！\";\n      } catch (error) {\n        this.message = \"登录失败：\" + error.message;\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 3,
                "id": "UserNameLogin",
                "title": "账号密码登录"
              },
              {
                "markdown": "使用 **短信验证码登录** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **短信验证码登录**\n\n**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ phone_number: `+86 ${phone}` });\n\n// 登录\nawait auth.signInWithSms({\n  verificationInfo: res,\n  verificationCode: code,\n  phoneNum: `+86 ${phone}`\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>手机号：</text>\n      <input v-model=\"phone\" placeholder=\"13800000000\" />\n    </view>\n    <view>\n      <text>验证码：</text>\n      <input v-model=\"code\" placeholder=\"验证码\" />\n      <button @click=\"sendCode\" :disabled=\"!phone\">发送验证码</button>\n    </view>\n    <button @click=\"login\" :disabled=\"!verificationInfo || !code\">登录</button>\n    <text\n      v-if=\"message\"\n      :style=\"{ color: message.includes('成功') ? 'green' : 'red' }\"\n      >{{ message }}</text\n    >\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      phone: \"\",\n      code: \"\",\n      verificationInfo: null,\n      message: \"\"\n    };\n  },\n  methods: {\n    // 发送验证码\n    async sendCode() {\n      try {\n        const auth = cloudbase.auth();\n        const res = await auth.getVerification({\n          phone_number: `+86 ${this.phone}`\n        });\n        this.verificationInfo = res;\n        this.message = \"验证码已发送！\";\n      } catch (error) {\n        this.message = \"发送失败：\" + error.message;\n      }\n    },\n\n    // 登录\n    async login() {\n      try {\n        const auth = cloudbase.auth();\n        await auth.signInWithSms({\n          verificationInfo: this.verificationInfo,\n          verificationCode: this.code,\n          phoneNum: `+86 ${this.phone}`\n        });\n        this.message = \"登录成功！\";\n      } catch (error) {\n        this.message = \"登录失败：\" + error.message;\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 4,
                "id": "PhoneNumberLogin",
                "title": "短信验证码登录"
              },
              {
                "markdown": "使用 **邮箱验证码登录** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **邮箱验证码**\n\n**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ email });\n\n// 登录\nawait auth.signInWithEmail({\n  verificationInfo: res,\n  verificationCode: code,\n  email\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>邮箱：</text>\n      <input v-model=\"email\" placeholder=\"example@email.com\" />\n    </view>\n    <view>\n      <text>验证码：</text>\n      <input v-model=\"code\" placeholder=\"验证码\" />\n      <button @click=\"sendCode\" :disabled=\"!email\">发送验证码</button>\n    </view>\n    <button @click=\"login\" :disabled=\"!verificationInfo || !code\">登录</button>\n    <text\n      v-if=\"message\"\n      :style=\"{ color: message.includes('成功') ? 'green' : 'red' }\"\n      >{{ message }}</text\n    >\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      email: \"\",\n      code: \"\",\n      verificationInfo: null,\n      message: \"\"\n    };\n  },\n  methods: {\n    // 发送验证码\n    async sendCode() {\n      try {\n        const auth = cloudbase.auth();\n        const res = await auth.getVerification({ email: this.email });\n        this.verificationInfo = res;\n        this.message = \"验证码已发送！\";\n      } catch (error) {\n        this.message = \"发送失败：\" + error.message;\n      }\n    },\n\n    // 登录\n    async login() {\n      try {\n        const auth = cloudbase.auth();\n        await auth.signInWithEmail({\n          verificationInfo: this.verificationInfo,\n          verificationCode: this.code,\n          email: this.email\n        });\n        this.message = \"登录成功！\";\n      } catch (error) {\n        this.message = \"登录失败：\" + error.message;\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 5,
                "id": "email",
                "title": "邮箱验证码登录"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 手机号授权登录\nconst loginResult = await auth.signInWithPhoneAuth(code);\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <button open-type=\"getPhoneNumber\" @getphonenumber=\"handleGetPhoneNumber\">\n      微信小程序登录\n    </button>\n  </view>\n</template>\n\n<script>\nimport cloudbase from './utils/cloudbase';\n\nexport default {\n  data() {\n    return {}\n  },\n  methods: {\n    async handleGetPhoneNumber(event) {\n      if(!event.detail.code) {\n        console.error('获取手机号失败:', event.detail.errMsg);\n        uni.showToast({\n          title: '获取手机号失败',\n          icon: 'none'\n        });\n        return\n      }\n      console.log('获取到动态令牌(code):', event.detail.code);\n      uni.showLoading({\n        title: '登录中...'\n      });\n      try {\n        // 手机号授权登录\n        const auth = cloudbase.auth();\n        const loginResult = await auth.signInWithPhoneAuth( event.detail.code );\n        console.log('手机号授权登录结果:', loginResult);\n        uni.hideLoading();\n        uni.showToast({\n          title: '登录成功',\n          icon: 'success'\n        });\n      } catch (error: any) {\n        // 处理登录失败\n        console.error('手机号授权登录失败:', error);\n        uni.showToast({\n          title: error.message || '登录失败',\n          icon: 'none'\n        });\n      } finally {\n        uni.hideLoading();\n      }\n    }\n  }\n}\n</script>\n```",
                "index": 6,
                "title": "小程序手机号登录"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 微信 OpenID 登录\nconst loginResult = await auth.signInWithOpenId();\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <button @click=\"openIdLogin\">微信小程序登录</button>\n  </view>\n</template>\n\n<script>\nimport cloudbase from './utils/cloudbase';\n\nexport default {\n  data() {\n    return {}\n  },\n  methods: {\n    async openIdLogin() {\n      uni.showLoading({\n        title: '正在登录...'\n      });\n\n      try {\n        const auth = cloudbase.auth();\n        const loginResult = await auth.signInWithOpenId();\n        console.log('微信 OpenID 登录成功:', loginResult);\n        uni.hideLoading();\n\n        uni.showToast({\n          title: '登录成功',\n          icon: 'success'\n        });\n      } catch (error: any) {\n        uni.hideLoading();\n        console.error('微信 OpenID 登录失败:', error);\n        uni.showToast({\n          title: error.message || '登录失败，请重试',\n          icon: 'none'\n        });\n      }\n    }\n  }\n}\n</script>\n```",
                "index": 7,
                "title": "微信 OpenID 登录"
              }
            ]
          }
        ]
      }
    ],
    "_id": "5d2610946964bddf0bb68bc90de72b0d",
    "_openid": "anon",
    "createdAt": 1768209887018,
    "updatedAt": 1770372310807
  },
  {
    "category": "框架集成,小程序 / 小游戏,微信小游戏,原生API",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": 2,
    "hasTemplate": false,
    "docsUrl": "https://developers.weixin.qq.com/minigame/dev/wxcloud/",
    "content": [
      {
        "markdown": "在 `game.js` 中初始化云开发：",
        "index": 1,
        "title": "初始化 SDK",
        "type": "codeTab",
        "content": [
          {
            "markdown": "大部分云开发能力可通过 `小游戏原生 API` 直接调用，无需安装 SDK，若 `原生API` 不支持请使用 `Client SDK` 进行调用\n\n```js\nwx.cloud.init({\n  env: \"{%ENV_ID%}\"\n});\n```",
            "index": 1,
            "title": "原生API 初始化",
            "content": []
          },
          {
            "markdown": "**安装**\n\n使用 Client SDK 前请先安装 SDK\n\n在小游戏 `package.json` 所在目录（通常为游戏根目录）执行：\n\n```bash\nnpm i @cloudbase/wx-cloud-client-sdk --save\n```\n\n安装完成后，在微信开发者工具点击 **工具 → 构建 npm**。\n\n**初始化**\n\n```js\nconst { init } = require(\"@cloudbase/wx-cloud-client-sdk\");\n\nwx.cloud.init({\n  env: \"{%ENV_ID%}\"\n});\n\nconst cloudbase = init(wx.cloud);\n```",
            "index": 2,
            "title": "Client SDK 初始化",
            "content": []
          }
        ]
      },
      {
        "sideTabs": [
          {
            "id": "pg-db",
            "title": "PostgreSQL 数据库"
          }
        ],
        "index": 2,
        "title": "调用云开发能力",
        "type": "codeTab",
        "content": [
          {
            "index": 1,
            "id": "pg-db",
            "title": "PostgreSQL 数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\n// 查询 {%TABLE_NAME%} 表前 10 条数据\nconst { data, error } = await wx.cloud.rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .select(\"*\")\n  .limit(10);\n\nconsole.log(\"查询结果:\", data);\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "```js\n// 向 {%TABLE_NAME%} 表插入一条数据\n// 注意：anon 令牌（publishable key）仅有读权限，写操作需用户登录态或配置 RLS 写策略\nconst { data, error } = await wx.cloud.rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .insert({ title: \"新文章\", status: \"draft\" })\n  .select();\n\nconsole.log(\"新增结果:\", data);\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "```js\n// 更新 {%TABLE_NAME%} 表中 id=1 的记录\n// 注意：anon 令牌（publishable key）仅有读权限，写操作需用户登录态或配置 RLS 写策略\nconst { data, error } = await wx.cloud.rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .update({ status: \"published\" })\n  .eq(\"id\", 1)\n  .select();\n\nconsole.log(\"更新结果:\", data);\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "```js\n// 当 id 冲突时更新，否则插入\n// 注意：anon 令牌（publishable key）仅有读权限，写操作需用户登录态或配置 RLS 写策略\nconst { data, error } = await wx.cloud.rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .upsert({ id: 1, title: \"标题\", status: \"published\" }, { onConflict: \"id\" })\n  .select();\n\nconsole.log(\"更新或创建结果:\", data);\n```",
                "index": 4,
                "title": "更新或创建数据"
              },
              {
                "markdown": "```js\n// 删除 {%TABLE_NAME%} 表中 id=1 的记录\n// 注意：anon 令牌（publishable key）仅有读权限，写操作需用户登录态或配置 RLS 写策略\nconst { data, error } = await wx.cloud.rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .delete()\n  .eq(\"id\", 1);\n\nconsole.log(\"删除完成:\", error);\n```",
                "index": 5,
                "title": "删除数据"
              }
            ]
          },
          {
            "markdown": "请使用 `Client SDK` 进行调用",
            "index": 1,
            "id": "mysql-db",
            "title": "MySQL数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\n// 查询 {%TABLE_NAME%} 表前10条数据\nconst { data, error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .select(\"*\")\n  .limit(10);\n\nconsole.log(\"查询结果:\", data);\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "```js\n// 新增 {%TABLE_NAME%} 表数据\nconst { data, error } = await cloudbase.rdb().from(\"{%TABLE_NAME%}\").insert({\n  title: \"示例标题\"\n});\n\nconsole.log(\"新增结果:\", error ? \"失败\" : \"成功\");\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "```js\n// 更新 {%TABLE_NAME%} 表中 id 为 <数据ID> 的数据\nconst { data, error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .update({\n    title: \"更新后的标题\"\n  })\n  .eq(\"id\", \"<数据ID>\");\n\nconsole.log(\"更新结果:\", error ? \"失败\" : \"成功\");\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "```js\n// 如果 {%TABLE_NAME%} 表中存在 id 为 1 的记录则更新 title 为\"示例标题\"，不存在则插入新记录\nconst { data, error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .upsert({ id: 1, title: \"示例标题\" });\n\nconsole.log(\"新增更新结果:\", error ? \"失败\" : \"成功\");\n```",
                "index": 4,
                "title": "更新或创建数据"
              },
              {
                "markdown": "```js\n// 删除 {%TABLE_NAME%} 表中 id 为 <数据ID> 的数据\nconst { data, error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .delete()\n  .eq(\"id\", \"<数据ID>\");\n\nconsole.log(\"删除结果:\", error ? \"失败\" : \"成功\");\n```",
                "index": 5,
                "title": "删除数据"
              }
            ]
          },
          {
            "index": 2,
            "id": "doc-db",
            "title": "文档型数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\nconst db = wx.cloud.database();\n\n// 查询 {%TABLE_NAME%} 表前10条数据\nconst res = await db.collection(\"{%TABLE_NAME%}\").limit(10).get();\n\nconsole.log(res.data);\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "```js\nconst db = wx.cloud.database();\n\n// 新增 {%TABLE_NAME%} 表数据\nconst res = await db.collection(\"{%TABLE_NAME%}\").add({\n  data: {\n    title: \"示例标题\",\n    content: \"示例内容\"\n  }\n});\n\nconsole.log(res);\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "```js\nconst db = wx.cloud.database();\n\n// 更新 {%TABLE_NAME%} 表中 id 为 <数据ID> 的数据\nconst res = await db\n  .collection(\"{%TABLE_NAME%}\")\n  .doc(\"<数据ID>\")\n  .update({\n    data: {\n      title: \"更新后的标题\"\n    }\n  });\n\nconsole.log(res.stats.updated);\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "```js\nconst db = wx.cloud.database();\n\n// 删除 {%TABLE_NAME%} 表中 id 为 <数据ID> 的数据\nconst res = await db.collection(\"{%TABLE_NAME%}\").doc(\"<数据ID>\").remove();\n\nconsole.log(res.stats.removed);\n```",
                "index": 4,
                "title": "删除数据"
              }
            ]
          },
          {
            "markdown": "请使用 `Client SDK` 进行调用",
            "index": 3,
            "id": "data-model",
            "title": "数据模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\n// 查询 {%TABLE_NAME%} 数据模型前10条数据\nconst res = await cloudbase.models[\"{%TABLE_NAME%}\"].list({\n  pageNumber: 1,\n  pagesize: 10\n});\n\nconsole.log(res.data.records);\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "```js\n// 新增 {%TABLE_NAME%} 数据模型数据\nconst res = await cloudbase.models[\"{%TABLE_NAME%}\"].create({\n  data: {\n    title: \"示例标题\",\n    content: \"示例内容\"\n  }\n});\n\nconsole.log(res.data);\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "```js\n// 更新 {%TABLE_NAME%} 数据模型中 _id 为 <数据ID> 的数据\nconst res = await cloudbase.models[\"{%TABLE_NAME%}\"].update({\n  data: {\n    title: \"更新后的标题\"\n  },\n  filter: {\n    where: {\n      _id: {\n        $eq: \"<数据ID>\"\n      }\n    }\n  }\n});\n\nconsole.log(res.data);\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "```js\n// 删除 {%TABLE_NAME%} 数据模型中 _id 为 <数据ID> 的数据\nconst res = await cloudbase.models[\"{%TABLE_NAME%}\"].delete({\n  filter: {\n    where: {\n      _id: {\n        $eq: \"<数据ID>\"\n      }\n    }\n  }\n});\n\nconsole.log(res.data);\n```",
                "index": 4,
                "title": "删除数据"
              }
            ]
          },
          {
            "markdown": "```js\n// 调用 {%FUNCTION_NAME%} 云函数\nconst res = await wx.cloud.callFunction({\n  name: \"{%FUNCTION_NAME%}\",\n  data: {} // 云函数入参\n});\n\nconsole.log(res.result);\n```",
            "index": 4,
            "id": "scf",
            "title": "云函数",
            "content": []
          },
          {
            "index": 5,
            "id": "storage",
            "title": "云存储",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\n// 小游戏可以通过 canvas 生成图片或使用其他方式获取文件路径\nconst filePath = \"本地文件路径\"; // 例如通过 canvas.toTempFilePath 获取\n\nconst res = await wx.cloud.uploadFile({\n  cloudPath: \"images/\" + Date.now() + \".png\", // 上传至云端的路径\n  filePath: filePath // 小游戏临时文件路径\n});\n\nconsole.log(res.fileID);\n```",
                "index": 1,
                "title": "上传文件"
              },
              {
                "markdown": "```js\nconst res = await wx.cloud.getTempFileURL({\n  fileList: [\"cloud://xxx.png\"] // 文件 fileID 列表\n});\n\nconsole.log(res.fileList);\n// fileList示例\n// [{\n//    fileID: \"cloud://xxx.png\", // 文件 ID\n//    tempFileURL: \"https://xxx.png\", // 临时文件网络链接\n//    maxAge: 120 * 60 * 1000, // 有效期\n// }]\n```",
                "index": 2,
                "title": "获取文件链接"
              },
              {
                "markdown": "```js\nconst res = await wx.cloud.downloadFile({\n  fileID: \"cloud://xxx.png\" // 文件 fileID\n});\n\nconsole.log(res.tempFilePath); // 返回临时文件路径\n```",
                "index": 3,
                "title": "下载文件"
              },
              {
                "markdown": "```js\nconst res = await wx.cloud.deleteFile({\n  fileList: [\"cloud://xxx.png\"] // 文件 fileID 列表\n});\n\nconsole.log(res.fileList);\n```",
                "index": 4,
                "title": "删除文件"
              }
            ]
          },
          {
            "index": 6,
            "id": "ai-model",
            "title": "大模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\nconst res = await wx.cloud.extend.AI.createModel(\n  \"{%AI_MODEL_NAME%}\"\n).streamText({\n  data: {\n    model: \"{%AI_SUB_MODEL_NAME%}\",\n    messages: [\n      {\n        role: \"user\",\n        content: \"你好\"\n      }\n    ]\n  }\n});\n\nfor await (let event of res.eventStream) {\n  if (event.data === \"[DONE]\") {\n    break;\n  }\n  const data = JSON.parse(event.data);\n\n  // 当使用 deepseek-r1 时，模型会生成思维链内容\n  const think = data?.choices?.[0]?.delta?.reasoning_content;\n  if (think) {\n    console.log(think);\n  }\n\n  // 打印生成文本内容\n  const text = data?.choices?.[0]?.delta?.content;\n  if (text) {\n    console.log(text);\n  }\n}\n```",
                "index": 1,
                "id": "text-aiModel",
                "title": "生文模型"
              },
              {
                "markdown": "生图模型通过调用云函数来实现，在生图模型页面点击「一键创建云函数」，函数调用示例如下：\n\n```js\n// 调用云函数生成图片\nwx.cloud.callFunction({\n  name: \"<YOUR_FUNCTION_NAME>\",\n  data: {\n    prompt: \"一只可爱的猫咪在阳光下玩耍\"\n  },\n  success: res => {\n    const result = res.result;\n    if (result.success) {\n      console.log(\"图片URL:\", result.imageUrl);\n      console.log(\"优化后的提示词:\", result.revised_prompt);\n      console.log(\"注意: 图片URL有效期为24小时\");\n      \n      // 在小游戏中可以使用图片URL进行后续处理\n      // 例如加载到Sprite或Canvas中\n    } else {\n      console.error(\"生成失败:\", result.code, result.message);\n    }\n  },\n  fail: err => {\n    console.error(\"调用失败:\", err);\n  }\n});\n```",
                "index": 2,
                "id": "image-aiModel",
                "title": "生图模型"
              }
            ]
          },
          {
            "markdown": "",
            "index": 7,
            "id": "agent",
            "title": "Agent",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\nconst res = await wx.cloud.extend.AI.bot.sendMessage({\n  data: {\n    botId: '{%AGENT_ID%}',\n    // 入参结构参考前后端通信协议：\n    //  https://docs.cloudbase.net/ai/agent/http-agent-protocol\n    threadId: '550e8400-e29b-41d4-a716-446655440000',\n    runId: 'run_001',\n    messages: [{ id: 'msg-1', role: 'user', content: '你好' }],\n    tools: [],\n    context: [],\n    state: {},\n    forwardedProps: {},\n  },\n});\n\nfor await (const event of res.eventStream) {\n  if (event.data === '[DONE]') {\n    break;\n  }\n  const data = JSON.parse(event.data);\n\n  // 当使用 deepseek-r1 时，模型会生成思维链内容\n  const think = data.reasoning_content;\n  if (think) {\n    console.log(think);\n  }\n\n  // 打印输出正文\n  const content = data.content;\n  if (content) {\n    console.log(content);\n  }\n}\n```",
                "index": 0,
                "id": "scf",
                "title": "函数型"
              },
              {
                "markdown": "```js\nconst res = await wx.cloud.extend.AI.bot.sendMessage({\n  data: {\n    botId: \"{%AGENT_ID%}\",\n    msg: \"你好\"\n  }\n});\n\nfor await (const event of res.eventStream) {\n  if (event.data === \"[DONE]\") {\n    break;\n  }\n  const data = JSON.parse(event.data);\n\n  // 当使用 deepseek-r1 时，模型会生成思维链内容\n  const think = data.reasoning_content;\n  if (think) {\n    console.log(think);\n  }\n\n  // 打印输出正文\n  const content = data.content;\n  if (content) {\n    console.log(content);\n  }\n}\n```",
                "index": 1,
                "id": "baas",
                "title": "普通型"
              }
            ]
          },
          {
            "markdown": "```js\n// 调用 <{%INSTANCE_ID%}> 云主机实例\nconst result = await wx.cloud.callContainer({\n    config: {\n        env: \"{%ENV_ID%}\"  // 与小程序已关联的云开发环境 ID\n    },\n    header: {\n        \"X-WX-SERVICE\": \"tcbanyservice\",        // 【必填】固定值，指定为云开发服务\n        \"X-Vm-Service\": \"{%INSTANCE_ID%}\",      // 【必填】替换为你的实例 ID\n        // 可以添加其他自定义 Header\n    },\n    path: \"/\",                  //业务自定义路径，根目录为 /\n    method: \"GET\",      // 业务自定义HTTP方法\n    //data: \"hello\"         // 业务自定义请求参数\n})\n\nconsole.log(result.data)\n```",
            "index": 5,
            "id": "vm",
            "title": "云主机",
            "content": []
          }
        ]
      }
    ],
    "_id": "5f26d9906972e0ed0052d61516e1904a",
    "_openid": "anon",
    "createdAt": 1769136365734,
    "updatedAt": 1770708257554
  },
  {
    "category": "框架集成,移动端框架,Flutter",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": 30,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/http-api/basic/overview",
    "content": [
      {
        "markdown": "通过 **HTTP 请求** 在 **Flutter** 中调用各种云开发能力\n\n在 `pubspec.yaml` 中添加依赖：\n\n```yaml\ndependencies:\n  http: ^1.1.0\n  flutter_dotenv: ^5.1.0\n```\n\n然后运行：\n\n```bash\nflutter pub get\n```",
        "index": 1,
        "title": "安装依赖",
        "content": []
      },
      {
        "markdown": "新增如下代码到您的 **Flutter** 项目",
        "index": 2,
        "title": "初始化配置",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```dart\nimport 'dart:convert';\nimport 'package:http/http.dart' as http;\nimport 'package:flutter_dotenv/flutter_dotenv.dart';\n\nclass CloudBaseClient {\n  late String envId;\n  late String accessToken;\n  late String baseUrl;\n  late Map<String, String> headers;\n\n  CloudBaseClient() {\n    envId = dotenv.env['CLOUDBASE_ENV_ID'] ?? '';\n    accessToken = dotenv.env['CLOUDBASE_ACCESS_TOKEN'] ?? '';\n    baseUrl = 'https://$envId.api.tcloudbasegateway.com';\n    headers = {\n      'Content-Type': 'application/json',\n      'Accept': 'application/json',\n      'Authorization': 'Bearer $accessToken',\n    };\n  }\n\n  /// 更新访问令牌\n  ///\n  /// [newToken] 新的访问令牌\n  void updateAccessToken(String newToken) {\n    accessToken = newToken;\n    headers['Authorization'] = 'Bearer $newToken';\n    print('访问令牌已更新');\n  }\n\n  /// 统一的HTTP请求方法\n  ///\n  /// [method] 请求方法 (GET, POST, PUT, PATCH, DELETE)\n  /// [path] API路径 (如 /v1/rdb/rest/table_name)\n  /// [body] 请求体数据\n  /// [customHeaders] 自定义headers\n  ///\n  /// 返回响应数据或null\n  Future<dynamic> request(\n    String method,\n    String path, {\n    dynamic body,\n    Map<String, String>? customHeaders,\n  }) async {\n    final url = Uri.parse('$baseUrl$path');\n    final requestHeaders = Map<String, String>.from(headers);\n\n    if (customHeaders != null) {\n      requestHeaders.addAll(customHeaders);\n    }\n\n    try {\n      http.Response response;\n\n      switch (method.toUpperCase()) {\n        case 'GET':\n          response = await http.get(url, headers: requestHeaders);\n          break;\n        case 'POST':\n          response = await http.post(\n            url,\n            headers: requestHeaders,\n            body: body != null ? jsonEncode(body) : null,\n          );\n          break;\n        case 'PUT':\n          response = await http.put(\n            url,\n            headers: requestHeaders,\n            body: body != null ? jsonEncode(body) : null,\n          );\n          break;\n        case 'PATCH':\n          response = await http.patch(\n            url,\n            headers: requestHeaders,\n            body: body != null ? jsonEncode(body) : null,\n          );\n          break;\n        case 'DELETE':\n          response = await http.delete(url, headers: requestHeaders);\n          break;\n        default:\n          throw Exception('不支持的HTTP方法: $method');\n      }\n\n      if (response.statusCode >= 200 && response.statusCode < 300) {\n        if (response.body.isEmpty) {\n          return true;\n        }\n        return jsonDecode(response.body);\n      } else {\n        print('请求失败: ${response.statusCode} ${response.body}');\n        return null;\n      }\n    } catch (e) {\n      print('请求失败: $e');\n      return null;\n    }\n  }\n}\n\nfinal cloudbase = CloudBaseClient();\n```",
            "index": 1,
            "title": "cloudbase_client.dart"
          },
          {
            "markdown": "> 💡提示：用户权限请参考「身份认证」模块获取 access_token\n\n```properties\n# 环境ID\nCLOUDBASE_ENV_ID={%ENV_ID%}\n\n# 匿名访问令牌\nCLOUDBASE_ACCESS_TOKEN={%PUBLISHABLE_KEY%}\n```",
            "index": 2,
            "title": ".env"
          }
        ]
      },
      {
        "sideTabs": [
          {
            "id": "pg-db",
            "title": "PostgreSQL 数据库"
          }
        ],
        "index": 3,
        "title": "调用云开发能力",
        "type": "codeTab",
        "content": [
          {
            "index": 1,
            "id": "pg-db",
            "title": "PostgreSQL 数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<void> example() async {\n  final cloudbase = CloudBaseClient();\n\n  // 查询 {%TABLE_NAME%} 表前 10 条数据\n  final data = await cloudbase.request(\n    \"GET\",\n    \"/v1/rdb/rest/{{%TABLE_NAME%}}?select=*&limit=10\",\n  );\n\n  if (data != null) {\n    print(\"查询结果: $data\");\n  }\n}\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<void> example() async {\n  final cloudbase = CloudBaseClient();\n\n  // 新增{%TABLE_NAME%}\n  final data = await cloudbase.request(\n    \"POST\",\n    \"/v1/rdb/rest/{{%TABLE_NAME%}}\",\n    body: '{\"title\": \"新文章\", \"status\": \"draft\"}',\n    headers: {\"Prefer\": \"return=representation\"},\n  );\n\n  if (data != null) {\n    print(\"新增结果: $data\");\n  }\n}\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<void> example() async {\n  final cloudbase = CloudBaseClient();\n\n  // 更新{%TABLE_NAME%}\n  final data = await cloudbase.request(\n    \"PATCH\",\n    \"/v1/rdb/rest/{{%TABLE_NAME%}}?id=eq.1\",\n    body: '{\"status\": \"published\"}',\n    headers: {\"Prefer\": \"return=representation\"},\n  );\n\n  if (data != null) {\n    print(\"更新结果: $data\");\n  }\n}\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<void> example() async {\n  final cloudbase = CloudBaseClient();\n\n  // 更新或创建{%TABLE_NAME%}\n  final data = await cloudbase.request(\n    \"POST\",\n    \"/v1/rdb/rest/{{%TABLE_NAME%}}\",\n    body: '{\"id\": 1, \"title\": \"标题\", \"status\": \"published\"}',\n    headers: {\"Prefer\": \"resolution=merge-duplicates,return=representation\"},\n  );\n\n  if (data != null) {\n    print(\"更新或创建结果: $data\");\n  }\n}\n```",
                "index": 4,
                "title": "更新或创建数据"
              },
              {
                "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<void> example() async {\n  final cloudbase = CloudBaseClient();\n\n  // 删除 {%TABLE_NAME%} 表中 id=1 的数据\n  final data = await cloudbase.request(\n    \"DELETE\",\n    \"/v1/rdb/rest/{{%TABLE_NAME%}}?id=eq.1\",\n  );\n\n  if (data != null) {\n    print(\"删除完成: $data\");\n  }\n}\n```",
                "index": 5,
                "title": "删除数据"
              }
            ]
          },
          {
            "index": 1,
            "id": "mysql-db",
            "title": "MySQL数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<List<dynamic>> getMysqlData(String tableName) async {\n  /// 查询 MySQL 数据库数据\n  final data = await cloudbase.request('GET', '/v1/rdb/rest/$tableName?limit=10');\n\n  if (data != null) {\n    print('查询成功: $data');\n    return data as List<dynamic>;\n  }\n  return [];\n}\n\n// 使用示例\nvoid main() async {\n  final result = await getMysqlData('{%TABLE_NAME%}');\n  print(result);\n}\n```",
                "index": 1,
                "title": "查询数据",
                "content": []
              },
              {
                "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<dynamic> addMysqlData(String tableName, Map<String, dynamic> data) async {\n  /// 新增 MySQL 数据库数据\n  final result = await cloudbase.request('POST', '/v1/rdb/rest/$tableName', body: data);\n\n  if (result != null) {\n    print('新增成功: $result');\n  }\n  return result;\n}\n\n// 使用示例\nvoid main() async {\n  final result = await addMysqlData('{%TABLE_NAME%}', {'title': '示例标题'});\n  print(result);\n}\n```",
                "index": 2,
                "title": "新增数据",
                "content": []
              },
              {
                "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<dynamic> updateMysqlData(String tableName, String dataId, Map<String, dynamic> data) async {\n  /// 更新 MySQL 数据库数据\n  final result = await cloudbase.request(\n    'PATCH',\n    '/v1/rdb/rest/$tableName?id=eq.$dataId',\n    body: data,\n  );\n\n  if (result != null) {\n    print('更新成功: $result');\n  }\n  return result;\n}\n\n// 使用示例\nvoid main() async {\n  final result = await updateMysqlData('{%TABLE_NAME%}', '<数据id>', {'title': '新标题'});\n  print(result);\n}\n```",
                "index": 3,
                "title": "更新数据",
                "content": []
              },
              {
                "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<bool> deleteMysqlData(String tableName, String dataId) async {\n  /// 删除 MySQL 数据库数据\n  final result = await cloudbase.request('DELETE', '/v1/rdb/rest/$tableName?id=eq.$dataId');\n\n  if (result != null) {\n    print('删除成功');\n    return true;\n  }\n  return false;\n}\n\n// 使用示例\nvoid main() async {\n  final result = await deleteMysqlData('{%TABLE_NAME%}', '<数据id>');\n  print(result);\n}\n```",
                "index": 4,
                "title": "删除数据",
                "content": []
              }
            ]
          },
          {
            "index": 2,
            "id": "data-model",
            "title": "数据模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<List<dynamic>> getModelData(String modelName, {String envType = 'prod'}) async {\n  /// 查询数据模型数据\n  final payload = {\n    'pageSize': 10,\n    'pageNumber': 1,\n    'getCount': true,\n  };\n\n  final result = await cloudbase.request('POST', '/v1/model/$envType/$modelName/list', body: payload);\n\n  if (result != null) {\n    final records = result['data']?['records'] ?? [];\n    print('查询成功: $records');\n    return records;\n  }\n  return [];\n}\n\n// 使用示例\nvoid main() async {\n  final records = await getModelData('{%TABLE_NAME%}');\n  print(records);\n}\n```",
                "index": 1,
                "title": "查询数据",
                "content": []
              },
              {
                "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<dynamic> addModelData(String modelName, Map<String, dynamic> data, {String envType = 'prod'}) async {\n  /// 新增数据模型数据\n  final result = await cloudbase.request(\n    'POST',\n    '/v1/model/$envType/$modelName/create',\n    body: {'data': data},\n  );\n\n  if (result != null) {\n    final docId = result['data']?['id'];\n    print('新增成功! id: $docId');\n  }\n  return result;\n}\n\n// 使用示例\nvoid main() async {\n  final result = await addModelData('{%TABLE_NAME%}', {'title': '示例标题'});\n  print(result);\n}\n```",
                "index": 2,
                "title": "新增数据",
                "content": []
              },
              {
                "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<bool> updateModelData(String modelName, String dataId, Map<String, dynamic> data, {String envType = 'prod'}) async {\n  /// 更新数据模型数据\n  final payload = {\n    'data': data,\n    'filter': {\n      'where': {\n        '_id': {'\\$eq': dataId}\n      }\n    }\n  };\n\n  final result = await cloudbase.request('PUT', '/v1/model/$envType/$modelName/update', body: payload);\n\n  if (result != null) {\n    print('更新成功!');\n    return true;\n  }\n  return false;\n}\n\n// 使用示例\nvoid main() async {\n  final result = await updateModelData('{%TABLE_NAME%}', '<数据id>', {'title': '新标题'});\n  print(result);\n}\n```",
                "index": 3,
                "title": "更新数据",
                "content": []
              },
              {
                "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<bool> deleteModelData(String modelName, String dataId, {String envType = 'prod'}) async {\n  /// 删除数据模型数据\n  final payload = {\n    'filter': {\n      'where': {\n        '_id': {'\\$eq': dataId}\n      }\n    }\n  };\n\n  final result = await cloudbase.request('POST', '/v1/model/$envType/$modelName/delete', body: payload);\n\n  if (result != null) {\n    print('删除成功!');\n    return true;\n  }\n  return false;\n}\n\n// 使用示例\nvoid main() async {\n  final result = await deleteModelData('{%TABLE_NAME%}', '<数据id>');\n  print(result);\n}\n```",
                "index": 4,
                "title": "删除数据",
                "content": []
              }
            ]
          },
          {
            "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<dynamic> callFunction(String functionName, {Map<String, dynamic>? data}) async {\n  /// 调用云函数\n  final result = await cloudbase.request('POST', '/v1/functions/$functionName', body: data ?? {});\n\n  if (result != null) {\n    print('云函数调用结果: $result');\n  }\n  return result;\n}\n\n// 使用示例\nvoid main() async {\n  final result = await callFunction('{%FUNCTION_NAME%}');\n  print(result);\n}\n```",
            "index": 3,
            "id": "scf",
            "title": "云函数"
          },
          {
            "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<dynamic> callContainer(String serviceName, {String path = '', String method = 'GET', Map<String, dynamic>? data}) async {\n  /// 调用云托管服务\n  final fullPath = '/v1/cloudrun/$serviceName/$path'.replaceAll(RegExp(r'/+$'), '');\n  final result = await cloudbase.request(method.toUpperCase(), fullPath, body: data);\n\n  if (result != null) {\n    print('云托管调用结果: $result');\n  }\n  return result;\n}\n\n// 使用示例\nvoid main() async {\n  final result = await callContainer('{%SERVICE_NAME%}');\n  print(result);\n}\n```",
            "index": 4,
            "id": "run",
            "title": "云托管"
          },
          {
            "index": 5,
            "id": "storage",
            "title": "云存储",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```dart\nimport 'dart:io';\nimport 'package:http/http.dart' as http;\nimport 'cloudbase_client.dart';\n\nFuture<Map<String, dynamic>?> uploadFile(String filePath, {String? objectId}) async {\n  /// 上传文件到云存储\n  final file = File(filePath);\n\n  if (!await file.exists()) {\n    print('文件不存在: $filePath');\n    return null;\n  }\n\n  if (objectId == null) {\n    final filename = filePath.split('/').last;\n    final timestamp = DateTime.now().millisecondsSinceEpoch;\n    objectId = 'uploads/$timestamp-$filename';\n  }\n\n  // 1. 获取上传信息\n  final uploadInfo = await cloudbase.request(\n    'POST',\n    '/v1/storages/get-objects-upload-info',\n    body: [{'objectId': objectId}],\n  );\n\n  if (uploadInfo == null || uploadInfo.isEmpty) {\n    return null;\n  }\n\n  final info = uploadInfo[0];\n  final uploadUrl = info['uploadUrl'];\n\n  try {\n    // 2. 上传文件\n    final fileData = await file.readAsBytes();\n    final uploadHeaders = {\n      'Authorization': info['authorization'],\n      'X-Cos-Security-Token': info['token'],\n      'X-Cos-Meta-Fileid': info['cloudObjectMeta'],\n    };\n\n    final uploadResponse = await http.put(\n      Uri.parse(uploadUrl),\n      headers: uploadHeaders,\n      body: fileData,\n    );\n\n    if (uploadResponse.statusCode >= 200 && uploadResponse.statusCode < 300) {\n      final result = {\n        'cloudObjectId': info['cloudObjectId'],\n        'downloadUrl': info['downloadUrl'],\n        'objectId': objectId,\n      };\n\n      print('文件上传成功:');\n      print('- 对象ID: ${result['objectId']}');\n      print('- 下载URL: ${result['downloadUrl']}');\n\n      return result;\n    }\n\n    print('文件上传失败: ${uploadResponse.statusCode}');\n    return null;\n  } catch (e) {\n    print('文件上传失败: $e');\n    return null;\n  }\n}\n\n// 使用示例\nvoid main() async {\n  final result = await uploadFile('./example.jpg');\n  print(result);\n}\n```",
                "index": 1,
                "title": "上传文件",
                "content": []
              },
              {
                "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<String?> getFileUrl(String cloudObjectId) async {\n  /// 获取云存储文件的临时访问链接\n  final result = await cloudbase.request(\n    'POST',\n    '/v1/storages/get-objects-download-info',\n    body: [{'cloudObjectId': cloudObjectId}],\n  );\n\n  if (result != null && result.isNotEmpty) {\n    final downloadUrl = result[0]['downloadUrl'];\n    print('文件链接: $downloadUrl');\n    return downloadUrl;\n  }\n  return null;\n}\n\n// 使用示例\nvoid main() async {\n  final fileUrl = await getFileUrl('cloud://xxx.png');\n  print(fileUrl);\n}\n```",
                "index": 2,
                "title": "获取文件链接",
                "content": []
              },
              {
                "markdown": "```dart\nimport 'dart:io';\nimport 'package:http/http.dart' as http;\nimport 'cloudbase_client.dart';\n\nFuture<bool> downloadFile(String cloudObjectId, {String savePath = './'}) async {\n  /// 下载云存储文件到本地\n  // 1. 获取下载链接\n  final result = await cloudbase.request(\n    'POST',\n    '/v1/storages/get-objects-download-info',\n    body: [{'cloudObjectId': cloudObjectId}],\n  );\n\n  if (result == null || result.isEmpty) {\n    return false;\n  }\n\n  final downloadUrl = result[0]['downloadUrl'];\n\n  try {\n    // 2. 从URL中提取文件名\n    final uri = Uri.parse(downloadUrl);\n    final filename = uri.pathSegments.last.split('?').first;\n\n    // 3. 确定完整路径\n    String fullPath;\n    final saveDir = Directory(savePath);\n    if (await saveDir.exists() || savePath.endsWith('/')) {\n      fullPath = '$savePath/$filename';\n    } else {\n      fullPath = savePath;\n    }\n\n    // 4. 下载文件\n    final fileResponse = await http.get(Uri.parse(downloadUrl));\n\n    if (fileResponse.statusCode >= 200 && fileResponse.statusCode < 300) {\n      // 5. 保存到本地\n      final file = File(fullPath);\n      await file.writeAsBytes(fileResponse.bodyBytes);\n\n      print('下载成功! 文件已保存到: $fullPath');\n      return true;\n    }\n\n    print('下载失败: ${fileResponse.statusCode}');\n    return false;\n  } catch (e) {\n    print('下载失败: $e');\n    return false;\n  }\n}\n\n// 使用示例\nvoid main() async {\n  // 下载到当前目录，使用原文件名\n  await downloadFile('cloud://xxx.png');\n\n  // 下载到指定目录\n  await downloadFile('cloud://xxx.png', savePath: './downloads/');\n\n  // 下载并重命名\n  await downloadFile('cloud://xxx.png', savePath: './my-image.png');\n}\n```",
                "index": 3,
                "title": "下载文件",
                "content": []
              },
              {
                "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<bool> deleteFile(dynamic cloudObjectIds) async {\n  /// 删除云存储文件\n  List<String> ids;\n  if (cloudObjectIds is String) {\n    ids = [cloudObjectIds];\n  } else if (cloudObjectIds is List<String>) {\n    ids = cloudObjectIds;\n  } else {\n    print('参数类型错误');\n    return false;\n  }\n\n  final data = ids.map((id) => {'cloudObjectId': id}).toList();\n  final result = await cloudbase.request('POST', '/v1/storages/delete-objects', body: data);\n\n  if (result != null) {\n    print('删除成功!');\n    return true;\n  }\n  return false;\n}\n\n// 使用示例\nvoid main() async {\n  final result = await deleteFile('cloud://xxx.png');\n  print(result);\n}\n```",
                "index": 4,
                "title": "删除文件",
                "content": []
              }
            ]
          },
          {
            "index": 6,
            "id": "ai-model",
            "title": "大模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```dart\nimport 'dart:convert';\nimport 'package:http/http.dart' as http;\nimport 'cloudbase_client.dart';\n\nFuture<String?> streamText(String model, String subModel, List<Map<String, String>> messages) async {\n  /// 流式文本生成\n  final payload = {\n    'model': subModel,\n    'messages': messages,\n    'stream': true,\n  };\n\n  final url = '${cloudbase.baseUrl}/v1/ai/$model/chat/completions';\n  final headers = Map<String, String>.from(cloudbase.headers);\n  headers['Accept'] = 'text/event-stream';\n\n  try {\n    final request = http.Request('POST', Uri.parse(url));\n    request.headers.addAll(headers);\n    request.body = jsonEncode(payload);\n\n    final streamedResponse = await request.send();\n\n    if (streamedResponse.statusCode >= 200 && streamedResponse.statusCode < 300) {\n      print('AI 流式响应:');\n      String fullContent = '';\n\n      await for (var chunk in streamedResponse.stream.transform(utf8.decoder)) {\n        final lines = chunk.split('\\n');\n        for (var line in lines) {\n          if (line.startsWith('data: ')) {\n            final dataStr = line.substring(6);\n            if (dataStr.trim() != '[DONE]') {\n              try {\n                final chunkData = jsonDecode(dataStr);\n                final content = chunkData['choices']?[0]?['delta']?['content'] ?? '';\n                if (content.isNotEmpty) {\n                  print(content);\n                  fullContent += content;\n                }\n              } catch (e) {\n                // 忽略JSON解析错误\n              }\n            }\n          }\n        }\n      }\n\n      return fullContent;\n    } else {\n      print('AI 调用失败: ${streamedResponse.statusCode}');\n      return null;\n    }\n  } catch (e) {\n    print('AI 调用失败: $e');\n    return null;\n  }\n}\n\n// 使用示例\nvoid main() async {\n  final response = await streamText(\n    '{%AI_MODEL_NAME%}',\n    '{%AI_SUB_MODEL_NAME%}',\n    [\n      {'role': 'system', 'content': '请严格按照七言绝句或七言律诗的格律要求创作'},\n      {'role': 'user', 'content': '春天'}\n    ],\n  );\n  print('\\n完整回复: $response');\n}\n```",
                "index": 1,
                "id": "text-aiModel",
                "title": "生文模型",
                "content": []
              },
              {
                "markdown": "生图模型通过调用云函数来实现，在生图模型页面点击「一键创建云函数」，函数调用示例如下：\n\n```dart\nimport 'cloudbase_client.dart';\n\nFuture<Map<String, dynamic>?> generateImage(String prompt) async {\n  /// 调用生图云函数\n  final result = await cloudbase.request(\n    'POST',\n    '/v1/functions/<YOUR_FUNCTION_NAME>/invoke',\n    body: {\n      'prompt': prompt,\n    },\n  );\n\n  if (result != null) {\n    final success = result['success'] ?? false;\n    \n    if (success) {\n      // 生成成功\n      print('生成成功!');\n      print('图片URL: ${result['imageUrl']}');\n      print('优化后的提示词: ${result['revised_prompt']}');\n\n      // 使用图片\n      // 注意：图片URL有效期为24小时，请及时保存或转存\n      return result;\n    } else {\n      // 生成失败\n      print('生成失败: ${result['code']} ${result['message']}');\n      return null;\n    }\n  }\n  return null;\n}\n\n// 使用示例\nvoid main() async {\n  final result = await generateImage('一只可爱的猫咪在阳光下玩耍');\n  if (result != null) {\n    print('图片URL: ${result['imageUrl']}');\n  }\n}\n```",
                "index": 2,
                "id": "image-aiModel",
                "title": "生图模型",
                "content": []
              }
            ]
          },
          {
            "markdown": "",
            "index": 7,
            "id": "agent",
            "title": "Agent",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```dart\n/**\n * Flutter 调用 Agent 示例（AG-UI 协议）\n * 协议文档：https://docs.cloudbase.net/ai/agent-development/protocol\n */\nimport 'dart:convert';\nimport 'package:http/http.dart' as http;\nimport 'cloudbase_client.dart';\n\nFuture<String?> chatWithAgentStream(String botId, String userMessage) async {\n  // 构建消息列表（AG-UI 协议格式）\n  final messages = [\n    {\n      'id': 'msg_001',\n      'role': 'user',\n      'content': userMessage,\n    }\n  ];\n\n  // AG-UI 协议请求参数\n  final payload = {\n    'messages': messages,                                    // 必填：消息列表\n    'threadId': '550e8400-e29b-41d4-a716-446655440000',      // 可选：会话ID，用于多轮对话\n    'runId': 'run_001',                                       // 可选：运行ID，用于追踪执行\n    'tools': [],                                              // 可选：前端工具定义\n    'context': [],                                            // 可选：上下文信息\n    'forwardedProps': {},                                     // 可选：透传参数\n  };\n\n  final url = '${cloudbase.baseUrl}/v1/aibot/bots/$botId/send-message';\n  final headers = Map<String, String>.from(cloudbase.headers);\n  headers['Accept'] = 'text/event-stream';\n\n  try {\n    final request = http.Request('POST', Uri.parse(url));\n    request.headers.addAll(headers);\n    request.body = jsonEncode(payload);\n\n    final streamedResponse = await request.send();\n\n    if (streamedResponse.statusCode >= 200 && streamedResponse.statusCode < 300) {\n      print('AI 流式响应:');\n      String fullContent = '';\n      String buffer = '';\n\n      await for (var chunk in streamedResponse.stream.transform(utf8.decoder)) {\n        buffer += chunk;\n\n        while (buffer.contains('\\n')) {\n          final newlineIndex = buffer.indexOf('\\n');\n          final line = buffer.substring(0, newlineIndex).trim();\n          buffer = buffer.substring(newlineIndex + 1);\n\n          if (line.startsWith('data: ')) {\n            final dataStr = line.substring(6).trim();\n            if (dataStr.isNotEmpty && dataStr != '[DONE]') {\n              try {\n                final chunkData = jsonDecode(dataStr);\n                final content = chunkData['content'] ??\n                    chunkData['choices']?[0]?['delta']?['content'] ??\n                    chunkData['choices']?[0]?['message']?['content'] ??\n                    '';\n                if (content.isNotEmpty) {\n                  print(content);\n                  fullContent += content;\n                }\n              } catch (e) {\n                // 忽略JSON解析错误\n              }\n            }\n          }\n        }\n      }\n\n      print('');\n      return fullContent;\n    } else {\n      print('AI 调用失败: ${streamedResponse.statusCode}');\n      return null;\n    }\n  } catch (e) {\n    print('AI 调用失败: $e');\n    return null;\n  }\n}\n\n// 使用示例\nvoid main() async {\n  final response = await chatWithAgentStream('{%AGENT_ID%}', '你是谁');\n  print('\\n完整回复: $response');\n}\n\n```",
                "index": 0,
                "id": "scf",
                "title": "函数型"
              },
              {
                "markdown": "```dart\nimport 'dart:convert';\nimport 'package:http/http.dart' as http;\nimport 'cloudbase_client.dart';\n\nFuture<String?> chatWithAgentStream(String botId, String msg, {List<Map<String, String>>? history}) async {\n  /// 流式调用Agent\n  final payload = {\n    'history': history ?? [],\n    'msg': msg,\n  };\n\n  final url = '${cloudbase.baseUrl}/v1/aibot/bots/$botId/send-message';\n  final headers = Map<String, String>.from(cloudbase.headers);\n  headers['Accept'] = 'text/event-stream';\n\n  try {\n    final request = http.Request('POST', Uri.parse(url));\n    request.headers.addAll(headers);\n    request.body = jsonEncode(payload);\n\n    final streamedResponse = await request.send();\n\n    if (streamedResponse.statusCode >= 200 && streamedResponse.statusCode < 300) {\n      print('AI 流式响应:');\n      String fullContent = '';\n      String buffer = '';\n\n      await for (var chunk in streamedResponse.stream.transform(utf8.decoder)) {\n        buffer += chunk;\n\n        while (buffer.contains('\\n')) {\n          final newlineIndex = buffer.indexOf('\\n');\n          final line = buffer.substring(0, newlineIndex).trim();\n          buffer = buffer.substring(newlineIndex + 1);\n\n          if (line.startsWith('data: ')) {\n            final dataStr = line.substring(6).trim();\n            if (dataStr.isNotEmpty && dataStr != '[DONE]') {\n              try {\n                final chunkData = jsonDecode(dataStr);\n                final content = chunkData['content'] ??\n                    chunkData['choices']?[0]?['delta']?['content'] ??\n                    chunkData['choices']?[0]?['message']?['content'] ??\n                    '';\n                if (content.isNotEmpty) {\n                  print(content);\n                  fullContent += content;\n                }\n              } catch (e) {\n                // 忽略JSON解析错误\n              }\n            }\n          }\n        }\n      }\n\n      print('');\n      return fullContent;\n    } else {\n      print('AI 调用失败: ${streamedResponse.statusCode}');\n      return null;\n    }\n  } catch (e) {\n    print('AI 调用失败: $e');\n    return null;\n  }\n}\n\n// 使用示例\nvoid main() async {\n  final response = await chatWithAgentStream('{%AGENT_ID%}', '你是谁');\n  print('\\n完整回复: $response');\n}\n```",
                "index": 1,
                "id": "baas",
                "title": "普通型"
              }
            ]
          },
          {
            "index": 8,
            "id": "identity",
            "title": "身份认证",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<Map<String, dynamic>?> signUpWithPhoneCode(String phoneNumber, String verificationCode, {String? username, String? password, String? captchaToken}) async {\n  try {\n    // 步骤1: 发送短信验证码\n    final sendBody = {\n      'phone_number': phoneNumber.startsWith('+86') ? phoneNumber : '+86$phoneNumber',\n      'target': 'NON_USER',  // \"NON_USER\" - 账号不存在才发送; \"ANY\" - 不限制\n    };\n\n    final sendHeaders = captchaToken != null ? {'x-captcha-token': captchaToken} : null;\n\n    final sendResult = await cloudbase.request(\n      'POST',\n      '/auth/v1/verification',\n      body: sendBody,\n      customHeaders: sendHeaders,\n    );\n\n    if (sendResult == null) {\n      print('发送验证码失败');\n      return null;\n    }\n\n    final verificationId = sendResult['verification_id'];\n    print('验证码发送成功! ID: $verificationId');\n\n    // 步骤2: 验证验证码\n    final verifyResult = await cloudbase.request(\n      'POST',\n      '/auth/v1/verification/verify',\n      body: {\n        'verification_id': verificationId,\n        'verification_code': verificationCode,\n      },\n    );\n\n    if (verifyResult == null) {\n      print('验证码错误');\n      return null;\n    }\n\n    final verificationToken = verifyResult['verification_token'];\n    print('验证成功!');\n\n    // 步骤3: 使用验证令牌注册\n    final signUpBody = {\n      'phone_number': phoneNumber.startsWith('+86') ? phoneNumber : '+86$phoneNumber',\n      'verification_token': verificationToken,\n    };\n\n    // 可选：添加用户名和密码\n    if (username != null) signUpBody['username'] = username;\n    if (password != null) signUpBody['password'] = password;\n\n    final signUpResult = await cloudbase.request(\n      'POST',\n      '/auth/v1/signup',\n      body: signUpBody,\n    );\n\n    if (signUpResult != null) {\n      final accessToken = signUpResult['access_token'];\n      final userId = signUpResult['sub'];\n\n      print('注册成功! 用户ID: $userId');\n      print('访问令牌: ${accessToken.substring(0, 20)}...');\n\n      // 更新访问令牌\n      cloudbase.updateAccessToken(accessToken);\n      return signUpResult;\n    }\n\n    print('注册失败');\n    return null;\n  } catch (e) {\n    print('注册失败: $e');\n    return null;\n  }\n}\n\n// 使用示例\nvoid main() async {\n  final result = await signUpWithPhoneCode('13800138000', '123456', username: 'myusername', password: 'mypassword');\n  if (result != null) {\n    print('手机号注册成功');\n  }\n}\n```",
                "index": 1,
                "title": "短信验证码注册",
                "content": []
              },
              {
                "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<Map<String, dynamic>?> signUpWithEmailCode(String email, String verificationCode, {String? username, String? password, String? captchaToken}) async {\n  try {\n    // 步骤1: 发送邮箱验证码\n    final sendBody = {\n      'email': email,\n      'target': 'NON_USER',  // \"NON_USER\" - 账号不存在才发送; \"ANY\" - 不限制\n    };\n\n    final sendHeaders = captchaToken != null ? {'x-captcha-token': captchaToken} : null;\n\n    final sendResult = await cloudbase.request(\n      'POST',\n      '/auth/v1/verification',\n      body: sendBody,\n      customHeaders: sendHeaders,\n    );\n\n    if (sendResult == null) {\n      print('发送验证码失败');\n      return null;\n    }\n\n    final verificationId = sendResult['verification_id'];\n    print('验证码发送成功! ID: $verificationId');\n\n    // 步骤2: 验证验证码\n    final verifyResult = await cloudbase.request(\n      'POST',\n      '/auth/v1/verification/verify',\n      body: {\n        'verification_id': verificationId,\n        'verification_code': verificationCode,\n      },\n    );\n\n    if (verifyResult == null) {\n      print('验证码错误');\n      return null;\n    }\n\n    final verificationToken = verifyResult['verification_token'];\n    print('验证成功!');\n\n    // 步骤3: 使用验证令牌注册\n    final signUpBody = {\n      'email': email,\n      'verification_token': verificationToken,\n    };\n\n    // 可选：添加用户名和密码\n    if (username != null) signUpBody['username'] = username;\n    if (password != null) signUpBody['password'] = password;\n\n    final signUpResult = await cloudbase.request(\n      'POST',\n      '/auth/v1/signup',\n      body: signUpBody,\n    );\n\n    if (signUpResult != null) {\n      final accessToken = signUpResult['access_token'];\n      final userId = signUpResult['sub'];\n\n      print('注册成功! 用户ID: $userId');\n      print('访问令牌: ${accessToken.substring(0, 20)}...');\n\n      // 更新访问令牌\n      cloudbase.updateAccessToken(accessToken);\n      return signUpResult;\n    }\n\n    print('注册失败');\n    return null;\n  } catch (e) {\n    print('注册失败: $e');\n    return null;\n  }\n}\n\n// 使用示例\nvoid main() async {\n  final result = await signUpWithEmailCode('user@example.com', '123456', username: 'myusername', password: 'mypassword');\n  if (result != null) {\n    print('邮箱注册成功');\n  }\n}\n```",
                "index": 2,
                "title": "邮箱验证码注册",
                "content": []
              },
              {
                "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<Map<String, dynamic>?> signIn(String username, String password) async {\n  /// 账号密码登录\n  final result = await cloudbase.request(\n    'POST',\n    '/auth/v1/signin',\n    body: {'username': username, 'password': password},\n  );\n\n  if (result != null) {\n    final accessToken = result['access_token'];\n    final refreshToken = result['refresh_token'];\n    final userId = result['sub'];\n\n    print('登录成功! 用户ID: $userId');\n    print('访问令牌: ${accessToken.substring(0, 20)}...');\n\n    // 更新访问令牌\n    cloudbase.updateAccessToken(accessToken);\n    return result;\n  }\n  return null;\n}\n\n// 使用示例\nvoid main() async {\n  final result = await signIn('your_username', 'your_password');\n  print(result);\n}\n```",
                "index": 3,
                "id": "UserNameLogin",
                "title": "账号密码登录",
                "content": []
              },
              {
                "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<bool> loginWithPhoneCode(String phoneNumber, String verificationCode, {String? captchaToken}) async {\n  try {\n    // 步骤1: 发送短信验证码\n    final sendBody = {\n      'phone_number': phoneNumber.startsWith('+86') ? phoneNumber : '+86$phoneNumber',\n      'target': 'ANY',  // \"ANY\" - 不限制，无论用户是否存在都发送; \"USER\" - 账号必须存在才发送\n    };\n\n    final sendHeaders = captchaToken != null ? {'x-captcha-token': captchaToken} : null;\n\n    final sendResult = await cloudbase.request(\n      'POST',\n      '/auth/v1/verification',\n      body: sendBody,\n      customHeaders: sendHeaders,\n    );\n\n    if (sendResult == null) {\n      print('发送验证码失败');\n      return false;\n    }\n\n    final verificationId = sendResult['verification_id'];\n    print('验证码发送成功! ID: $verificationId');\n\n    // 步骤2: 验证验证码\n    final verifyResult = await cloudbase.request(\n      'POST',\n      '/auth/v1/verification/verify',\n      body: {\n        'verification_id': verificationId,\n        'verification_code': verificationCode,\n      },\n    );\n\n    if (verifyResult == null) {\n      print('验证码错误');\n      return false;\n    }\n\n    final verificationToken = verifyResult['verification_token'];\n    print('验证成功!');\n\n    // 步骤3: 使用验证令牌登录\n    final loginResult = await cloudbase.request(\n      'POST',\n      '/auth/v1/signin',\n      body: {\n        'phone_number': phoneNumber.startsWith('+86') ? phoneNumber : '+86$phoneNumber',\n        'verification_token': verificationToken,\n      },\n    );\n\n    if (loginResult != null) {\n      final accessToken = loginResult['access_token'];\n      print('登录成功!');\n      cloudbase.updateAccessToken(accessToken);\n      return true;\n    }\n\n    print('登录失败');\n    return false;\n  } catch (e) {\n    print('登录失败: $e');\n    return false;\n  }\n}\n\n// 使用示例\nvoid main() async {\n  final success = await loginWithPhoneCode('13800138000', '123456');\n  if (success) {\n    print('手机号登录成功');\n  }\n}\n```",
                "index": 4,
                "id": "PhoneNumberLogin",
                "title": "短信验证码登录",
                "content": []
              },
              {
                "markdown": "```dart\nimport 'cloudbase_client.dart';\n\nFuture<bool> loginWithEmailCode(String email, String verificationCode, {String? captchaToken}) async {\n  try {\n    // 步骤1: 发送邮箱验证码\n    final sendBody = {\n      'email': email,\n      'target': 'ANY',  // \"ANY\" - 不限制，无论用户是否存在都发送; \"USER\" - 账号必须存在才发送\n    };\n\n    final sendHeaders = captchaToken != null ? {'x-captcha-token': captchaToken} : null;\n\n    final sendResult = await cloudbase.request(\n      'POST',\n      '/auth/v1/verification',\n      body: sendBody,\n      customHeaders: sendHeaders,\n    );\n\n    if (sendResult == null) {\n      print('发送验证码失败');\n      return false;\n    }\n\n    final verificationId = sendResult['verification_id'];\n    print('验证码发送成功! ID: $verificationId');\n\n    // 步骤2: 验证验证码\n    final verifyResult = await cloudbase.request(\n      'POST',\n      '/auth/v1/verification/verify',\n      body: {\n        'verification_id': verificationId,\n        'verification_code': verificationCode,\n      },\n    );\n\n    if (verifyResult == null) {\n      print('验证码错误');\n      return false;\n    }\n\n    final verificationToken = verifyResult['verification_token'];\n    print('验证成功!');\n\n    // 步骤3: 使用验证令牌登录\n    final loginResult = await cloudbase.request(\n      'POST',\n      '/auth/v1/signin',\n      body: {\n        'email': email,\n        'verification_token': verificationToken,\n      },\n    );\n\n    if (loginResult != null) {\n      final accessToken = loginResult['access_token'];\n      print('登录成功!');\n      cloudbase.updateAccessToken(accessToken);\n      return true;\n    }\n\n    print('登录失败');\n    return false;\n  } catch (e) {\n    print('登录失败: $e');\n    return false;\n  }\n}\n\n// 使用示例\nvoid main() async {\n  final success = await loginWithEmailCode('user@example.com', '123456');\n  if (success) {\n    print('邮箱登录成功');\n  }\n}\n```",
                "index": 5,
                "id": "email",
                "title": "邮箱验证码登录",
                "content": []
              }
            ]
          }
        ]
      }
    ],
    "_id": "6c87b79069773d6d00b8678227fbefe1",
    "_openid": "anon",
    "createdAt": 1769422189215,
    "updatedAt": 1770372002402
  },
  {
    "category": "框架集成,后端框架,Node.js",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": 20,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/api-reference/server/node-sdk/initialization",
    "content": [
      {
        "markdown": "`@cloudbase/node-sdk` 可以让您在 Node.js 服务端使用 JavaScript/TypeScript 访问 CloudBase 服务和资源。",
        "index": 1,
        "title": "安装 SDK",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```bash\nnpm i @cloudbase/node-sdk dotenv\n```",
            "index": 1,
            "title": "npm",
            "content": []
          },
          {
            "markdown": "```bash\nyarn add @cloudbase/node-sdk dotenv\n```",
            "index": 2,
            "title": "yarn",
            "content": []
          },
          {
            "markdown": "```bash\npnpm add @cloudbase/node-sdk dotenv\n```",
            "index": 3,
            "title": "pnpm",
            "content": []
          }
        ]
      },
      {
        "markdown": "新增如下代码到您的 Node.js 项目",
        "index": 2,
        "title": "初始化 SDK",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```js\nconst cloudbaseSDK = require(\"@cloudbase/node-sdk\");\nrequire(\"dotenv\").config();\n\nconst cloudbase = cloudbaseSDK.init({\n  env: process.env.CLOUDBASE_ENV_ID,\n  secretId: process.env.CLOUDBASE_SECRETID,\n  secretKey: process.env.CLOUDBASE_SECRETKEY\n});\n\nmodule.exports = { cloudbase };\n```",
            "index": 1,
            "title": "./utils/cloudbase.js",
            "content": []
          },
          {
            "markdown": "<div class=\"tea-alert tea-alert--brand\" style=\"padding:9px calc(var(--tea-space-100)*4)\">\n<div class=\"tea-alert__info\">\n请前往 <a target=\"_blank\"  class=\"tea-link-external\"  style =\"text-decoration:underline\" href=\"https://console.cloud.tencent.com/cam/capi\">腾讯云控制台/API密钥管理</a> 生成API密钥\n</div>\n</div>\n\n```properties\n# 环境ID\nCLOUDBASE_ENV_ID={%ENV_ID%}\n\n# 腾讯云API密钥ID\nCLOUDBASE_SECRET_ID={%SECRET_ID%}\n\n# 腾讯云API密钥Key\nCLOUDBASE_SECRET_KEY={%SECRET_KEY%}\n```",
            "index": 2,
            "title": ".env",
            "content": []
          }
        ]
      },
      {
        "sideTabs": [
          {
            "id": "pg-db",
            "title": "PostgreSQL 数据库"
          }
        ],
        "index": 3,
        "title": "调用云开发能力",
        "type": "codeTab",
        "content": [
          {
            "index": 1,
            "id": "pg-db",
            "title": "PostgreSQL 数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\n// 查询 {%TABLE_NAME%} 表前 10 条数据\nconst { data, error } = await cloudbase.rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .select(\"*\")\n  .limit(10);\n\nconsole.log(\"查询结果:\", data);\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\n// 向 {%TABLE_NAME%} 表插入一条数据\n// 注意：anon 令牌（publishable key）仅有读权限，写操作需用户登录态或配置 RLS 写策略\nconst { data, error } = await cloudbase.rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .insert({ title: \"新文章\", status: \"draft\" })\n  .select();\n\nconsole.log(\"新增结果:\", data);\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\n// 更新 {%TABLE_NAME%} 表中 id=1 的记录\n// 注意：anon 令牌（publishable key）仅有读权限，写操作需用户登录态或配置 RLS 写策略\nconst { data, error } = await cloudbase.rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .update({ status: \"published\" })\n  .eq(\"id\", 1)\n  .select();\n\nconsole.log(\"更新结果:\", data);\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\n// 当 id 冲突时更新，否则插入\n// 注意：anon 令牌（publishable key）仅有读权限，写操作需用户登录态或配置 RLS 写策略\nconst { data, error } = await cloudbase.rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .upsert({ id: 1, title: \"标题\", status: \"published\" }, { onConflict: \"id\" })\n  .select();\n\nconsole.log(\"更新或创建结果:\", data);\n```",
                "index": 4,
                "title": "更新或创建数据"
              },
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\n// 删除 {%TABLE_NAME%} 表中 id=1 的记录\n// 注意：anon 令牌（publishable key）仅有读权限，写操作需用户登录态或配置 RLS 写策略\nconst { data, error } = await cloudbase.rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .delete()\n  .eq(\"id\", 1);\n\nconsole.log(\"删除完成:\", error);\n```",
                "index": 5,
                "title": "删除数据"
              }
            ]
          },
          {
            "index": 1,
            "id": "mysql-db",
            "title": "MySQL数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function getData() {\n  // 查询 {%TABLE_NAME%} 表前10条数据\n  const { data, error } = await cloudbase\n    .rdb()\n    .from(\"{%TABLE_NAME%}\")\n    .select(\"*\")\n    .limit(10);\n\n  if (!error) {\n    console.log(\"查询成功:\", data);\n    return data;\n  } else {\n    console.error(\"查询失败:\", error);\n  }\n}\n\ngetData();\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function addData() {\n  // 新增 {%TABLE_NAME%} 表数据\n  const { data, error } = await cloudbase\n    .rdb()\n    .from(\"{%TABLE_NAME%}\")\n    .insert({ title: \"示例标题\" });\n\n  if (!error) {\n    console.log(\"新增成功:\", data);\n  } else {\n    console.error(\"新增失败:\", error);\n  }\n}\n\naddData();\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function updateData() {\n  // 更新 {%TABLE_NAME%} 表中 id 为指定值的数据\n  const { data, error } = await cloudbase\n    .rdb()\n    .from(\"{%TABLE_NAME%}\")\n    .update({ title: \"新标题\" })\n    .eq(\"id\", \"<数据id>\");\n\n  if (!error) {\n    console.log(\"更新成功:\", data);\n  } else {\n    console.error(\"更新失败:\", error);\n  }\n}\n\nupdateData();\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function upsertData() {\n  // 如果 {%TABLE_NAME%} 表中存在 id 为 1 的记录则更新 title 为\"示例标题\"，不存在则插入新记录\n  const { data, error } = await cloudbase\n    .rdb()\n    .from(\"{%TABLE_NAME%}\")\n    .upsert({ id: 1, title: \"示例标题\" });\n\n  if (!error) {\n    console.log(\"操作成功:\", data);\n  } else {\n    console.error(\"操作失败:\", error);\n  }\n}\n\nupsertData();\n```",
                "index": 4,
                "title": "更新或创建数据"
              },
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function deleteData() {\n  // 删除 {%TABLE_NAME%} 表中 id 为指定值的数据\n  const { data, error } = await cloudbase\n    .rdb()\n    .from(\"{%TABLE_NAME%}\")\n    .delete()\n    .eq(\"id\", \"<数据id>\");\n\n  if (!error) {\n    console.log(\"删除成功:\", data);\n  } else {\n    console.error(\"删除失败:\", error);\n  }\n}\n\ndeleteData();\n```",
                "index": 5,
                "title": "删除数据"
              }
            ]
          },
          {
            "index": 2,
            "id": "doc-db",
            "title": "文档型数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function getData() {\n  // 查询 {%TABLE_NAME%} 表前10条数据\n  const db = cloudbase.database();\n  const res = await db.collection(\"{%TABLE_NAME%}\").limit(10).get();\n\n  console.log(\"查询成功:\", res.data);\n  return res.data;\n}\n\ngetData();\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function addData() {\n  try {\n    // 新增 {%TABLE_NAME%} 表数据\n    const db = cloudbase.database();\n    const res = await db\n      .collection(\"{%TABLE_NAME%}\")\n      .add({ title: \"示例标题\" });\n\n    console.log(`新增成功! id: ${res.id}`);\n  } catch (error) {\n    console.error(\"新增失败:\", error);\n  }\n}\n\naddData();\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function updateData() {\n  try {\n    // 更新 {%TABLE_NAME%} 表中 id 为指定值的数据\n    const db = cloudbase.database();\n    await db\n      .collection(\"{%TABLE_NAME%}\")\n      .doc(\"<数据id>\")\n      .update({ title: \"新标题\" });\n\n    console.log(\"更新成功!\");\n  } catch (error) {\n    console.error(\"更新失败:\", error);\n  }\n}\n\nupdateData();\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function deleteData() {\n  try {\n    // 删除 {%TABLE_NAME%} 表中 id 为指定值的数据\n    const db = cloudbase.database();\n    await db.collection(\"{%TABLE_NAME%}\").doc(\"<数据id>\").remove();\n\n    console.log(\"删除成功!\");\n  } catch (error) {\n    console.error(\"删除失败:\", error);\n  }\n}\n\ndeleteData();\n```",
                "index": 4,
                "title": "删除数据"
              }
            ]
          },
          {
            "index": 3,
            "id": "data-model",
            "title": "数据模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function getData() {\n  // 查询 {%TABLE_NAME%} 数据模型前10条数据\n  const res = await cloudbase.models[\"{%TABLE_NAME%}\"].list({\n    pageNumber: 1,\n    pagesize: 10\n  });\n\n  console.log(\"查询成功:\", res.data?.records);\n  return res.data?.records;\n}\n\ngetData();\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function addData() {\n  try {\n    // 新增 {%TABLE_NAME%} 数据模型数据\n    const res = await cloudbase.models[\"{%TABLE_NAME%}\"].create({\n      data: { title: \"示例标题\" }\n    });\n\n    console.log(`新增成功! id: ${res.data.id}`);\n  } catch (error) {\n    console.error(\"新增失败:\", error);\n  }\n}\n\naddData();\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function updateData() {\n  try {\n    // 更新 {%TABLE_NAME%} 数据模型中 _id 为指定值的数据\n    await cloudbase.models[\"{%TABLE_NAME%}\"].update({\n      data: { title: \"新标题\" },\n      filter: { where: { _id: { $eq: \"<数据id>\" } } }\n    });\n\n    console.log(\"更新成功!\");\n  } catch (error) {\n    console.error(\"更新失败:\", error);\n  }\n}\n\nupdateData();\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function deleteData() {\n  try {\n    // 删除 {%TABLE_NAME%} 数据模型中 _id 为指定值的数据\n    await cloudbase.models[\"{%TABLE_NAME%}\"].delete({\n      filter: { where: { _id: { $eq: \"<数据id>\" } } }\n    });\n\n    console.log(\"删除成功!\");\n  } catch (error) {\n    console.error(\"删除失败:\", error);\n  }\n}\n\ndeleteData();\n```",
                "index": 4,
                "title": "删除数据"
              }
            ]
          },
          {
            "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function callFunction() {\n  // 调用 {%FUNCTION_NAME%} 云函数\n  const res = await cloudbase.callFunction({\n    name: \"{%FUNCTION_NAME%}\",\n    data: {}\n  });\n\n  console.log(\"云函数返回:\", res.result);\n  return res.result;\n}\n\ncallFunction();\n```",
            "index": 4,
            "id": "scf",
            "title": "云函数",
            "content": []
          },
          {
            "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function callRun() {\n  // 调用 {%SERVICE_NAME%} 云托管服务\n  const res = await cloudbase.callContainer({\n    name: \"{%SERVICE_NAME%}\"\n    method: 'POST',\n    path: '/',\n    header:{\n      'Content-Type': 'application/json; charset=utf-8'\n    },\n    data: {},\n  });\n}\n\ncallRun();\n```",
            "index": 5,
            "id": "run",
            "title": "云托管",
            "content": []
          },
          {
            "index": 6,
            "id": "storage",
            "title": "云存储",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\nconst fs = require(\"fs\");\n\nasync function uploadFile() {\n  const filePath = \"./example.png\"; // 本地文件路径\n  const cloudPath = `images/${Date.now()}-example.png`; // 上传至云端的路径\n\n  const res = await cloudbase.uploadFile({\n    cloudPath: cloudPath,\n    fileContent: fs.createReadStream(filePath)\n  });\n\n  console.log(\"上传成功:\", res.fileID);\n  return res.fileID;\n}\n\nuploadFile();\n```",
                "index": 1,
                "title": "上传文件"
              },
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function getFileUrl() {\n  const res = await cloudbase.getTempFileURL({\n    fileList: [\"cloud://xxx.png\"] // 文件 fileID 列表\n  });\n\n  console.log(\"文件链接:\", res.fileList[0].tempFileURL);\n  return res.fileList[0].tempFileURL;\n}\n\ngetFileUrl();\n```",
                "index": 2,
                "title": "获取文件链接"
              },
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\nconst fs = require(\"fs\");\n\nasync function downloadFile() {\n  const res = await cloudbase.downloadFile({\n    fileID: \"cloud://xxx.png\" // 文件 fileID\n  });\n\n  // 将文件保存到本地\n  fs.writeFileSync(\"./downloaded-file.png\", res.fileContent);\n  console.log(\"下载成功!\");\n}\n\ndownloadFile();\n```",
                "index": 3,
                "title": "下载文件"
              },
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function deleteFile() {\n  const res = await cloudbase.deleteFile({\n    fileList: [\"cloud://xxx.png\"] // 文件 fileID 列表\n  });\n\n  if (res.fileList[0].code === \"SUCCESS\") {\n    console.log(\"删除成功!\");\n  } else {\n    console.error(\"删除失败:\", res.fileList);\n  }\n}\n\ndeleteFile();\n```",
                "index": 4,
                "title": "删除文件"
              }
            ]
          },
          {
            "index": 7,
            "id": "ai-model",
            "title": "大模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function callAIModel(input) {\n  const ai = cloudbase.ai();\n  // 使用自定义模型请修改为对应的模型提供商标识符\n  const model = ai.createModel(\"{%AI_MODEL_NAME%}\");\n\n  try {\n    const res = await model.streamText({\n      model: \"{%AI_SUB_MODEL_NAME%}\",\n      messages: [\n        {\n          role: \"system\",\n          content:\n            \"请严格按照七言绝句或七言律诗的格律要求创作，平仄需符合规则，押韵要和谐自然，韵脚字需在同一韵部。\"\n        },\n        { role: \"user\", content: input }\n      ]\n    });\n\n    let response = \"\";\n    for await (let str of res.textStream) {\n      process.stdout.write(str);\n      response += str;\n    }\n    return response;\n  } catch (err) {\n    console.error(\"error:\", err);\n    return null;\n  }\n}\n\n// 调用示例\ncallAIModel(\"春天\");\n```",
                "index": 1,
                "title": "SDK调用"
              },
              {
                "markdown": "<div class=\"tea-alert tea-alert--brand\" style=\"padding:9px calc(var(--tea-space-100)*4)\">\n<div class=\"tea-alert__info\">\n前往 <a target=\"_blank\" class=\"tea-link-external\" style=\"text-decoration:underline\" href=\"https://tcb.cloud.tencent.com/dev#/env/apikey\">环境配置</a> 获取服务端 API Key。\n</div>\n</div>\n\n**安装依赖**\n\n```bash\nnpm i @langchain/openai\n```\n\n**使用示例：**\n\n```js\nconst { ChatOpenAI } = require(\"@langchain/openai\");\n\nconst model = new ChatOpenAI({\n  modelName: \"{%AI_SUB_MODEL_NAME%}\",\n  apiKey: \"<CLOUDBASE_API_KEY>\",\n  configuration: {\n    baseURL: \"https://{%ENV_ID%}.api.tcloudbasegateway.com/v1/ai/{%AI_MODEL_NAME%}\"\n  }\n});\n\nasync function main() {\n  const response = await model.invoke(\"你好\");\n  console.log(\"AI回答:\", response.content);\n}\n\nmain();\n```",
                "index": 2,
                "title": "LangChain"
              },
              {
                "markdown": "<div class=\"tea-alert tea-alert--brand\" style=\"padding:9px calc(var(--tea-space-100)*4)\">\n<div class=\"tea-alert__info\">\n前往 <a target=\"_blank\" class=\"tea-link-external\" style=\"text-decoration:underline\" href=\"https://tcb.cloud.tencent.com/dev#/env/apikey\">环境配置</a> 获取服务端 API Key。\n</div>\n</div>\n\n**安装依赖**\n\n```bash\nnpm i openai\n```\n\n**使用示例：**\n\n```js\nconst OpenAI = require(\"openai\");\n\nconst client = new OpenAI({\n  apiKey: \"<CLOUDBASE_API_KEY>\",\n  baseURL: \"https://{%ENV_ID%}.api.tcloudbasegateway.com/v1/ai/{%AI_MODEL_NAME%}\"\n});\n\nasync function main() {\n  const completion = await client.chat.completions.create({\n    model: \"{%AI_SUB_MODEL_NAME%}\",\n    messages: [\n      { role: \"user\", content: \"hi\" }\n    ],\n    temperature: 0.3,\n    stream: true\n  });\n\n  for await (const chunk of completion) {\n    console.log(chunk);\n  }\n}\n\nmain();\n```",
                "index": 3,
                "title": "OpenAI SDK"
              },
              {
                "markdown": "生图模型通过调用云函数来实现，在生图模型页面点击「一键创建云函数」，函数调用示例如下：\n\n```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function generateImage() {\n  // 调用生图云函数\n  const res = await cloudbase.callFunction({\n    name: \"<YOUR_FUNCTION_NAME>\",\n    data: {\n      prompt: \"一只可爱的猫咪在阳光下玩耍\"\n    }\n  });\n\n  const result = res.result;\n\n  if (result.success) {\n    // 生成成功\n    console.log(\"生成成功!\");\n    console.log(\"图片URL:\", result.imageUrl);\n    console.log(\"优化后的提示词:\", result.revised_prompt);\n\n    // 使用图片\n    // 注意：图片URL有效期为24小时，请及时保存或转存\n  } else {\n    // 生成失败\n    console.error(\"生成失败:\", result.code, result.message);\n  }\n}\n\ngenerateImage();\n```",
                "index": 4,
                "id": "image-aiModel",
                "title": "生图模型"
              }
            ]
          },
          {
            "markdown": "",
            "index": 8,
            "id": "agent",
            "title": "Agent",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\nconst { cloudbase } = require('./utils/cloudbase');\n\nasync function callAgent(input) {\n  const ai = cloudbase.ai();\n  await auth.signInAnonymously();\n\n  try {\n    console.log('正在生成答案...');\n    const res = await ai.bot.sendMessage({\n      botId: '{%AGENT_ID%}', // 替换为你的AgentId\n      // 入参结构参考前后端通信协议：\n      //  https://docs.cloudbase.net/ai/agent/http-agent-protocol\n      threadId: '550e8400-e29b-41d4-a716-446655440000',\n      runId: 'run_001',\n      messages: [\n        {\n          id: 'msg_001',\n          role: 'user',\n          content: '你好',\n        },\n      ],\n      tools: [],\n      context: [],\n      state: {},\n      forwardedProps: {},\n    });\n\n    let response = '';\n    for await (let str of res.textStream) {\n      process.stdout.write(str);\n      response += str;\n    }\n    console.log('\\n生成完成！');\n    return response;\n  } catch (err) {\n    console.error('生成失败:', err);\n    return null;\n  }\n}\n\n// 调用示例\ncallAgent('你是谁');\n\n```",
                "index": 0,
                "id": "scf",
                "title": "函数型"
              },
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function callAgent(input) {\n  const ai = cloudbase.ai();\n  await auth.signInAnonymously();\n\n  try {\n    console.log(\"正在生成答案...\");\n    const res = await ai.bot.sendMessage({\n      botId: \"{%AGENT_ID%}\", // 替换为你的AgentId\n      msg: input\n    });\n\n    let response = \"\";\n    for await (let str of res.textStream) {\n      process.stdout.write(str);\n      response += str;\n    }\n    console.log(\"\\n生成完成！\");\n    return response;\n  } catch (err) {\n    console.error(\"生成失败:\", err);\n    return null;\n  }\n}\n\n// 调用示例\ncallAgent(\"你是谁\");\n```",
                "index": 1,
                "id": "baas",
                "title": "普通型"
              }
            ]
          }
        ]
      }
    ],
    "_id": "743372846960e03b0b51a163769d7a31",
    "_openid": "anon",
    "createdAt": 1767956539595,
    "updatedAt": 1777691436951
  },
  {
    "category": "框架集成,前端框架,Vue(Vite)",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": 11,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/api-reference/webv2/initialization",
    "content": [
      {
        "markdown": "`@cloudbase/js-sdk` 可以让您在 Web 端(如 PC Web 页面、微信公众平台 H5 等)使用 JavaScript 访问 CloudBase 服务和资源。",
        "index": 1,
        "title": "安装 SDK",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```bash\nnpm i @cloudbase/js-sdk\n```",
            "index": 1,
            "title": "npm",
            "content": []
          },
          {
            "markdown": "```bash\nyarn add @cloudbase/js-sdk\n```",
            "index": 2,
            "title": "yarn",
            "content": []
          },
          {
            "markdown": "```bash\npnpm add @cloudbase/js-sdk\n```",
            "index": 3,
            "title": "pnpm",
            "content": []
          }
        ]
      },
      {
        "markdown": "新增如下代码到您的 Vue 项目",
        "index": 2,
        "title": "初始化 SDK",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```js\nimport cloudbaseSDK from \"@cloudbase/js-sdk\";\n\nexport const cloudbase = cloudbaseSDK.init({\n  env: import.meta.env.VITE_CLOUDBASE_ENV_ID,\n  region: import.meta.env.VITE_CLOUDBASE_REGION,\n  accessKey: import.meta.env.VITE_CLOUDBASE_ACCESS_KEY\n});\n```",
            "index": 1,
            "title": "src/utils/cloudbase.js",
            "content": []
          },
          {
            "markdown": "```properties\n# 环境ID\nVITE_CLOUDBASE_ENV_ID={%ENV_ID%}\n\n# 环境所在地域\nVITE_CLOUDBASE_REGION={%REGION%}\n\n# 匿名访问令牌\nVITE_CLOUDBASE_ACCESS_KEY={%PUBLISHABLE_KEY%}\n```",
            "index": 2,
            "title": ".env",
            "content": []
          }
        ]
      },
      {
        "index": 3,
        "title": "调用云开发能力",
        "type": "codeTab",
        "content": [
          {
            "index": 1,
            "id": "mysql-db",
            "title": "MySQL数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 查询 {%TABLE_NAME%} 表前10条数据\nconst { data: result, error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .select(\"*\")\n  .limit(10);\nif (!error) {\n  console.log(result);\n}\n```\n\n**完整示例:**\n\n```vue\n<template>\n  <ul>\n    <li v-for=\"item in data\" :key=\"item.id\">{{ item.title }}</li>\n  </ul>\n</template>\n\n<script setup>\nimport { ref, onMounted } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst data = ref([]);\n\nconst getData = async () => {\n  // 查询 {%TABLE_NAME%} 表前10条数据\n  const { data: result, error } = await cloudbase\n    .rdb()\n    .from(\"{%TABLE_NAME%}\")\n    .select(\"*\")\n    .limit(10);\n  if (!error) data.value = result || [];\n};\n\nonMounted(() => {\n  getData();\n});\n</script>\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 新增 {%TABLE_NAME%} 表数据\nconst { error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .insert({ title: \"示例标题\" });\nif (!error) {\n  console.log(\"新增成功\");\n}\n```\n\n**完整示例:**\n\n```vue\n<template>\n  <div>\n    <input v-model=\"title\" />\n    <button @click=\"addData\">新增</button>\n    <p v-if=\"message\" :style=\"{ color: message.includes(\"成功\") ? \"green\" : \"red\" }\">{{ message }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst title = ref(\"\");\nconst message = ref(\"\");\n\nconst addData = async () => {\n  // 新增 {%TABLE_NAME%} 表数据\n  const { error } = await cloudbase.rdb().from(\"{%TABLE_NAME%}\").insert({ title: title.value });\n  if (!error) {\n    title.value = \"\";\n    message.value = \"新增成功！\";\n  } else {\n    message.value = \"新增失败：\" + error.message;\n  }\n};\n</script>\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 更新 {%TABLE_NAME%} 表中 id 为指定值的数据\nconst { error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .update({ title: \"新标题\" })\n  .eq(\"id\", \"<数据id>\");\nif (!error) {\n  console.log(\"更新成功\");\n}\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <button @click=\"updateData\">更新</button>\n    <p v-if=\"message\" :style=\"{ color: message.includes(\"成功\") ? \"green\" : \"red\" }\">{{ message }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst message = ref(\"\");\n\nconst updateData = async () => {\n  // 更新 {%TABLE_NAME%} 表中 id 为指定值的数据\n  const { error } = await cloudbase.rdb().from(\"{%TABLE_NAME%}\").update({ title: \"新标题\" }).eq(\"id\", \"<数据id>\");\n  if (!error) {\n    message.value = \"更新成功！\";\n  } else {\n    message.value = \"更新失败：\" + error.message;\n  }\n};\n</script>\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 如果 {%TABLE_NAME%} 表中存在 id 为 1 的记录则更新 title 为\"示例标题\"，不存在则插入新记录\nconst { error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .upsert({ id: 1, title: \"示例标题\" });\nif (!error) {\n  console.log(\"操作成功\");\n}\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <button @click=\"upsertData\">更新或创建</button>\n    <p v-if=\"message\" :style=\"{ color: message.includes(\"成功\") ? \"green\" : \"red\" }\">{{ message }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst message = ref(\"\");\n\nconst upsertData = async () => {\n  // 如果 {%TABLE_NAME%} 表中存在 id 为 1 的记录则更新 title 为\"示例标题\"，不存在则插入新记录\n  const { error } = await cloudbase.rdb().from(\"{%TABLE_NAME%}\").upsert({ id: 1, title: \"示例标题\" });\n  if (!error) {\n    message.value = \"操作成功！\";\n  } else {\n    message.value = \"操作失败：\" + error.message;\n  }\n};\n</script>\n```",
                "index": 4,
                "title": "更新或创建数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 删除 {%TABLE_NAME%} 表中 id 为指定值的数据\nconst { error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .delete()\n  .eq(\"id\", \"<数据id>\");\nif (!error) {\n  console.log(\"删除成功\");\n}\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <button @click=\"deleteData\">删除</button>\n    <p v-if=\"message\" :style=\"{ color: message.includes(\"成功\") ? \"green\" : \"red\" }\">{{ message }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst message = ref(\"\");\n\nconst deleteData = async () => {\n  // 删除 {%TABLE_NAME%} 表中 id 为指定值的数据\n  const { error } = await cloudbase.rdb().from(\"{%TABLE_NAME%}\").delete().eq(\"id\", \"<数据id>\");\n  if (!error) {\n    message.value = \"删除成功！\";\n  } else {\n    message.value = \"删除失败：\" + error.message;\n  }\n};\n</script>\n```",
                "index": 5,
                "title": "删除数据"
              }
            ]
          },
          {
            "index": 2,
            "id": "doc-db",
            "title": "文档型数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 查询 {%TABLE_NAME%} 表前10条数据\nconst db = cloudbase.database();\nconst res = await db.collection(\"{%TABLE_NAME%}\").limit(10).get();\nconsole.log(res.data);\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <ul>\n    <li v-for=\"item in data\" :key=\"item._id\">{{ item.title }}</li>\n  </ul>\n</template>\n\n<script setup>\nimport { ref, onMounted } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst data = ref([]);\n\nconst getData = async () => {\n  // 查询 {%TABLE_NAME%} 表前10条数据\n  const db = cloudbase.database();\n  const res = await db.collection(\"{%TABLE_NAME%}\").limit(10).get();\n  data.value = res.data || [];\n};\n\nonMounted(() => {\n  getData();\n});\n</script>\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 新增 {%TABLE_NAME%} 表数据\nconst db = cloudbase.database();\nconst res = await db.collection(\"{%TABLE_NAME%}\").add({ title: \"示例标题\" });\nconsole.log(`新增成功! id: ${res.id}`);\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <button @click=\"addData\">新增</button>\n    <p v-if=\"message\" :style=\"{ color: message.includes(\"成功\") ? \"green\" : \"red\" }\">{{ message }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst message = ref(\"\");\n\nconst addData = async () => {\n  try {\n    // 新增 {%TABLE_NAME%} 表数据\n    const db = cloudbase.database();\n    const res = await db.collection(\"{%TABLE_NAME%}\").add({ title: \"示例标题\" });\n    message.value = `新增成功! id: ${res.id}`;\n  } catch (error) {\n    message.value = \"新增失败：\" + error.message;\n  }\n};\n</script>\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 更新 {%TABLE_NAME%} 表中 id 为指定值的数据\nconst db = cloudbase.database();\nawait db\n  .collection(\"{%TABLE_NAME%}\")\n  .doc(\"<数据id>\")\n  .update({ title: \"新标题\" });\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <button @click=\"updateData\">更新</button>\n    <p v-if=\"message\" :style=\"{ color: message.includes(\"成功\") ? \"green\" : \"red\" }\">{{ message }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst message = ref(\"\");\n\nconst updateData = async () => {\n  try {\n    // 更新 {%TABLE_NAME%} 表中 id 为指定值的数据\n    const db = cloudbase.database();\n    await db.collection(\"{%TABLE_NAME%}\").doc(\"<数据id>\").update({ title: \"新标题\" });\n    message.value = \"更新成功！\";\n  } catch (error) {\n    message.value = \"更新失败：\" + error.message;\n  }\n};\n</script>\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 删除 {%TABLE_NAME%} 表中 id 为指定值的数据\nconst db = cloudbase.database();\nawait db.collection(\"{%TABLE_NAME%}\").doc(\"<数据id>\").remove();\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <button @click=\"deleteData\">删除</button>\n    <p v-if=\"message\" :style=\"{ color: message.includes(\"成功\") ? \"green\" : \"red\" }\">{{ message }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst message = ref(\"\");\n\nconst deleteData = async () => {\n  try {\n    // 删除 {%TABLE_NAME%} 表中 id 为指定值的数据\n    const db = cloudbase.database();\n    await db.collection(\"{%TABLE_NAME%}\").doc(\"<数据id>\").remove();\n    message.value = \"删除成功！\";\n  } catch (error) {\n    message.value = \"删除失败：\" + error.message;\n  }\n};\n</script>\n```",
                "index": 4,
                "title": "删除数据"
              }
            ]
          },
          {
            "index": 3,
            "id": "data-model",
            "title": "数据模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 查询 {%TABLE_NAME%} 数据模型前10条数据\nconst res = await cloudbase.models[\"{%TABLE_NAME%}\"].list({\n  pageNumber: 1,\n  pagesize: 10\n});\nconsole.log(res.data?.records);\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <ul>\n    <li v-for=\"item in data\" :key=\"item._id\">{{ item.title }}</li>\n  </ul>\n</template>\n\n<script setup>\nimport { ref, onMounted } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst data = ref([]);\n\nconst getData = async () => {\n  // 查询 {%TABLE_NAME%} 数据模型前10条数据\n  const res = await cloudbase.models[\"{%TABLE_NAME%}\"].list({\n    pageNumber: 1,\n    pagesize: 10\n  });\n  data.value = res.data?.records || [];\n};\n\nonMounted(() => {\n  getData();\n});\n</script>\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 新增 {%TABLE_NAME%} 数据模型数据\nconst res = await cloudbase.models[\"{%TABLE_NAME%}\"].create({\n  data: { title: \"示例标题\" }\n});\nconsole.log(`新增成功! id: ${res.data.id}`);\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <button @click=\"addData\">新增</button>\n    <p v-if=\"message\" :style=\"{ color: message.includes(\"成功\") ? \"green\" : \"red\" }\">{{ message }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst message = ref(\"\");\n\nconst addData = async () => {\n  try {\n    // 新增 {%TABLE_NAME%} 数据模型数据\n    const res = await cloudbase.models[\"{%TABLE_NAME%}\"].create({ data: { title: \"示例标题\" } });\n    message.value = `新增成功! id: ${res.data.id}`;\n  } catch (error) {\n    message.value = \"新增失败：\" + error.message;\n  }\n};\n</script>\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 更新 {%TABLE_NAME%} 数据模型中 _id 为指定值的数据\nawait cloudbase.models[\"{%TABLE_NAME%}\"].update({\n  data: { title: \"新标题\" },\n  filter: { where: { _id: { $eq: \"<数据id>\" } } }\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <button @click=\"updateData\">更新</button>\n    <p v-if=\"message\" :style=\"{ color: message.includes(\"成功\") ? \"green\" : \"red\" }\">{{ message }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst message = ref(\"\");\n\nconst updateData = async () => {\n  try {\n    // 更新 {%TABLE_NAME%} 数据模型中 _id 为指定值的数据\n    await cloudbase.models[\"{%TABLE_NAME%}\"].update({\n      data: { title: \"新标题\" },\n      filter: { where: { _id: { $eq: \"<数据id>\" } } }\n    });\n    message.value = \"更新成功！\";\n  } catch (error) {\n    message.value = \"更新失败：\" + error.message;\n  }\n};\n</script>\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 删除 {%TABLE_NAME%} 数据模型中 _id 为指定值的数据\nawait cloudbase.models[\"{%TABLE_NAME%}\"].delete({\n  filter: { where: { _id: { $eq: \"<数据id>\" } } }\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <button @click=\"deleteData\">删除</button>\n    <p v-if=\"message\" :style=\"{ color: message.includes(\"成功\") ? \"green\" : \"red\" }\">{{ message }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst message = ref(\"\");\n\nconst deleteData = async () => {\n  try {\n    // 删除 {%TABLE_NAME%} 数据模型中 _id 为指定值的数据\n    await cloudbase.models[\"{%TABLE_NAME%}\"].delete({\n      filter: { where: { _id: { $eq: \"<数据id>\" } } }\n    });\n    message.value = \"删除成功！\";\n  } catch (error) {\n    message.value = \"删除失败：\" + error.message;\n  }\n};\n</script>\n```",
                "index": 4,
                "title": "删除数据"
              }
            ]
          },
          {
            "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 调用 {%FUNCTION_NAME%} 云函数\nconst res = await cloudbase.callFunction({\n  name: \"{%FUNCTION_NAME%}\",\n  data: {}\n});\nconsole.log(res.result);\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <button @click=\"getData\">调用云函数</button>\n    <pre v-if=\"data\">{{ JSON.stringify(data, null, 2) }}</pre>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst data = ref(null);\n\nconst getData = async () => {\n  // 调用 {%FUNCTION_NAME%} 云函数\n  const res = await cloudbase.callFunction({\n    name: \"{%FUNCTION_NAME%}\",\n    data: {}\n  });\n  data.value = res.result;\n};\n</script>\n```",
            "index": 4,
            "id": "scf",
            "title": "云函数",
            "content": []
          },
          {
            "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 调用 {%SERVICE_NAME%} 云托管服务\nconst res = await cloudbase.callContainer({\n  name: \"{%SERVICE_NAME%}\"\n  method: 'POST',\n  path: '/',\n  header:{\n    'Content-Type': 'application/json; charset=utf-8'\n  },\n  data: {},\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <button @click=\"getData\">调用云托管</button>\n    <pre v-if=\"data\">{{ JSON.stringify(data, null, 2) }}</pre>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst data = ref(null);\n\nconst getData = async () => {\n  // 调用 {%SERVICE_NAME%} 云托管服务\n  const res = await cloudbase.callContainer({\n    name: \"{%SERVICE_NAME%}\"\n    method: 'POST',\n    path: '/',\n    header:{\n      'Content-Type': 'application/json; charset=utf-8'\n    },\n    data: {},\n  });\n  data.value = res;\n};\n</script>\n```",
            "index": 5,
            "id": "run",
            "title": "云托管",
            "content": []
          },
          {
            "index": 6,
            "id": "storage",
            "title": "云存储",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst res = await cloudbase.uploadFile({\n  cloudPath: `images/${Date.now()}-${file.name}`, // 上传至云端的路径\n  filePath: file\n});\nconsole.log(res.fileID);\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <input type=\"file\" @change=\"uploadFile\" />\n    <p v-if=\"fileID\">上传成功: {{ fileID }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst fileID = ref(\"\");\n\nconst uploadFile = async e => {\n  const file = e.target.files[0];\n  const res = await cloudbase.uploadFile({\n    cloudPath: `images/${Date.now()}-${file.name}`, // 上传至云端的路径\n    filePath: file\n  });\n  fileID.value = res.fileID;\n};\n</script>\n```",
                "index": 1,
                "title": "上传文件"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst res = await cloudbase.getTempFileURL({\n  fileList: [\"cloud://xxx.png\"] // 文件 fileID 列表\n});\nconsole.log(res.fileList[0].tempFileURL);\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <button @click=\"getData\">获取链接</button>\n    <p v-if=\"fileUrl\">链接: {{ fileUrl }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst fileUrl = ref(\"\");\n\nconst getData = async () => {\n  const res = await cloudbase.getTempFileURL({\n    fileList: [\"cloud://xxx.png\"] // 文件 fileID 列表\n  });\n  fileUrl.value = res.fileList[0].tempFileURL;\n};\n</script>\n```",
                "index": 2,
                "title": "获取文件链接"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nawait cloudbase.downloadFile({\n  fileID: \"cloud://xxx.png\" // 文件 fileID\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <button @click=\"downloadFile\">下载文件</button>\n</template>\n\n<script setup>\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst downloadFile = async () => {\n  await cloudbase.downloadFile({\n    fileID: \"cloud://xxx.png\" // 文件 fileID\n  });\n};\n</script>\n```",
                "index": 3,
                "title": "下载文件"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst res = await cloudbase.deleteFile({\n  fileList: [\"cloud://xxx.png\"] // 文件 fileID 列表\n});\nif (res.fileList[0].code === \"SUCCESS\") {\n  console.log(\"删除成功\");\n}\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <button @click=\"deleteFile\">删除文件</button>\n    <p v-if=\"message\">{{ message }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst message = ref(\"\");\n\nconst deleteFile = async () => {\n  const res = await cloudbase.deleteFile({\n    fileList: [\"cloud://xxx.png\"] // 文件 fileID 列表\n  });\n  if (res.fileList[0].code === \"SUCCESS\") {\n    message.value = \"删除成功！\";\n  } else {\n    ((message.value = \"删除失败！\"), res.fileList);\n  }\n};\n</script>\n```",
                "index": 4,
                "title": "删除文件"
              }
            ]
          },
          {
            "index": 7,
            "id": "ai-model",
            "title": "大模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst res = await cloudbase\n  .ai()\n  .createModel(\"{%AI_MODEL_NAME%}\")\n  .streamText({\n    model: \"{%AI_SUB_MODEL_NAME%}\",\n    messages: [{ role: \"user\", content: \"你好\" }]\n  });\n\nfor await (let data of res.dataStream) {\n  // 如果有则打印思维链内容\n  const think = data?.choices?.[0]?.delta?.reasoning_content;\n  if (think) console.log(think);\n\n  // 打印生成文本内容\n  const text = data?.choices?.[0]?.delta?.content;\n  if (text) console.log(text);\n}\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <input v-model=\"input\" placeholder=\"请输入大模型对话内容\" />\n    <button @click=\"getData\">发送</button>\n    <p>{{ data }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst data = ref(\"\");\nconst input = ref(\"\");\n\nconst getData = async () => {\n  const res = await cloudbase\n    .ai()\n    .createModel(\"{%AI_MODEL_NAME%}\")\n    .streamText({\n      model: \"{%AI_SUB_MODEL_NAME%}\",\n      messages: [{ role: \"user\", content: input.value }]\n    });\n\n  let result = \"\";\n  for await (let item of res.dataStream) {\n    // 如果有则打印思维链内容\n    const think = item?.choices?.[0]?.delta?.reasoning_content;\n    if (think) {\n      result += think;\n    }\n\n    // 打印生成文本内容\n    const text = item?.choices?.[0]?.delta?.content;\n    if (text) result += text;\n\n    data.value = result;\n  }\n};\n</script>\n```",
                "index": 1,
                "id": "text-aiModel",
                "title": "生文模型"
              },
              {
                "markdown": "生图模型通过调用云函数来实现，在生图模型页面点击「一键创建云函数」，函数调用示例如下：\n\n**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 调用生图云函数\nconst res = await cloudbase.callFunction({\n  name: \"<YOUR_FUNCTION_NAME>\",\n  data: {\n    prompt: \"一只可爱的猫咪在阳光下玩耍\"\n  }\n});\n\nconst result = res.result;\n\nif (result.success) {\n  // 生成成功\n  console.log(\"生成成功!\");\n  console.log(\"图片URL:\", result.imageUrl);\n  console.log(\"优化后的提示词:\", result.revised_prompt);\n\n  // 使用图片\n  // 注意：图片URL有效期为24小时，请及时保存或转存\n} else {\n  // 生成失败\n  console.error(\"生成失败:\", result.code, result.message);\n}\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <input v-model=\"prompt\" placeholder=\"请输入图片描述\" />\n    <button @click=\"generateImage\" :disabled=\"!prompt || loading\">\n      {{ loading ? \"生成中...\" : \"生成图片\" }}\n    </button>\n    <p v-if=\"message\" :style=\"{ color: message.includes('成功') ? 'green' : 'red' }\">\n      {{ message }}\n    </p>\n    <div v-if=\"imageUrl\">\n      <img :src=\"imageUrl\" alt=\"生成的图片\" style=\"max-width: 100%\" />\n      <p style=\"font-size: 12px; color: #666\">\n        注意：图片URL有效期为24小时，请及时保存\n      </p>\n    </div>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst prompt = ref(\"\");\nconst imageUrl = ref(\"\");\nconst message = ref(\"\");\nconst loading = ref(false);\n\nconst generateImage = async () => {\n  loading.value = true;\n  message.value = \"\";\n  imageUrl.value = \"\";\n\n  try {\n    // 调用生图云函数\n    const res = await cloudbase.callFunction({\n      name: \"<YOUR_FUNCTION_NAME>\",\n      data: {\n        prompt: prompt.value\n      }\n    });\n\n    const result = res.result;\n\n    if (result.success) {\n      imageUrl.value = result.imageUrl;\n      message.value = \"生成成功！\";\n    } else {\n      message.value = `生成失败：${result.message}`;\n    }\n  } catch (error) {\n    message.value = \"调用失败：\" + error.message;\n  } finally {\n    loading.value = false;\n  }\n};\n</script>\n```",
                "index": 2,
                "id": "image-aiModel",
                "title": "生图模型"
              }
            ]
          },
          {
            "markdown": "",
            "index": 8,
            "id": "agent",
            "title": "Agent",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from './utils/cloudbase';\n\nconst res = await cloudbase.ai().bot.sendMessage({\n  botId: '{%AGENT_ID%}',\n  // 入参结构参考前后端通信协议：\n  //  https://docs.cloudbase.net/ai/agent/http-agent-protocol\n  threadId: '550e8400-e29b-41d4-a716-446655440000',\n  runId: 'run_001',\n  messages: [\n    {\n      id: 'msg_001',\n      role: 'user',\n      content: '你好',\n    },\n  ],\n  tools: [],\n  context: [],\n  state: {},\n  forwardedProps: {},\n});\n\nfor await (const data of res.dataStream) {\n  // 如果有则打印思维链内容\n  const think = data.reasoning_content;\n  if (think) console.log(think);\n\n  // 打印输出正文\n  const content = data.content;\n  if (content) console.log(content);\n}\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <input v-model=\"input\" placeholder=\"请输入Agent对话内容\" />\n    <button @click=\"getData\">发送</button>\n    <p>{{ data }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst data = ref(\"\");\nconst input = ref(\"\");\n\nconst getData = async () => {\n  const res = await cloudbase.ai().bot.sendMessage({\n    botId: \"{%AGENT_ID%}\",\n    // 入参结构参考前后端通信协议：\n    //  https://docs.cloudbase.net/ai/agent/http-agent-protocol\n    threadId: '550e8400-e29b-41d4-a716-446655440000',\n    runId: 'run_001',\n    messages: [\n      {\n        id: 'msg_001',\n        role: 'user',\n        content: input.value,\n      },\n    ],\n    tools: [],\n    context: [],\n    state: {},\n    forwardedProps: {},\n    });\n\n  let result = \"\";\n  for await (const item of res.dataStream) {\n    // 如果有则打印思维链内容\n    const think = item.reasoning_content;\n    if (think) {\n      result += think;\n    }\n\n    // 打印输出正文\n    const content = item.content;\n    if (content) result += content;\n\n    data.value = result;\n  }\n};\n</script>\n\n```",
                "index": 0,
                "id": "scf",
                "title": "函数型"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst res = await cloudbase.ai().bot.sendMessage({\n  botId: \"{%AGENT_ID%}\",\n  msg: \"你好\"\n});\n\nfor await (const data of res.dataStream) {\n  // 如果有则打印思维链内容\n  const think = data.reasoning_content;\n  if (think) console.log(think);\n\n  // 打印输出正文\n  const content = data.content;\n  if (content) console.log(content);\n}\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <input v-model=\"input\" placeholder=\"请输入Agent对话内容\" />\n    <button @click=\"getData\">发送</button>\n    <p>{{ data }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst data = ref(\"\");\nconst input = ref(\"\");\n\nconst getData = async () => {\n  const res = await cloudbase.ai().bot.sendMessage({\n    botId: \"{%AGENT_ID%}\",\n    msg: input.value\n  });\n\n  let result = \"\";\n  for await (const item of res.dataStream) {\n    // 如果有则打印思维链内容\n    const think = item.reasoning_content;\n    if (think) {\n      result += think;\n    }\n\n    // 打印输出正文\n    const content = item.content;\n    if (content) result += content;\n\n    data.value = result;\n  }\n};\n</script>\n```",
                "index": 1,
                "id": "baas",
                "title": "普通型"
              }
            ]
          },
          {
            "index": 9,
            "id": "identity",
            "title": "身份认证",
            "type": "sideTab",
            "content": [
              {
                "markdown": "使用 **短信验证码注册** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **短信验证码**\n\n**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ phone_number: phone });\n\n// 验证验证码\nconst verifyRes = await auth.verify({\n  verification_id: verificationId,\n  verification_code: code\n});\n\n// 注册（如用户已存在则自动登录）\nawait auth.signUp({\n  phone_number: `+86 ${phone}`,\n  verification_code: code,\n  verification_token: verifyRes.verification_token,\n  name: `user_${phone.slice(-4)}`,\n  password: \"admin@123\"\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <label>手机号：</label>\n    <input v-model=\"phone\" placeholder=\"13800000000\" />\n    <div>\n      <label>验证码：</label>\n      <input v-model=\"code\" placeholder=\"验证码\" />\n      <button :disabled=\"!phone\" @click=\"sendCode\">发送验证码</button>\n    </div>\n    <button :disabled=\"!verificationId || !code\" @click=\"register\">注册</button>\n    <p v-if=\"message\" :style=\"{ color: message.includes(\"成功\") ? \"green\" : \"red\" }\">{{ message }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst phone = ref(\"\");\nconst code = ref(\"\");\nconst verificationId = ref(\"\");\nconst message = ref(\"\");\n\n// 发送验证码\nconst sendCode = async () => {\n  try {\n    const auth = cloudbase.auth();\n    const res = await auth.getVerification({ phone_number: phone.value });\n    verificationId.value = res.verification_id;\n    message.value = \"验证码已发送！\";\n  } catch (error) {\n    message.value = \"发送失败：\" + error.message;\n  }\n};\n\n// 注册\nconst register = async () => {\n  try {\n    const auth = cloudbase.auth();\n    // 验证验证码\n    const verifyRes = await auth.verify({\n      verification_id: verificationId.value,\n      verification_code: code.value,\n    });\n    // 注册（如用户已存在则自动登录）\n    await auth.signUp({\n      phone_number: `+86 ${phone.value}`,\n      verification_code: code.value,\n      verification_token: verifyRes.verification_token,\n      name: `user_${phone.value.slice(-4)}`,\n      password: \"admin@123\"\n    });\n    message.value = \"注册成功！\";\n  } catch (error) {\n    message.value = \"注册失败：\" + error.message;\n  }\n};\n</script>\n```",
                "index": 1,
                "title": "短信验证码注册"
              },
              {
                "markdown": "使用 **邮箱验证码注册** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **邮箱验证码**\n\n**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ email });\n\n// 验证验证码\nconst verifyRes = await auth.verify({\n  verification_id: verificationId,\n  verification_code: code\n});\n\n// 注册（如用户已存在则自动登录）\nawait auth.signUp({\n  email,\n  verification_code: code,\n  verification_token: verifyRes.verification_token,\n  name: `user_${email.slice(-4)}`,\n  password: \"admin@123\"\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <label>邮箱：</label>\n    <input v-model=\"email\" placeholder=\"example@email.com\" />\n    <div>\n      <label>验证码：</label>\n      <input v-model=\"code\" placeholder=\"验证码\" />\n      <button :disabled=\"!email\" @click=\"sendCode\">发送验证码</button>\n    </div>\n    <button :disabled=\"!verificationId || !code\" @click=\"register\">注册</button>\n    <p v-if=\"message\" :style=\"{ color: message.includes(\"成功\") ? \"green\" : \"red\" }\">{{ message }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst email = ref(\"\");\nconst code = ref(\"\");\nconst verificationId = ref(\"\");\nconst message = ref(\"\");\n\n// 发送验证码\nconst sendCode = async () => {\n  try {\n    const auth = cloudbase.auth();\n    const res = await auth.getVerification({ email: email.value });\n    verificationId.value = res.verification_id;\n    message.value = \"验证码已发送！\";\n  } catch (error) {\n    message.value = \"发送失败：\" + error.message;\n  }\n};\n\n// 注册\nconst register = async () => {\n  try {\n    const auth = cloudbase.auth();\n    // 验证验证码\n    const verifyRes = await auth.verify({\n      verification_id: verificationId.value,\n      verification_code: code.value,\n    });\n    // 注册（如用户已存在则自动登录）\n    await auth.signUp({\n      email: email.value,\n      verification_code: code.value,\n      verification_token: verifyRes.verification_token,\n      name: `user_${email.value.slice(-4)}`,\n      password: \"admin@123\"\n    });\n    message.value = \"注册成功！\";\n  } catch (error) {\n    message.value = \"注册失败：\" + error.message;\n  }\n};\n</script>\n```",
                "index": 2,
                "title": "邮箱验证码注册"
              },
              {
                "markdown": "使用 **账号密码登录** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **用户名密码登录**\n\n**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\nawait auth.signIn({\n  username, // 可以是用户名、手机号或邮箱\n  password\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <label>账号：</label>\n    <input v-model=\"username\" placeholder=\"用户名/手机号/邮箱\" />\n    注：手机号登录请添加区号 +86\n    <br />\n    <label>密码：</label>\n    <input\n      type=\"password\"\n      v-model=\"password\"\n      placeholder=\"请输入密码\"\n    />\n    <br />\n    <button :disabled=\"!username || !password\" @click=\"login\">登录</button>\n    <p v-if=\"message\" :style=\"{ color: message.includes(\"成功\") ? \"green\" : \"red\" }\">{{ message }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst username = ref(\"\");\nconst password = ref(\"\");\nconst message = ref(\"\");\n\n// 登录\nconst login = async () => {\n  try {\n    const auth = cloudbase.auth();\n    await auth.signIn({\n      username: username.value, // 可以是用户名、手机号或邮箱\n      password: password.value,\n    });\n    message.value = \"登录成功！\";\n  } catch (error) {\n    message.value = \"登录失败：\" + error.message;\n  }\n};\n</script>\n```",
                "index": 3,
                "id": "UserNameLogin",
                "title": "账号密码登录"
              },
              {
                "markdown": "使用 **短信验证码登录** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **短信验证码登录**\n\n**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ phone_number: `+86 ${phone}` });\n\n// 登录\nawait auth.signInWithSms({\n  verificationInfo: res,\n  verificationCode: code,\n  phoneNum: `+86 ${phone}`\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <label>手机号：</label>\n    <input v-model=\"phone\" placeholder=\"13800000000\" />\n    <div>\n      <label>验证码：</label>\n      <input v-model=\"code\" placeholder=\"验证码\" />\n      <button @click=\"sendCode\" :disabled=\"!phone\">发送验证码</button>\n    </div>\n    <button @click=\"login\" :disabled=\"!verificationInfo || !code\">登录</button>\n    <p v-if=\"message\" :style=\"{ color: message.includes(\"成功\") ? \"green\" : \"red\" }\">{{ message }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst phone = ref(\"\");\nconst code = ref(\"\");\nconst verificationInfo = ref(null);\nconst message = ref(\"\");\n\n// 发送验证码\nconst sendCode = async () => {\n  try {\n    const auth = cloudbase.auth();\n    const res = await auth.getVerification({ phone_number: `+86 ${phone.value}` });\n    verificationInfo.value = res;\n    message.value = \"验证码已发送！\";\n  } catch (error) {\n    message.value = \"发送失败：\" + error.message;\n  }\n};\n\n// 登录\nconst login = async () => {\n  try {\n    const auth = cloudbase.auth();\n    await auth.signInWithSms({\n      verificationInfo: verificationInfo.value,\n      verificationCode: code.value,\n      phoneNum: `+86 ${phone.value}`\n    });\n    message.value = \"登录成功！\";\n  } catch (error) {\n    message.value = \"登录失败：\" + error.message;\n  }\n};\n</script>\n```",
                "index": 4,
                "id": "PhoneNumberLogin",
                "title": "短信验证码登录"
              },
              {
                "markdown": "使用 **邮箱验证码登录** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **邮箱验证码**\n\n**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ email });\n\n// 登录\nawait auth.signInWithEmail({\n  verificationInfo: res,\n  verificationCode: code,\n  email\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <label>邮箱：</label>\n    <input v-model=\"email\" placeholder=\"example@email.com\" />\n    <div>\n      <label>验证码：</label>\n      <input v-model=\"code\" placeholder=\"验证码\" />\n      <button @click=\"sendCode\" :disabled=\"!email\">发送验证码</button>\n    </div>\n    <button @click=\"login\" :disabled=\"!verificationInfo || !code\">登录</button>\n    <p v-if=\"message\" :style=\"{ color: message.includes(\"成功\") ? \"green\" : \"red\" }\">{{ message }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst email = ref(\"\");\nconst code = ref(\"\");\nconst verificationInfo = ref(null);\nconst message = ref(\"\");\n\n// 发送验证码\nconst sendCode = async () => {\n  try {\n    const auth = cloudbase.auth();\n    const res = await auth.getVerification({ email: email.value });\n    verificationInfo.value = res;\n    message.value = \"验证码已发送！\";\n  } catch (error) {\n    message.value = \"发送失败：\" + error.message;\n  }\n};\n\n// 登录\nconst login = async () => {\n  try {\n    const auth = cloudbase.auth();\n    await auth.signInWithEmail({\n      verificationInfo: verificationInfo.value,\n      verificationCode: code.value,\n      email: email.value\n    });\n    message.value = \"登录成功！\";\n  } catch (error) {\n    message.value = \"登录失败：\" + error.message;\n  }\n};\n</script>\n```",
                "index": 5,
                "id": "email",
                "title": "邮箱验证码登录"
              },
              {
                "markdown": "使用 **Google 授权登录** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **Google 授权登录**\n\n**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 步骤1：生成Google授权URL并跳转\nconst state = Date.now().toString();\nlocalStorage.setItem(\"google_login_state\", state);\nconst { uri } = await auth.genProviderRedirectUri({\n  provider_id: \"google\",\n  provider_redirect_uri: window.location.href,\n  state: state\n});\nwindow.location.href = uri;\n\n// 步骤2：使用code换取provider_token\nconst { provider_token } = await auth.grantProviderToken({\n  provider_id: \"google\",\n  provider_redirect_uri: window.location.origin + window.location.pathname,\n  provider_code: code\n});\n\n// 步骤3：使用provider_token登录\nawait auth.signInWithProvider({\n  provider_token: provider_token\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <button v-if=\"!isCallback\" @click=\"startGoogleLogin\">Google登录</button>\n    <p v-if=\"isCallback\">正在处理Google登录...</p>\n    <p v-if=\"message\" :style=\"{ color: message.includes(\"成功\") ? \"green\" : \"red\" }\">\n      {{ message }}\n    </p>\n  </div>\n</template>\n\n<script setup>\nimport { ref, onMounted } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst message = ref(\"\");\nconst isCallback = ref(false);\n\nonMounted(() => {\n  // 检查是否是Google回调页面\n  const urlParams = new URLSearchParams(window.location.search);\n  const code = urlParams.get(\"code\");\n  const state = urlParams.get(\"state\");\n\n  if (code && state) {\n    isCallback.value = true;\n    handleGoogleCallback(code, state);\n  }\n});\n\n// 步骤1：跳转到Google授权页\nconst startGoogleLogin = async () => {\n  try {\n    const auth = cloudbase.auth();\n    const state = Date.now().toString(); // 生成唯一标识，防止CSRF攻击\n\n    // 保存state到本地，用于回调时验证\n    localStorage.setItem(\"google_login_state\", state);\n\n    // 生成Google授权URL\n    const { uri } = await auth.genProviderRedirectUri({\n      provider_id: \"google\", // 固定值，代表Google开放平台\n      provider_redirect_uri: window.location.href, // 授权后回调当前页面\n      state: state,\n    });\n\n    // 跳转到Google授权页\n    window.location.href = uri;\n  } catch (error) {\n    message.value = \"跳转失败：\" + error.message;\n  }\n};\n\n// 步骤2和3：处理Google回调并完成登录\nconst handleGoogleCallback = async (code, state) => {\n  try {\n    // 验证state是否匹配，防止CSRF攻击\n    const savedState = localStorage.getItem(\"google_login_state\");\n    if (savedState !== state) {\n      message.value = \"登录失败：状态验证失败\";\n      return;\n    }\n\n    const auth = cloudbase.auth();\n\n    // 使用code换取provider_token\n    const { provider_token } = await auth.grantProviderToken({\n      provider_id: \"google\",\n      provider_redirect_uri: window.location.origin + window.location.pathname,\n      provider_code: code,\n    });\n\n    try {\n      // 尝试直接登录\n      await auth.signInWithProvider({\n        provider_token: provider_token,\n      });\n\n      message.value = \"登录成功！\";\n\n      // 清除URL参数并清除本地存储\n      localStorage.removeItem(\"google_login_state\");\n      window.history.replaceState({}, document.title, window.location.pathname);\n\n    } catch (loginError) {\n      // 如果是首次Google登录，需要先注册并绑定\n      if (loginError.error === \"not_found\") {\n        message.value = \"检测到首次Google登录，需要绑定账号...\";\n\n        // 这里需要引导用户完成注册流程\n        // 例如：收集手机号验证码进行注册\n        // 注册成功后调用 bindWithProvider 绑定Google身份\n\n        // 示例：假设已有其他方式注册的账号，直接绑定\n        await auth.bindWithProvider({\n          provider_token: provider_token,\n        });\n\n        // 绑定成功后重新登录\n        await auth.signInWithProvider({\n          provider_token: provider_token,\n        });\n\n        message.value = \"绑定并登录成功！\";\n\n        // 清除URL参数和本地存储\n        localStorage.removeItem(\"google_login_state\");\n        window.history.replaceState({}, document.title, window.location.pathname);\n\n      } else {\n        throw loginError;\n      }\n    }\n  } catch (error) {\n    message.value = \"登录失败：\" + error.message;\n    localStorage.removeItem(\"google_login_state\");\n  }\n};\n</script>\n```",
                "index": 6,
                "id": "google",
                "title": "Google 授权登录"
              }
            ]
          }
        ]
      }
    ],
    "_id": "7916cf0e6980628a0099b5211c573509",
    "_openid": "anon",
    "createdAt": 1770021514567,
    "updatedAt": 1770021514567
  },
  {
    "category": "框架集成,ORMs,Drizzle",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": 42,
    "hasTemplate": false,
    "docsUrl": "https://orm.drizzle.team/docs/get-started-mysql",
    "content": [
      {
        "markdown": "使用 `Drizzle` 操作 **MySQL数据库**\n```bash\nnpm install drizzle-orm mysql2\n```",
        "title": "安装依赖",
        "type": "",
        "content": []
      },
      {
        "markdown": "新增如下代码到您的 **Drizzle** 项目",
        "title": "使用示例",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```js\nimport { drizzle } from \"drizzle-orm/mysql2\";\nimport mysql from \"mysql2/promise\";\nimport { todos } from \"./schema.js\";\n\nasync function main() {\n  const connection = await mysql.createConnection(process.env.DATABASE_URL);\n  const db = drizzle(connection);\n\n  const allTodos = await db.select().from(todos);\n  console.log(allTodos);\n\n  await connection.end();\n}\n\nmain().catch(console.error);\n```",
            "title": "index.js"
          },
          {
            "markdown": "```js\nimport { mysqlTable, text } from \"drizzle-orm/mysql-core\";\n\nexport const todos = mysqlTable(\"todos\", {\n  id: text(\"_id\").primaryKey(),\n  title: text(\"title\"),\n});\n```",
            "id": "",
            "title": "schema.js"
          },
          {
            "markdown": "```\nDATABASE_URL=mysql://{%DATABASE_URL%}\n```",
            "id": "mysqlString",
            "title": ".env"
          }
        ]
      }
    ],
    "_id": "8656c02469649dce0bbc72b5405eb43c",
    "_openid": "anon",
    "createdAt": 1768201678814,
    "updatedAt": 1770105727531
  },
  {
    "category": "框架集成,移动端框架,React Native",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": 33,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/api-reference/webv2/adapter",
    "content": [
      {
        "markdown": "`@cloudbase/js-sdk` 配合 `@cloudbase/adapter-rn` 可以让您在 React Native 项目中使用 JavaScript 访问 CloudBase 服务和资源。",
        "index": 1,
        "title": "安装 SDK",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```bash\nnpm i @cloudbase/js-sdk @cloudbase/adapter-rn\n```",
            "index": 1,
            "title": "npm"
          },
          {
            "markdown": "```bash\nyarn add @cloudbase/js-sdk @cloudbase/adapter-rn\n```",
            "index": 2,
            "title": "yarn"
          },
          {
            "markdown": "```bash\npnpm add @cloudbase/js-sdk @cloudbase/adapter-rn\n```\n\niOS 需要安装原生依赖：\n\n```bash\ncd ios && pod install && cd ..\n```",
            "index": 3,
            "title": "pnpm"
          }
        ]
      },
      {
        "markdown": "新增如下代码到您的 React Native 项目",
        "index": 2,
        "title": "初始化 SDK",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```js\nimport cloudbaseSDK from \"@cloudbase/js-sdk\";\nimport adapter from \"@cloudbase/adapter-rn\";\n\ncloudbaseSDK.useAdapters(adapter);\n\nconst cloudbase = cloudbaseSDK.init({\n  // 环境 ID\n  env: \"{%ENV_ID%}\",\n  // 地域\n  region: \"{%REGION%}\",\n  // 匿名访问令牌\n  accessKey: \"{%PUBLISHABLE_KEY%}\"\n});\n\nexport default cloudbase;\n```",
            "index": 1,
            "title": "src/utils/cloudbase.js"
          }
        ]
      },
      {
        "index": 3,
        "title": "调用云开发能力",
        "type": "codeTab",
        "content": [
          {
            "index": 1,
            "id": "mysql-db",
            "title": "MySQL数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst { data, error } = await cloudbase\n  .database()\n  .from(\"{%TABLE_NAME%}\")\n  .select(\"*\")\n  .limit(10);\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, Button, FlatList, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function QueryData() {\n  const [dataList, setDataList] = useState([]);\n\n  // 查询数据\n  const getData = async () => {\n    try {\n      const { data, error } = await cloudbase\n        .database()\n        .from(\"{%TABLE_NAME%}\")\n        .select(\"*\")\n        .limit(10);\n\n      if (!error) {\n        setDataList(data);\n        Alert.alert(\"成功\", \"查询成功\");\n      } else {\n        Alert.alert(\"失败\", \"查询失败\");\n      }\n    } catch (error) {\n      Alert.alert(\"错误\", `查询失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Button title=\"查询数据\" onPress={getData} />\n      {dataList.length > 0 ? (\n        <FlatList\n          data={dataList}\n          keyExtractor={(item, index) => index.toString()}\n          renderItem={({ item }) => (\n            <View style={styles.item}>\n              <Text>{JSON.stringify(item)}</Text>\n            </View>\n          )}\n        />\n      ) : (\n        <Text>暂无数据</Text>\n      )}\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  item: {\n    padding: 10,\n    marginVertical: 5,\n    backgroundColor: \"#f9f9f9\",\n    borderRadius: 5\n  }\n});\n```",
                "index": 1,
                "title": "查询数据",
                "content": []
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst { data, error } = await cloudbase\n  .database()\n  .from(\"{%TABLE_NAME%}\")\n  .insert({ title });\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, TextInput, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function AddData() {\n  const [title, setTitle] = useState(\"\");\n\n  // 新增数据\n  const addData = async () => {\n    try {\n      const { data, error } = await cloudbase\n        .database()\n        .from(\"{%TABLE_NAME%}\")\n        .insert({ title });\n\n      if (!error) {\n        Alert.alert(\"成功\", \"新增成功\");\n        setTitle(\"\");\n      } else {\n        Alert.alert(\"失败\", \"新增失败\");\n      }\n    } catch (error) {\n      Alert.alert(\"错误\", `新增失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>标题：</Text>\n      <TextInput\n        style={styles.input}\n        value={title}\n        onChangeText={setTitle}\n        placeholder=\"请输入标题\"\n      />\n      <Button title=\"新增数据\" onPress={addData} disabled={!title} />\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  }\n});\n```",
                "index": 2,
                "title": "新增数据",
                "content": []
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst { data, error } = await cloudbase\n  .database()\n  .from(\"{%TABLE_NAME%}\")\n  .update({ title: newTitle })\n  .eq(\"id\", dataId);\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, TextInput, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function UpdateData() {\n  const [dataId, setDataId] = useState(\"\");\n  const [newTitle, setNewTitle] = useState(\"\");\n\n  // 更新数据\n  const updateData = async () => {\n    try {\n      const { data, error } = await cloudbase\n        .database()\n        .from(\"{%TABLE_NAME%}\")\n        .update({ title: newTitle })\n        .eq(\"id\", dataId);\n\n      if (!error) {\n        Alert.alert(\"成功\", \"更新成功\");\n        setDataId(\"\");\n        setNewTitle(\"\");\n      } else {\n        Alert.alert(\"失败\", \"更新失败\");\n      }\n    } catch (error) {\n      Alert.alert(\"错误\", `更新失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>数据ID：</Text>\n      <TextInput\n        style={styles.input}\n        value={dataId}\n        onChangeText={setDataId}\n        placeholder=\"请输入数据ID\"\n      />\n      <Text>新标题：</Text>\n      <TextInput\n        style={styles.input}\n        value={newTitle}\n        onChangeText={setNewTitle}\n        placeholder=\"请输入新标题\"\n      />\n      <Button\n        title=\"更新数据\"\n        onPress={updateData}\n        disabled={!dataId || !newTitle}\n      />\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  }\n});\n```",
                "index": 3,
                "title": "更新数据",
                "content": []
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst { data, error } = await cloudbase\n  .database()\n  .from(\"{%TABLE_NAME%}\")\n  .upsert({ id: parseInt(id), title });\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, TextInput, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function UpsertData() {\n  const [id, setId] = useState(\"\");\n  const [title, setTitle] = useState(\"\");\n\n  // 更新或创建数据\n  const upsertData = async () => {\n    try {\n      const { data, error } = await cloudbase\n        .database()\n        .from(\"{%TABLE_NAME%}\")\n        .upsert({ id: parseInt(id), title });\n\n      if (!error) {\n        Alert.alert(\"成功\", \"操作成功\");\n        setId(\"\");\n        setTitle(\"\");\n      } else {\n        Alert.alert(\"失败\", \"操作失败\");\n      }\n    } catch (error) {\n      Alert.alert(\"错误\", `操作失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>ID：</Text>\n      <TextInput\n        style={styles.input}\n        value={id}\n        onChangeText={setId}\n        placeholder=\"请输入ID\"\n        keyboardType=\"numeric\"\n      />\n      <Text>标题：</Text>\n      <TextInput\n        style={styles.input}\n        value={title}\n        onChangeText={setTitle}\n        placeholder=\"请输入标题\"\n      />\n      <Button\n        title=\"更新或创建\"\n        onPress={upsertData}\n        disabled={!id || !title}\n      />\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  }\n});\n```",
                "index": 4,
                "title": "更新或创建数据",
                "content": []
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst { data, error } = await cloudbase\n  .database()\n  .from(\"{%TABLE_NAME%}\")\n  .delete()\n  .eq(\"id\", dataId);\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, TextInput, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function DeleteData() {\n  const [dataId, setDataId] = useState(\"\");\n\n  // 删除数据\n  const deleteData = async () => {\n    try {\n      const { data, error } = await cloudbase\n        .database()\n        .from(\"{%TABLE_NAME%}\")\n        .delete()\n        .eq(\"id\", dataId);\n\n      if (!error) {\n        Alert.alert(\"成功\", \"删除成功\");\n        setDataId(\"\");\n      } else {\n        Alert.alert(\"失败\", \"删除失败\");\n      }\n    } catch (error) {\n      Alert.alert(\"错误\", `删除失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>数据ID：</Text>\n      <TextInput\n        style={styles.input}\n        value={dataId}\n        onChangeText={setDataId}\n        placeholder=\"请输入要删除的数据ID\"\n      />\n      <Button title=\"删除数据\" onPress={deleteData} disabled={!dataId} />\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  }\n});\n```",
                "index": 5,
                "title": "删除数据",
                "content": []
              }
            ]
          },
          {
            "index": 2,
            "id": "doc-db",
            "title": "文档型数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst db = cloudbase.database();\nconst res = await db.collection(\"{%TABLE_NAME%}\").limit(10).get();\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, Button, FlatList, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function QueryDocData() {\n  const [dataList, setDataList] = useState([]);\n\n  // 查询数据\n  const getData = async () => {\n    try {\n      const db = cloudbase.database();\n      const res = await db.collection(\"{%TABLE_NAME%}\").limit(10).get();\n\n      setDataList(res.data);\n      Alert.alert(\"成功\", \"查询成功\");\n    } catch (error) {\n      Alert.alert(\"错误\", `查询失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Button title=\"查询数据\" onPress={getData} />\n      {dataList.length > 0 ? (\n        <FlatList\n          data={dataList}\n          keyExtractor={(item, index) => index.toString()}\n          renderItem={({ item }) => (\n            <View style={styles.item}>\n              <Text>{JSON.stringify(item)}</Text>\n            </View>\n          )}\n        />\n      ) : (\n        <Text>暂无数据</Text>\n      )}\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  item: {\n    padding: 10,\n    marginVertical: 5,\n    backgroundColor: \"#f9f9f9\",\n    borderRadius: 5\n  }\n});\n```",
                "index": 1,
                "title": "查询数据",
                "content": []
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst db = cloudbase.database();\nconst res = await db.collection(\"{%TABLE_NAME%}\").add({ title });\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, TextInput, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function AddDocData() {\n  const [title, setTitle] = useState(\"\");\n\n  // 新增数据\n  const addData = async () => {\n    try {\n      const db = cloudbase.database();\n      const res = await db.collection(\"{%TABLE_NAME%}\").add({ title });\n\n      Alert.alert(\"成功\", `新增成功! id: ${res.id}`);\n      setTitle(\"\");\n    } catch (error) {\n      Alert.alert(\"错误\", `新增失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>标题：</Text>\n      <TextInput\n        style={styles.input}\n        value={title}\n        onChangeText={setTitle}\n        placeholder=\"请输入标题\"\n      />\n      <Button title=\"新增数据\" onPress={addData} disabled={!title} />\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  }\n});\n```",
                "index": 2,
                "title": "新增数据",
                "content": []
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst db = cloudbase.database();\nawait db.collection(\"{%TABLE_NAME%}\").doc(dataId).update({ title: newTitle });\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, TextInput, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function UpdateDocData() {\n  const [dataId, setDataId] = useState(\"\");\n  const [newTitle, setNewTitle] = useState(\"\");\n\n  // 更新数据\n  const updateData = async () => {\n    try {\n      const db = cloudbase.database();\n      await db\n        .collection(\"{%TABLE_NAME%}\")\n        .doc(dataId)\n        .update({ title: newTitle });\n\n      Alert.alert(\"成功\", \"更新成功\");\n      setDataId(\"\");\n      setNewTitle(\"\");\n    } catch (error) {\n      Alert.alert(\"错误\", `更新失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>数据ID：</Text>\n      <TextInput\n        style={styles.input}\n        value={dataId}\n        onChangeText={setDataId}\n        placeholder=\"请输入数据ID\"\n      />\n      <Text>新标题：</Text>\n      <TextInput\n        style={styles.input}\n        value={newTitle}\n        onChangeText={setNewTitle}\n        placeholder=\"请输入新标题\"\n      />\n      <Button\n        title=\"更新数据\"\n        onPress={updateData}\n        disabled={!dataId || !newTitle}\n      />\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  }\n});\n```",
                "index": 3,
                "title": "更新数据",
                "content": []
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst db = cloudbase.database();\nawait db.collection(\"{%TABLE_NAME%}\").doc(dataId).remove();\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, TextInput, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function DeleteDocData() {\n  const [dataId, setDataId] = useState(\"\");\n\n  // 删除数据\n  const deleteData = async () => {\n    try {\n      const db = cloudbase.database();\n      await db.collection(\"{%TABLE_NAME%}\").doc(dataId).remove();\n\n      Alert.alert(\"成功\", \"删除成功\");\n      setDataId(\"\");\n    } catch (error) {\n      Alert.alert(\"错误\", `删除失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>数据ID：</Text>\n      <TextInput\n        style={styles.input}\n        value={dataId}\n        onChangeText={setDataId}\n        placeholder=\"请输入要删除的数据ID\"\n      />\n      <Button title=\"删除数据\" onPress={deleteData} disabled={!dataId} />\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  }\n});\n```",
                "index": 4,
                "title": "删除数据",
                "content": []
              }
            ]
          },
          {
            "index": 3,
            "id": "data-model",
            "title": "数据模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst res = await cloudbase.models[\"{%TABLE_NAME%}\"].list({\n  pageNumber: 1,\n  pagesize: 10\n});\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, Button, FlatList, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function QueryModelData() {\n  const [dataList, setDataList] = useState([]);\n\n  // 查询数据\n  const getData = async () => {\n    try {\n      const res = await cloudbase.models[\"{%TABLE_NAME%}\"].list({\n        pageNumber: 1,\n        pagesize: 10\n      });\n\n      setDataList(res.data?.records || []);\n      Alert.alert(\"成功\", \"查询成功\");\n    } catch (error) {\n      Alert.alert(\"错误\", `查询失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Button title=\"查询数据\" onPress={getData} />\n      {dataList.length > 0 ? (\n        <FlatList\n          data={dataList}\n          keyExtractor={(item, index) => index.toString()}\n          renderItem={({ item }) => (\n            <View style={styles.item}>\n              <Text>{JSON.stringify(item)}</Text>\n            </View>\n          )}\n        />\n      ) : (\n        <Text>暂无数据</Text>\n      )}\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  item: {\n    padding: 10,\n    marginVertical: 5,\n    backgroundColor: \"#f9f9f9\",\n    borderRadius: 5\n  }\n});\n```",
                "index": 1,
                "title": "查询数据",
                "content": []
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst res = await cloudbase.models[\"{%TABLE_NAME%}\"].create({\n  data: { title }\n});\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, TextInput, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function AddModelData() {\n  const [title, setTitle] = useState(\"\");\n\n  // 新增数据\n  const addData = async () => {\n    try {\n      const res = await cloudbase.models[\"{%TABLE_NAME%}\"].create({\n        data: { title }\n      });\n\n      Alert.alert(\"成功\", `新增成功! id: ${res.data.id}`);\n      setTitle(\"\");\n    } catch (error) {\n      Alert.alert(\"错误\", `新增失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>标题：</Text>\n      <TextInput\n        style={styles.input}\n        value={title}\n        onChangeText={setTitle}\n        placeholder=\"请输入标题\"\n      />\n      <Button title=\"新增数据\" onPress={addData} disabled={!title} />\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  }\n});\n```",
                "index": 2,
                "title": "新增数据",
                "content": []
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nawait cloudbase.models[\"{%TABLE_NAME%}\"].update({\n  data: { title: newTitle },\n  filter: { where: { _id: { $eq: dataId } } }\n});\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, TextInput, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function UpdateModelData() {\n  const [dataId, setDataId] = useState(\"\");\n  const [newTitle, setNewTitle] = useState(\"\");\n\n  // 更新数据\n  const updateData = async () => {\n    try {\n      await cloudbase.models[\"{%TABLE_NAME%}\"].update({\n        data: { title: newTitle },\n        filter: { where: { _id: { $eq: dataId } } }\n      });\n\n      Alert.alert(\"成功\", \"更新成功\");\n      setDataId(\"\");\n      setNewTitle(\"\");\n    } catch (error) {\n      Alert.alert(\"错误\", `更新失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>数据ID：</Text>\n      <TextInput\n        style={styles.input}\n        value={dataId}\n        onChangeText={setDataId}\n        placeholder=\"请输入数据ID\"\n      />\n      <Text>新标题：</Text>\n      <TextInput\n        style={styles.input}\n        value={newTitle}\n        onChangeText={setNewTitle}\n        placeholder=\"请输入新标题\"\n      />\n      <Button\n        title=\"更新数据\"\n        onPress={updateData}\n        disabled={!dataId || !newTitle}\n      />\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  }\n});\n```",
                "index": 3,
                "title": "更新数据",
                "content": []
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nawait cloudbase.models[\"{%TABLE_NAME%}\"].delete({\n  filter: { where: { _id: { $eq: dataId } } }\n});\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, TextInput, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function DeleteModelData() {\n  const [dataId, setDataId] = useState(\"\");\n\n  // 删除数据\n  const deleteData = async () => {\n    try {\n      await cloudbase.models[\"{%TABLE_NAME%}\"].delete({\n        filter: { where: { _id: { $eq: dataId } } }\n      });\n\n      Alert.alert(\"成功\", \"删除成功\");\n      setDataId(\"\");\n    } catch (error) {\n      Alert.alert(\"错误\", `删除失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>数据ID：</Text>\n      <TextInput\n        style={styles.input}\n        value={dataId}\n        onChangeText={setDataId}\n        placeholder=\"请输入要删除的数据ID\"\n      />\n      <Button title=\"删除数据\" onPress={deleteData} disabled={!dataId} />\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  }\n});\n```",
                "index": 4,
                "title": "删除数据",
                "content": []
              }
            ]
          },
          {
            "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst res = await cloudbase.callFunction({\n  name: \"{%FUNCTION_NAME%}\",\n  data: {}\n});\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function CallFunction() {\n  const [result, setResult] = useState(null);\n\n  // 调用云函数\n  const callFunction = async () => {\n    try {\n      const res = await cloudbase.callFunction({\n        name: \"{%FUNCTION_NAME%}\",\n        data: {}\n      });\n\n      setResult(res.result);\n      Alert.alert(\"成功\", \"调用成功\");\n    } catch (error) {\n      Alert.alert(\"错误\", `调用失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Button title=\"调用云函数\" onPress={callFunction} />\n      {result && (\n        <View style={styles.resultContainer}>\n          <Text>返回结果：</Text>\n          <Text>{JSON.stringify(result)}</Text>\n        </View>\n      )}\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  resultContainer: {\n    marginTop: 20,\n    padding: 10,\n    backgroundColor: \"#f9f9f9\",\n    borderRadius: 5\n  }\n});\n```",
            "index": 4,
            "id": "scf",
            "title": "云函数"
          },
          {
            "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 调用 {%SERVICE_NAME%} 云托管服务\nconst res = await cloudbase.callContainer({\n  name: \"{%SERVICE_NAME%}\"\n  method: 'POST',\n  path: '/',\n  header:{\n    'Content-Type': 'application/json; charset=utf-8'\n  },\n  data: {},\n});\n```\n\n**完整示例：**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function CallRun() {\n  const [result, setResult] = useState(null);\n\n  // 调用云托管\n  const callRun = async () => {\n    try {\n      // 调用 {%SERVICE_NAME%} 云托管服务\n      const res = await cloudbase.callContainer({\n        name: \"{%SERVICE_NAME%}\"\n        method: 'POST',\n        path: '/',\n        header:{\n          'Content-Type': 'application/json; charset=utf-8'\n        },\n        data: {},\n      });\n\n      setResult(res);\n      Alert.alert(\"成功\", \"调用成功\");\n    } catch (error) {\n      Alert.alert(\"错误\", `调用失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Button title=\"调用云托管\" onPress={callRun} />\n      {result && (\n        <View style={styles.resultContainer}>\n          <Text>返回结果：</Text>\n          <Text>{JSON.stringify(result)}</Text>\n        </View>\n      )}\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  resultContainer: {\n    marginTop: 20,\n    padding: 10,\n    backgroundColor: \"#f9f9f9\",\n    borderRadius: 5\n  }\n});\n```",
            "index": 5,
            "id": "run",
            "title": "云托管"
          },
          {
            "index": 6,
            "id": "storage",
            "title": "云存储",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst res = await cloudbase.uploadFile({\n  cloudPath: cloudPath,\n  filePath: asset.uri\n});\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, Button, StyleSheet, Alert } from \"react-native\";\nimport { launchImageLibrary } from \"react-native-image-picker\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function UploadFile() {\n  const [fileId, setFileId] = useState(\"\");\n\n  // 上传文件\n  const uploadFile = async () => {\n    try {\n      const result = await launchImageLibrary({\n        mediaType: \"photo\",\n        quality: 0.8\n      });\n\n      if (result.didCancel) {\n        return;\n      }\n\n      if (result.errorCode) {\n        Alert.alert(\"错误\", \"选择图片失败\");\n        return;\n      }\n\n      const asset = result.assets[0];\n      const fileExtension = asset.fileName?.split(\".\").pop() || \"jpg\";\n      const cloudPath = `images/${Date.now()}-${Math.random()}.${fileExtension}`;\n\n      const res = await cloudbase.uploadFile({\n        cloudPath: cloudPath,\n        filePath: asset.uri\n      });\n\n      setFileId(res.fileID);\n      Alert.alert(\"成功\", \"上传成功\");\n    } catch (error) {\n      Alert.alert(\"错误\", `上传失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Button title=\"选择并上传图片\" onPress={uploadFile} />\n      {fileId && (\n        <View style={styles.resultContainer}>\n          <Text>上传成功！</Text>\n          <Text>文件ID: {fileId}</Text>\n        </View>\n      )}\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  resultContainer: {\n    marginTop: 20,\n    padding: 10,\n    backgroundColor: \"#f9f9f9\",\n    borderRadius: 5\n  }\n});\n```",
                "index": 1,
                "title": "上传文件",
                "content": []
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst res = await cloudbase.getTempFileURL({\n  fileList: [fileId]\n});\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport {\n  View,\n  Text,\n  TextInput,\n  Button,\n  Image,\n  StyleSheet,\n  Alert\n} from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function GetFileUrl() {\n  const [fileId, setFileId] = useState(\"\");\n  const [fileUrl, setFileUrl] = useState(\"\");\n\n  // 获取文件链接\n  const getFileUrl = async () => {\n    try {\n      const res = await cloudbase.getTempFileURL({\n        fileList: [fileId]\n      });\n\n      setFileUrl(res.fileList[0].tempFileURL);\n      Alert.alert(\"成功\", \"获取成功\");\n    } catch (error) {\n      Alert.alert(\"错误\", `获取失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>文件ID：</Text>\n      <TextInput\n        style={styles.input}\n        value={fileId}\n        onChangeText={setFileId}\n        placeholder=\"请输入文件ID (cloud://xxx.png)\"\n      />\n      <Button title=\"获取文件链接\" onPress={getFileUrl} disabled={!fileId} />\n      {fileUrl && (\n        <View style={styles.resultContainer}>\n          <Text>文件链接：</Text>\n          <Text>{fileUrl}</Text>\n          <Image\n            source={{ uri: fileUrl }}\n            style={styles.image}\n            resizeMode=\"contain\"\n          />\n        </View>\n      )}\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  },\n  resultContainer: {\n    marginTop: 20,\n    padding: 10,\n    backgroundColor: \"#f9f9f9\",\n    borderRadius: 5\n  },\n  image: {\n    width: \"100%\",\n    height: 200,\n    marginTop: 10\n  }\n});\n```",
                "index": 2,
                "title": "获取文件链接",
                "content": []
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst res = await cloudbase.downloadFile({\n  fileID: fileId\n});\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, TextInput, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function DownloadFile() {\n  const [fileId, setFileId] = useState(\"\");\n  const [localPath, setLocalPath] = useState(\"\");\n\n  // 下载文件\n  const downloadFile = async () => {\n    try {\n      const res = await cloudbase.downloadFile({\n        fileID: fileId\n      });\n\n      setLocalPath(res.tempFilePath);\n      Alert.alert(\"成功\", \"下载成功\");\n    } catch (error) {\n      Alert.alert(\"错误\", `下载失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>文件ID：</Text>\n      <TextInput\n        style={styles.input}\n        value={fileId}\n        onChangeText={setFileId}\n        placeholder=\"请输入文件ID (cloud://xxx.png)\"\n      />\n      <Button title=\"下载文件\" onPress={downloadFile} disabled={!fileId} />\n      {localPath && (\n        <View style={styles.resultContainer}>\n          <Text>下载成功！</Text>\n          <Text>本地路径: {localPath}</Text>\n        </View>\n      )}\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  },\n  resultContainer: {\n    marginTop: 20,\n    padding: 10,\n    backgroundColor: \"#f9f9f9\",\n    borderRadius: 5\n  }\n});\n```",
                "index": 3,
                "title": "下载文件",
                "content": []
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst res = await cloudbase.deleteFile({\n  fileList: [fileId]\n});\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, TextInput, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function DeleteFile() {\n  const [fileId, setFileId] = useState(\"\");\n\n  // 删除文件\n  const deleteFile = async () => {\n    try {\n      const res = await cloudbase.deleteFile({\n        fileList: [fileId]\n      });\n\n      if (res.fileList[0].code === \"SUCCESS\") {\n        Alert.alert(\"成功\", \"删除成功\");\n        setFileId(\"\");\n      } else {\n        Alert.alert(\"失败\", \"删除失败\");\n      }\n    } catch (error) {\n      Alert.alert(\"错误\", `删除失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>文件ID：</Text>\n      <TextInput\n        style={styles.input}\n        value={fileId}\n        onChangeText={setFileId}\n        placeholder=\"请输入文件ID (cloud://xxx.png)\"\n      />\n      <Button title=\"删除文件\" onPress={deleteFile} disabled={!fileId} />\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  }\n});\n```",
                "index": 4,
                "title": "删除文件",
                "content": []
              }
            ]
          },
          {
            "index": 7,
            "id": "ai-model",
            "title": "大模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst ai = cloudbase.ai();\nconst model = ai.createModel(\"{%AI_MODEL_NAME%}\");\n\n// 确保已登录\nconst loginState = await cloudbase.auth().getLoginState();\nif (!loginState) {\n  await cloudbase.auth().signInAnonymously();\n}\n\nconst res = await model.streamText({\n  model: \"{%AI_SUB_MODEL_NAME%}\",\n  messages: [\n    {\n      role: \"system\",\n      content:\n        \"请严格按照七言绝句或七言律诗的格律要求创作，平仄需符合规则，押韵要和谐自然，韵脚字需在同一韵部。\"\n    },\n    { role: \"user\", content: input }\n  ]\n});\n\nfor await (let str of res.textStream) {\n  // 处理流式响应\n}\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport {\n  View,\n  Text,\n  TextInput,\n  Button,\n  StyleSheet,\n  Alert,\n  ActivityIndicator\n} from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function CallAIModel() {\n  const [input, setInput] = useState(\"\");\n  const [response, setResponse] = useState(\"\");\n  const [isGenerating, setIsGenerating] = useState(false);\n\n  // 调用大模型\n  const callAIModel = async () => {\n    setIsGenerating(true);\n    setResponse(\"\");\n\n    try {\n      const ai = cloudbase.ai();\n      const model = ai.createModel(\"{%AI_MODEL_NAME%}\");\n\n      // 确保已登录\n      const loginState = await cloudbase.auth().getLoginState();\n      if (!loginState) {\n        await cloudbase.auth().signInAnonymously();\n      }\n\n      const res = await model.streamText({\n        model: \"{%AI_SUB_MODEL_NAME%}\",\n        messages: [\n          {\n            role: \"system\",\n            content:\n              \"请严格按照七言绝句或七言律诗的格律要求创作，平仄需符合规则，押韵要和谐自然，韵脚字需在同一韵部。\"\n          },\n          { role: \"user\", content: input }\n        ]\n      });\n\n      for await (let str of res.textStream) {\n        setResponse(prev => prev + str);\n      }\n\n      Alert.alert(\"成功\", \"生成完成\");\n    } catch (err) {\n      Alert.alert(\"错误\", `生成失败: ${err.message}`);\n    } finally {\n      setIsGenerating(false);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>输入主题：</Text>\n      <TextInput\n        style={styles.input}\n        value={input}\n        onChangeText={setInput}\n        placeholder=\"请输入主题，如：春天\"\n      />\n      <Button\n        title=\"生成内容\"\n        onPress={callAIModel}\n        disabled={!input || isGenerating}\n      />\n      {isGenerating && <ActivityIndicator size=\"large\" style={styles.loader} />}\n      {response && (\n        <View style={styles.resultContainer}>\n          <Text>生成结果：</Text>\n          <Text>{response}</Text>\n        </View>\n      )}\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  },\n  loader: {\n    marginVertical: 20\n  },\n  resultContainer: {\n    marginTop: 20,\n    padding: 10,\n    backgroundColor: \"#f9f9f9\",\n    borderRadius: 5\n  }\n});\n```",
                "index": 1,
                "id": "text-aiModel",
                "title": "生文模型",
                "content": []
              },
              {
                "markdown": "生图模型通过调用云函数来实现，在生图模型页面点击「一键创建云函数」，函数调用示例如下：\n\n**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst res = await cloudbase.callFunction({\n  name: \"<YOUR_FUNCTION_NAME>\",\n  data: { prompt: \"一只可爱的猫咪在阳光下玩耍\" }\n});\n\nif (res.result.success) {\n  console.log(\"图片URL:\", res.result.imageUrl);\n  console.log(\"优化后的提示词:\", res.result.revised_prompt);\n} else {\n  console.error(\"生成失败:\", res.result.code, res.result.message);\n}\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport {\n  View,\n  Text,\n  TextInput,\n  Button,\n  Image,\n  StyleSheet,\n  Alert,\n  ActivityIndicator\n} from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function GenerateImage() {\n  const [prompt, setPrompt] = useState(\"\");\n  const [imageUrl, setImageUrl] = useState(\"\");\n  const [revisedPrompt, setRevisedPrompt] = useState(\"\");\n  const [isGenerating, setIsGenerating] = useState(false);\n\n  // 生成图片\n  const generateImage = async () => {\n    setIsGenerating(true);\n    setImageUrl(\"\");\n    setRevisedPrompt(\"\");\n\n    try {\n      const res = await cloudbase.callFunction({\n        name: \"<YOUR_FUNCTION_NAME>\",\n        data: { prompt }\n      });\n\n      if (res.result.success) {\n        setImageUrl(res.result.imageUrl);\n        setRevisedPrompt(res.result.revised_prompt || \"\");\n        Alert.alert(\"成功\", \"图片生成成功\");\n      } else {\n        Alert.alert(\n          \"失败\",\n          `生成失败: ${res.result.code} - ${res.result.message}`\n        );\n      }\n    } catch (err) {\n      Alert.alert(\"错误\", `生成失败: ${err.message}`);\n    } finally {\n      setIsGenerating(false);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>输入描述：</Text>\n      <TextInput\n        style={styles.input}\n        value={prompt}\n        onChangeText={setPrompt}\n        placeholder=\"例如：一只可爱的猫咪在阳光下玩耍\"\n        multiline\n      />\n      <Button\n        title=\"生成图片\"\n        onPress={generateImage}\n        disabled={!prompt || isGenerating}\n      />\n      {isGenerating && <ActivityIndicator size=\"large\" style={styles.loader} />}\n      {imageUrl && (\n        <View style={styles.resultContainer}>\n          <Text style={styles.label}>生成结果：</Text>\n          <Image\n            source={{ uri: imageUrl }}\n            style={styles.image}\n            resizeMode=\"contain\"\n          />\n          {revisedPrompt && (\n            <View style={styles.promptContainer}>\n              <Text style={styles.label}>优化后的提示词：</Text>\n              <Text>{revisedPrompt}</Text>\n            </View>\n          )}\n          <Text style={styles.note}>注意：图片URL有效期为24小时</Text>\n        </View>\n      )}\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    minHeight: 80,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    paddingVertical: 10,\n    borderRadius: 5,\n    textAlignVertical: \"top\"\n  },\n  loader: {\n    marginVertical: 20\n  },\n  resultContainer: {\n    marginTop: 20,\n    padding: 10,\n    backgroundColor: \"#f9f9f9\",\n    borderRadius: 5\n  },\n  label: {\n    fontWeight: \"bold\",\n    marginBottom: 5\n  },\n  image: {\n    width: \"100%\",\n    height: 300,\n    marginVertical: 10\n  },\n  promptContainer: {\n    marginTop: 10\n  },\n  note: {\n    marginTop: 10,\n    fontSize: 12,\n    color: \"#666\",\n    fontStyle: \"italic\"\n  }\n});\n```",
                "index": 2,
                "id": "image-aiModel",
                "title": "生图模型",
                "content": []
              }
            ]
          },
          {
            "markdown": "",
            "index": 8,
            "id": "agent",
            "title": "Agent",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\n/**\n * React Native 调用 Agent 示例（AG-UI 协议）\n * 协议文档：https://docs.cloudbase.net/ai/agent-development/protocol\n */\nimport cloudbase from './utils/cloudbase';\n\n// 确保已登录\nconst loginState = await cloudbase.auth().getLoginState();\nif (!loginState) {\n  await cloudbase.auth().signInAnonymously();\n}\n\nconst ai = cloudbase.ai();\n\n// 构建消息列表（AG-UI 协议格式）\nconst messages = [\n  {\n    id: 'msg_001',\n    role: 'user',\n    content: input,\n  },\n];\n\n// AG-UI 协议请求参数\nconst res = await ai.bot.sendMessage({\n  botId: '{%AGENT_ID%}',\n  data: {\n    messages,                                            // 必填：消息列表\n    threadId: '550e8400-e29b-41d4-a716-446655440000',   // 可选：会话ID，用于多轮对话\n    runId: 'run_001',                                    // 可选：运行ID，用于追踪执行\n    tools: [],                                           // 可选：前端工具定义\n    context: [],                                         // 可选：上下文信息\n    forwardedProps: {},                                  // 可选：透传参数\n  },\n});\n\n// 处理流式响应\nfor await (const str of res.textStream) {\n  console.log(str);\n}\n\n```\n\n**完整示例:**\n\n```jsx\n/**\n * React Native 调用 Agent 完整示例（AG-UI 协议）\n * 协议文档：https://docs.cloudbase.net/ai/agent-development/protocol\n */\nimport React, { useState } from 'react';\nimport { View, Text, TextInput, Button, StyleSheet, Alert, ActivityIndicator } from 'react-native';\nimport cloudbase from './utils/cloudbase';\n\nexport default function CallAgent() {\n  const [input, setInput] = useState('');\n  const [response, setResponse] = useState('');\n  const [isGenerating, setIsGenerating] = useState(false);\n\n  // 调用Agent（AG-UI 协议）\n  const callAgent = async () => {\n    setIsGenerating(true);\n    setResponse('');\n\n    try {\n      const ai = cloudbase.ai();\n\n      // 确保已登录\n      const loginState = await cloudbase.auth().getLoginState();\n      if (!loginState) {\n        await cloudbase.auth().signInAnonymously();\n      }\n\n      // 构建消息列表（AG-UI 协议格式）\n      const messages = [\n        {\n          id: 'msg_001',\n          role: 'user',\n          content: input,\n        },\n      ];\n\n      // AG-UI 协议请求参数\n      const res = await ai.bot.sendMessage({\n        botId: '{%AGENT_ID%}',\n        data: {\n          messages,                                            // 必填：消息列表\n          threadId: '550e8400-e29b-41d4-a716-446655440000',   // 可选：会话ID，用于多轮对话\n          runId: 'run_001',                                    // 可选：运行ID，用于追踪执行\n          tools: [],                                           // 可选：前端工具定义\n          context: [],                                         // 可选：上下文信息\n          forwardedProps: {},                                  // 可选：透传参数\n        },\n      });\n\n      // 处理流式响应\n      for await (const str of res.textStream) {\n        setResponse((prev) => prev + str);\n      }\n\n      Alert.alert('成功', '生成完成');\n    } catch (err) {\n      Alert.alert('错误', `生成失败: ${err.message}`);\n    } finally {\n      setIsGenerating(false);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>输入问题：</Text>\n      <TextInput style={styles.input} value={input} onChangeText={setInput} placeholder=\"请输入问题，如：你是谁\" />\n      <Button title=\"发送消息\" onPress={callAgent} disabled={!input || isGenerating} />\n      {isGenerating && <ActivityIndicator size=\"large\" style={styles.loader} />}\n      {response && (\n        <View style={styles.resultContainer}>\n          <Text>回答：</Text>\n          <Text>{response}</Text>\n        </View>\n      )}\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20,\n  },\n  input: {\n    height: 40,\n    borderColor: '#ccc',\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5,\n  },\n  loader: {\n    marginVertical: 20,\n  },\n  resultContainer: {\n    marginTop: 20,\n    padding: 10,\n    backgroundColor: '#f9f9f9',\n    borderRadius: 5,\n  },\n});\n\n```",
                "index": 0,
                "id": "scf",
                "title": "函数型"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst ai = cloudbase.ai();\n\n// 确保已登录\nconst loginState = await cloudbase.auth().getLoginState();\nif (!loginState) {\n  await cloudbase.auth().signInAnonymously();\n}\n\nconst res = await ai.bot.sendMessage({\n  botId: \"{%AGENT_ID%}\",\n  msg: input\n});\n\nfor await (let str of res.textStream) {\n  // 处理流式响应\n}\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport {\n  View,\n  Text,\n  TextInput,\n  Button,\n  StyleSheet,\n  Alert,\n  ActivityIndicator\n} from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function CallAgent() {\n  const [input, setInput] = useState(\"\");\n  const [response, setResponse] = useState(\"\");\n  const [isGenerating, setIsGenerating] = useState(false);\n\n  // 调用Agent\n  const callAgent = async () => {\n    setIsGenerating(true);\n    setResponse(\"\");\n\n    try {\n      const ai = cloudbase.ai();\n\n      // 确保已登录\n      const loginState = await cloudbase.auth().getLoginState();\n      if (!loginState) {\n        await cloudbase.auth().signInAnonymously();\n      }\n\n      const res = await ai.bot.sendMessage({\n        botId: \"{%AGENT_ID%}\",\n        msg: input\n      });\n\n      for await (let str of res.textStream) {\n        setResponse(prev => prev + str);\n      }\n\n      Alert.alert(\"成功\", \"生成完成\");\n    } catch (err) {\n      Alert.alert(\"错误\", `生成失败: ${err.message}`);\n    } finally {\n      setIsGenerating(false);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>输入问题：</Text>\n      <TextInput\n        style={styles.input}\n        value={input}\n        onChangeText={setInput}\n        placeholder=\"请输入问题，如：你是谁\"\n      />\n      <Button\n        title=\"发送消息\"\n        onPress={callAgent}\n        disabled={!input || isGenerating}\n      />\n      {isGenerating && <ActivityIndicator size=\"large\" style={styles.loader} />}\n      {response && (\n        <View style={styles.resultContainer}>\n          <Text>回答：</Text>\n          <Text>{response}</Text>\n        </View>\n      )}\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  },\n  loader: {\n    marginVertical: 20\n  },\n  resultContainer: {\n    marginTop: 20,\n    padding: 10,\n    backgroundColor: \"#f9f9f9\",\n    borderRadius: 5\n  }\n});\n```",
                "index": 1,
                "id": "baas",
                "title": "普通型"
              }
            ]
          },
          {
            "index": 9,
            "id": "identity",
            "title": "身份认证",
            "type": "sideTab",
            "content": [
              {
                "markdown": "使用 **短信验证码注册** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **短信验证码**\n\n**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ phone_number: phone });\n\n// 验证验证码\nconst verifyRes = await auth.verify({\n  verification_id: verificationId,\n  verification_code: code\n});\n\n// 注册（如用户已存在则自动登录）\nawait auth.signUp({\n  phone_number: `+86 ${phone}`,\n  verification_code: code,\n  verification_token: verifyRes.verification_token,\n  name: `user_${phone.slice(-4)}`,\n  password: \"admin@123\"\n});\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, TextInput, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function SmsRegister() {\n  const [phone, setPhone] = useState(\"\");\n  const [code, setCode] = useState(\"\");\n  const [verificationId, setVerificationId] = useState(\"\");\n  const [message, setMessage] = useState(\"\");\n\n  // 发送验证码\n  const sendCode = async () => {\n    try {\n      const auth = cloudbase.auth();\n      const res = await auth.getVerification({ phone_number: phone });\n      setVerificationId(res.verification_id);\n      setMessage(\"验证码已发送！\");\n    } catch (error) {\n      setMessage(`发送失败: ${error.message}`);\n    }\n  };\n\n  // 注册\n  const register = async () => {\n    try {\n      const auth = cloudbase.auth();\n      // 验证验证码\n      const verifyRes = await auth.verify({\n        verification_id: verificationId,\n        verification_code: code\n      });\n      // 注册（如用户已存在则自动登录）\n      await auth.signUp({\n        phone_number: `+86 ${phone}`,\n        verification_code: code,\n        verification_token: verifyRes.verification_token,\n        name: `user_${phone.slice(-4)}`,\n        password: \"admin@123\"\n      });\n      setMessage(\"注册成功！\");\n      Alert.alert(\"成功\", \"注册成功\");\n    } catch (error) {\n      setMessage(`注册失败: ${error.message}`);\n      Alert.alert(\"失败\", `注册失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>手机号：</Text>\n      <TextInput\n        style={styles.input}\n        value={phone}\n        onChangeText={setPhone}\n        placeholder=\"13800000000\"\n        keyboardType=\"phone-pad\"\n      />\n      <Text>验证码：</Text>\n      <View style={styles.row}>\n        <TextInput\n          style={[styles.input, styles.codeInput]}\n          value={code}\n          onChangeText={setCode}\n          placeholder=\"验证码\"\n          keyboardType=\"numeric\"\n        />\n        <Button title=\"发送验证码\" onPress={sendCode} disabled={!phone} />\n      </View>\n      <Button\n        title=\"注册\"\n        onPress={register}\n        disabled={!verificationId || !code}\n      />\n      {message && (\n        <Text\n          style={[\n            styles.message,\n            { color: message.includes(\"成功\") ? \"green\" : \"red\" }\n          ]}\n        >\n          {message}\n        </Text>\n      )}\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  },\n  row: {\n    flexDirection: \"row\",\n    alignItems: \"center\"\n  },\n  codeInput: {\n    flex: 1,\n    marginRight: 10\n  },\n  message: {\n    marginTop: 20,\n    textAlign: \"center\"\n  }\n});\n```",
                "index": 1,
                "title": "短信验证码注册",
                "content": []
              },
              {
                "markdown": "使用 **邮箱验证码注册** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **邮箱验证码**\n\n**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ email });\n\n// 验证验证码\nconst verifyRes = await auth.verify({\n  verification_id: verificationId,\n  verification_code: code\n});\n\n// 注册（如用户已存在则自动登录）\nawait auth.signUp({\n  email,\n  verification_code: code,\n  verification_token: verifyRes.verification_token,\n  name: `user_${email.slice(-4)}`,\n  password: \"admin@123\"\n});\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, TextInput, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function EmailRegister() {\n  const [email, setEmail] = useState(\"\");\n  const [code, setCode] = useState(\"\");\n  const [verificationId, setVerificationId] = useState(\"\");\n  const [message, setMessage] = useState(\"\");\n\n  // 发送验证码\n  const sendCode = async () => {\n    try {\n      const auth = cloudbase.auth();\n      const res = await auth.getVerification({ email });\n      setVerificationId(res.verification_id);\n      setMessage(\"验证码已发送！\");\n    } catch (error) {\n      setMessage(`发送失败: ${error.message}`);\n    }\n  };\n\n  // 注册\n  const register = async () => {\n    try {\n      const auth = cloudbase.auth();\n      // 验证验证码\n      const verifyRes = await auth.verify({\n        verification_id: verificationId,\n        verification_code: code\n      });\n      // 注册（如用户已存在则自动登录）\n      await auth.signUp({\n        email,\n        verification_code: code,\n        verification_token: verifyRes.verification_token,\n        name: `user_${email.slice(-4)}`,\n        password: \"admin@123\"\n      });\n      setMessage(\"注册成功！\");\n      Alert.alert(\"成功\", \"注册成功\");\n    } catch (error) {\n      setMessage(`注册失败: ${error.message}`);\n      Alert.alert(\"失败\", `注册失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>邮箱：</Text>\n      <TextInput\n        style={styles.input}\n        value={email}\n        onChangeText={setEmail}\n        placeholder=\"example@email.com\"\n        keyboardType=\"email-address\"\n      />\n      <Text>验证码：</Text>\n      <View style={styles.row}>\n        <TextInput\n          style={[styles.input, styles.codeInput]}\n          value={code}\n          onChangeText={setCode}\n          placeholder=\"验证码\"\n          keyboardType=\"numeric\"\n        />\n        <Button title=\"发送验证码\" onPress={sendCode} disabled={!email} />\n      </View>\n      <Button\n        title=\"注册\"\n        onPress={register}\n        disabled={!verificationId || !code}\n      />\n      {message && (\n        <Text\n          style={[\n            styles.message,\n            { color: message.includes(\"成功\") ? \"green\" : \"red\" }\n          ]}\n        >\n          {message}\n        </Text>\n      )}\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  },\n  row: {\n    flexDirection: \"row\",\n    alignItems: \"center\"\n  },\n  codeInput: {\n    flex: 1,\n    marginRight: 10\n  },\n  message: {\n    marginTop: 20,\n    textAlign: \"center\"\n  }\n});\n```",
                "index": 2,
                "title": "邮箱验证码注册",
                "content": []
              },
              {
                "markdown": "使用 **账号密码登录** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **用户名密码登录**\n\n**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\nawait auth.signIn({\n  username, // 可以是用户名、手机号或邮箱\n  password\n});\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, TextInput, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function PasswordLogin() {\n  const [username, setUsername] = useState(\"\");\n  const [password, setPassword] = useState(\"\");\n  const [message, setMessage] = useState(\"\");\n\n  // 登录\n  const login = async () => {\n    try {\n      const auth = cloudbase.auth();\n      await auth.signIn({\n        username, // 可以是用户名、手机号或邮箱\n        password\n      });\n      setMessage(\"登录成功！\");\n      Alert.alert(\"成功\", \"登录成功\");\n    } catch (error) {\n      setMessage(`登录失败: ${error.message}`);\n      Alert.alert(\"失败\", `登录失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>账号：</Text>\n      <TextInput\n        style={styles.input}\n        value={username}\n        onChangeText={setUsername}\n        placeholder=\"用户名/手机号/邮箱\"\n      />\n      <Text style={styles.note}>注：手机号登录请添加区号 +86</Text>\n      <Text>密码：</Text>\n      <TextInput\n        style={styles.input}\n        value={password}\n        onChangeText={setPassword}\n        placeholder=\"请输入密码\"\n        secureTextEntry\n      />\n      <Button title=\"登录\" onPress={login} disabled={!username || !password} />\n      {message && (\n        <Text\n          style={[\n            styles.message,\n            { color: message.includes(\"成功\") ? \"green\" : \"red\" }\n          ]}\n        >\n          {message}\n        </Text>\n      )}\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  },\n  note: {\n    fontSize: 12,\n    color: \"#666\",\n    marginBottom: 10\n  },\n  message: {\n    marginTop: 20,\n    textAlign: \"center\"\n  }\n});\n```",
                "index": 3,
                "id": "UserNameLogin",
                "title": "账号密码登录",
                "content": []
              },
              {
                "markdown": "使用 **短信验证码登录** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **短信验证码登录**\n\n**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ phone_number: `+86 ${phone}` });\n\n// 登录\nawait auth.signInWithSms({\n  verificationInfo: res,\n  verificationCode: code,\n  phoneNum: `+86 ${phone}`\n});\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, TextInput, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function SmsLogin() {\n  const [phone, setPhone] = useState(\"\");\n  const [code, setCode] = useState(\"\");\n  const [verificationInfo, setVerificationInfo] = useState(null);\n  const [message, setMessage] = useState(\"\");\n\n  // 发送验证码\n  const sendCode = async () => {\n    try {\n      const auth = cloudbase.auth();\n      const res = await auth.getVerification({ phone_number: `+86 ${phone}` });\n      setVerificationInfo(res);\n      setMessage(\"验证码已发送！\");\n    } catch (error) {\n      setMessage(`发送失败: ${error.message}`);\n    }\n  };\n\n  // 登录\n  const login = async () => {\n    try {\n      const auth = cloudbase.auth();\n      await auth.signInWithSms({\n        verificationInfo,\n        verificationCode: code,\n        phoneNum: `+86 ${phone}`\n      });\n      setMessage(\"登录成功！\");\n      Alert.alert(\"成功\", \"登录成功\");\n    } catch (error) {\n      setMessage(`登录失败: ${error.message}`);\n      Alert.alert(\"失败\", `登录失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>手机号：</Text>\n      <TextInput\n        style={styles.input}\n        value={phone}\n        onChangeText={setPhone}\n        placeholder=\"13800000000\"\n        keyboardType=\"phone-pad\"\n      />\n      <Text>验证码：</Text>\n      <View style={styles.row}>\n        <TextInput\n          style={[styles.input, styles.codeInput]}\n          value={code}\n          onChangeText={setCode}\n          placeholder=\"验证码\"\n          keyboardType=\"numeric\"\n        />\n        <Button title=\"发送验证码\" onPress={sendCode} disabled={!phone} />\n      </View>\n      <Button\n        title=\"登录\"\n        onPress={login}\n        disabled={!verificationInfo || !code}\n      />\n      {message && (\n        <Text\n          style={[\n            styles.message,\n            { color: message.includes(\"成功\") ? \"green\" : \"red\" }\n          ]}\n        >\n          {message}\n        </Text>\n      )}\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  },\n  row: {\n    flexDirection: \"row\",\n    alignItems: \"center\"\n  },\n  codeInput: {\n    flex: 1,\n    marginRight: 10\n  },\n  message: {\n    marginTop: 20,\n    textAlign: \"center\"\n  }\n});\n```",
                "index": 4,
                "id": "PhoneNumberLogin",
                "title": "短信验证码登录",
                "content": []
              },
              {
                "markdown": "使用 **邮箱验证码登录** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **邮箱验证码**\n\n**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ email });\n\n// 登录\nawait auth.signInWithEmail({\n  verificationInfo: res,\n  verificationCode: code,\n  email\n});\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, TextInput, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function EmailLogin() {\n  const [email, setEmail] = useState(\"\");\n  const [code, setCode] = useState(\"\");\n  const [verificationInfo, setVerificationInfo] = useState(null);\n  const [message, setMessage] = useState(\"\");\n\n  // 发送验证码\n  const sendCode = async () => {\n    try {\n      const auth = cloudbase.auth();\n      const res = await auth.getVerification({ email });\n      setVerificationInfo(res);\n      setMessage(\"验证码已发送！\");\n    } catch (error) {\n      setMessage(`发送失败: ${error.message}`);\n    }\n  };\n\n  // 登录\n  const login = async () => {\n    try {\n      const auth = cloudbase.auth();\n      await auth.signInWithEmail({\n        verificationInfo,\n        verificationCode: code,\n        email\n      });\n      setMessage(\"登录成功！\");\n      Alert.alert(\"成功\", \"登录成功\");\n    } catch (error) {\n      setMessage(`登录失败: ${error.message}`);\n      Alert.alert(\"失败\", `登录失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>邮箱：</Text>\n      <TextInput\n        style={styles.input}\n        value={email}\n        onChangeText={setEmail}\n        placeholder=\"example@email.com\"\n        keyboardType=\"email-address\"\n      />\n      <Text>验证码：</Text>\n      <View style={styles.row}>\n        <TextInput\n          style={[styles.input, styles.codeInput]}\n          value={code}\n          onChangeText={setCode}\n          placeholder=\"验证码\"\n          keyboardType=\"numeric\"\n        />\n        <Button title=\"发送验证码\" onPress={sendCode} disabled={!email} />\n      </View>\n      <Button\n        title=\"登录\"\n        onPress={login}\n        disabled={!verificationInfo || !code}\n      />\n      {message && (\n        <Text\n          style={[\n            styles.message,\n            { color: message.includes(\"成功\") ? \"green\" : \"red\" }\n          ]}\n        >\n          {message}\n        </Text>\n      )}\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  },\n  row: {\n    flexDirection: \"row\",\n    alignItems: \"center\"\n  },\n  codeInput: {\n    flex: 1,\n    marginRight: 10\n  },\n  message: {\n    marginTop: 20,\n    textAlign: \"center\"\n  }\n});\n```",
                "index": 5,
                "id": "email",
                "title": "邮箱验证码登录",
                "content": []
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\nawait auth.signInAnonymously();\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Button, Text, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function AnonymousLogin() {\n  const [message, setMessage] = useState(\"\");\n\n  // 匿名登录\n  const anonymousLogin = async () => {\n    try {\n      const auth = cloudbase.auth();\n      await auth.signInAnonymously();\n      setMessage(\"匿名登录成功！\");\n      Alert.alert(\"成功\", \"匿名登录成功\");\n    } catch (error) {\n      setMessage(`登录失败: ${error.message}`);\n      Alert.alert(\"失败\", `登录失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Button title=\"匿名登录\" onPress={anonymousLogin} />\n      {message && (\n        <Text\n          style={[\n            styles.message,\n            { color: message.includes(\"成功\") ? \"green\" : \"red\" }\n          ]}\n        >\n          {message}\n        </Text>\n      )}\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20,\n    justifyContent: \"center\"\n  },\n  message: {\n    marginTop: 20,\n    textAlign: \"center\"\n  }\n});\n```",
                "index": 6,
                "title": "匿名登录",
                "content": []
              }
            ]
          }
        ]
      }
    ],
    "_id": "a5016600697c22f10035299e08eee5e6",
    "_openid": "anon",
    "createdAt": 1769743089446,
    "updatedAt": 1770021226400
  },
  {
    "category": "框架集成,ORMs,Drizzle",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": 42,
    "hasTemplate": false,
    "docsUrl": "https://orm.drizzle.team/docs/get-started-mysql",
    "content": [
      {
        "markdown": "使用 `Drizzle` 操作 **MySQL数据库**\n```bash\nnpm install drizzle-orm mysql2\n```",
        "title": "安装依赖",
        "type": "",
        "content": []
      },
      {
        "markdown": "新增如下代码到您的 **Drizzle** 项目",
        "title": "使用示例",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```js\nimport { drizzle } from \"drizzle-orm/mysql2\";\nimport mysql from \"mysql2/promise\";\nimport { todos } from \"./schema.js\";\n\nasync function main() {\n  const connection = await mysql.createConnection(process.env.DATABASE_URL);\n  const db = drizzle(connection);\n\n  const allTodos = await db.select().from(todos);\n  console.log(allTodos);\n\n  await connection.end();\n}\n\nmain().catch(console.error);\n```",
            "title": "index.js"
          },
          {
            "markdown": "```js\nimport { mysqlTable, text } from \"drizzle-orm/mysql-core\";\n\nexport const todos = mysqlTable(\"todos\", {\n  id: text(\"_id\").primaryKey(),\n  title: text(\"title\"),\n});\n```",
            "id": "",
            "title": "schema.js"
          },
          {
            "markdown": "```\nDATABASE_URL=mysql://{%DATABASE_URL%}\n```",
            "id": "mysqlString",
            "title": ".env"
          }
        ]
      }
    ],
    "_id": "a5016600697c257300356a567177679e",
    "_openid": "anon",
    "createdAt": 1769743731128,
    "updatedAt": 1769743898835
  },
  {
    "category": "框架集成,ORMs,Prisma",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": 41,
    "hasTemplate": false,
    "docsUrl": "https://prisma.org.cn/docs/getting-started/prisma-orm/quickstart/mysql",
    "content": [
      {
        "docsUrl": "",
        "markdown": "使用 `Prisma` 操作 **MySQL数据库**\n\n新增如下代码到您的 **Prisma** 项目",
        "title": "修改环境变量",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```\nDATABASE_URL=mysql://{%DATABASE_URL%}\n```",
            "index": 2,
            "id": "mysqlString",
            "title": ".env"
          },
          {
            "markdown": "```prisma\ngenerator client {\n  provider = \"prisma-client-js\"\n}\n\ndatasource db {\n  provider = \"mysql\"\n  url      = env(\"DATABASE_URL\")\n}\n```",
            "index": 1,
            "id": "",
            "title": "prisma/schema.prisma"
          }
        ]
      }
    ],
    "_id": "a5016600697c257700356a874dfde726",
    "_openid": "anon",
    "createdAt": 1769743735158,
    "updatedAt": 1769743904536
  },
  {
    "category": "框架集成,小程序 / 小游戏,微信小游戏,原生API",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": 2,
    "hasTemplate": false,
    "docsUrl": "https://developers.weixin.qq.com/minigame/dev/wxcloud/",
    "content": [
      {
        "markdown": "在 `game.js` 中初始化云开发：",
        "index": 1,
        "title": "初始化 SDK",
        "type": "codeTab",
        "content": [
          {
            "markdown": "大部分云开发能力可通过 `小游戏原生 API` 直接调用，无需安装 SDK，若 `原生API` 不支持请使用 `Client SDK` 进行调用\n\n```js\nwx.cloud.init({\n  env: \"{%ENV_ID%}\"\n});\n```",
            "index": 1,
            "title": "原生API 初始化",
            "content": []
          },
          {
            "markdown": "**安装**\n\n使用 Client SDK 前请先安装 SDK\n\n在小游戏 `package.json` 所在目录（通常为游戏根目录）执行：\n\n```bash\nnpm i @cloudbase/wx-cloud-client-sdk --save\n```\n\n安装完成后，在微信开发者工具点击 **工具 → 构建 npm**。\n\n**初始化**\n\n```js\nconst { init } = require(\"@cloudbase/wx-cloud-client-sdk\");\n\nwx.cloud.init({\n  env: \"{%ENV_ID%}\"\n});\n\nconst cloudbase = init(wx.cloud);\n```",
            "index": 2,
            "title": "Client SDK 初始化",
            "content": []
          }
        ]
      },
      {
        "index": 2,
        "title": "调用云开发能力",
        "type": "codeTab",
        "content": [
          {
            "markdown": "请使用 `Client SDK` 进行调用",
            "index": 1,
            "id": "mysql-db",
            "title": "MySQL数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\n// 查询 {%TABLE_NAME%} 表前10条数据\nconst { data, error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .select(\"*\")\n  .limit(10);\n\nconsole.log(\"查询结果:\", data);\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "```js\n// 新增 {%TABLE_NAME%} 表数据\nconst { data, error } = await cloudbase.rdb().from(\"{%TABLE_NAME%}\").insert({\n  title: \"示例标题\"\n});\n\nconsole.log(\"新增结果:\", error ? \"失败\" : \"成功\");\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "```js\n// 更新 {%TABLE_NAME%} 表中 id 为 <数据ID> 的数据\nconst { data, error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .update({\n    title: \"更新后的标题\"\n  })\n  .eq(\"id\", \"<数据ID>\");\n\nconsole.log(\"更新结果:\", error ? \"失败\" : \"成功\");\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "```js\n// 如果 {%TABLE_NAME%} 表中存在 id 为 1 的记录则更新 title 为\"示例标题\"，不存在则插入新记录\nconst { data, error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .upsert({ id: 1, title: \"示例标题\" });\n\nconsole.log(\"新增更新结果:\", error ? \"失败\" : \"成功\");\n```",
                "index": 4,
                "title": "更新或创建数据"
              },
              {
                "markdown": "```js\n// 删除 {%TABLE_NAME%} 表中 id 为 <数据ID> 的数据\nconst { data, error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .delete()\n  .eq(\"id\", \"<数据ID>\");\n\nconsole.log(\"删除结果:\", error ? \"失败\" : \"成功\");\n```",
                "index": 5,
                "title": "删除数据"
              }
            ]
          },
          {
            "index": 2,
            "id": "doc-db",
            "title": "文档型数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\nconst db = wx.cloud.database();\n\n// 查询 {%TABLE_NAME%} 表前10条数据\nconst res = await db.collection(\"{%TABLE_NAME%}\").limit(10).get();\n\nconsole.log(res.data);\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "```js\nconst db = wx.cloud.database();\n\n// 新增 {%TABLE_NAME%} 表数据\nconst res = await db.collection(\"{%TABLE_NAME%}\").add({\n  data: {\n    title: \"示例标题\",\n    content: \"示例内容\"\n  }\n});\n\nconsole.log(res);\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "```js\nconst db = wx.cloud.database();\n\n// 更新 {%TABLE_NAME%} 表中 id 为 <数据ID> 的数据\nconst res = await db\n  .collection(\"{%TABLE_NAME%}\")\n  .doc(\"<数据ID>\")\n  .update({\n    data: {\n      title: \"更新后的标题\"\n    }\n  });\n\nconsole.log(res.stats.updated);\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "```js\nconst db = wx.cloud.database();\n\n// 删除 {%TABLE_NAME%} 表中 id 为 <数据ID> 的数据\nconst res = await db.collection(\"{%TABLE_NAME%}\").doc(\"<数据ID>\").remove();\n\nconsole.log(res.stats.removed);\n```",
                "index": 4,
                "title": "删除数据"
              }
            ]
          },
          {
            "markdown": "请使用 `Client SDK` 进行调用",
            "index": 3,
            "id": "data-model",
            "title": "数据模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\n// 查询 {%TABLE_NAME%} 数据模型前10条数据\nconst res = await cloudbase.models[\"{%TABLE_NAME%}\"].list({\n  pageNumber: 1,\n  pagesize: 10\n});\n\nconsole.log(res.data.records);\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "```js\n// 新增 {%TABLE_NAME%} 数据模型数据\nconst res = await cloudbase.models[\"{%TABLE_NAME%}\"].create({\n  data: {\n    title: \"示例标题\",\n    content: \"示例内容\"\n  }\n});\n\nconsole.log(res.data);\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "```js\n// 更新 {%TABLE_NAME%} 数据模型中 _id 为 <数据ID> 的数据\nconst res = await cloudbase.models[\"{%TABLE_NAME%}\"].update({\n  data: {\n    title: \"更新后的标题\"\n  },\n  filter: {\n    where: {\n      _id: {\n        $eq: \"<数据ID>\"\n      }\n    }\n  }\n});\n\nconsole.log(res.data);\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "```js\n// 删除 {%TABLE_NAME%} 数据模型中 _id 为 <数据ID> 的数据\nconst res = await cloudbase.models[\"{%TABLE_NAME%}\"].delete({\n  filter: {\n    where: {\n      _id: {\n        $eq: \"<数据ID>\"\n      }\n    }\n  }\n});\n\nconsole.log(res.data);\n```",
                "index": 4,
                "title": "删除数据"
              }
            ]
          },
          {
            "markdown": "```js\n// 调用 {%FUNCTION_NAME%} 云函数\nconst res = await wx.cloud.callFunction({\n  name: \"{%FUNCTION_NAME%}\",\n  data: {} // 云函数入参\n});\n\nconsole.log(res.result);\n```",
            "index": 4,
            "id": "scf",
            "title": "云函数",
            "content": []
          },
          {
            "index": 5,
            "id": "storage",
            "title": "云存储",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\n// 小游戏可以通过 canvas 生成图片或使用其他方式获取文件路径\nconst filePath = \"本地文件路径\"; // 例如通过 canvas.toTempFilePath 获取\n\nconst res = await wx.cloud.uploadFile({\n  cloudPath: \"images/\" + Date.now() + \".png\", // 上传至云端的路径\n  filePath: filePath // 小游戏临时文件路径\n});\n\nconsole.log(res.fileID);\n```",
                "index": 1,
                "title": "上传文件"
              },
              {
                "markdown": "```js\nconst res = await wx.cloud.getTempFileURL({\n  fileList: [\"cloud://xxx.png\"] // 文件 fileID 列表\n});\n\nconsole.log(res.fileList);\n// fileList示例\n// [{\n//    fileID: \"cloud://xxx.png\", // 文件 ID\n//    tempFileURL: \"https://xxx.png\", // 临时文件网络链接\n//    maxAge: 120 * 60 * 1000, // 有效期\n// }]\n```",
                "index": 2,
                "title": "获取文件链接"
              },
              {
                "markdown": "```js\nconst res = await wx.cloud.downloadFile({\n  fileID: \"cloud://xxx.png\" // 文件 fileID\n});\n\nconsole.log(res.tempFilePath); // 返回临时文件路径\n```",
                "index": 3,
                "title": "下载文件"
              },
              {
                "markdown": "```js\nconst res = await wx.cloud.deleteFile({\n  fileList: [\"cloud://xxx.png\"] // 文件 fileID 列表\n});\n\nconsole.log(res.fileList);\n```",
                "index": 4,
                "title": "删除文件"
              }
            ]
          },
          {
            "index": 6,
            "id": "ai-model",
            "title": "大模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\nconst res = await wx.cloud.extend.AI.createModel(\n  \"{%AI_MODEL_NAME%}\"\n).streamText({\n  data: {\n    model: \"{%AI_SUB_MODEL_NAME%}\",\n    messages: [\n      {\n        role: \"user\",\n        content: \"你好\"\n      }\n    ]\n  }\n});\n\nfor await (let event of res.eventStream) {\n  if (event.data === \"[DONE]\") {\n    break;\n  }\n  const data = JSON.parse(event.data);\n\n  // 当使用 deepseek-r1 时，模型会生成思维链内容\n  const think = data?.choices?.[0]?.delta?.reasoning_content;\n  if (think) {\n    console.log(think);\n  }\n\n  // 打印生成文本内容\n  const text = data?.choices?.[0]?.delta?.content;\n  if (text) {\n    console.log(text);\n  }\n}\n```",
                "index": 1,
                "id": "text-aiModel",
                "title": "生文模型"
              },
              {
                "markdown": "生图模型通过调用云函数来实现，在生图模型页面点击「一键创建云函数」，函数调用示例如下：\n\n```js\n// 调用云函数生成图片\nwx.cloud.callFunction({\n  name: \"<YOUR_FUNCTION_NAME>\",\n  data: {\n    prompt: \"一只可爱的猫咪在阳光下玩耍\"\n  },\n  success: res => {\n    const result = res.result;\n    if (result.success) {\n      console.log(\"图片URL:\", result.imageUrl);\n      console.log(\"优化后的提示词:\", result.revised_prompt);\n      console.log(\"注意: 图片URL有效期为24小时\");\n      \n      // 在小游戏中可以使用图片URL进行后续处理\n      // 例如加载到Sprite或Canvas中\n    } else {\n      console.error(\"生成失败:\", result.code, result.message);\n    }\n  },\n  fail: err => {\n    console.error(\"调用失败:\", err);\n  }\n});\n```",
                "index": 2,
                "id": "image-aiModel",
                "title": "生图模型"
              }
            ]
          },
          {
            "markdown": "",
            "index": 7,
            "id": "agent",
            "title": "Agent",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\nconst res = await wx.cloud.extend.AI.bot.sendMessage({\n  data: {\n    botId: '{%AGENT_ID%}',\n    // 入参结构参考前后端通信协议：\n    //  https://docs.cloudbase.net/ai/agent/http-agent-protocol\n    threadId: '550e8400-e29b-41d4-a716-446655440000',\n    runId: 'run_001',\n    messages: [{ id: 'msg-1', role: 'user', content: '你好' }],\n    tools: [],\n    context: [],\n    state: {},\n    forwardedProps: {},\n  },\n});\n\nfor await (const event of res.eventStream) {\n  if (event.data === '[DONE]') {\n    break;\n  }\n  const data = JSON.parse(event.data);\n\n  // 当使用 deepseek-r1 时，模型会生成思维链内容\n  const think = data.reasoning_content;\n  if (think) {\n    console.log(think);\n  }\n\n  // 打印输出正文\n  const content = data.content;\n  if (content) {\n    console.log(content);\n  }\n}\n```",
                "index": 0,
                "id": "scf",
                "title": "函数型"
              },
              {
                "markdown": "```js\nconst res = await wx.cloud.extend.AI.bot.sendMessage({\n  data: {\n    botId: \"{%AGENT_ID%}\",\n    msg: \"你好\"\n  }\n});\n\nfor await (const event of res.eventStream) {\n  if (event.data === \"[DONE]\") {\n    break;\n  }\n  const data = JSON.parse(event.data);\n\n  // 当使用 deepseek-r1 时，模型会生成思维链内容\n  const think = data.reasoning_content;\n  if (think) {\n    console.log(think);\n  }\n\n  // 打印输出正文\n  const content = data.content;\n  if (content) {\n    console.log(content);\n  }\n}\n```",
                "index": 1,
                "id": "baas",
                "title": "普通型"
              }
            ]
          }
        ]
      }
    ],
    "_id": "a5016600698062a10092ca601e1d0d2d",
    "_openid": "anon",
    "createdAt": 1770021537574,
    "updatedAt": 1770021537574
  },
  {
    "category": "框架集成,后端框架,Java",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": 23,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/http-api/basic/overview",
    "content": [
      {
        "markdown": "通过 **HTTP 请求** 在 **Java** 中调用各种云开发能力",
        "index": 1,
        "title": "安装依赖",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```xml\n<dependencies>\n    <!-- HTTP 客户端 -->\n    <dependency>\n        <groupId>com.squareup.okhttp3</groupId>\n        <artifactId>okhttp</artifactId>\n        <version>4.12.0</version>\n    </dependency>\n\n    <!-- JSON 处理 -->\n    <dependency>\n        <groupId>com.google.code.gson</groupId>\n        <artifactId>gson</artifactId>\n        <version>2.10.1</version>\n    </dependency>\n\n    <!-- 环境变量加载 -->\n    <dependency>\n        <groupId>io.github.cdimascio</groupId>\n        <artifactId>dotenv-java</artifactId>\n        <version>3.0.0</version>\n    </dependency>\n</dependencies>\n```",
            "index": 1,
            "title": "Maven"
          },
          {
            "markdown": "```groovy\ndependencies {\n    implementation 'com.squareup.okhttp3:okhttp:4.12.0'\n    implementation 'com.google.code.gson:gson:2.10.1'\n    implementation 'io.github.cdimascio:dotenv-java:3.0.0'\n}\n```",
            "index": 2,
            "title": "Gradle"
          }
        ]
      },
      {
        "markdown": "新增如下代码到您的 **Java** 项目",
        "index": 2,
        "title": "初始化配置",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```java\npackage com.cloudbase;\n\nimport com.google.gson.Gson;\nimport com.google.gson.JsonObject;\nimport io.github.cdimascio.dotenv.Dotenv;\nimport okhttp3.*;\n\nimport java.io.IOException;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class CloudBaseClient {\n    private final String envId;\n    private final String accessToken;\n    private final String baseUrl;\n    private final OkHttpClient client;\n    private final Gson gson;\n    private final Map<String, String> defaultHeaders;\n\n    public CloudBaseClient() {\n        // 加载环境变量\n        Dotenv dotenv = Dotenv.configure().ignoreIfMissing().load();\n        this.envId = dotenv.get(\"CLOUDBASE_ENV_ID\");\n        this.accessToken = dotenv.get(\"CLOUDBASE_ACCESS_TOKEN\");\n        this.baseUrl = \"https://\" + envId + \".api.tcloudbasegateway.com\";\n\n        this.client = new OkHttpClient();\n        this.gson = new Gson();\n\n        // 设置默认请求头\n        this.defaultHeaders = new HashMap<>();\n        this.defaultHeaders.put(\"Content-Type\", \"application/json\");\n        this.defaultHeaders.put(\"Accept\", \"application/json\");\n        this.defaultHeaders.put(\"Authorization\", \"Bearer \" + accessToken);\n    }\n\n    public String getEnvId() {\n        return envId;\n    }\n\n    public String getAccessToken() {\n        return accessToken;\n    }\n\n    public OkHttpClient getClient() {\n        return client;\n    }\n\n    public Gson getGson() {\n        return gson;\n    }\n\n    /**\n     * 统一的HTTP请求方法\n     *\n     * @param method 请求方法 (GET, POST, PUT, PATCH, DELETE)\n     * @param path API路径 (如 /v1/rdb/rest/table_name)\n     * @param body 请求体 (可选)\n     * @param customHeaders 自定义请求头 (可选)\n     * @return 响应数据或null\n     */\n    public JsonObject request(String method, String path, Object body, Map<String, String> customHeaders) {\n        try {\n            String url = baseUrl + path;\n\n            // 构建请求头\n            Headers.Builder headersBuilder = new Headers.Builder();\n            defaultHeaders.forEach(headersBuilder::add);\n            if (customHeaders != null) {\n                customHeaders.forEach(headersBuilder::add);\n            }\n\n            // 构建请求体\n            RequestBody requestBody = null;\n            if (body != null) {\n                String jsonBody = gson.toJson(body);\n                requestBody = RequestBody.create(jsonBody, MediaType.parse(\"application/json\"));\n            } else if (method.equals(\"POST\") || method.equals(\"PUT\") || method.equals(\"PATCH\")) {\n                requestBody = RequestBody.create(\"\", MediaType.parse(\"application/json\"));\n            }\n\n            // 构建请求\n            Request.Builder requestBuilder = new Request.Builder()\n                    .url(url)\n                    .headers(headersBuilder.build())\n                    .method(method, requestBody);\n\n            // 发送请求\n            try (Response response = client.newCall(requestBuilder.build()).execute()) {\n                if (!response.isSuccessful()) {\n                    System.err.println(\"请求失败: \" + response.code() + \" \" + response.message());\n                    return null;\n                }\n\n                // 如果响应为空，返回成功标识\n                String responseBody = response.body().string();\n                if (responseBody == null || responseBody.isEmpty()) {\n                    JsonObject result = new JsonObject();\n                    result.addProperty(\"success\", true);\n                    return result;\n                }\n\n                return gson.fromJson(responseBody, JsonObject.class);\n            }\n        } catch (IOException e) {\n            System.err.println(\"请求失败: \" + e.getMessage());\n            return null;\n        }\n    }\n\n    public JsonObject request(String method, String path, Object body) {\n        return request(method, path, body, null);\n    }\n\n    public JsonObject request(String method, String path) {\n        return request(method, path, null, null);\n    }\n}\n```",
            "index": 1,
            "title": "CloudBaseClient.java"
          },
          {
            "markdown": "> 💡提示：如需管理员权限，请通过 [云开发平台/ApiKey管理页](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}&#/env/apikey) 获取 APIKey 替换 CLOUDBASE_ACCESS_TOKEN\n\n```properties\n# 环境ID\nCLOUDBASE_ENV_ID={%ENV_ID%}\n\n# 匿名访问令牌\nCLOUDBASE_ACCESS_TOKEN={%PUBLISHABLE_KEY%}\n```",
            "index": 2,
            "title": ".env"
          }
        ]
      },
      {
        "sideTabs": [
          {
            "id": "pg-db",
            "title": "PostgreSQL 数据库"
          }
        ],
        "index": 3,
        "title": "调用云开发能力",
        "type": "codeTab",
        "content": [
          {
            "index": 1,
            "id": "pg-db",
            "title": "PostgreSQL 数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonObject;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class Example {\n    public static void main(String[] args) {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 查询 {%TABLE_NAME%} 表前 10 条数据\n        JsonObject data = cloudbase.request(\"GET\", \"/v1/rdb/rest/{{%TABLE_NAME%}}?select=*&limit=10\");\n\n        if (data != null) {\n            System.out.println(\"查询结果: \" + data);\n        }\n    }\n}\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonObject;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class Example {\n    public static void main(String[] args) {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 新增{%TABLE_NAME%}\n        Map<String, String> headers = new HashMap<>();\n        headers.put(\"Prefer\", \"return=representation\");\n        JsonObject data = cloudbase.request(\"POST\", \"/v1/rdb/rest/{{%TABLE_NAME%}}\", \"{\"title\":\"新文章\",\"status\":\"draft\"}\", headers);\n\n        if (data != null) {\n            System.out.println(\"新增结果: \" + data);\n        }\n    }\n}\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonObject;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class Example {\n    public static void main(String[] args) {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 更新{%TABLE_NAME%}\n        Map<String, String> headers = new HashMap<>();\n        headers.put(\"Prefer\", \"return=representation\");\n        JsonObject data = cloudbase.request(\"PATCH\", \"/v1/rdb/rest/{{%TABLE_NAME%}}?id=eq.1\", \"{\"status\":\"published\"}\", headers);\n\n        if (data != null) {\n            System.out.println(\"更新结果: \" + data);\n        }\n    }\n}\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonObject;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class Example {\n    public static void main(String[] args) {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 更新或创建{%TABLE_NAME%}\n        Map<String, String> headers = new HashMap<>();\n        headers.put(\"Prefer\", \"resolution=merge-duplicates,return=representation\");\n        JsonObject data = cloudbase.request(\"POST\", \"/v1/rdb/rest/{{%TABLE_NAME%}}\", \"{\"id\":1,\"title\":\"标题\",\"status\":\"published\"}\", headers);\n\n        if (data != null) {\n            System.out.println(\"更新或创建结果: \" + data);\n        }\n    }\n}\n```",
                "index": 4,
                "title": "更新或创建数据"
              },
              {
                "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonObject;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class Example {\n    public static void main(String[] args) {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 删除 {%TABLE_NAME%} 表中 id=1 的数据\n        JsonObject data = cloudbase.request(\"DELETE\", \"/v1/rdb/rest/{{%TABLE_NAME%}}?id=eq.1\");\n\n        if (data != null) {\n            System.out.println(\"删除完成: \" + data);\n        }\n    }\n}\n```",
                "index": 5,
                "title": "删除数据"
              }
            ]
          },
          {
            "index": 1,
            "id": "mysql-db",
            "title": "MySQL数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonObject;\n\npublic class Example {\n    public static void main(String[] args) {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 查询 MySQL 数据库数据\n        JsonObject data = cloudbase.request(\"GET\", \"/v1/rdb/rest/{%TABLE_NAME%}?limit=10\");\n\n        if (data != null) {\n            System.out.println(\"查询成功: \" + data);\n        }\n    }\n}\n```",
                "index": 1,
                "title": "查询数据",
                "content": []
              },
              {
                "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonObject;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class Example {\n    public static void main(String[] args) {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 准备数据\n        Map<String, Object> data = new HashMap<>();\n        data.put(\"title\", \"示例标题\");\n\n        // 新增 MySQL 数据库数据\n        JsonObject result = cloudbase.request(\"POST\", \"/v1/rdb/rest/{%TABLE_NAME%}\", data);\n\n        if (result != null) {\n            System.out.println(\"新增成功: \" + result);\n        }\n    }\n}\n```",
                "index": 2,
                "title": "新增数据",
                "content": []
              },
              {
                "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonObject;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class Example {\n    public static void main(String[] args) {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 准备更新数据\n        Map<String, Object> data = new HashMap<>();\n        data.put(\"title\", \"新标题\");\n\n        // 更新 MySQL 数据库数据\n        String dataId = \"<数据id>\";\n        JsonObject result = cloudbase.request(\"PATCH\", \"/v1/rdb/rest/{%TABLE_NAME%}?id=eq.\" + dataId, data);\n\n        if (result != null) {\n            System.out.println(\"更新成功: \" + result);\n        }\n    }\n}\n```",
                "index": 3,
                "title": "更新数据",
                "content": []
              },
              {
                "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonObject;\n\npublic class Example {\n    public static void main(String[] args) {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 删除 MySQL 数据库数据\n        String dataId = \"<数据id>\";\n        JsonObject result = cloudbase.request(\"DELETE\", \"/v1/rdb/rest/{%TABLE_NAME%}?id=eq.\" + dataId);\n\n        if (result != null) {\n            System.out.println(\"删除成功\");\n        }\n    }\n}\n```",
                "index": 4,
                "title": "删除数据",
                "content": []
              }
            ]
          },
          {
            "index": 2,
            "id": "data-model",
            "title": "数据模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonArray;\nimport com.google.gson.JsonObject;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class Example {\n    public static void main(String[] args) {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 准备查询参数\n        Map<String, Object> payload = new HashMap<>();\n        payload.put(\"pageSize\", 10);\n        payload.put(\"pageNumber\", 1);\n        payload.put(\"getCount\", true);\n\n        // 查询数据模型数据\n        JsonObject result = cloudbase.request(\"POST\", \"/v1/model/prod/{%TABLE_NAME%}/list\", payload);\n\n        if (result != null) {\n            JsonArray records = result.getAsJsonObject(\"data\").getAsJsonArray(\"records\");\n            System.out.println(\"查询成功: \" + records);\n        }\n    }\n}\n```",
                "index": 1,
                "title": "查询数据",
                "content": []
              },
              {
                "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonObject;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class Example {\n    public static void main(String[] args) {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 准备数据\n        Map<String, Object> data = new HashMap<>();\n        data.put(\"title\", \"示例标题\");\n\n        Map<String, Object> payload = new HashMap<>();\n        payload.put(\"data\", data);\n\n        // 新增数据模型数据\n        JsonObject result = cloudbase.request(\"POST\", \"/v1/model/prod/{%TABLE_NAME%}/create\", payload);\n\n        if (result != null) {\n            String docId = result.getAsJsonObject(\"data\").get(\"id\").getAsString();\n            System.out.println(\"新增成功! id: \" + docId);\n        }\n    }\n}\n```",
                "index": 2,
                "title": "新增数据",
                "content": []
              },
              {
                "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonObject;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class Example {\n    public static void main(String[] args) {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 准备更新数据\n        Map<String, Object> data = new HashMap<>();\n        data.put(\"title\", \"新标题\");\n\n        // 准备过滤条件\n        Map<String, Object> eqCondition = new HashMap<>();\n        eqCondition.put(\"$eq\", \"<数据id>\");\n\n        Map<String, Object> whereCondition = new HashMap<>();\n        whereCondition.put(\"_id\", eqCondition);\n\n        Map<String, Object> filter = new HashMap<>();\n        filter.put(\"where\", whereCondition);\n\n        Map<String, Object> payload = new HashMap<>();\n        payload.put(\"data\", data);\n        payload.put(\"filter\", filter);\n\n        // 更新数据模型数据\n        JsonObject result = cloudbase.request(\"PUT\", \"/v1/model/prod/{%TABLE_NAME%}/update\", payload);\n\n        if (result != null) {\n            System.out.println(\"更新成功!\");\n        }\n    }\n}\n```",
                "index": 3,
                "title": "更新数据",
                "content": []
              },
              {
                "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonObject;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class Example {\n    public static void main(String[] args) {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 准备过滤条件\n        Map<String, Object> eqCondition = new HashMap<>();\n        eqCondition.put(\"$eq\", \"<数据id>\");\n\n        Map<String, Object> whereCondition = new HashMap<>();\n        whereCondition.put(\"_id\", eqCondition);\n\n        Map<String, Object> filter = new HashMap<>();\n        filter.put(\"where\", whereCondition);\n\n        Map<String, Object> payload = new HashMap<>();\n        payload.put(\"filter\", filter);\n\n        // 删除数据模型数据\n        JsonObject result = cloudbase.request(\"POST\", \"/v1/model/prod/{%TABLE_NAME%}/delete\", payload);\n\n        if (result != null) {\n            System.out.println(\"删除成功!\");\n        }\n    }\n}\n```",
                "index": 4,
                "title": "删除数据",
                "content": []
              }
            ]
          },
          {
            "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonObject;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class Example {\n    public static void main(String[] args) {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 调用云函数\n        Map<String, Object> data = new HashMap<>();\n        // data.put(\"key\", \"value\"); // 可选参数\n\n        JsonObject result = cloudbase.request(\"POST\", \"/v1/functions/{%FUNCTION_NAME%}\", data);\n\n        if (result != null) {\n            System.out.println(\"云函数调用结果: \" + result);\n        }\n    }\n}\n```",
            "index": 3,
            "id": "scf",
            "title": "云函数"
          },
          {
            "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonObject;\n\npublic class Example {\n    public static void main(String[] args) {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 调用云托管服务\n        String serviceName = \"{%SERVICE_NAME%}\";\n        String path = \"\"; // 可选路径\n        String fullPath = \"/v1/cloudrun/\" + serviceName + (path.isEmpty() ? \"\" : \"/\" + path);\n\n        JsonObject result = cloudbase.request(\"GET\", fullPath);\n\n        if (result != null) {\n            System.out.println(\"云托管调用结果: \" + result);\n        }\n    }\n}\n```",
            "index": 4,
            "id": "run",
            "title": "云托管"
          },
          {
            "index": 5,
            "id": "storage",
            "title": "云存储",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonArray;\nimport com.google.gson.JsonObject;\nimport okhttp3.*;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.file.Files;\nimport java.util.*;\n\npublic class Example {\n    public static void main(String[] args) throws IOException {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 上传文件到云存储\n        String filePath = \"./example.jpg\";\n        String objectId = \"uploads/\" + System.currentTimeMillis() + \"-\" + new File(filePath).getName();\n\n        // 1. 获取上传信息\n        List<Map<String, String>> uploadInfoRequest = new ArrayList<>();\n        Map<String, String> objectInfo = new HashMap<>();\n        objectInfo.put(\"objectId\", objectId);\n        uploadInfoRequest.add(objectInfo);\n\n        JsonObject uploadInfoResponse = cloudbase.request(\"POST\", \"/v1/storages/get-objects-upload-info\", uploadInfoRequest);\n\n        if (uploadInfoResponse == null) {\n            System.err.println(\"获取上传信息失败\");\n            return;\n        }\n\n        JsonObject uploadInfo = uploadInfoResponse.getAsJsonArray().get(0).getAsJsonObject();\n        String uploadUrl = uploadInfo.get(\"uploadUrl\").getAsString();\n        String authorization = uploadInfo.get(\"authorization\").getAsString();\n        String token = uploadInfo.get(\"token\").getAsString();\n        String cloudObjectMeta = uploadInfo.get(\"cloudObjectMeta\").getAsString();\n\n        // 2. 上传文件\n        File file = new File(filePath);\n        byte[] fileData = Files.readAllBytes(file.toPath());\n\n        OkHttpClient client = new OkHttpClient();\n        RequestBody requestBody = RequestBody.create(fileData, MediaType.parse(\"application/octet-stream\"));\n\n        Request uploadRequest = new Request.Builder()\n                .url(uploadUrl)\n                .put(requestBody)\n                .addHeader(\"Authorization\", authorization)\n                .addHeader(\"X-Cos-Security-Token\", token)\n                .addHeader(\"X-Cos-Meta-Fileid\", cloudObjectMeta)\n                .build();\n\n        try (Response response = client.newCall(uploadRequest).execute()) {\n            if (response.isSuccessful()) {\n                String cloudObjectId = uploadInfo.get(\"cloudObjectId\").getAsString();\n                String downloadUrl = uploadInfo.get(\"downloadUrl\").getAsString();\n\n                System.out.println(\"文件上传成功:\");\n                System.out.println(\"- 对象ID: \" + objectId);\n                System.out.println(\"- 云对象ID: \" + cloudObjectId);\n                System.out.println(\"- 下载URL: \" + downloadUrl);\n            } else {\n                System.err.println(\"文件上传失败: \" + response.code());\n            }\n        }\n    }\n}\n```",
                "index": 1,
                "title": "上传文件",
                "content": []
              },
              {
                "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonArray;\nimport com.google.gson.JsonObject;\nimport java.util.*;\n\npublic class Example {\n    public static void main(String[] args) {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 获取云存储文件的临时访问链接\n        String cloudObjectId = \"cloud://xxx.png\";\n\n        List<Map<String, String>> request = new ArrayList<>();\n        Map<String, String> objectInfo = new HashMap<>();\n        objectInfo.put(\"cloudObjectId\", cloudObjectId);\n        request.add(objectInfo);\n\n        JsonObject result = cloudbase.request(\"POST\", \"/v1/storages/get-objects-download-info\", request);\n\n        if (result != null) {\n            String downloadUrl = result.getAsJsonArray().get(0).getAsJsonObject().get(\"downloadUrl\").getAsString();\n            System.out.println(\"文件链接: \" + downloadUrl);\n        }\n    }\n}\n```",
                "index": 2,
                "title": "获取文件链接",
                "content": []
              },
              {
                "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonObject;\nimport okhttp3.OkHttpClient;\nimport okhttp3.Request;\nimport okhttp3.Response;\n\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.util.*;\n\npublic class Example {\n    public static void main(String[] args) throws IOException {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 下载云存储文件到本地\n        String cloudObjectId = \"cloud://xxx.png\";\n        String savePath = \"./downloaded.png\";\n\n        // 1. 获取下载链接\n        List<Map<String, String>> request = new ArrayList<>();\n        Map<String, String> objectInfo = new HashMap<>();\n        objectInfo.put(\"cloudObjectId\", cloudObjectId);\n        request.add(objectInfo);\n\n        JsonObject result = cloudbase.request(\"POST\", \"/v1/storages/get-objects-download-info\", request);\n\n        if (result == null) {\n            System.err.println(\"获取下载链接失败\");\n            return;\n        }\n\n        String downloadUrl = result.getAsJsonArray().get(0).getAsJsonObject().get(\"downloadUrl\").getAsString();\n\n        // 2. 下载文件\n        OkHttpClient client = new OkHttpClient();\n        Request downloadRequest = new Request.Builder().url(downloadUrl).build();\n\n        try (Response response = client.newCall(downloadRequest).execute()) {\n            if (response.isSuccessful() && response.body() != null) {\n                try (FileOutputStream fos = new FileOutputStream(savePath)) {\n                    fos.write(response.body().bytes());\n                }\n                System.out.println(\"下载成功! 文件已保存到: \" + savePath);\n            } else {\n                System.err.println(\"下载失败: \" + response.code());\n            }\n        }\n    }\n}\n```",
                "index": 3,
                "title": "下载文件",
                "content": []
              },
              {
                "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonObject;\nimport java.util.*;\n\npublic class Example {\n    public static void main(String[] args) {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 删除云存储文件\n        String cloudObjectId = \"cloud://xxx.png\";\n\n        List<Map<String, String>> request = new ArrayList<>();\n        Map<String, String> objectInfo = new HashMap<>();\n        objectInfo.put(\"cloudObjectId\", cloudObjectId);\n        request.add(objectInfo);\n\n        JsonObject result = cloudbase.request(\"POST\", \"/v1/storages/delete-objects\", request);\n\n        if (result != null) {\n            System.out.println(\"删除成功!\");\n        }\n    }\n}\n```",
                "index": 4,
                "title": "删除文件",
                "content": []
              }
            ]
          },
          {
            "index": 6,
            "id": "ai-model",
            "title": "大模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonObject;\nimport okhttp3.*;\n\nimport java.io.BufferedReader;\nimport java.io.IOException;\nimport java.io.InputStreamReader;\nimport java.nio.charset.StandardCharsets;\nimport java.util.*;\n\npublic class Example {\n    public static void main(String[] args) throws IOException {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 流式文本生成\n        String model = \"{%AI_MODEL_NAME%}\";\n        String subModel = \"{%AI_SUB_MODEL_NAME%}\";\n\n        // 准备消息\n        List<Map<String, String>> messages = new ArrayList<>();\n        Map<String, String> systemMsg = new HashMap<>();\n        systemMsg.put(\"role\", \"system\");\n        systemMsg.put(\"content\", \"请严格按照七言绝句或七言律诗的格律要求创作，平仄需符合规则，押韵要和谐自然，韵脚字需在同一韵部。\");\n        messages.add(systemMsg);\n\n        Map<String, String> userMsg = new HashMap<>();\n        userMsg.put(\"role\", \"user\");\n        userMsg.put(\"content\", \"春天\");\n        messages.add(userMsg);\n\n        // 准备请求体\n        Map<String, Object> payload = new HashMap<>();\n        payload.put(\"model\", subModel);\n        payload.put(\"messages\", messages);\n        payload.put(\"stream\", true);\n\n        // 使用 CloudBaseClient 的配置构建流式请求\n        String url = \"https://\" + cloudbase.getEnvId() + \".api.tcloudbasegateway.com/v1/ai/\" + model + \"/chat/completions\";\n        String jsonPayload = cloudbase.getGson().toJson(payload);\n\n        RequestBody requestBody = RequestBody.create(jsonPayload, MediaType.parse(\"application/json\"));\n\n        Request request = new Request.Builder()\n                .url(url)\n                .post(requestBody)\n                .addHeader(\"Content-Type\", \"application/json\")\n                .addHeader(\"Accept\", \"text/event-stream\")\n                .addHeader(\"Authorization\", \"Bearer \" + cloudbase.getAccessToken())\n                .build();\n\n        System.out.println(\"AI 流式响应:\");\n        StringBuilder fullContent = new StringBuilder();\n\n        try (Response response = cloudbase.getClient().newCall(request).execute()) {\n            if (response.isSuccessful() && response.body() != null) {\n                BufferedReader reader = new BufferedReader(\n                    new InputStreamReader(response.body().byteStream(), StandardCharsets.UTF_8)\n                );\n                String line;\n\n                while ((line = reader.readLine()) != null) {\n                    if (line.startsWith(\"data: \")) {\n                        String dataStr = line.substring(6);\n                        if (!dataStr.trim().equals(\"[DONE]\")) {\n                            try {\n                                JsonObject chunkData = cloudbase.getGson().fromJson(dataStr, JsonObject.class);\n                                if (chunkData.has(\"choices\") && chunkData.getAsJsonArray(\"choices\").size() > 0) {\n                                    JsonObject choice = chunkData.getAsJsonArray(\"choices\").get(0).getAsJsonObject();\n                                    if (choice.has(\"delta\") && choice.getAsJsonObject(\"delta\").has(\"content\")) {\n                                        String content = choice.getAsJsonObject(\"delta\").get(\"content\").getAsString();\n                                        System.out.print(content);\n                                        fullContent.append(content);\n                                    }\n                                }\n                            } catch (Exception e) {\n                                // 忽略JSON解析错误\n                            }\n                        }\n                    }\n                }\n                System.out.println(); // 换行\n            }\n        }\n    }\n}\n```",
                "index": 1,
                "id": "text-aiModel",
                "title": "生文模型",
                "content": []
              },
              {
                "markdown": "生图模型通过调用云函数来实现，在生图模型页面点击「一键创建云函数」，函数调用示例如下：\n\n```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonObject;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class Example {\n    public static void main(String[] args) {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        try {\n            // 准备调用参数\n            Map<String, Object> data = new HashMap<>();\n            data.put(\"prompt\", \"一只可爱的猫咪在阳光下玩耍\");\n\n            // 调用云函数生成图片\n            JsonObject result = cloudbase.request(\"POST\", \"/v1/functions/<YOUR_FUNCTION_NAME>\", data);\n\n            if (result != null) {\n                boolean success = result.has(\"success\") && result.get(\"success\").getAsBoolean();\n                \n                if (success) {\n                    String imageUrl = result.get(\"imageUrl\").getAsString();\n                    String revisedPrompt = result.has(\"revised_prompt\") \n                        ? result.get(\"revised_prompt\").getAsString() \n                        : \"\";\n                    \n                    System.out.println(\"生成成功!\");\n                    System.out.println(\"图片URL: \" + imageUrl);\n                    System.out.println(\"优化后的提示词: \" + revisedPrompt);\n                    System.out.println(\"注意: 图片URL有效期为24小时\");\n                } else {\n                    String code = result.has(\"code\") ? result.get(\"code\").getAsString() : \"\";\n                    String message = result.has(\"message\") ? result.get(\"message\").getAsString() : \"\";\n                    System.err.println(\"生成失败: \" + code + \" - \" + message);\n                }\n            } else {\n                System.err.println(\"请求失败\");\n            }\n        } catch (Exception e) {\n            System.err.println(\"生成图片时出错: \" + e.getMessage());\n        }\n    }\n}\n```",
                "index": 2,
                "id": "image-aiModel",
                "title": "生图模型",
                "content": []
              }
            ]
          },
          {
            "markdown": "",
            "index": 7,
            "id": "agent",
            "title": "Agent",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```java\n/**\n * Java 调用 Agent 示例（AG-UI 协议）\n * 协议文档：https://docs.cloudbase.net/ai/agent-development/protocol\n */\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonObject;\nimport okhttp3.*;\n\nimport java.io.BufferedReader;\nimport java.io.IOException;\nimport java.io.InputStreamReader;\nimport java.nio.charset.StandardCharsets;\nimport java.util.*;\n\npublic class Example {\n    public static void main(String[] args) throws IOException {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 流式调用Agent（AG-UI 协议）\n        String botId = \"{%AGENT_ID%}\";\n\n        // 准备消息列表（AG-UI 协议格式）\n        List<Map<String, Object>> messages = new ArrayList<>();\n        Map<String, Object> userMessage = new HashMap<>();\n        userMessage.put(\"id\", \"msg-\" + UUID.randomUUID().toString());\n        userMessage.put(\"role\", \"user\");\n        userMessage.put(\"content\", \"你是谁\");\n        messages.add(userMessage);\n\n        // 准备请求体（AG-UI 协议）\n        Map<String, Object> payload = new HashMap<>();\n        payload.put(\"messages\", messages);                    // 必填：消息列表\n        payload.put(\"threadId\", \"thread-\" + UUID.randomUUID().toString()); // 可选：会话ID，用于多轮对话\n        payload.put(\"runId\", \"run-\" + UUID.randomUUID().toString());       // 可选：本次运行ID\n        payload.put(\"tools\", new ArrayList<>());              // 可选：前端工具定义\n        payload.put(\"context\", new ArrayList<>());            // 可选：上下文信息\n        payload.put(\"forwardedProps\", new HashMap<>());       // 可选：透传参数\n\n        // 使用 CloudBaseClient 的配置构建流式请求\n        String url = \"https://\" + cloudbase.getEnvId() + \".api.tcloudbasegateway.com/v1/aibot/bots/\" + botId + \"/send-message\";\n        String jsonPayload = cloudbase.getGson().toJson(payload);\n\n        RequestBody requestBody = RequestBody.create(jsonPayload, MediaType.parse(\"application/json\"));\n\n        Request request = new Request.Builder()\n                .url(url)\n                .post(requestBody)\n                .addHeader(\"Content-Type\", \"application/json\")\n                .addHeader(\"Accept\", \"text/event-stream\")\n                .addHeader(\"Authorization\", \"Bearer \" + cloudbase.getAccessToken())\n                .build();\n\n        System.out.println(\"AI 流式响应:\");\n        StringBuilder fullContent = new StringBuilder();\n\n        try (Response response = cloudbase.getClient().newCall(request).execute()) {\n            if (response.isSuccessful() && response.body() != null) {\n                BufferedReader reader = new BufferedReader(\n                    new InputStreamReader(response.body().byteStream(), StandardCharsets.UTF_8)\n                );\n                String line;\n\n                while ((line = reader.readLine()) != null) {\n                    if (line.startsWith(\"data: \")) {\n                        String dataStr = line.substring(6).trim();\n                        if (!dataStr.isEmpty() && !dataStr.equals(\"[DONE]\")) {\n                            try {\n                                JsonObject chunkData = cloudbase.getGson().fromJson(dataStr, JsonObject.class);\n\n                                // 支持多种响应格式\n                                String content = null;\n                                if (chunkData.has(\"content\")) {\n                                    content = chunkData.get(\"content\").getAsString();\n                                } else if (chunkData.has(\"choices\") && chunkData.getAsJsonArray(\"choices\").size() > 0) {\n                                    JsonObject choice = chunkData.getAsJsonArray(\"choices\").get(0).getAsJsonObject();\n                                    if (choice.has(\"delta\") && choice.getAsJsonObject(\"delta\").has(\"content\")) {\n                                        content = choice.getAsJsonObject(\"delta\").get(\"content\").getAsString();\n                                    } else if (choice.has(\"message\") && choice.getAsJsonObject(\"message\").has(\"content\")) {\n                                        content = choice.getAsJsonObject(\"message\").get(\"content\").getAsString();\n                                    }\n                                }\n\n                                if (content != null && !content.isEmpty()) {\n                                    System.out.print(content);\n                                    fullContent.append(content);\n                                }\n                            } catch (Exception e) {\n                                // 忽略JSON解析错误\n                            }\n                        }\n                    }\n                }\n                System.out.println(); // 换行\n            }\n        }\n    }\n}\n\n```",
                "index": 0,
                "id": "scf",
                "title": "函数型"
              },
              {
                "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonObject;\nimport okhttp3.*;\n\nimport java.io.BufferedReader;\nimport java.io.IOException;\nimport java.io.InputStreamReader;\nimport java.nio.charset.StandardCharsets;\nimport java.util.*;\n\npublic class Example {\n    public static void main(String[] args) throws IOException {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 流式调用Agent\n        String botId = \"{%AGENT_ID%}\";\n        String msg = \"你是谁\";\n        List<Map<String, String>> history = new ArrayList<>();\n\n        // 准备请求体\n        Map<String, Object> payload = new HashMap<>();\n        payload.put(\"history\", history);\n        payload.put(\"msg\", msg);\n\n        // 使用 CloudBaseClient 的配置构建流式请求\n        String url = \"https://\" + cloudbase.getEnvId() + \".api.tcloudbasegateway.com/v1/aibot/bots/\" + botId + \"/send-message\";\n        String jsonPayload = cloudbase.getGson().toJson(payload);\n\n        RequestBody requestBody = RequestBody.create(jsonPayload, MediaType.parse(\"application/json\"));\n\n        Request request = new Request.Builder()\n                .url(url)\n                .post(requestBody)\n                .addHeader(\"Content-Type\", \"application/json\")\n                .addHeader(\"Accept\", \"text/event-stream\")\n                .addHeader(\"Authorization\", \"Bearer \" + cloudbase.getAccessToken())\n                .build();\n\n        System.out.println(\"AI 流式响应:\");\n        StringBuilder fullContent = new StringBuilder();\n\n        try (Response response = cloudbase.getClient().newCall(request).execute()) {\n            if (response.isSuccessful() && response.body() != null) {\n                BufferedReader reader = new BufferedReader(\n                    new InputStreamReader(response.body().byteStream(), StandardCharsets.UTF_8)\n                );\n                String line;\n\n                while ((line = reader.readLine()) != null) {\n                    if (line.startsWith(\"data: \")) {\n                        String dataStr = line.substring(6).trim();\n                        if (!dataStr.isEmpty() && !dataStr.equals(\"[DONE]\")) {\n                            try {\n                                JsonObject chunkData = cloudbase.getGson().fromJson(dataStr, JsonObject.class);\n\n                                // 支持多种响应格式\n                                String content = null;\n                                if (chunkData.has(\"content\")) {\n                                    content = chunkData.get(\"content\").getAsString();\n                                } else if (chunkData.has(\"choices\") && chunkData.getAsJsonArray(\"choices\").size() > 0) {\n                                    JsonObject choice = chunkData.getAsJsonArray(\"choices\").get(0).getAsJsonObject();\n                                    if (choice.has(\"delta\") && choice.getAsJsonObject(\"delta\").has(\"content\")) {\n                                        content = choice.getAsJsonObject(\"delta\").get(\"content\").getAsString();\n                                    } else if (choice.has(\"message\") && choice.getAsJsonObject(\"message\").has(\"content\")) {\n                                        content = choice.getAsJsonObject(\"message\").get(\"content\").getAsString();\n                                    }\n                                }\n\n                                if (content != null && !content.isEmpty()) {\n                                    System.out.print(content);\n                                    fullContent.append(content);\n                                }\n                            } catch (Exception e) {\n                                // 忽略JSON解析错误\n                            }\n                        }\n                    }\n                }\n                System.out.println(); // 换行\n            }\n        }\n    }\n}\n```",
                "index": 1,
                "id": "baas",
                "title": "普通型"
              }
            ]
          },
          {
            "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonObject;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class Example {\n    public static void main(String[] args) {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 账号密码登录\n        Map<String, String> credentials = new HashMap<>();\n        credentials.put(\"username\", \"your_username\");\n        credentials.put(\"password\", \"your_password\");\n\n        JsonObject result = cloudbase.request(\"POST\", \"/auth/v1/signin\", credentials);\n\n        if (result != null) {\n            String accessToken = result.get(\"access_token\").getAsString();\n            String refreshToken = result.get(\"refresh_token\").getAsString();\n            String userId = result.get(\"sub\").getAsString();\n\n            System.out.println(\"登录成功! 用户ID: \" + userId);\n            System.out.println(\"访问令牌: \" + accessToken.substring(0, 20) + \"...\");\n        }\n    }\n}\n```",
            "index": 8,
            "id": "identity",
            "title": "身份认证"
          }
        ]
      }
    ],
    "_id": "ab9277866964c1d50bc1b5f038631e16",
    "_openid": "anon",
    "createdAt": 1768210901891,
    "updatedAt": 1770370763773
  },
  {
    "category": "框架集成,后端框架,Go",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": 22,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/http-api/basic/overview",
    "content": [
      {
        "markdown": "通过 **HTTP 请求** 在 **Go** 中调用各种云开发能力\n\n```bash\ngo get github.com/joho/godotenv\n```",
        "index": 1,
        "title": "安装依赖",
        "content": []
      },
      {
        "markdown": "新增如下代码到您的 **Go** 项目",
        "index": 2,
        "title": "初始化配置",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```go\npackage main\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\n\t\"github.com/joho/godotenv\"\n)\n\ntype CloudBaseClient struct {\n\tEnvID       string\n\tAccessToken string\n\tBaseURL     string\n\tHTTPClient  *http.Client\n}\n\nfunc NewCloudBaseClient() *CloudBaseClient {\n\tgodotenv.Load()\n\n\tenvID := os.Getenv(\"CLOUDBASE_ENV_ID\")\n\taccessToken := os.Getenv(\"CLOUDBASE_ACCESS_TOKEN\")\n\n\treturn &CloudBaseClient{\n\t\tEnvID:       envID,\n\t\tAccessToken: accessToken,\n\t\tBaseURL:     fmt.Sprintf(\"https://%s.api.tcloudbasegateway.com\", envID),\n\t\tHTTPClient:  &http.Client{},\n\t}\n}\n\nfunc (c *CloudBaseClient) Request(method, path string, body interface{}, customHeaders map[string]string) (interface{}, error) {\n\turl := c.BaseURL + path\n\n\tvar reqBody io.Reader\n\tif body != nil {\n\t\tjsonData, err := json.Marshal(body)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"JSON序列化失败: %w\", err)\n\t\t}\n\t\treqBody = bytes.NewBuffer(jsonData)\n\t}\n\n\treq, err := http.NewRequest(method, url, reqBody)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"创建请求失败: %w\", err)\n\t}\n\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\treq.Header.Set(\"Accept\", \"application/json\")\n\treq.Header.Set(\"Authorization\", \"Bearer \"+c.AccessToken)\n\n\tfor key, value := range customHeaders {\n\t\treq.Header.Set(key, value)\n\t}\n\n\tresp, err := c.HTTPClient.Do(req)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"请求失败: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode < 200 || resp.StatusCode >= 300 {\n\t\tbodyBytes, _ := io.ReadAll(resp.Body)\n\t\treturn nil, fmt.Errorf(\"请求失败，状态码: %d, 响应: %s\", resp.StatusCode, string(bodyBytes))\n\t}\n\n\tbodyBytes, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"读取响应失败: %w\", err)\n\t}\n\n\tif len(bodyBytes) == 0 {\n\t\treturn true, nil\n\t}\n\n\tvar result interface{}\n\tif err := json.Unmarshal(bodyBytes, &result); err != nil {\n\t\treturn nil, fmt.Errorf(\"JSON解析失败: %w\", err)\n\t}\n\n\treturn result, nil\n}\n\nvar Cloudbase = NewCloudBaseClient()\n```",
            "index": 1,
            "title": "cloudbase_client.go"
          },
          {
            "markdown": "> 💡提示：如需管理员权限，请通过 [云开发平台/ApiKey管理页](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}&#/env/apikey) 获取 APIKey 替换 CLOUDBASE_ACCESS_TOKEN\n\n```properties\n# 环境ID\nCLOUDBASE_ENV_ID={%ENV_ID%}\n\n# 匿名访问令牌\nCLOUDBASE_ACCESS_TOKEN={%PUBLISHABLE_KEY%}\n```",
            "index": 2,
            "title": ".env"
          }
        ]
      },
      {
        "index": 3,
        "title": "调用云开发能力",
        "type": "codeTab",
        "content": [
          {
            "index": 1,
            "id": "mysql-db",
            "title": "MySQL数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```go\npackage main\n\nimport \"fmt\"\n\nfunc GetMySQLData(tableName string) (interface{}, error) {\n\tpath := fmt.Sprintf(\"/v1/rdb/rest/%s?limit=10\", tableName)\n\tdata, err := Cloudbase.Request(\"GET\", path, nil, nil)\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfmt.Println(\"查询成功:\", data)\n\treturn data, nil\n}\n\n// 使用示例\nfunc main() {\n\tresult, err := GetMySQLData(\"{%TABLE_NAME%}\")\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t}\n}\n```",
                "index": 1,
                "title": "查询数据",
                "content": []
              },
              {
                "markdown": "```go\npackage main\n\nimport \"fmt\"\n\nfunc AddMySQLData(tableName string, data map[string]interface{}) (interface{}, error) {\n\tpath := fmt.Sprintf(\"/v1/rdb/rest/%s\", tableName)\n\tresult, err := Cloudbase.Request(\"POST\", path, data, nil)\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfmt.Println(\"新增成功:\", result)\n\treturn result, nil\n}\n\n// 使用示例\nfunc main() {\n\tresult, err := AddMySQLData(\"{%TABLE_NAME%}\", map[string]interface{}{\n\t\t\"title\": \"示例标题\",\n\t})\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t}\n}\n```",
                "index": 2,
                "title": "新增数据",
                "content": []
              },
              {
                "markdown": "```go\npackage main\n\nimport \"fmt\"\n\nfunc UpdateMySQLData(tableName, dataID string, data map[string]interface{}) (interface{}, error) {\n\tpath := fmt.Sprintf(\"/v1/rdb/rest/%s?id=eq.%s\", tableName, dataID)\n\tresult, err := Cloudbase.Request(\"PATCH\", path, data, nil)\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfmt.Println(\"更新成功:\", result)\n\treturn result, nil\n}\n\n// 使用示例\nfunc main() {\n\tresult, err := UpdateMySQLData(\"{%TABLE_NAME%}\", \"<数据id>\", map[string]interface{}{\n\t\t\"title\": \"新标题\",\n\t})\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t}\n}\n```",
                "index": 3,
                "title": "更新数据",
                "content": []
              },
              {
                "markdown": "```go\npackage main\n\nimport \"fmt\"\n\nfunc DeleteMySQLData(tableName, dataID string) (bool, error) {\n\tpath := fmt.Sprintf(\"/v1/rdb/rest/%s?id=eq.%s\", tableName, dataID)\n\t_, err := Cloudbase.Request(\"DELETE\", path, nil, nil)\n\n\tif err != nil {\n\t\treturn false, err\n\t}\n\n\tfmt.Println(\"删除成功\")\n\treturn true, nil\n}\n\n// 使用示例\nfunc main() {\n\tsuccess, err := DeleteMySQLData(\"{%TABLE_NAME%}\", \"<数据id>\")\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t}\n\tfmt.Println(\"删除结果:\", success)\n}\n```",
                "index": 4,
                "title": "删除数据",
                "content": []
              }
            ]
          },
          {
            "index": 2,
            "id": "data-model",
            "title": "数据模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```go\npackage main\n\nimport \"fmt\"\n\nfunc GetModelData(modelName, envType string) ([]interface{}, error) {\n\tif envType == \"\" {\n\t\tenvType = \"prod\"\n\t}\n\n\tpath := fmt.Sprintf(\"/v1/model/%s/%s/list\", envType, modelName)\n\tpayload := map[string]interface{}{\n\t\t\"pageSize\":   10,\n\t\t\"pageNumber\": 1,\n\t\t\"getCount\":   true,\n\t}\n\n\tresult, err := Cloudbase.Request(\"POST\", path, payload, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif resultMap, ok := result.(map[string]interface{}); ok {\n\t\tif data, ok := resultMap[\"data\"].(map[string]interface{}); ok {\n\t\t\tif records, ok := data[\"records\"].([]interface{}); ok {\n\t\t\t\tfmt.Println(\"查询成功:\", records)\n\t\t\t\treturn records, nil\n\t\t\t}\n\t\t}\n\t}\n\n\treturn []interface{}{}, nil\n}\n\n// 使用示例\nfunc main() {\n\trecords, err := GetModelData(\"{%TABLE_NAME%}\", \"prod\")\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t}\n}\n```",
                "index": 1,
                "title": "查询数据",
                "content": []
              },
              {
                "markdown": "```go\npackage main\n\nimport \"fmt\"\n\nfunc AddModelData(modelName string, data map[string]interface{}, envType string) (interface{}, error) {\n\tif envType == \"\" {\n\t\tenvType = \"prod\"\n\t}\n\n\tpath := fmt.Sprintf(\"/v1/model/%s/%s/create\", envType, modelName)\n\tpayload := map[string]interface{}{\n\t\t\"data\": data,\n\t}\n\n\tresult, err := Cloudbase.Request(\"POST\", path, payload, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif resultMap, ok := result.(map[string]interface{}); ok {\n\t\tif dataMap, ok := resultMap[\"data\"].(map[string]interface{}); ok {\n\t\t\tif docID, ok := dataMap[\"id\"].(string); ok {\n\t\t\t\tfmt.Printf(\"新增成功! id: %s\\n\", docID)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result, nil\n}\n\n// 使用示例\nfunc main() {\n\tresult, err := AddModelData(\"{%TABLE_NAME%}\", map[string]interface{}{\n\t\t\"title\": \"示例标题\",\n\t}, \"prod\")\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t}\n}\n```",
                "index": 2,
                "title": "新增数据",
                "content": []
              },
              {
                "markdown": "```go\npackage main\n\nimport \"fmt\"\n\nfunc UpdateModelData(modelName, dataID string, data map[string]interface{}, envType string) (bool, error) {\n\tif envType == \"\" {\n\t\tenvType = \"prod\"\n\t}\n\n\tpath := fmt.Sprintf(\"/v1/model/%s/%s/update\", envType, modelName)\n\tpayload := map[string]interface{}{\n\t\t\"data\": data,\n\t\t\"filter\": map[string]interface{}{\n\t\t\t\"where\": map[string]interface{}{\n\t\t\t\t\"_id\": map[string]interface{}{\n\t\t\t\t\t\"$eq\": dataID,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\t_, err := Cloudbase.Request(\"PUT\", path, payload, nil)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\n\tfmt.Println(\"更新成功!\")\n\treturn true, nil\n}\n\n// 使用示例\nfunc main() {\n\tsuccess, err := UpdateModelData(\"{%TABLE_NAME%}\", \"<数据id>\", map[string]interface{}{\n\t\t\"title\": \"新标题\",\n\t}, \"prod\")\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t}\n}\n```",
                "index": 3,
                "title": "更新数据",
                "content": []
              },
              {
                "markdown": "```go\npackage main\n\nimport \"fmt\"\n\nfunc DeleteModelData(modelName, dataID, envType string) (bool, error) {\n\tif envType == \"\" {\n\t\tenvType = \"prod\"\n\t}\n\n\tpath := fmt.Sprintf(\"/v1/model/%s/%s/delete\", envType, modelName)\n\tpayload := map[string]interface{}{\n\t\t\"filter\": map[string]interface{}{\n\t\t\t\"where\": map[string]interface{}{\n\t\t\t\t\"_id\": map[string]interface{}{\n\t\t\t\t\t\"$eq\": dataID,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\t_, err := Cloudbase.Request(\"POST\", path, payload, nil)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\n\tfmt.Println(\"删除成功!\")\n\treturn true, nil\n}\n\n// 使用示例\nfunc main() {\n\tsuccess, err := DeleteModelData(\"{%TABLE_NAME%}\", \"<数据id>\", \"prod\")\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t}\n}\n```",
                "index": 4,
                "title": "删除数据",
                "content": []
              }
            ]
          },
          {
            "markdown": "```go\npackage main\n\nimport \"fmt\"\n\nfunc CallFunction(functionName string, data map[string]interface{}) (interface{}, error) {\n\tif data == nil {\n\t\tdata = map[string]interface{}{}\n\t}\n\n\tpath := fmt.Sprintf(\"/v1/functions/%s\", functionName)\n\tresult, err := Cloudbase.Request(\"POST\", path, data, nil)\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfmt.Println(\"云函数调用结果:\", result)\n\treturn result, nil\n}\n\n// 使用示例\nfunc main() {\n\tresult, err := CallFunction(\"{%FUNCTION_NAME%}\", nil)\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t}\n}\n```",
            "index": 3,
            "id": "scf",
            "title": "云函数"
          },
          {
            "markdown": "```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\nfunc CallContainer(serviceName, path, method string, data map[string]interface{}) (interface{}, error) {\n\tif method == \"\" {\n\t\tmethod = \"GET\"\n\t}\n\n\tfullPath := fmt.Sprintf(\"/v1/cloudrun/%s/%s\", serviceName, path)\n\tfullPath = strings.TrimSuffix(fullPath, \"/\")\n\n\tresult, err := Cloudbase.Request(strings.ToUpper(method), fullPath, data, nil)\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfmt.Println(\"云托管调用结果:\", result)\n\treturn result, nil\n}\n\n// 使用示例\nfunc main() {\n\tresult, err := CallContainer(\"{%SERVICE_NAME%}\", \"\", \"GET\", nil)\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t}\n}\n```",
            "index": 4,
            "id": "run",
            "title": "云托管"
          },
          {
            "index": 5,
            "id": "storage",
            "title": "云存储",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"time\"\n)\n\nfunc UploadFile(filePath, objectID string) (map[string]interface{}, error) {\n\tif objectID == \"\" {\n\t\tfilename := filepath.Base(filePath)\n\t\ttimestamp := time.Now().UnixMilli()\n\t\tobjectID = fmt.Sprintf(\"uploads/%d-%s\", timestamp, filename)\n\t}\n\n\tuploadInfo, err := Cloudbase.Request(\"POST\", \"/v1/storages/get-objects-upload-info\",\n\t\t[]map[string]interface{}{{\"objectId\": objectID}}, nil)\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tinfoList, ok := uploadInfo.([]interface{})\n\tif !ok || len(infoList) == 0 {\n\t\treturn nil, fmt.Errorf(\"获取上传信息失败\")\n\t}\n\n\tinfo := infoList[0].(map[string]interface{})\n\tuploadURL := info[\"uploadUrl\"].(string)\n\n\tfile, err := os.Open(filePath)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"文件不存在: %s\", filePath)\n\t}\n\tdefer file.Close()\n\n\tfileData, err := io.ReadAll(file)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"读取文件失败: %w\", err)\n\t}\n\n\treq, err := http.NewRequest(\"PUT\", uploadURL, bytes.NewReader(fileData))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treq.Header.Set(\"Authorization\", info[\"authorization\"].(string))\n\treq.Header.Set(\"X-Cos-Security-Token\", info[\"token\"].(string))\n\treq.Header.Set(\"X-Cos-Meta-Fileid\", info[\"cloudObjectMeta\"].(string))\n\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"文件上传失败: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode < 200 || resp.StatusCode >= 300 {\n\t\treturn nil, fmt.Errorf(\"上传失败，状态码: %d\", resp.StatusCode)\n\t}\n\n\tresult := map[string]interface{}{\n\t\t\"cloudObjectId\": info[\"cloudObjectId\"],\n\t\t\"downloadUrl\":   info[\"downloadUrl\"],\n\t\t\"objectId\":      objectID,\n\t}\n\n\tfmt.Println(\"文件上传成功:\")\n\tfmt.Printf(\"- 对象ID: %s\\n\", result[\"objectId\"])\n\tfmt.Printf(\"- 下载URL: %s\\n\", result[\"downloadUrl\"])\n\n\treturn result, nil\n}\n\n// 使用示例\nfunc main() {\n\tresult, err := UploadFile(\"./example.jpg\", \"\")\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t}\n}\n```",
                "index": 1,
                "title": "上传文件",
                "content": []
              },
              {
                "markdown": "```go\npackage main\n\nimport \"fmt\"\n\nfunc GetFileURL(cloudObjectID string) (string, error) {\n\tresult, err := Cloudbase.Request(\"POST\", \"/v1/storages/get-objects-download-info\",\n\t\t[]map[string]interface{}{{\"cloudObjectId\": cloudObjectID}}, nil)\n\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tif resultList, ok := result.([]interface{}); ok && len(resultList) > 0 {\n\t\tif info, ok := resultList[0].(map[string]interface{}); ok {\n\t\t\tif downloadURL, ok := info[\"downloadUrl\"].(string); ok {\n\t\t\t\tfmt.Println(\"文件链接:\", downloadURL)\n\t\t\t\treturn downloadURL, nil\n\t\t\t}\n\t\t}\n\t}\n\n\treturn \"\", fmt.Errorf(\"获取文件链接失败\")\n}\n\n// 使用示例\nfunc main() {\n\tfileURL, err := GetFileURL(\"cloud://xxx.png\")\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t}\n}\n```",
                "index": 2,
                "title": "获取文件链接",
                "content": []
              },
              {
                "markdown": "```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n)\n\nfunc DownloadFile(cloudObjectID, savePath string) (bool, error) {\n\tif savePath == \"\" {\n\t\tsavePath = \"./\"\n\t}\n\n\tresult, err := Cloudbase.Request(\"POST\", \"/v1/storages/get-objects-download-info\",\n\t\t[]map[string]interface{}{{\"cloudObjectId\": cloudObjectID}}, nil)\n\n\tif err != nil {\n\t\treturn false, err\n\t}\n\n\tif resultList, ok := result.([]interface{}); ok && len(resultList) > 0 {\n\t\tif info, ok := resultList[0].(map[string]interface{}); ok {\n\t\t\tdownloadURL := info[\"downloadUrl\"].(string)\n\n\t\t\tparts := strings.Split(downloadURL, \"/\")\n\t\t\tfilename := strings.Split(parts[len(parts)-1], \"?\")[0]\n\n\t\t\tfileInfo, err := os.Stat(savePath)\n\t\t\tvar fullPath string\n\t\t\tif err == nil && fileInfo.IsDir() || strings.HasSuffix(savePath, \"/\") {\n\t\t\t\tfullPath = filepath.Join(savePath, filename)\n\t\t\t} else {\n\t\t\t\tfullPath = savePath\n\t\t\t}\n\n\t\t\tresp, err := http.Get(downloadURL)\n\t\t\tif err != nil {\n\t\t\t\treturn false, fmt.Errorf(\"下载失败: %w\", err)\n\t\t\t}\n\t\t\tdefer resp.Body.Close()\n\n\t\t\tif resp.StatusCode < 200 || resp.StatusCode >= 300 {\n\t\t\t\treturn false, fmt.Errorf(\"下载失败，状态码: %d\", resp.StatusCode)\n\t\t\t}\n\n\t\t\toutFile, err := os.Create(fullPath)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tdefer outFile.Close()\n\n\t\t\t_, err = io.Copy(outFile, resp.Body)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\n\t\t\tfmt.Printf(\"下载成功! 文件已保存到: %s\\n\", fullPath)\n\t\t\treturn true, nil\n\t\t}\n\t}\n\n\treturn false, fmt.Errorf(\"下载失败\")\n}\n\n// 使用示例\nfunc main() {\n\t// 下载到当前目录，使用原文件名\n\tsuccess, err := DownloadFile(\"cloud://xxx.png\", \"\")\n\n\t// 下载到指定目录\n\t// success, err := DownloadFile(\"cloud://xxx.png\", \"./downloads/\")\n\n\t// 下载并重命名\n\t// success, err := DownloadFile(\"cloud://xxx.png\", \"./my-image.png\")\n\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t}\n}\n```",
                "index": 3,
                "title": "下载文件",
                "content": []
              },
              {
                "markdown": "```go\npackage main\n\nimport \"fmt\"\n\nfunc DeleteFile(cloudObjectIDs interface{}) (bool, error) {\n\tvar data []map[string]interface{}\n\n\tswitch v := cloudObjectIDs.(type) {\n\tcase string:\n\t\tdata = []map[string]interface{}{{\"cloudObjectId\": v}}\n\tcase []string:\n\t\tfor _, id := range v {\n\t\t\tdata = append(data, map[string]interface{}{\"cloudObjectId\": id})\n\t\t}\n\tdefault:\n\t\treturn false, fmt.Errorf(\"不支持的参数类型\")\n\t}\n\n\t_, err := Cloudbase.Request(\"POST\", \"/v1/storages/delete-objects\", data, nil)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\n\tfmt.Println(\"删除成功!\")\n\treturn true, nil\n}\n\n// 使用示例\nfunc main() {\n\tsuccess, err := DeleteFile(\"cloud://xxx.png\")\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t}\n}\n```",
                "index": 4,
                "title": "删除文件",
                "content": []
              }
            ]
          },
          {
            "index": 6,
            "id": "ai-model",
            "title": "大模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```go\npackage main\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"strings\"\n)\n\nfunc StreamText(model, subModel string, messages []map[string]string) (string, error) {\n\tpayload := map[string]interface{}{\n\t\t\"model\":    subModel,\n\t\t\"messages\": messages,\n\t\t\"stream\":   true,\n\t}\n\n\tjsonData, err := json.Marshal(payload)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\turl := fmt.Sprintf(\"%s/v1/ai/%s/chat/completions\", Cloudbase.BaseURL, model)\n\treq, err := http.NewRequest(\"POST\", url, bytes.NewBuffer(jsonData))\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\treq.Header.Set(\"Accept\", \"text/event-stream\")\n\treq.Header.Set(\"Authorization\", \"Bearer \"+Cloudbase.AccessToken)\n\n\tresp, err := Cloudbase.HTTPClient.Do(req)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"AI 调用失败: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\tfmt.Println(\"AI 流式响应:\")\n\tfullContent := \"\"\n\tscanner := bufio.NewScanner(resp.Body)\n\n\tfor scanner.Scan() {\n\t\tline := scanner.Text()\n\t\tif strings.HasPrefix(line, \"data: \") {\n\t\t\tdataStr := strings.TrimPrefix(line, \"data: \")\n\t\t\tif strings.TrimSpace(dataStr) != \"[DONE]\" {\n\t\t\t\tvar chunkData map[string]interface{}\n\t\t\t\tif err := json.Unmarshal([]byte(dataStr), &chunkData); err == nil {\n\t\t\t\t\tif choices, ok := chunkData[\"choices\"].([]interface{}); ok && len(choices) > 0 {\n\t\t\t\t\t\tif choice, ok := choices[0].(map[string]interface{}); ok {\n\t\t\t\t\t\t\tif delta, ok := choice[\"delta\"].(map[string]interface{}); ok {\n\t\t\t\t\t\t\t\tif content, ok := delta[\"content\"].(string); ok {\n\t\t\t\t\t\t\t\t\tfmt.Print(content)\n\t\t\t\t\t\t\t\t\tfullContent += content\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tfmt.Println()\n\treturn fullContent, nil\n}\n\n// 使用示例\nfunc main() {\n\tresponse, err := StreamText(\n\t\t\"{%AI_MODEL_NAME%}\",\n\t\t\"{%AI_SUB_MODEL_NAME%}\",\n\t\t[]map[string]string{\n\t\t\t{\"role\": \"system\", \"content\": \"请严格按照七言绝句或七言律诗的格律要求创作，平仄需符合规则，押韵要和谐自然，韵脚字需在同一韵部。\"},\n\t\t\t{\"role\": \"user\", \"content\": \"春天\"},\n\t\t},\n\t)\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t}\n}\n```",
                "index": 1,
                "id": "text-aiModel",
                "title": "生文模型",
                "content": []
              },
              {
                "markdown": "生图模型通过调用云函数来实现，在生图模型页面点击「一键创建云函数」，函数调用示例如下：\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc GenerateImage(prompt string) (map[string]interface{}, error) {\n\t// 准备调用参数\n\tdata := map[string]interface{}{\n\t\t\"prompt\": prompt,\n\t}\n\n\t// 调用云函数生成图片\n\tresult, err := Cloudbase.Request(\"POST\", \"/v1/functions/<YOUR_FUNCTION_NAME>\", data, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif resultMap, ok := result.(map[string]interface{}); ok {\n\t\tif success, ok := resultMap[\"success\"].(bool); ok && success {\n\t\t\timageUrl := resultMap[\"imageUrl\"].(string)\n\t\t\trevisedPrompt := \"\"\n\t\t\tif rp, ok := resultMap[\"revised_prompt\"].(string); ok {\n\t\t\t\trevisedPrompt = rp\n\t\t\t}\n\n\t\t\tfmt.Println(\"生成成功!\")\n\t\t\tfmt.Printf(\"图片URL: %s\\n\", imageUrl)\n\t\t\tfmt.Printf(\"优化后的提示词: %s\\n\", revisedPrompt)\n\t\t\tfmt.Println(\"注意: 图片URL有效期为24小时\")\n\n\t\t\treturn resultMap, nil\n\t\t} else {\n\t\t\tcode := \"\"\n\t\t\tmessage := \"\"\n\t\t\tif c, ok := resultMap[\"code\"].(string); ok {\n\t\t\t\tcode = c\n\t\t\t}\n\t\t\tif m, ok := resultMap[\"message\"].(string); ok {\n\t\t\t\tmessage = m\n\t\t\t}\n\t\t\treturn nil, fmt.Errorf(\"生成失败: %s - %s\", code, message)\n\t\t}\n\t}\n\n\treturn nil, fmt.Errorf(\"请求失败\")\n}\n\n// 使用示例\nfunc main() {\n\tresult, err := GenerateImage(\"一只可爱的猫咪在阳光下玩耍\")\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t} else {\n\t\tfmt.Println(\"图片生成完成:\", result)\n\t}\n}\n```",
                "index": 2,
                "id": "image-aiModel",
                "title": "生图模型",
                "content": []
              }
            ]
          },
          {
            "markdown": "",
            "index": 7,
            "id": "agent",
            "title": "Agent",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```go\n/*\nGo 调用 Agent 示例（AG-UI 协议）\n协议文档：https://docs.cloudbase.net/ai/agent-development/protocol\n*/\npackage main\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n)\n\n// Message AG-UI 协议消息结构\ntype Message struct {\n\tID      string `json:\"id\"`\n\tRole    string `json:\"role\"`\n\tContent string `json:\"content\"`\n}\n\n// AGUIRequest AG-UI 协议请求体\ntype AGUIRequest struct {\n\tMessages       []Message              `json:\"messages\"`                 // 必填：消息列表\n\tThreadID       string                 `json:\"threadId,omitempty\"`       // 可选：会话ID，用于多轮对话\n\tRunID          string                 `json:\"runId,omitempty\"`          // 可选：运行ID，用于追踪执行\n\tTools          []interface{}          `json:\"tools,omitempty\"`          // 可选：前端工具定义\n\tContext        []interface{}          `json:\"context,omitempty\"`        // 可选：上下文信息\n\tForwardedProps map[string]interface{} `json:\"forwardedProps,omitempty\"` // 可选：透传参数\n}\n\nfunc ChatWithAgentStream(botID, msg string, history []Message) (string, error) {\n\tif history == nil {\n\t\thistory = []Message{}\n\t}\n\n\turl := fmt.Sprintf(\"%s/v1/aibot/bots/%s/send-message\", Cloudbase.BaseURL, botID)\n\n\t// 构建消息列表（AG-UI 协议格式）\n\tmessages := make([]Message, 0, len(history)+1)\n\n\t// 添加历史消息\n\tmessages = append(messages, history...)\n\n\t// 添加当前用户消息\n\tmessages = append(messages, Message{\n\t\tID:      fmt.Sprintf(\"msg-%s\", uuid.New().String()),\n\t\tRole:    \"user\",\n\t\tContent: msg,\n\t})\n\n\t// AG-UI 协议请求体\n\tpayload := AGUIRequest{\n\t\tMessages:       messages,\n\t\tThreadID:       fmt.Sprintf(\"thread-%s\", uuid.New().String()),\n\t\tRunID:          fmt.Sprintf(\"run-%s\", uuid.New().String()),\n\t\tTools:          []interface{}{},\n\t\tContext:        []interface{}{},\n\t\tForwardedProps: map[string]interface{}{},\n\t}\n\n\tjsonData, err := json.Marshal(payload)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treq, err := http.NewRequest(\"POST\", url, bytes.NewBuffer(jsonData))\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\treq.Header.Set(\"Accept\", \"text/event-stream\")\n\treq.Header.Set(\"Authorization\", \"Bearer \"+Cloudbase.AccessToken)\n\n\tclient := &http.Client{Timeout: 30 * time.Second}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"AI 调用失败: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\tfmt.Println(\"AI 流式响应:\")\n\tfullContent := \"\"\n\tscanner := bufio.NewScanner(resp.Body)\n\n\tfor scanner.Scan() {\n\t\tline := strings.TrimSpace(scanner.Text())\n\t\tif strings.HasPrefix(line, \"data: \") {\n\t\t\tdataStr := strings.TrimSpace(strings.TrimPrefix(line, \"data: \"))\n\t\t\tif dataStr != \"\" && dataStr != \"[DONE]\" {\n\t\t\t\tvar chunkData map[string]interface{}\n\t\t\t\tif err := json.Unmarshal([]byte(dataStr), &chunkData); err == nil {\n\t\t\t\t\tvar content string\n\t\t\t\t\tif c, ok := chunkData[\"content\"].(string); ok {\n\t\t\t\t\t\tcontent = c\n\t\t\t\t\t} else if choices, ok := chunkData[\"choices\"].([]interface{}); ok && len(choices) > 0 {\n\t\t\t\t\t\tif choice, ok := choices[0].(map[string]interface{}); ok {\n\t\t\t\t\t\t\tif delta, ok := choice[\"delta\"].(map[string]interface{}); ok {\n\t\t\t\t\t\t\t\tif c, ok := delta[\"content\"].(string); ok {\n\t\t\t\t\t\t\t\t\tcontent = c\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if message, ok := choice[\"message\"].(map[string]interface{}); ok {\n\t\t\t\t\t\t\t\tif c, ok := message[\"content\"].(string); ok {\n\t\t\t\t\t\t\t\t\tcontent = c\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif content != \"\" {\n\t\t\t\t\t\tfmt.Print(content)\n\t\t\t\t\t\tfullContent += content\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tfmt.Println()\n\treturn fullContent, nil\n}\n\n// 使用示例\nfunc main() {\n\tresponse, err := ChatWithAgentStream(\"{%AGENT_ID%}\", \"你是谁\", nil)\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t}\n\t_ = response\n}\n\n```",
                "index": 0,
                "id": "scf",
                "title": "函数型"
              },
              {
                "markdown": "```go\npackage main\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"strings\"\n\t\"time\"\n)\n\nfunc ChatWithAgentStream(botID, msg string, history []map[string]string) (string, error) {\n\tif history == nil {\n\t\thistory = []map[string]string{}\n\t}\n\n\turl := fmt.Sprintf(\"%s/v1/aibot/bots/%s/send-message\", Cloudbase.BaseURL, botID)\n\tpayload := map[string]interface{}{\n\t\t\"history\": history,\n\t\t\"msg\":     msg,\n\t}\n\n\tjsonData, err := json.Marshal(payload)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treq, err := http.NewRequest(\"POST\", url, bytes.NewBuffer(jsonData))\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\treq.Header.Set(\"Accept\", \"text/event-stream\")\n\treq.Header.Set(\"Authorization\", \"Bearer \"+Cloudbase.AccessToken)\n\n\tclient := &http.Client{Timeout: 30 * time.Second}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"AI 调用失败: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\tfmt.Println(\"AI 流式响应:\")\n\tfullContent := \"\"\n\tscanner := bufio.NewScanner(resp.Body)\n\n\tfor scanner.Scan() {\n\t\tline := strings.TrimSpace(scanner.Text())\n\t\tif strings.HasPrefix(line, \"data: \") {\n\t\t\tdataStr := strings.TrimSpace(strings.TrimPrefix(line, \"data: \"))\n\t\t\tif dataStr != \"\" && dataStr != \"[DONE]\" {\n\t\t\t\tvar chunkData map[string]interface{}\n\t\t\t\tif err := json.Unmarshal([]byte(dataStr), &chunkData); err == nil {\n\t\t\t\t\tvar content string\n\t\t\t\t\tif c, ok := chunkData[\"content\"].(string); ok {\n\t\t\t\t\t\tcontent = c\n\t\t\t\t\t} else if choices, ok := chunkData[\"choices\"].([]interface{}); ok && len(choices) > 0 {\n\t\t\t\t\t\tif choice, ok := choices[0].(map[string]interface{}); ok {\n\t\t\t\t\t\t\tif delta, ok := choice[\"delta\"].(map[string]interface{}); ok {\n\t\t\t\t\t\t\t\tif c, ok := delta[\"content\"].(string); ok {\n\t\t\t\t\t\t\t\t\tcontent = c\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if message, ok := choice[\"message\"].(map[string]interface{}); ok {\n\t\t\t\t\t\t\t\tif c, ok := message[\"content\"].(string); ok {\n\t\t\t\t\t\t\t\t\tcontent = c\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif content != \"\" {\n\t\t\t\t\t\tfmt.Print(content)\n\t\t\t\t\t\tfullContent += content\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tfmt.Println()\n\treturn fullContent, nil\n}\n\n// 使用示例\nfunc main() {\n\tresponse, err := ChatWithAgentStream(\"{%AGENT_ID%}\", \"你是谁\", nil)\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t}\n}\n```",
                "index": 1,
                "id": "baas",
                "title": "普通型"
              }
            ]
          },
          {
            "markdown": "```go\npackage main\n\nimport \"fmt\"\n\nfunc SignIn(username, password string) (map[string]interface{}, error) {\n\tresult, err := Cloudbase.Request(\"POST\", \"/auth/v1/signin\",\n\t\tmap[string]interface{}{\n\t\t\t\"username\": username,\n\t\t\t\"password\": password,\n\t\t}, nil)\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif resultMap, ok := result.(map[string]interface{}); ok {\n\t\taccessToken := resultMap[\"access_token\"].(string)\n\t\tuserID := resultMap[\"sub\"].(string)\n\n\t\tfmt.Printf(\"登录成功! 用户ID: %s\\n\", userID)\n\t\tfmt.Printf(\"访问令牌: %s...\\n\", accessToken[:20])\n\t\treturn resultMap, nil\n\t}\n\n\treturn nil, fmt.Errorf(\"登录失败\")\n}\n\n// 使用示例\nfunc main() {\n\tresult, err := SignIn(\"your_username\", \"your_password\")\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t}\n}\n```",
            "index": 8,
            "id": "identity",
            "title": "身份认证"
          }
        ]
      }
    ],
    "_id": "aca45c22697c22eb003813cf0f5241c6",
    "_openid": "anon",
    "createdAt": 1769743083874,
    "updatedAt": 1770021220571
  },
  {
    "category": "CloudBase MCP,WindSurf",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": 17,
    "hasTemplate": true,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/windsurf",
    "content": [
      {
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "将以下配置添加到 `.windsurf/mcp.json`: \n```json\n{\n  \"mcpServers\": {\n    \"cloudbase\": {\n      \"command\": \"npx\",\n      \"args\": [\"@cloudbase/cloudbase-mcp@latest\"],\n      \"env\": {\n        \"INTEGRATION_IDE\": \"WindSurf\",\n        \"CLOUDBASE_MCP_PLUGINS_DISABLED\": \"interactive\"\n      }\n    }\n  }\n}\n```\n",
            "title": "手动配置",
            "content": []
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "b387ab55697c2e140036bea56d11472f",
    "_openid": "1524963278340493312",
    "createdAt": 1769745940590,
    "updatedAt": 1769757579699
  },
  {
    "category": "CloudBase MCP,Gemini CLI",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": 9,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/gemini-cli",
    "content": [
      {
        "docsUrl": "",
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "将以下配置添加到 `.gemini/settings.json`:\n```json\n{\n  \"mcpServers\": {\n    \"cloudbase\": {\n      \"command\": \"npx\",\n      \"args\": [\"@cloudbase/cloudbase-mcp@latest\"],\n      \"env\": {\n        \"INTEGRATION_IDE\": \"Gemini\"\n      }\n    }\n  }\n}\n```\n",
            "title": "手动配置"
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "b387ab55697c2e140036bea66fbbce1d",
    "_openid": "1524963278340493312",
    "createdAt": 1769745940590,
    "updatedAt": 1769745940590
  },
  {
    "category": "CloudBase MCP,Google Antigravity",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": 16,
    "hasTemplate": true,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/antigravity",
    "content": [
      {
        "docsUrl": "",
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "将以下配置添加到 `.agent/rules/`: \n```json\n{\n  \"mcpServers\": {\n    \"cloudbase\": {\n      \"command\": \"npx\",\n      \"args\": [\"@cloudbase/cloudbase-mcp@latest\"],\n      \"env\": {\n        \"INTEGRATION_IDE\": \"Antigravity\"\n      }\n    }\n  }\n}\n```\n",
            "title": "手动配置"
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "b387ab55697c2e140036bea7029103d3",
    "_openid": "1524963278340493312",
    "createdAt": 1769745940590,
    "updatedAt": 1769745940590
  },
  {
    "category": "CloudBase MCP,微信开发者工具",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": 0,
    "hasTemplate": true,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/wechat-devtools",
    "content": [
      {
        "docsUrl": "",
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "<p style=\"margin-bottom: 0;font-weight: bold\">\n步骤 1：安装 CodeBuddy 扩展\n</p>\n<ol style=\"color: #00000080; font-size: 12px;margin-top: 0;margin-bottom: 8px;\">\n<li style=\"margin-top:0\">在微信开发者工具 2.0 以上版本中，你可以使用快捷键 Ctrl + Shift + X（Windows/Linux）或 Shift + Command + X（macOS）快速打开扩展面板</li>\n<li style=\"margin-top:0\">在扩展市场中搜索「CodeBuddy」</li>\n<li style=\"margin-top:0\">安装「腾讯云代码助手 CodeBuddy」扩展\n</li>\n</ol>\n\n<p style=\"margin-bottom: 0;margin-top: 8px;font-weight: bold\">\n步骤 2：安装 CloudBase MCP\n</p>\n<ol style=\"color: #00000080; font-size: 12px;margin-top: 0;\">\n<li style=\"margin-top:0\">安装完成后，在工具栏找到 CodeBuddy 图标</li>\n<li style=\"margin-top:0\">点击右上角的 CodeBuddy 设置图标</li>\n<li style=\"margin-top:0\">在 MCP 市场中搜索并安装「CloudBase MCP」</li>\n</ol>",
            "title": "手动配置"
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "b387ab55697c2e140036bea8090494ea",
    "_openid": "1524963278340493312",
    "createdAt": 1769745940590,
    "updatedAt": 1769745940590
  },
  {
    "category": "CloudBase MCP,Trae",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": 6,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/trae",
    "content": [
      {
        "docsUrl": "",
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "将以下配置添加到 `.trae/mcp.json`:\n```json\n{\n  \"mcpServers\": {\n    \"cloudbase\": {\n      \"command\": \"npx\",\n      \"args\": [\"@cloudbase/cloudbase-mcp@latest\"],\n      \"env\": {\n        \"INTEGRATION_IDE\": \"Trae\"\n      }\n    }\n  }\n}\n```\n",
            "title": "手动配置"
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "b387ab55697c2e140036bea94a87f52b",
    "_openid": "1524963278340493312",
    "createdAt": 1769745940590,
    "updatedAt": 1769745940590
  },
  {
    "category": "CloudBase MCP,Cursor",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": 1,
    "hasTemplate": true,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/cursor",
    "content": [
      {
        "docsUrl": "",
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "将以下配置添加到 `.cursor/mcp.json`:\n```json\n{\n  \"mcpServers\": {\n    \"cloudbase\": {\n      \"command\": \"npx\",\n      \"args\": [\"@cloudbase/cloudbase-mcp@latest\"],\n      \"env\": {\n        \"INTEGRATION_IDE\": \"Cursor\"\n      }\n    }\n  }\n}\n```\n",
            "title": "手动配置"
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "b387ab55697c2e140036beaa1a5e0d1b",
    "_openid": "1524963278340493312",
    "createdAt": 1769745940590,
    "updatedAt": 1769745940590
  },
  {
    "category": "CloudBase MCP,CodeBuddy",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": 2,
    "hasTemplate": true,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/codebuddy",
    "content": [
      {
        "docsUrl": "",
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "CodeBuddy IDE 已内置集成 CloudBase MCP，建议优先使用配置集成方式，[查看 BaaS 集成文档](https://www.codebuddy.ai/docs/zh/ide/User-guide/Integration)",
            "title": "内置集成"
          },
          {
            "markdown": "手动配置 MCP 请查看 [CodeBuddy 文档](https://www.codebuddy.ai/docs/zh/ide/Config%20MCP) \n```json\n{\n  \"mcpServers\": {\n    \"cloudbase\": {\n      \"command\": \"npx\",\n      \"args\": [\"@cloudbase/cloudbase-mcp@latest\"],\n      \"env\": {\n        \"INTEGRATION_IDE\": \"CodeBuddyManual\"\n      }\n    }\n  }\n}\n```\n",
            "title": "手动配置"
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "b387ab55697c2e140036beab417f61e3",
    "_openid": "1524963278340493312",
    "createdAt": 1769745940590,
    "updatedAt": 1770708807834
  },
  {
    "category": "CloudBase MCP,VSCode",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": 5,
    "hasTemplate": true,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/github-copilot",
    "content": [
      {
        "docsUrl": "",
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "将以下配置添加到 `.vscode/mcp.json`:\n```json\n{\n  \"mcpServers\": {\n    \"cloudbase\": {\n      \"command\": \"npx\",\n      \"args\": [\"@cloudbase/cloudbase-mcp@latest\"],\n      \"env\": {\n        \"INTEGRATION_IDE\": \"VSCode\"\n      }\n    }\n  }\n}\n```\n",
            "title": "手动配置"
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "b387ab55697c2e140036beac6976d9d4",
    "_openid": "1524963278340493312",
    "createdAt": 1769745940590,
    "updatedAt": 1769745940590
  },
  {
    "category": "CloudBase MCP,文心快码",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": 8,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/baidu-comate",
    "content": [
      {
        "docsUrl": "",
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "将以下配置添加到 `.baidu-comate/mcp.json`: \n```json\n{\n  \"mcpServers\": {\n    \"cloudbase\": {\n      \"command\": \"npx\",\n      \"args\": [\"@cloudbase/cloudbase-mcp@latest\"],\n      \"env\": {\n        \"INTEGRATION_IDE\": \"Comate\"\n      }\n    }\n  }\n}\n```\n",
            "title": "手动配置"
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "b387ab55697c2e140036bead6a98aed4",
    "_openid": "1524963278340493312",
    "createdAt": 1769745940590,
    "updatedAt": 1769745940590
  },
  {
    "category": "CloudBase MCP,OpenAI Codex CLI",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": 10,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/openai-codex-cli",
    "content": [
      {
        "docsUrl": "",
        "markdown": "**前置步骤：** \n```bash\nnpm i @cloudbase/cloudbase-mcp -g\n```\n\n根据运行系统在终端中运行指令：\n\n**MacOS, Linux, WSL:**\n```bash\ncodex mcp add cloudbase --env INTEGRATION_IDE=CodeX -- cloudbase-mcp\n```\n\n**Windows Powershell:**\n```bash\ncodex mcp add cloudbase --env INTEGRATION_IDE=CodeX -- cmd /c cloudbase-mcp\n```",
        "title": "安装",
        "type": "",
        "content": []
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "b387ab55697c2e140036beae357527d0",
    "_openid": "1524963278340493312",
    "createdAt": 1769745940590,
    "updatedAt": 1769745940590
  },
  {
    "category": "CloudBase MCP,Augment Code",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": 13,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/augment-code",
    "content": [
      {
        "docsUrl": "",
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "将以下配置添加到 `.vscode/settings.json`: \n```json\n{\n  \"mcpServers\": {\n    \"cloudbase\": {\n      \"command\": \"npx\",\n      \"args\": [\"@cloudbase/cloudbase-mcp@latest\"],\n      \"env\": {\n        \"INTEGRATION_IDE\": \"Augment\"\n      }\n    }\n  }\n}\n```\n",
            "title": "手动配置"
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "b387ab55697c2e140036beaf6ba5b8d3",
    "_openid": "1524963278340493312",
    "createdAt": 1769745940590,
    "updatedAt": 1769745940590
  },
  {
    "category": "CloudBase MCP,RooCode",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": 12,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/roocode",
    "content": [
      {
        "docsUrl": "",
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "将以下配置添加到 `.roocode/mcp.json`: \n```json\n{\n  \"mcpServers\": {\n    \"cloudbase\": {\n      \"command\": \"npx\",\n      \"args\": [\"@cloudbase/cloudbase-mcp@latest\"],\n\t  \"disabled\": false,\n      \"env\": {\n        \"INTEGRATION_IDE\": \"RooCode\"\n      }\n    }\n  }\n}\n```\n",
            "title": "手动配置"
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "b387ab55697c2e140036beb00f76ba5e",
    "_openid": "1524963278340493312",
    "createdAt": 1769745940590,
    "updatedAt": 1769745940590
  },
  {
    "category": "CloudBase MCP,OpenCode",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": 14,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/opencode",
    "content": [
      {
        "docsUrl": "",
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "将以下配置添加到 `.opencode.json`: \n```json\n{\n  \"mcpServers\": {\n    \"cloudbase\": {\n      \"command\": \"npx\",\n      \"args\": [\"@cloudbase/cloudbase-mcp@latest\"],\n      \"env\": {\n        \"INTEGRATION_IDE\": \"OpenCode\"\n      }\n    }\n  }\n}\n```\n",
            "title": "手动配置"
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "b387ab55697c2e140036beb122f75821",
    "_openid": "1524963278340493312",
    "createdAt": 1769745940590,
    "updatedAt": 1769745940590
  },
  {
    "category": "CloudBase MCP,Claude Code",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": 3,
    "hasTemplate": true,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/claude-code",
    "content": [
      {
        "docsUrl": "",
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "将以下配置添加到 `.mcp.json`:\n```json\n{\n  \"mcpServers\": {\n    \"cloudbase\": {\n      \"command\": \"npx\",\n      \"args\": [\"@cloudbase/cloudbase-mcp@latest\"],\n      \"env\": {\n        \"INTEGRATION_IDE\": \"ClaudeCode\"\n      }\n    }\n  }\n}\n```\n",
            "title": "手动配置"
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "b387ab55697c2e140036beb26644519c",
    "_openid": "1524963278340493312",
    "createdAt": 1769745940590,
    "updatedAt": 1769745940590
  },
  {
    "category": "CloudBase MCP,Qwen Code",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": 11,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/qwen-code",
    "content": [
      {
        "docsUrl": "",
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "将以下配置添加到 `.qwen/settings.json`: \n```json\n{\n  \"mcpServers\": {\n    \"cloudbase\": {\n      \"command\": \"npx\",\n      \"args\": [\"@cloudbase/cloudbase-mcp@latest\"],\n      \"env\": {\n        \"INTEGRATION_IDE\": \"Qwen\"\n      }\n    }\n  }\n}\n```\n",
            "title": "手动配置"
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "b387ab55697c2e140036beb37bea827c",
    "_openid": "1524963278340493312",
    "createdAt": 1769745940590,
    "updatedAt": 1769745940590
  },
  {
    "category": "CloudBase MCP,通义灵码",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": 7,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/tongyi-lingma",
    "content": [
      {
        "docsUrl": "",
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "手动配置 MCP 请查看 [通义灵码文档](https://help.aliyun.com/zh/lingma/user-guide/guide-for-using-mcp) \n```json\n{\n  \"mcpServers\": {\n    \"cloudbase\": {\n      \"command\": \"npx\",\n      \"args\": [\"@cloudbase/cloudbase-mcp@latest\"],\n      \"env\": {\n        \"INTEGRATION_IDE\": \"LingMa\"\n      }\n    }\n  }\n}\n```\n",
            "title": "手动配置"
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "b387ab55697c2e140036beb4255a9237",
    "_openid": "1524963278340493312",
    "createdAt": 1769745940590,
    "updatedAt": 1769745940590
  },
  {
    "category": "CloudBase MCP,Kiro",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": 19,
    "hasTemplate": true,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/kiro",
    "content": [
      {
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "将以下配置添加到项目目录下的 `.kiro/settings/mcp.json`: \n```json\n{\n  \"mcpServers\": {\n    \"cloudbase\": {\n      \"command\": \"npx\",\n      \"args\": [\"@cloudbase/cloudbase-mcp@latest\"],\n      \"env\": {\n        \"INTEGRATION_IDE\": \"Kiro\"\n      }\n    }\n  }\n}\n```",
            "title": "手动配置"
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "tab",
        "content": []
      }
    ],
    "_id": "b387ab55697c2e140036beb5202bb2bd",
    "_openid": "1524963278340493312",
    "createdAt": 1769745940590,
    "updatedAt": 1769745940590
  },
  {
    "category": "CloudBase MCP,Qoder",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": 15,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/qoder",
    "content": [
      {
        "docsUrl": "",
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "将以下配置添加到 `Qoder 设置 > MCP`: \n```json\n{\n  \"mcpServers\": {\n    \"cloudbase\": {\n      \"command\": \"npx\",\n      \"args\": [\"@cloudbase/cloudbase-mcp@latest\"],\n      \"env\": {\n        \"INTEGRATION_IDE\": \"Qorder\"\n      }\n    }\n  }\n}\n```\n",
            "title": "手动配置"
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "b387ab55697c2e140036beb6214b8288",
    "_openid": "1524963278340493312",
    "createdAt": 1769745940590,
    "updatedAt": 1769745940590
  },
  {
    "category": "CloudBase MCP,CodeBuddy Code",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": 4,
    "hasTemplate": true,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/codebuddy-code",
    "content": [
      {
        "docsUrl": "",
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "```bash\ncodebuddy mcp add --scope project cloudbase --env INTEGRATION_IDE=CodeBuddyCode -- npx @cloudbase/cloudbase-mcp@latest\n```",
            "title": "CLI 命令"
          },
          {
            "markdown": "将以下配置添加到 `.mcp.json`:\n```json\n{\n  \"mcpServers\": {\n    \"cloudbase\": {\n      \"command\": \"npx\",\n      \"args\": [\"@cloudbase/cloudbase-mcp@latest\"],\n      \"env\": {\n        \"INTEGRATION_IDE\": \"CodeBuddyCode\"\n      }\n    }\n  }\n}\n```\n",
            "title": "手动配置"
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "b387ab55697c2e140036beb745be8a93",
    "_openid": "1524963278340493312",
    "createdAt": 1769745940590,
    "updatedAt": 1769745940590
  },
  {
    "category": "CloudBase MCP,Cline",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": 18,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/cline",
    "content": [
      {
        "docsUrl": "",
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "将以下配置添加到 `.cline/mcp.json`: \n```json\n{\n  \"mcpServers\": {\n    \"cloudbase\": {\n      \"autoApprove\": [],\n      \"timeout\": 60,\n      \"command\": \"npx\",\n      \"args\": [\"@cloudbase/cloudbase-mcp@latest\"],\n      \"env\": {\n        \"INTEGRATION_IDE\": \"Cline\"\n      },\n      \"transportType\": \"stdio\",\n      \"disabled\": false\n    }\n  }\n}\n```\n",
            "title": "手动配置"
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "b387ab55697c2e140036beb856edaaa4",
    "_openid": "1524963278340493312",
    "createdAt": 1769745940590,
    "updatedAt": 1769745940590
  },
  {
    "category": "框架集成,小程序 / 小游戏,微信小游戏,Cocos",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": 3,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/api-reference/webv2/adapter",
    "content": [
      {
        "markdown": "`@cloudbase/js-sdk` 配合 `@cloudbase/adapter-cocos_native` 可以让您在 Cocos 项目中访问 CloudBase 服务和资源。",
        "index": 1,
        "title": "安装 SDK",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```bash\nnpm i @cloudbase/js-sdk @cloudbase/adapter-cocos_native\n```",
            "index": 1,
            "title": "npm",
            "content": []
          },
          {
            "markdown": "```bash\nyarn add @cloudbase/js-sdk @cloudbase/adapter-cocos_native\n```",
            "index": 2,
            "title": "yarn",
            "content": []
          },
          {
            "markdown": "```bash\npnpm add @cloudbase/js-sdk @cloudbase/adapter-cocos_native\n```",
            "index": 3,
            "title": "pnpm",
            "content": []
          }
        ]
      },
      {
        "markdown": "新增如下代码到您的 Cocos 项目",
        "index": 2,
        "title": "初始化 SDK",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```js\nimport cloudbaseSDK from \"@cloudbase/js-sdk\";\nimport adapter from \"@cloudbase/adapter-cocos_native\";\n\n// 注册适配器\ncloudbaseSDK.useAdapters(adapter);\n\nconst cloudbase = cloudbaseSDK.init({\n  // 环境 ID\n  env: \"{%ENV_ID%}\",\n  // 地域\n  region: \"{%REGION%}\",\n  // 匿名访问令牌\n  accessKey: \"{%PUBLISHABLE_KEY%}\"\n});\n\nexport default cloudbase;\n```",
            "index": 1,
            "title": "scripts/services/CloudbaseService.js",
            "content": []
          }
        ]
      },
      {
        "index": 3,
        "title": "调用云开发能力",
        "type": "codeTab",
        "content": [
          {
            "index": 1,
            "id": "mysql-db",
            "title": "MySQL数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst { data, error } = await cloudbase\n  .database()\n  .from(\"{%TABLE_NAME%}\")\n  .select(\"*\")\n  .limit(10);\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('QueryData')\nexport class QueryData extends Component {\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onLoad() {\n    try {\n      const { data, error } = await cloudbase.database().from(\"{%TABLE_NAME%}\").select(\"*\").limit(10);\n\n      if (!error) {\n        this.resultLabel.string = `查询成功：${JSON.stringify(data)}`;\n        console.log('查询结果：', data);\n      } else {\n        this.resultLabel.string = '查询失败';\n        console.error('查询失败：', error);\n      }\n    } catch (error) {\n      this.resultLabel.string = `查询失败: ${error.message}`;\n      console.error('查询失败：', error);\n    }\n  }\n}\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst { data, error } = await cloudbase\n  .database()\n  .from(\"{%TABLE_NAME%}\")\n  .insert({ title: \"示例标题\" });\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('AddData')\nexport class AddData extends Component {\n  @property(EditBox)\n  titleInput: EditBox = null;\n\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onAddButtonClick() {\n    const title = this.titleInput.string;\n    if (!title) {\n      this.resultLabel.string = '请输入标题';\n      return;\n    }\n\n    try {\n      const { data, error } = await cloudbase.database().from(\"{%TABLE_NAME%}\").insert({ title });\n\n      if (!error) {\n        this.resultLabel.string = '新增成功';\n        this.titleInput.string = '';\n        console.log('新增成功：', data);\n      } else {\n        this.resultLabel.string = '新增失败';\n        console.error('新增失败：', error);\n      }\n    } catch (error) {\n      this.resultLabel.string = `新增失败: ${error.message}`;\n      console.error('新增失败：', error);\n    }\n  }\n}\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst { data, error } = await cloudbase\n  .database()\n  .from(\"{%TABLE_NAME%}\")\n  .update({ title: \"新标题\" })\n  .eq(\"id\", dataId);\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('UpdateData')\nexport class UpdateData extends Component {\n  @property(EditBox)\n  idInput: EditBox = null;\n\n  @property(EditBox)\n  titleInput: EditBox = null;\n\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onUpdateButtonClick() {\n    const dataId = this.idInput.string;\n    const newTitle = this.titleInput.string;\n\n    if (!dataId || !newTitle) {\n      this.resultLabel.string = '请输入数据ID和新标题';\n      return;\n    }\n\n    try {\n      const { data, error } = await cloudbase.database().from(\"{%TABLE_NAME%}\").update({ title: newTitle }).eq(\"id\", dataId);\n\n      if (!error) {\n        this.resultLabel.string = '更新成功';\n        this.idInput.string = '';\n        this.titleInput.string = '';\n        console.log('更新成功：', data);\n      } else {\n        this.resultLabel.string = '更新失败';\n        console.error('更新失败：', error);\n      }\n    } catch (error) {\n      this.resultLabel.string = `更新失败: ${error.message}`;\n      console.error('更新失败：', error);\n    }\n  }\n}\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst { data, error } = await cloudbase\n  .database()\n  .from(\"{%TABLE_NAME%}\")\n  .upsert({ id: 1, title: \"标题\" });\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('UpsertData')\nexport class UpsertData extends Component {\n  @property(EditBox)\n  idInput: EditBox = null;\n\n  @property(EditBox)\n  titleInput: EditBox = null;\n\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onUpsertButtonClick() {\n    const id = parseInt(this.idInput.string);\n    const title = this.titleInput.string;\n\n    if (!id || !title) {\n      this.resultLabel.string = '请输入ID和标题';\n      return;\n    }\n\n    try {\n      const { data, error } = await cloudbase.database().from(\"{%TABLE_NAME%}\").upsert({ id, title });\n\n      if (!error) {\n        this.resultLabel.string = '操作成功';\n        this.idInput.string = '';\n        this.titleInput.string = '';\n        console.log('操作成功：', data);\n      } else {\n        this.resultLabel.string = '操作失败';\n        console.error('操作失败：', error);\n      }\n    } catch (error) {\n      this.resultLabel.string = `操作失败: ${error.message}`;\n      console.error('操作失败：', error);\n    }\n  }\n}\n```",
                "index": 4,
                "title": "更新或创建数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst { data, error } = await cloudbase\n  .database()\n  .from(\"{%TABLE_NAME%}\")\n  .delete()\n  .eq(\"id\", dataId);\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('DeleteData')\nexport class DeleteData extends Component {\n  @property(EditBox)\n  idInput: EditBox = null;\n\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onDeleteButtonClick() {\n    const dataId = this.idInput.string;\n\n    if (!dataId) {\n      this.resultLabel.string = '请输入要删除的数据ID';\n      return;\n    }\n\n    try {\n      const { data, error } = await cloudbase.database().from(\"{%TABLE_NAME%}\").delete().eq(\"id\", dataId);\n\n      if (!error) {\n        this.resultLabel.string = '删除成功';\n        this.idInput.string = '';\n        console.log('删除成功：', data);\n      } else {\n        this.resultLabel.string = '删除失败';\n        console.error('删除失败：', error);\n      }\n    } catch (error) {\n      this.resultLabel.string = `删除失败: ${error.message}`;\n      console.error('删除失败：', error);\n    }\n  }\n}\n```",
                "index": 5,
                "title": "删除数据"
              }
            ]
          },
          {
            "index": 2,
            "id": "doc-db",
            "title": "文档型数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst db = cloudbase.database();\nconst res = await db.collection(\"{%TABLE_NAME%}\").limit(10).get();\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('QueryDocData')\nexport class QueryDocData extends Component {\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onLoad() {\n    try {\n      const db = cloudbase.database();\n      const res = await db.collection(\"{%TABLE_NAME%}\").limit(10).get();\n\n      this.resultLabel.string = `查询成功：${JSON.stringify(res.data)}`;\n      console.log('查询结果：', res.data);\n    } catch (error) {\n      this.resultLabel.string = `查询失败: ${error.message}`;\n      console.error('查询失败：', error);\n    }\n  }\n}\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst db = cloudbase.database();\nconst res = await db.collection(\"{%TABLE_NAME%}\").add({ title: \"示例标题\" });\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('AddDocData')\nexport class AddDocData extends Component {\n  @property(EditBox)\n  titleInput: EditBox = null;\n\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onAddButtonClick() {\n    const title = this.titleInput.string;\n    if (!title) {\n      this.resultLabel.string = '请输入标题';\n      return;\n    }\n\n    try {\n      const db = cloudbase.database();\n      const res = await db.collection(\"{%TABLE_NAME%}\").add({ title });\n\n      this.resultLabel.string = `新增成功! id: ${res.id}`;\n      this.titleInput.string = '';\n      console.log('新增成功：', res);\n    } catch (error) {\n      this.resultLabel.string = `新增失败: ${error.message}`;\n      console.error('新增失败：', error);\n    }\n  }\n}\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst db = cloudbase.database();\nawait db.collection(\"{%TABLE_NAME%}\").doc(dataId).update({ title: \"新标题\" });\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('UpdateDocData')\nexport class UpdateDocData extends Component {\n  @property(EditBox)\n  idInput: EditBox = null;\n\n  @property(EditBox)\n  titleInput: EditBox = null;\n\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onUpdateButtonClick() {\n    const dataId = this.idInput.string;\n    const newTitle = this.titleInput.string;\n\n    if (!dataId || !newTitle) {\n      this.resultLabel.string = '请输入数据ID和新标题';\n      return;\n    }\n\n    try {\n      const db = cloudbase.database();\n      await db.collection(\"{%TABLE_NAME%}\").doc(dataId).update({ title: newTitle });\n\n      this.resultLabel.string = '更新成功';\n      this.idInput.string = '';\n      this.titleInput.string = '';\n      console.log('更新成功');\n    } catch (error) {\n      this.resultLabel.string = `更新失败: ${error.message}`;\n      console.error('更新失败：', error);\n    }\n  }\n}\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst db = cloudbase.database();\nawait db.collection(\"{%TABLE_NAME%}\").doc(dataId).remove();\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('DeleteDocData')\nexport class DeleteDocData extends Component {\n  @property(EditBox)\n  idInput: EditBox = null;\n\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onDeleteButtonClick() {\n    const dataId = this.idInput.string;\n\n    if (!dataId) {\n      this.resultLabel.string = '请输入要删除的数据ID';\n      return;\n    }\n\n    try {\n      const db = cloudbase.database();\n      await db.collection(\"{%TABLE_NAME%}\").doc(dataId).remove();\n\n      this.resultLabel.string = '删除成功';\n      this.idInput.string = '';\n      console.log('删除成功');\n    } catch (error) {\n      this.resultLabel.string = `删除失败: ${error.message}`;\n      console.error('删除失败：', error);\n    }\n  }\n}\n```",
                "index": 4,
                "title": "删除数据"
              }
            ]
          },
          {
            "index": 3,
            "id": "data-model",
            "title": "数据模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst res = await cloudbase.models[\"{%TABLE_NAME%}\"].list({\n  pageNumber: 1,\n  pagesize: 10\n});\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('QueryModelData')\nexport class QueryModelData extends Component {\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onLoad() {\n    try {\n      const res = await cloudbase.models[\"{%TABLE_NAME%}\"].list({ pageNumber: 1, pagesize: 10 });\n\n      const records = res.data?.records || [];\n      this.resultLabel.string = `查询成功：${JSON.stringify(records)}`;\n      console.log('查询结果：', records);\n    } catch (error) {\n      this.resultLabel.string = `查询失败: ${error.message}`;\n      console.error('查询失败：', error);\n    }\n  }\n}\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst res = await cloudbase.models[\"{%TABLE_NAME%}\"].create({\n  data: { title: \"示例标题\" }\n});\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('AddModelData')\nexport class AddModelData extends Component {\n  @property(EditBox)\n  titleInput: EditBox = null;\n\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onAddButtonClick() {\n    const title = this.titleInput.string;\n    if (!title) {\n      this.resultLabel.string = '请输入标题';\n      return;\n    }\n\n    try {\n      const res = await cloudbase.models[\"{%TABLE_NAME%}\"].create({ data: { title } });\n\n      this.resultLabel.string = `新增成功! id: ${res.data.id}`;\n      this.titleInput.string = '';\n      console.log('新增成功：', res);\n    } catch (error) {\n      this.resultLabel.string = `新增失败: ${error.message}`;\n      console.error('新增失败：', error);\n    }\n  }\n}\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nawait cloudbase.models[\"{%TABLE_NAME%}\"].update({\n  data: { title: \"新标题\" },\n  filter: { where: { _id: { $eq: dataId } } }\n});\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('UpdateModelData')\nexport class UpdateModelData extends Component {\n  @property(EditBox)\n  idInput: EditBox = null;\n\n  @property(EditBox)\n  titleInput: EditBox = null;\n\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onUpdateButtonClick() {\n    const dataId = this.idInput.string;\n    const newTitle = this.titleInput.string;\n\n    if (!dataId || !newTitle) {\n      this.resultLabel.string = '请输入数据ID和新标题';\n      return;\n    }\n\n    try {\n      await cloudbase.models[\"{%TABLE_NAME%}\"].update({\n        data: { title: newTitle },\n        filter: { where: { _id: { $eq: dataId } } }\n      });\n\n      this.resultLabel.string = '更新成功';\n      this.idInput.string = '';\n      this.titleInput.string = '';\n      console.log('更新成功');\n    } catch (error) {\n      this.resultLabel.string = `更新失败: ${error.message}`;\n      console.error('更新失败：', error);\n    }\n  }\n}\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nawait cloudbase.models[\"{%TABLE_NAME%}\"].delete({\n  filter: { where: { _id: { $eq: dataId } } }\n});\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('DeleteModelData')\nexport class DeleteModelData extends Component {\n  @property(EditBox)\n  idInput: EditBox = null;\n\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onDeleteButtonClick() {\n    const dataId = this.idInput.string;\n\n    if (!dataId) {\n      this.resultLabel.string = '请输入要删除的数据ID';\n      return;\n    }\n\n    try {\n      await cloudbase.models[\"{%TABLE_NAME%}\"].delete({\n        filter: { where: { _id: { $eq: dataId } } }\n      });\n\n      this.resultLabel.string = '删除成功';\n      this.idInput.string = '';\n      console.log('删除成功');\n    } catch (error) {\n      this.resultLabel.string = `删除失败: ${error.message}`;\n      console.error('删除失败：', error);\n    }\n  }\n}\n```",
                "index": 4,
                "title": "删除数据"
              }
            ]
          },
          {
            "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst res = await cloudbase.callFunction({\n  name: \"{%FUNCTION_NAME%}\",\n  data: {}\n});\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('CallFunction')\nexport class CallFunction extends Component {\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onCallButtonClick() {\n    try {\n      const res = await cloudbase.callFunction({\n        name: \"{%FUNCTION_NAME%}\",\n        data: {}\n      });\n\n      this.resultLabel.string = `调用成功：${JSON.stringify(res.result)}`;\n      console.log('调用结果：', res.result);\n    } catch (error) {\n      this.resultLabel.string = `调用失败: ${error.message}`;\n      console.error('调用失败：', error);\n    }\n  }\n}\n```",
            "index": 4,
            "id": "scf",
            "title": "云函数",
            "content": []
          },
          {
            "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\n// 调用 {%SERVICE_NAME%} 云托管服务\nconst res = await cloudbase.callContainer({\n  name: \"{%SERVICE_NAME%}\"\n  method: 'POST',\n  path: '/',\n  header:{\n    'Content-Type': 'application/json; charset=utf-8'\n  },\n  data: {},\n});\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('CallRun')\nexport class CallRun extends Component {\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onCallButtonClick() {\n    try {\n      // 调用 {%SERVICE_NAME%} 云托管服务\n      const res = await cloudbase.callContainer({\n        name: \"{%SERVICE_NAME%}\"\n        method: 'POST',\n        path: '/',\n        header:{\n          'Content-Type': 'application/json; charset=utf-8'\n        },\n        data: {},\n      });\n\n      this.resultLabel.string = `调用成功：${JSON.stringify(res)}`;\n      console.log('调用结果：', res);\n    } catch (error) {\n      this.resultLabel.string = `调用失败: ${error.message}`;\n      console.error('调用失败：', error);\n    }\n  }\n}\n```",
            "index": 5,
            "id": "run",
            "title": "云托管",
            "content": []
          },
          {
            "index": 6,
            "id": "storage",
            "title": "云存储",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst res = await cloudbase.uploadFile({\n  cloudPath: `images/${Date.now()}.png`,\n  filePath: filePath\n});\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('UploadFile')\nexport class UploadFile extends Component {\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onUploadButtonClick() {\n    try {\n      // 注意：实际使用中需要从用户选择或游戏资源中获取文件路径\n      const filePath = 'path/to/your/file.png';\n      const cloudPath = `images/${Date.now()}-${Math.random()}.png`;\n\n      const res = await cloudbase.uploadFile({\n        cloudPath: cloudPath,\n        filePath: filePath\n      });\n\n      this.resultLabel.string = `上传成功！文件ID: ${res.fileID}`;\n      console.log('上传成功：', res);\n    } catch (error) {\n      this.resultLabel.string = `上传失败: ${error.message}`;\n      console.error('上传失败：', error);\n    }\n  }\n}\n```",
                "index": 1,
                "title": "上传文件"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst res = await cloudbase.getTempFileURL({\n  fileList: [fileId]\n});\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('GetFileUrl')\nexport class GetFileUrl extends Component {\n  @property(EditBox)\n  fileIdInput: EditBox = null;\n\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onGetUrlButtonClick() {\n    const fileId = this.fileIdInput.string;\n\n    if (!fileId) {\n      this.resultLabel.string = '请输入文件ID';\n      return;\n    }\n\n    try {\n      const res = await cloudbase.getTempFileURL({\n        fileList: [fileId]\n      });\n\n      const fileUrl = res.fileList[0].tempFileURL;\n      this.resultLabel.string = `文件链接：${fileUrl}`;\n      console.log('文件链接：', fileUrl);\n    } catch (error) {\n      this.resultLabel.string = `获取失败: ${error.message}`;\n      console.error('获取失败：', error);\n    }\n  }\n}\n```",
                "index": 2,
                "title": "获取文件链接"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst res = await cloudbase.downloadFile({\n  fileID: fileId\n});\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('DownloadFile')\nexport class DownloadFile extends Component {\n  @property(EditBox)\n  fileIdInput: EditBox = null;\n\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onDownloadButtonClick() {\n    const fileId = this.fileIdInput.string;\n\n    if (!fileId) {\n      this.resultLabel.string = '请输入文件ID';\n      return;\n    }\n\n    try {\n      const res = await cloudbase.downloadFile({\n        fileID: fileId\n      });\n\n      this.resultLabel.string = `下载成功！本地路径: ${res.tempFilePath}`;\n      console.log('下载成功：', res);\n    } catch (error) {\n      this.resultLabel.string = `下载失败: ${error.message}`;\n      console.error('下载失败：', error);\n    }\n  }\n}\n```",
                "index": 3,
                "title": "下载文件"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst res = await cloudbase.deleteFile({\n  fileList: [fileId]\n});\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('DeleteFile')\nexport class DeleteFile extends Component {\n  @property(EditBox)\n  fileIdInput: EditBox = null;\n\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onDeleteButtonClick() {\n    const fileId = this.fileIdInput.string;\n\n    if (!fileId) {\n      this.resultLabel.string = '请输入文件ID';\n      return;\n    }\n\n    try {\n      const res = await cloudbase.deleteFile({\n        fileList: [fileId]\n      });\n\n      if (res.fileList[0].code === \"SUCCESS\") {\n        this.resultLabel.string = '删除成功';\n        this.fileIdInput.string = '';\n        console.log('删除成功');\n      } else {\n        this.resultLabel.string = '删除失败';\n        console.error('删除失败');\n      }\n    } catch (error) {\n      this.resultLabel.string = `删除失败: ${error.message}`;\n      console.error('删除失败：', error);\n    }\n  }\n}\n```",
                "index": 4,
                "title": "删除文件"
              }
            ]
          },
          {
            "index": 7,
            "id": "ai-model",
            "title": "大模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst ai = cloudbase.ai();\nconst model = ai.createModel(\"{%AI_MODEL_NAME%}\");\n\n// 确保已登录\nconst loginState = await cloudbase.auth().getLoginState();\nif (!loginState) {\n  await cloudbase.auth().signInAnonymously();\n}\n\nconst res = await model.streamText({\n  model: \"{%AI_SUB_MODEL_NAME%}\",\n  messages: [\n    { role: \"system\", content: \"系统提示词\" },\n    { role: \"user\", content: \"用户输入\" }\n  ]\n});\n\nfor await (let str of res.textStream) {\n  // 处理流式响应\n}\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('CallAIModel')\nexport class CallAIModel extends Component {\n  @property(EditBox)\n  inputBox: EditBox = null;\n\n  @property(Label)\n  resultLabel: Label = null;\n\n  @property(Label)\n  statusLabel: Label = null;\n\n  async onGenerateButtonClick() {\n    const input = this.inputBox.string;\n    if (!input) {\n      this.statusLabel.string = '请输入主题';\n      return;\n    }\n\n    this.statusLabel.string = '生成中...';\n    this.resultLabel.string = '';\n\n    try {\n      const ai = cloudbase.ai();\n      const model = ai.createModel(\"{%AI_MODEL_NAME%}\");\n\n      // 确保已登录\n      const loginState = await cloudbase.auth().getLoginState();\n      if (!loginState) {\n        await cloudbase.auth().signInAnonymously();\n      }\n\n      const res = await model.streamText({\n        model: \"{%AI_SUB_MODEL_NAME%}\",\n        messages: [\n          { role: \"system\", content: \"请严格按照七言绝句或七言律诗的格律要求创作，平仄需符合规则，押韵要和谐自然，韵脚字需在同一韵部。\" },\n          { role: \"user\", content: input }\n        ]\n      });\n\n      let fullText = '';\n      for await (let str of res.textStream) {\n        fullText += str;\n        this.resultLabel.string = fullText;\n      }\n\n      this.statusLabel.string = '生成完成';\n      console.log('生成完成：', fullText);\n    } catch (err) {\n      this.statusLabel.string = '生成失败';\n      this.resultLabel.string = `错误: ${err.message}`;\n      console.error('生成失败：', err);\n    }\n  }\n}\n```",
                "index": 1,
                "id": "text-aiModel",
                "title": "生文模型"
              },
              {
                "markdown": "生图模型通过调用云函数来实现，在生图模型页面点击「一键创建云函数」，函数调用示例如下：\n\n**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\n// 调用生图云函数\nconst res = await cloudbase.callFunction({\n  name: \"<YOUR_FUNCTION_NAME>\",\n  data: {\n    prompt: \"一只可爱的猫咪在阳光下玩耍\"\n  }\n});\n\nconst result = res.result;\n\nif (result.success) {\n  // 生成成功\n  console.log(\"生成成功!\");\n  console.log(\"图片URL:\", result.imageUrl);\n  console.log(\"优化后的提示词:\", result.revised_prompt);\n\n  // 使用图片\n  // 注意：图片URL有效期为24小时，请及时保存或转存\n} else {\n  // 生成失败\n  console.error(\"生成失败:\", result.code, result.message);\n}\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label, Sprite } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('GenerateImage')\nexport class GenerateImage extends Component {\n  @property(EditBox)\n  promptInput: EditBox = null;\n\n  @property(Label)\n  statusLabel: Label = null;\n\n  @property(Sprite)\n  imageSprite: Sprite = null;\n\n  async onGenerateButtonClick() {\n    const prompt = this.promptInput.string;\n    if (!prompt) {\n      this.statusLabel.string = '请输入图片描述';\n      return;\n    }\n\n    this.statusLabel.string = '生成中...';\n\n    try {\n      // 调用生图云函数\n      const res = await cloudbase.callFunction({\n        name: \"<YOUR_FUNCTION_NAME>\",\n        data: {\n          prompt: prompt\n        }\n      });\n\n      const result = res.result;\n\n      if (result.success) {\n        this.statusLabel.string = '生成成功！';\n        console.log('图片URL:', result.imageUrl);\n        console.log('优化后的提示词:', result.revised_prompt);\n\n        // 加载图片到 Sprite\n        // 注意：需要使用网络加载图片的方式\n        // 具体实现可根据 Cocos Creator 版本调整\n      } else {\n        this.statusLabel.string = `生成失败：${result.message}`;\n        console.error('生成失败:', result.code, result.message);\n      }\n    } catch (err) {\n      this.statusLabel.string = '调用失败';\n      console.error('调用失败:', err);\n    }\n  }\n}\n```",
                "index": 2,
                "id": "image-aiModel",
                "title": "生图模型"
              }
            ]
          },
          {
            "markdown": "",
            "index": 8,
            "id": "agent",
            "title": "Agent",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```javascript\nimport cloudbase from './services/CloudbaseService';\n\nconst ai = cloudbase.ai();\n\n// 确保已登录\nconst loginState = await cloudbase.auth().getLoginState();\nif (!loginState) {\n  await cloudbase.auth().signInAnonymously();\n}\n\nconst res = await ai.bot.sendMessage({\n  botId: '{%AGENT_ID%}',\n  // 入参结构参考前后端通信协议：\n  // https://docs.cloudbase.net/ai/agent/http-agent-protocol\n  threadId: '550e8400-e29b-41d4-a716-446655440000',\n  runId: 'run_001',\n  messages: [\n    {\n      id: 'msg-1',\n      role: 'user',\n      content: '你好',\n    },\n  ],\n  tools: [],\n  context: [],\n  state: {},\n  forwardedProps: {},\n});\n\nfor await (let str of res.textStream) {\n  // 处理流式响应\n}\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('CallAgent')\nexport class CallAgent extends Component {\n  @property(EditBox)\n  inputBox: EditBox = null;\n\n  @property(Label)\n  resultLabel: Label = null;\n\n  @property(Label)\n  statusLabel: Label = null;\n\n  async onSendButtonClick() {\n    const input = this.inputBox.string;\n    if (!input) {\n      this.statusLabel.string = '请输入问题';\n      return;\n    }\n\n    this.statusLabel.string = '发送中...';\n    this.resultLabel.string = '';\n\n    try {\n      const ai = cloudbase.ai();\n\n      // 确保已登录\n      const loginState = await cloudbase.auth().getLoginState();\n      if (!loginState) {\n        await cloudbase.auth().signInAnonymously();\n      }\n\n      const res = await ai.bot.sendMessage({\n        botId: '{%AGENT_ID%}',\n        // 入参结构参考前后端通信协议：\n        // https://docs.cloudbase.net/ai/agent/http-agent-protocol\n        threadId: '550e8400-e29b-41d4-a716-446655440000',\n        runId: 'run_001',\n        messages: [\n          {\n            id: 'msg-1',\n            role: 'user',\n            content: input,\n          },\n        ],\n        tools: [],\n        context: [],\n        state: {},\n        forwardedProps: {},\n      });\n\n      let fullText = '';\n      for await (let str of res.textStream) {\n        fullText += str;\n        this.resultLabel.string = fullText;\n      }\n\n      this.statusLabel.string = '回答完成';\n      console.log('回答完成：', fullText);\n    } catch (err) {\n      this.statusLabel.string = '发送失败';\n      this.resultLabel.string = `错误: ${err.message}`;\n      console.error('发送失败：', err);\n    }\n  }\n}\n\n```",
                "index": 0,
                "id": "scf",
                "title": "函数型"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst ai = cloudbase.ai();\n\n// 确保已登录\nconst loginState = await cloudbase.auth().getLoginState();\nif (!loginState) {\n  await cloudbase.auth().signInAnonymously();\n}\n\nconst res = await ai.bot.sendMessage({\n  botId: \"{%AGENT_ID%}\",\n  msg: \"用户消息\"\n});\n\nfor await (let str of res.textStream) {\n  // 处理流式响应\n}\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('CallAgent')\nexport class CallAgent extends Component {\n  @property(EditBox)\n  inputBox: EditBox = null;\n\n  @property(Label)\n  resultLabel: Label = null;\n\n  @property(Label)\n  statusLabel: Label = null;\n\n  async onSendButtonClick() {\n    const input = this.inputBox.string;\n    if (!input) {\n      this.statusLabel.string = '请输入问题';\n      return;\n    }\n\n    this.statusLabel.string = '发送中...';\n    this.resultLabel.string = '';\n\n    try {\n      const ai = cloudbase.ai();\n\n      // 确保已登录\n      const loginState = await cloudbase.auth().getLoginState();\n      if (!loginState) {\n        await cloudbase.auth().signInAnonymously();\n      }\n\n      const res = await ai.bot.sendMessage({\n        botId: '{%AGENT_ID%}',\n        msg: input,\n      });\n\n      let fullText = '';\n      for await (let str of res.textStream) {\n        fullText += str;\n        this.resultLabel.string = fullText;\n      }\n\n      this.statusLabel.string = '回答完成';\n      console.log('回答完成：', fullText);\n    } catch (err) {\n      this.statusLabel.string = '发送失败';\n      this.resultLabel.string = `错误: ${err.message}`;\n      console.error('发送失败：', err);\n    }\n  }\n}\n```",
                "index": 1,
                "id": "baas",
                "title": "普通型"
              }
            ]
          },
          {
            "index": 9,
            "id": "identity",
            "title": "身份认证",
            "type": "sideTab",
            "content": [
              {
                "markdown": "使用 **短信验证码注册** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **短信验证码**\n\n**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ phone_number: phone });\nconst verificationId = res.verification_id;\n\n// 验证验证码\nconst verifyRes = await auth.verify({\n  verification_id: verificationId,\n  verification_code: code\n});\n\n// 注册\nawait auth.signUp({\n  phone_number: `+86 ${phone}`,\n  verification_code: code,\n  verification_token: verifyRes.verification_token,\n  name: `user_${phone.slice(-4)}`,\n  password: \"admin@123\"\n});\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('SmsRegister')\nexport class SmsRegister extends Component {\n  @property(EditBox)\n  phoneInput: EditBox = null;\n\n  @property(EditBox)\n  codeInput: EditBox = null;\n\n  @property(Label)\n  messageLabel: Label = null;\n\n  private verificationId: string = '';\n\n  // 发送验证码\n  async onSendCodeButtonClick() {\n    const phone = this.phoneInput.string;\n    if (!phone) {\n      this.messageLabel.string = '请输入手机号';\n      return;\n    }\n\n    try {\n      const auth = cloudbase.auth();\n      const res = await auth.getVerification({ phone_number: phone });\n      this.verificationId = res.verification_id;\n      this.messageLabel.string = '验证码已发送！';\n    } catch (error) {\n      this.messageLabel.string = `发送失败: ${error.message}`;\n    }\n  }\n\n  // 注册\n  async onRegisterButtonClick() {\n    const phone = this.phoneInput.string;\n    const code = this.codeInput.string;\n\n    if (!this.verificationId || !code) {\n      this.messageLabel.string = '请先发送验证码';\n      return;\n    }\n\n    try {\n      const auth = cloudbase.auth();\n      // 验证验证码\n      const verifyRes = await auth.verify({\n        verification_id: this.verificationId,\n        verification_code: code,\n      });\n      // 注册（如用户已存在则自动登录）\n      await auth.signUp({\n        phone_number: `+86 ${phone}`,\n        verification_code: code,\n        verification_token: verifyRes.verification_token,\n        name: `user_${phone.slice(-4)}`,\n        password: \"admin@123\"\n      });\n      this.messageLabel.string = '注册成功！';\n      console.log('注册成功');\n    } catch (error) {\n      this.messageLabel.string = `注册失败: ${error.message}`;\n      console.error('注册失败：', error);\n    }\n  }\n}\n```",
                "index": 1,
                "title": "短信验证码注册"
              },
              {
                "markdown": "使用 **邮箱验证码注册** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **邮箱验证码**\n\n**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ email });\nconst verificationId = res.verification_id;\n\n// 验证验证码\nconst verifyRes = await auth.verify({\n  verification_id: verificationId,\n  verification_code: code\n});\n\n// 注册\nawait auth.signUp({\n  email,\n  verification_code: code,\n  verification_token: verifyRes.verification_token,\n  name: `user_${email.slice(-4)}`,\n  password: \"admin@123\"\n});\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('EmailRegister')\nexport class EmailRegister extends Component {\n  @property(EditBox)\n  emailInput: EditBox = null;\n\n  @property(EditBox)\n  codeInput: EditBox = null;\n\n  @property(Label)\n  messageLabel: Label = null;\n\n  private verificationId: string = '';\n\n  // 发送验证码\n  async onSendCodeButtonClick() {\n    const email = this.emailInput.string;\n    if (!email) {\n      this.messageLabel.string = '请输入邮箱';\n      return;\n    }\n\n    try {\n      const auth = cloudbase.auth();\n      const res = await auth.getVerification({ email });\n      this.verificationId = res.verification_id;\n      this.messageLabel.string = '验证码已发送！';\n    } catch (error) {\n      this.messageLabel.string = `发送失败: ${error.message}`;\n    }\n  }\n\n  // 注册\n  async onRegisterButtonClick() {\n    const email = this.emailInput.string;\n    const code = this.codeInput.string;\n\n    if (!this.verificationId || !code) {\n      this.messageLabel.string = '请先发送验证码';\n      return;\n    }\n\n    try {\n      const auth = cloudbase.auth();\n      // 验证验证码\n      const verifyRes = await auth.verify({\n        verification_id: this.verificationId,\n        verification_code: code,\n      });\n      // 注册（如用户已存在则自动登录）\n      await auth.signUp({\n        email,\n        verification_code: code,\n        verification_token: verifyRes.verification_token,\n        name: `user_${email.slice(-4)}`,\n        password: \"admin@123\"\n      });\n      this.messageLabel.string = '注册成功！';\n      console.log('注册成功');\n    } catch (error) {\n      this.messageLabel.string = `注册失败: ${error.message}`;\n      console.error('注册失败：', error);\n    }\n  }\n}\n```",
                "index": 2,
                "title": "邮箱验证码注册"
              },
              {
                "markdown": "使用 **账号密码登录** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **用户名密码登录**\n\n**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst auth = cloudbase.auth();\nawait auth.signIn({\n  username, // 可以是用户名、手机号或邮箱\n  password\n});\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('PasswordLogin')\nexport class PasswordLogin extends Component {\n  @property(EditBox)\n  usernameInput: EditBox = null;\n\n  @property(EditBox)\n  passwordInput: EditBox = null;\n\n  @property(Label)\n  messageLabel: Label = null;\n\n  async onLoginButtonClick() {\n    const username = this.usernameInput.string;\n    const password = this.passwordInput.string;\n\n    if (!username || !password) {\n      this.messageLabel.string = '请输入账号和密码';\n      return;\n    }\n\n    try {\n      const auth = cloudbase.auth();\n      await auth.signIn({\n        username, // 可以是用户名、手机号或邮箱\n        password,\n      });\n      this.messageLabel.string = '登录成功！';\n      console.log('登录成功');\n    } catch (error) {\n      this.messageLabel.string = `登录失败: ${error.message}`;\n      console.error('登录失败：', error);\n    }\n  }\n}\n```",
                "index": 3,
                "id": "UserNameLogin",
                "title": "账号密码登录"
              },
              {
                "markdown": "使用 **短信验证码登录** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **短信验证码登录**\n\n**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ phone_number: `+86 ${phone}` });\nconst verificationInfo = res;\n\n// 登录\nawait auth.signInWithSms({\n  verificationInfo: verificationInfo,\n  verificationCode: code,\n  phoneNum: `+86 ${phone}`\n});\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('SmsLogin')\nexport class SmsLogin extends Component {\n  @property(EditBox)\n  phoneInput: EditBox = null;\n\n  @property(EditBox)\n  codeInput: EditBox = null;\n\n  @property(Label)\n  messageLabel: Label = null;\n\n  private verificationInfo: any = null;\n\n  // 发送验证码\n  async onSendCodeButtonClick() {\n    const phone = this.phoneInput.string;\n    if (!phone) {\n      this.messageLabel.string = '请输入手机号';\n      return;\n    }\n\n    try {\n      const auth = cloudbase.auth();\n      const res = await auth.getVerification({ phone_number: `+86 ${phone}` });\n      this.verificationInfo = res;\n      this.messageLabel.string = '验证码已发送！';\n    } catch (error) {\n      this.messageLabel.string = `发送失败: ${error.message}`;\n    }\n  }\n\n  // 登录\n  async onLoginButtonClick() {\n    const phone = this.phoneInput.string;\n    const code = this.codeInput.string;\n\n    if (!this.verificationInfo || !code) {\n      this.messageLabel.string = '请先发送验证码';\n      return;\n    }\n\n    try {\n      const auth = cloudbase.auth();\n      await auth.signInWithSms({\n        verificationInfo: this.verificationInfo,\n        verificationCode: code,\n        phoneNum: `+86 ${phone}`\n      });\n      this.messageLabel.string = '登录成功！';\n      console.log('登录成功');\n    } catch (error) {\n      this.messageLabel.string = `登录失败: ${error.message}`;\n      console.error('登录失败：', error);\n    }\n  }\n}\n```",
                "index": 4,
                "id": "PhoneNumberLogin",
                "title": "短信验证码登录"
              },
              {
                "markdown": "使用 **邮箱验证码登录** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **邮箱验证码**\n\n**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ email });\nconst verificationInfo = res;\n\n// 登录\nawait auth.signInWithEmail({\n  verificationInfo: verificationInfo,\n  verificationCode: code,\n  email\n});\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('EmailLogin')\nexport class EmailLogin extends Component {\n  @property(EditBox)\n  emailInput: EditBox = null;\n\n  @property(EditBox)\n  codeInput: EditBox = null;\n\n  @property(Label)\n  messageLabel: Label = null;\n\n  private verificationInfo: any = null;\n\n  // 发送验证码\n  async onSendCodeButtonClick() {\n    const email = this.emailInput.string;\n    if (!email) {\n      this.messageLabel.string = '请输入邮箱';\n      return;\n    }\n\n    try {\n      const auth = cloudbase.auth();\n      const res = await auth.getVerification({ email });\n      this.verificationInfo = res;\n      this.messageLabel.string = '验证码已发送！';\n    } catch (error) {\n      this.messageLabel.string = `发送失败: ${error.message}`;\n    }\n  }\n\n  // 登录\n  async onLoginButtonClick() {\n    const email = this.emailInput.string;\n    const code = this.codeInput.string;\n\n    if (!this.verificationInfo || !code) {\n      this.messageLabel.string = '请先发送验证码';\n      return;\n    }\n\n    try {\n      const auth = cloudbase.auth();\n      await auth.signInWithEmail({\n        verificationInfo: this.verificationInfo,\n        verificationCode: code,\n        email\n      });\n      this.messageLabel.string = '登录成功！';\n      console.log('登录成功');\n    } catch (error) {\n      this.messageLabel.string = `登录失败: ${error.message}`;\n      console.error('登录失败：', error);\n    }\n  }\n}\n```",
                "index": 5,
                "id": "email",
                "title": "邮箱验证码登录"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst auth = cloudbase.auth();\nawait auth.signInAnonymously();\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('AnonymousLogin')\nexport class AnonymousLogin extends Component {\n  @property(Label)\n  messageLabel: Label = null;\n\n  async onLoginButtonClick() {\n    try {\n      const auth = cloudbase.auth();\n      await auth.signInAnonymously();\n      this.messageLabel.string = '匿名登录成功！';\n      console.log('匿名登录成功');\n    } catch (error) {\n      this.messageLabel.string = `登录失败: ${error.message}`;\n      console.error('登录失败：', error);\n    }\n  }\n}\n```",
                "index": 6,
                "title": "匿名登录"
              }
            ]
          }
        ]
      }
    ],
    "_id": "b387ab556980627c0092eff50392c1e6",
    "_openid": "anon",
    "createdAt": 1770021500262,
    "updatedAt": 1770021500262
  },
  {
    "category": "框架集成,移动端框架,Android Kotlin",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": 31,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/http-api/basic/overview",
    "content": [
      {
        "markdown": "通过 **HTTP 请求** 在 **Android Kotlin** 中调用各种云开发能力\n\n在 `build.gradle` (Module) 中添加依赖：\n\n```gradle\ndependencies {\n    implementation 'com.squareup.okhttp3:okhttp:4.12.0'\n    implementation 'com.google.code.gson:gson:2.10.1'\n    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3'\n}\n```",
        "index": 1,
        "title": "安装依赖",
        "content": []
      },
      {
        "markdown": "新增如下代码到您的 **Android Kotlin** 项目",
        "index": 2,
        "title": "初始化配置",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```kotlin\npackage com.example.cloudbase\n\nimport com.google.gson.Gson\nimport com.google.gson.reflect.TypeToken\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.withContext\nimport okhttp3.MediaType.Companion.toMediaType\nimport okhttp3.OkHttpClient\nimport okhttp3.Request\nimport okhttp3.RequestBody.Companion.toRequestBody\nimport java.util.concurrent.TimeUnit\n\nclass CloudBaseClient(\n    private val envId: String,\n    private var accessToken: String\n) {\n    private val baseUrl = \"https://$envId.api.tcloudbasegateway.com\"\n    private val gson = Gson()\n\n    private val client = OkHttpClient.Builder()\n        .connectTimeout(30, TimeUnit.SECONDS)\n        .readTimeout(30, TimeUnit.SECONDS)\n        .writeTimeout(30, TimeUnit.SECONDS)\n        .build()\n\n    /**\n     * 更新访问令牌\n     *\n     * @param newToken 新的访问令牌\n     */\n    fun updateAccessToken(newToken: String) {\n        this.accessToken = newToken\n        println(\"访问令牌已更新\")\n    }\n\n    /**\n     * 统一的HTTP请求方法\n     *\n     * @param method 请求方法 (GET, POST, PUT, PATCH, DELETE)\n     * @param path API路径 (如 /v1/rdb/rest/table_name)\n     * @param body 请求体数据\n     * @param customHeaders 自定义headers\n     *\n     * @return 响应数据或null\n     */\n    suspend fun <T> request(\n        method: String,\n        path: String,\n        body: Any? = null,\n        customHeaders: Map<String, String> = emptyMap(),\n        typeToken: TypeToken<T>? = null\n    ): T? = withContext(Dispatchers.IO) {\n        val url = \"$baseUrl$path\"\n\n        val requestBuilder = Request.Builder()\n            .url(url)\n            .header(\"Content-Type\", \"application/json\")\n            .header(\"Accept\", \"application/json\")\n            .header(\"Authorization\", \"Bearer $accessToken\")\n\n        // 添加自定义headers\n        customHeaders.forEach { (key, value) ->\n            requestBuilder.header(key, value)\n        }\n\n        // 设置请求方法和body\n        when (method.uppercase()) {\n            \"GET\" -> requestBuilder.get()\n            \"POST\", \"PUT\", \"PATCH\", \"DELETE\" -> {\n                val jsonBody = if (body != null) {\n                    gson.toJson(body).toRequestBody(\"application/json\".toMediaType())\n                } else {\n                    \"{}\".toRequestBody(\"application/json\".toMediaType())\n                }\n                when (method.uppercase()) {\n                    \"POST\" -> requestBuilder.post(jsonBody)\n                    \"PUT\" -> requestBuilder.put(jsonBody)\n                    \"PATCH\" -> requestBuilder.patch(jsonBody)\n                    \"DELETE\" -> requestBuilder.delete(jsonBody)\n                }\n            }\n        }\n\n        try {\n            val response = client.newCall(requestBuilder.build()).execute()\n\n            if (response.isSuccessful) {\n                val responseBody = response.body?.string()\n\n                // 如果响应为空，返回true表示成功\n                if (responseBody.isNullOrEmpty()) {\n                    @Suppress(\"UNCHECKED_CAST\")\n                    return@withContext true as? T\n                }\n\n                return@withContext if (typeToken != null) {\n                    gson.fromJson(responseBody, typeToken.type)\n                } else {\n                    @Suppress(\"UNCHECKED_CAST\")\n                    gson.fromJson(responseBody, Any::class.java) as? T\n                }\n            } else {\n                println(\"请求失败: ${response.code} ${response.body?.string()}\")\n                return@withContext null\n            }\n        } catch (e: Exception) {\n            println(\"请求失败: ${e.message}\")\n            e.printStackTrace()\n            return@withContext null\n        }\n    }\n}\n\n// 配置文件或初始化时创建实例\n// val cloudbase = CloudBaseClient(\n//     envId = \"your-env-id\",\n//     accessToken = \"your-access-token\"\n// )\n```",
            "index": 1,
            "title": "CloudBaseClient.kt"
          },
          {
            "markdown": "在 `local.properties` 或配置文件中添加：\n\n> 💡提示：用户权限请参考「身份认证」模块获取 access_token\n\n```properties\n# 环境ID\nCLOUDBASE_ENV_ID={%ENV_ID%}\n\n# 匿名访问令牌\nCLOUDBASE_ACCESS_TOKEN={%PUBLISHABLE_KEY%}\n```",
            "index": 2,
            "title": "配置文件"
          }
        ]
      },
      {
        "sideTabs": [
          {
            "id": "pg-db",
            "title": "PostgreSQL 数据库"
          }
        ],
        "index": 3,
        "title": "调用云开发能力",
        "type": "codeTab",
        "content": [
          {
            "index": 1,
            "id": "pg-db",
            "title": "PostgreSQL 数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```kotlin\nsuspend fun getPgData(cloudbase: CloudBaseClient, tableName: String): List<Map<String, Any>>? {\n    // 查询 PG 数据库数据\n    val data = cloudbase.request<List<Map<String, Any>>>(\n        method = \"GET\",\n        path = \"/v1/rdb/rest/$tableName?select=*&limit=10\",\n        typeToken = object : TypeToken<List<Map<String, Any>>>() {}\n    )\n\n    if (data != null) {\n        println(\"查询成功: $data\")\n    }\n    return data ?: emptyList()\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val result = getPgData(cloudbase, \"{%TABLE_NAME%}\")\n//     println(result)\n// }\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "```kotlin\nsuspend fun addPgData(cloudbase: CloudBaseClient, tableName: String, data: Map<String, Any>): Map<String, Any>? {\n    // 新增 PG 数据库数据\n    val result = cloudbase.request<Map<String, Any>>(\n        method = \"POST\",\n        path = \"/v1/rdb/rest/$tableName\",\n        body = data,\n        typeToken = object : TypeToken<Map<String, Any>>() {}\n    )\n\n    if (result != null) {\n        println(\"新增成功: $result\")\n    }\n    return result\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val result = addPgData(cloudbase, \"{%TABLE_NAME%}\", mapOf(\"title\" to \"示例标题\"))\n//     println(result)\n// }\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "```kotlin\nsuspend fun updatePgData(cloudbase: CloudBaseClient, tableName: String, dataId: String, data: Map<String, Any>): Any? {\n    // 更新 PG 数据库数据\n    val result = cloudbase.request<Any>(\n        method = \"PATCH\",\n        path = \"/v1/rdb/rest/$tableName?id=eq.$dataId\",\n        body = data\n    )\n\n    if (result != null) {\n        println(\"更新成功: $result\")\n    }\n    return result\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val result = updatePgData(cloudbase, \"{%TABLE_NAME%}\", \"<数据id>\", mapOf(\"title\" to \"新标题\"))\n//     println(result)\n// }\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "```kotlin\nsuspend fun upsertPgData(cloudbase: CloudBaseClient, tableName: String, data: Map<String, Any>): Any? {\n    // 更新或创建 PG 数据库数据\n    val result = cloudbase.request<Any>(\n        method = \"POST\",\n        path = \"/v1/rdb/rest/$tableName\",\n        body = data\n    )\n\n    if (result != null) {\n        println(\"更新或创建成功: $result\")\n    }\n    return result\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val result = upsertPgData(cloudbase, \"{%TABLE_NAME%}\", mapOf(\"id\" to 1, \"title\" to \"标题\"))\n//     println(result)\n// }\n```",
                "index": 4,
                "title": "更新或创建数据"
              },
              {
                "markdown": "```kotlin\nsuspend fun deletePgData(cloudbase: CloudBaseClient, tableName: String, dataId: String): Boolean {\n    // 删除 PG 数据库数据\n    val result = cloudbase.request<Any>(\n        method = \"DELETE\",\n        path = \"/v1/rdb/rest/$tableName?id=eq.$dataId\"\n    )\n\n    if (result != null) {\n        println(\"删除成功\")\n        return true\n    }\n    return false\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val result = deletePgData(cloudbase, \"{%TABLE_NAME%}\", \"<数据id>\")\n//     println(result)\n// }\n```",
                "index": 5,
                "title": "删除数据"
              }
            ]
          },
          {
            "index": 1,
            "id": "mysql-db",
            "title": "MySQL数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```kotlin\nimport com.google.gson.reflect.TypeToken\n\nsuspend fun getMysqlData(cloudbase: CloudBaseClient, tableName: String): List<Map<String, Any>>? {\n    // 查询 MySQL 数据库数据\n    val data = cloudbase.request<List<Map<String, Any>>>(\n        method = \"GET\",\n        path = \"/v1/rdb/rest/$tableName?limit=10\",\n        typeToken = object : TypeToken<List<Map<String, Any>>>() {}\n    )\n\n    if (data != null) {\n        println(\"查询成功: $data\")\n    }\n    return data ?: emptyList()\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val result = getMysqlData(cloudbase, \"{%TABLE_NAME%}\")\n//     println(result)\n// }\n```",
                "index": 1,
                "title": "查询数据",
                "content": []
              },
              {
                "markdown": "```kotlin\nsuspend fun addMysqlData(cloudbase: CloudBaseClient, tableName: String, data: Map<String, Any>): Map<String, Any>? {\n    // 新增 MySQL 数据库数据\n    val result = cloudbase.request<Map<String, Any>>(\n        method = \"POST\",\n        path = \"/v1/rdb/rest/$tableName\",\n        body = data,\n        typeToken = object : TypeToken<Map<String, Any>>() {}\n    )\n\n    if (result != null) {\n        println(\"新增成功: $result\")\n    }\n    return result\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val result = addMysqlData(cloudbase, \"{%TABLE_NAME%}\", mapOf(\"title\" to \"示例标题\"))\n//     println(result)\n// }\n```",
                "index": 2,
                "title": "新增数据",
                "content": []
              },
              {
                "markdown": "```kotlin\nsuspend fun updateMysqlData(cloudbase: CloudBaseClient, tableName: String, dataId: String, data: Map<String, Any>): Any? {\n    // 更新 MySQL 数据库数据\n    val result = cloudbase.request<Any>(\n        method = \"PATCH\",\n        path = \"/v1/rdb/rest/$tableName?id=eq.$dataId\",\n        body = data\n    )\n\n    if (result != null) {\n        println(\"更新成功: $result\")\n    }\n    return result\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val result = updateMysqlData(cloudbase, \"{%TABLE_NAME%}\", \"<数据id>\", mapOf(\"title\" to \"新标题\"))\n//     println(result)\n// }\n```",
                "index": 3,
                "title": "更新数据",
                "content": []
              },
              {
                "markdown": "```kotlin\nsuspend fun deleteMysqlData(cloudbase: CloudBaseClient, tableName: String, dataId: String): Boolean {\n    // 删除 MySQL 数据库数据\n    val result = cloudbase.request<Any>(\n        method = \"DELETE\",\n        path = \"/v1/rdb/rest/$tableName?id=eq.$dataId\"\n    )\n\n    if (result != null) {\n        println(\"删除成功\")\n        return true\n    }\n    return false\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val result = deleteMysqlData(cloudbase, \"{%TABLE_NAME%}\", \"<数据id>\")\n//     println(result)\n// }\n```",
                "index": 4,
                "title": "删除数据",
                "content": []
              }
            ]
          },
          {
            "index": 2,
            "id": "data-model",
            "title": "数据模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```kotlin\nimport com.google.gson.reflect.TypeToken\n\nsuspend fun getModelData(cloudbase: CloudBaseClient, modelName: String, envType: String = \"prod\"): List<Map<String, Any>> {\n    // 查询数据模型数据\n    val payload = mapOf(\n        \"pageSize\" to 10,\n        \"pageNumber\" to 1,\n        \"getCount\" to true\n    )\n\n    val result = cloudbase.request<Map<String, Any>>(\n        method = \"POST\",\n        path = \"/v1/model/$envType/$modelName/list\",\n        body = payload,\n        typeToken = object : TypeToken<Map<String, Any>>() {}\n    )\n\n    if (result != null) {\n        val records = (result[\"data\"] as? Map<*, *>)?.get(\"records\") as? List<Map<String, Any>> ?: emptyList()\n        println(\"查询成功: $records\")\n        return records\n    }\n    return emptyList()\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val records = getModelData(cloudbase, \"{%TABLE_NAME%}\")\n//     println(records)\n// }\n```",
                "index": 1,
                "title": "查询数据",
                "content": []
              },
              {
                "markdown": "```kotlin\nsuspend fun addModelData(cloudbase: CloudBaseClient, modelName: String, data: Map<String, Any>, envType: String = \"prod\"): Map<String, Any>? {\n    // 新增数据模型数据\n    val result = cloudbase.request<Map<String, Any>>(\n        method = \"POST\",\n        path = \"/v1/model/$envType/$modelName/create\",\n        body = mapOf(\"data\" to data),\n        typeToken = object : TypeToken<Map<String, Any>>() {}\n    )\n\n    if (result != null) {\n        val docId = (result[\"data\"] as? Map<*, *>)?.get(\"id\")\n        println(\"新增成功! id: $docId\")\n    }\n    return result\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val result = addModelData(cloudbase, \"{%TABLE_NAME%}\", mapOf(\"title\" to \"示例标题\"))\n//     println(result)\n// }\n```",
                "index": 2,
                "title": "新增数据",
                "content": []
              },
              {
                "markdown": "```kotlin\nsuspend fun updateModelData(cloudbase: CloudBaseClient, modelName: String, dataId: String, data: Map<String, Any>, envType: String = \"prod\"): Boolean {\n    // 更新数据模型数据\n    val payload = mapOf(\n        \"data\" to data,\n        \"filter\" to mapOf(\n            \"where\" to mapOf(\n                \"_id\" to mapOf(\"\\$eq\" to dataId)\n            )\n        )\n    )\n\n    val result = cloudbase.request<Any>(\n        method = \"PUT\",\n        path = \"/v1/model/$envType/$modelName/update\",\n        body = payload\n    )\n\n    if (result != null) {\n        println(\"更新成功!\")\n        return true\n    }\n    return false\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val result = updateModelData(cloudbase, \"{%TABLE_NAME%}\", \"<数据id>\", mapOf(\"title\" to \"新标题\"))\n//     println(result)\n// }\n```",
                "index": 3,
                "title": "更新数据",
                "content": []
              },
              {
                "markdown": "```kotlin\nsuspend fun deleteModelData(cloudbase: CloudBaseClient, modelName: String, dataId: String, envType: String = \"prod\"): Boolean {\n    // 删除数据模型数据\n    val payload = mapOf(\n        \"filter\" to mapOf(\n            \"where\" to mapOf(\n                \"_id\" to mapOf(\"\\$eq\" to dataId)\n            )\n        )\n    )\n\n    val result = cloudbase.request<Any>(\n        method = \"POST\",\n        path = \"/v1/model/$envType/$modelName/delete\",\n        body = payload\n    )\n\n    if (result != null) {\n        println(\"删除成功!\")\n        return true\n    }\n    return false\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val result = deleteModelData(cloudbase, \"{%TABLE_NAME%}\", \"<数据id>\")\n//     println(result)\n// }\n```",
                "index": 4,
                "title": "删除数据",
                "content": []
              }
            ]
          },
          {
            "markdown": "```kotlin\nsuspend fun callFunction(cloudbase: CloudBaseClient, functionName: String, data: Map<String, Any>? = null): Map<String, Any>? {\n    // 调用云函数\n    val result = cloudbase.request<Map<String, Any>>(\n        method = \"POST\",\n        path = \"/v1/functions/$functionName\",\n        body = data ?: emptyMap<String, Any>(),\n        typeToken = object : TypeToken<Map<String, Any>>() {}\n    )\n\n    if (result != null) {\n        println(\"云函数调用结果: $result\")\n    }\n    return result\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val result = callFunction(cloudbase, \"{%FUNCTION_NAME%}\")\n//     println(result)\n// }\n```",
            "index": 3,
            "id": "scf",
            "title": "云函数"
          },
          {
            "markdown": "```kotlin\nsuspend fun callContainer(cloudbase: CloudBaseClient, serviceName: String, path: String = \"\", method: String = \"GET\", data: Map<String, Any>? = null): Any? {\n    // 调用云托管服务\n    val fullPath = \"/v1/cloudrun/$serviceName/$path\".trimEnd('/')\n    val result = cloudbase.request<Any>(\n        method = method.uppercase(),\n        path = fullPath,\n        body = data\n    )\n\n    if (result != null) {\n        println(\"云托管调用结果: $result\")\n    }\n    return result\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val result = callContainer(cloudbase, \"{%SERVICE_NAME%}\")\n//     println(result)\n// }\n```",
            "index": 4,
            "id": "run",
            "title": "云托管"
          },
          {
            "index": 5,
            "id": "storage",
            "title": "云存储",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```kotlin\nimport okhttp3.OkHttpClient\nimport okhttp3.Request\nimport okhttp3.RequestBody.Companion.toRequestBody\nimport java.io.File\n\nsuspend fun uploadFile(cloudbase: CloudBaseClient, filePath: String, objectId: String? = null): Map<String, String>? = withContext(Dispatchers.IO) {\n    // 上传文件到云存储\n    val file = File(filePath)\n\n    if (!file.exists()) {\n        println(\"文件不存在: $filePath\")\n        return@withContext null\n    }\n\n    val finalObjectId = objectId ?: \"uploads/${System.currentTimeMillis()}-${file.name}\"\n\n    // 1. 获取上传信息\n    val uploadInfo = cloudbase.request<List<Map<String, Any>>>(\n        method = \"POST\",\n        path = \"/v1/storages/get-objects-upload-info\",\n        body = listOf(mapOf(\"objectId\" to finalObjectId)),\n        typeToken = object : TypeToken<List<Map<String, Any>>>() {}\n    )\n\n    if (uploadInfo.isNullOrEmpty()) {\n        return@withContext null\n    }\n\n    val info = uploadInfo[0]\n    val uploadUrl = info[\"uploadUrl\"] as String\n\n    try {\n        // 2. 上传文件\n        val fileData = file.readBytes()\n        val uploadHeaders = mapOf(\n            \"Authorization\" to (info[\"authorization\"] as String),\n            \"X-Cos-Security-Token\" to (info[\"token\"] as String),\n            \"X-Cos-Meta-Fileid\" to (info[\"cloudObjectMeta\"] as String)\n        )\n\n        val requestBuilder = Request.Builder()\n            .url(uploadUrl)\n            .put(fileData.toRequestBody())\n\n        uploadHeaders.forEach { (key, value) ->\n            requestBuilder.header(key, value)\n        }\n\n        val client = OkHttpClient()\n        val uploadResponse = client.newCall(requestBuilder.build()).execute()\n\n        if (uploadResponse.isSuccessful) {\n            val result = mapOf(\n                \"cloudObjectId\" to (info[\"cloudObjectId\"] as String),\n                \"downloadUrl\" to (info[\"downloadUrl\"] as String),\n                \"objectId\" to finalObjectId\n            )\n\n            println(\"文件上传成功:\")\n            println(\"- 对象ID: ${result[\"objectId\"]}\")\n            println(\"- 下载URL: ${result[\"downloadUrl\"]}\")\n\n            return@withContext result\n        }\n\n        println(\"文件上传失败: ${uploadResponse.code}\")\n        return@withContext null\n    } catch (e: Exception) {\n        println(\"文件上传失败: ${e.message}\")\n        e.printStackTrace()\n        return@withContext null\n    }\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val result = uploadFile(cloudbase, \"/path/to/example.jpg\")\n//     println(result)\n// }\n```",
                "index": 1,
                "title": "上传文件",
                "content": []
              },
              {
                "markdown": "```kotlin\nsuspend fun getFileUrl(cloudbase: CloudBaseClient, cloudObjectId: String): String? {\n    // 获取云存储文件的临时访问链接\n    val result = cloudbase.request<List<Map<String, Any>>>(\n        method = \"POST\",\n        path = \"/v1/storages/get-objects-download-info\",\n        body = listOf(mapOf(\"cloudObjectId\" to cloudObjectId)),\n        typeToken = object : TypeToken<List<Map<String, Any>>>() {}\n    )\n\n    if (!result.isNullOrEmpty()) {\n        val downloadUrl = result[0][\"downloadUrl\"] as? String\n        println(\"文件链接: $downloadUrl\")\n        return downloadUrl\n    }\n    return null\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val fileUrl = getFileUrl(cloudbase, \"cloud://xxx.png\")\n//     println(fileUrl)\n// }\n```",
                "index": 2,
                "title": "获取文件链接",
                "content": []
              },
              {
                "markdown": "```kotlin\nimport okhttp3.OkHttpClient\nimport okhttp3.Request\nimport java.io.File\n\nsuspend fun downloadFile(cloudbase: CloudBaseClient, cloudObjectId: String, savePath: String = \"./\"): Boolean = withContext(Dispatchers.IO) {\n    // 下载云存储文件到本地\n    // 1. 获取下载链接\n    val result = cloudbase.request<List<Map<String, Any>>>(\n        method = \"POST\",\n        path = \"/v1/storages/get-objects-download-info\",\n        body = listOf(mapOf(\"cloudObjectId\" to cloudObjectId)),\n        typeToken = object : TypeToken<List<Map<String, Any>>>() {}\n    )\n\n    if (result.isNullOrEmpty()) {\n        return@withContext false\n    }\n\n    val downloadUrl = result[0][\"downloadUrl\"] as String\n\n    try {\n        // 2. 从URL中提取文件名\n        val filename = downloadUrl.split(\"/\").last().split(\"?\").first()\n\n        // 3. 确定完整路径\n        val fullPath = if (File(savePath).isDirectory || savePath.endsWith(\"/\")) {\n            \"$savePath/$filename\"\n        } else {\n            savePath\n        }\n\n        // 4. 下载文件\n        val client = OkHttpClient()\n        val request = Request.Builder().url(downloadUrl).build()\n        val fileResponse = client.newCall(request).execute()\n\n        if (fileResponse.isSuccessful) {\n            // 5. 保存到本地\n            val file = File(fullPath)\n            file.parentFile?.mkdirs()\n            file.writeBytes(fileResponse.body!!.bytes())\n\n            println(\"下载成功! 文件已保存到: $fullPath\")\n            return@withContext true\n        }\n\n        println(\"下载失败: ${fileResponse.code}\")\n        return@withContext false\n    } catch (e: Exception) {\n        println(\"下载失败: ${e.message}\")\n        e.printStackTrace()\n        return@withContext false\n    }\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     // 下载到指定目录\n//     downloadFile(cloudbase, \"cloud://xxx.png\", \"/sdcard/Download/\")\n//\n//     // 下载并重命名\n//     downloadFile(cloudbase, \"cloud://xxx.png\", \"/sdcard/Download/my-image.png\")\n// }\n```",
                "index": 3,
                "title": "下载文件",
                "content": []
              },
              {
                "markdown": "```kotlin\nsuspend fun deleteFile(cloudbase: CloudBaseClient, cloudObjectIds: Any): Boolean {\n    // 删除云存储文件\n    val ids = when (cloudObjectIds) {\n        is String -> listOf(cloudObjectIds)\n        is List<*> -> cloudObjectIds.filterIsInstance<String>()\n        else -> {\n            println(\"参数类型错误\")\n            return false\n        }\n    }\n\n    val data = ids.map { mapOf(\"cloudObjectId\" to it) }\n    val result = cloudbase.request<Any>(\n        method = \"POST\",\n        path = \"/v1/storages/delete-objects\",\n        body = data\n    )\n\n    if (result != null) {\n        println(\"删除成功!\")\n        return true\n    }\n    return false\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val result = deleteFile(cloudbase, \"cloud://xxx.png\")\n//     println(result)\n// }\n```",
                "index": 4,
                "title": "删除文件",
                "content": []
              }
            ]
          },
          {
            "index": 6,
            "id": "ai-model",
            "title": "大模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```kotlin\nimport okhttp3.OkHttpClient\nimport okhttp3.Request\nimport okhttp3.RequestBody.Companion.toRequestBody\nimport okhttp3.MediaType.Companion.toMediaType\nimport com.google.gson.Gson\n\nsuspend fun streamText(cloudbase: CloudBaseClient, model: String, subModel: String, messages: List<Map<String, String>>): String? = withContext(Dispatchers.IO) {\n    // 流式文本生成\n    val payload = mapOf(\n        \"model\" to subModel,\n        \"messages\" to messages,\n        \"stream\" to true\n    )\n\n    val url = \"${cloudbase.baseUrl}/v1/ai/$model/chat/completions\"\n    val gson = Gson()\n\n    val requestBody = gson.toJson(payload).toRequestBody(\"application/json\".toMediaType())\n\n    val request = Request.Builder()\n        .url(url)\n        .header(\"Content-Type\", \"application/json\")\n        .header(\"Accept\", \"text/event-stream\")\n        .header(\"Authorization\", \"Bearer ${cloudbase.accessToken}\")\n        .post(requestBody)\n        .build()\n\n    try {\n        val client = OkHttpClient()\n        val response = client.newCall(request).execute()\n\n        if (response.isSuccessful) {\n            println(\"AI 流式响应:\")\n            var fullContent = \"\"\n\n            response.body?.source()?.use { source ->\n                while (!source.exhausted()) {\n                    val line = source.readUtf8Line() ?: continue\n\n                    if (line.startsWith(\"data: \")) {\n                        val dataStr = line.substring(6)\n                        if (dataStr.trim() != \"[DONE]\") {\n                            try {\n                                val chunkData = gson.fromJson(dataStr, Map::class.java)\n                                val choices = chunkData[\"choices\"] as? List<*>\n                                val delta = (choices?.get(0) as? Map<*, *>)?.get(\"delta\") as? Map<*, *>\n                                val content = delta?.get(\"content\") as? String ?: \"\"\n\n                                if (content.isNotEmpty()) {\n                                    print(content)\n                                    fullContent += content\n                                }\n                            } catch (e: Exception) {\n                                // 忽略JSON解析错误\n                            }\n                        }\n                    }\n                }\n            }\n\n            println()\n            return@withContext fullContent\n        } else {\n            println(\"AI 调用失败: ${response.code}\")\n            return@withContext null\n        }\n    } catch (e: Exception) {\n        println(\"AI 调用失败: ${e.message}\")\n        e.printStackTrace()\n        return@withContext null\n    }\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val response = streamText(\n//         cloudbase,\n//         \"{%AI_MODEL_NAME%}\",\n//         \"{%AI_SUB_MODEL_NAME%}\",\n//         listOf(\n//             mapOf(\"role\" to \"system\", \"content\" to \"请严格按照七言绝句或七言律诗的格律要求创作\"),\n//             mapOf(\"role\" to \"user\", \"content\" to \"春天\")\n//         )\n//     )\n//     println(\"\\n完整回复: $response\")\n// }\n```",
                "index": 1,
                "id": "text-aiModel",
                "title": "生文模型",
                "content": []
              },
              {
                "markdown": "生图模型通过调用云函数来实现，在生图模型页面点击「一键创建云函数」，函数调用示例如下：\n\n```kotlin\nimport com.google.gson.Gson\n\nsuspend fun generateImage(cloudbase: CloudBaseClient, prompt: String): Map<String, Any>? = withContext(Dispatchers.IO) {\n    /// 调用生图云函数\n    val result = cloudbase.request(\n        \"POST\",\n        \"/v1/functions/<YOUR_FUNCTION_NAME>/invoke\",\n        mapOf(\"prompt\" to prompt)\n    )\n\n    if (result != null) {\n        val success = result[\"success\"] as? Boolean ?: false\n        \n        if (success) {\n            // 生成成功\n            println(\"生成成功!\")\n            println(\"图片URL: ${result[\"imageUrl\"]}\")\n            println(\"优化后的提示词: ${result[\"revised_prompt\"]}\")\n\n            // 使用图片\n            // 注意：图片URL有效期为24小时，请及时保存或转存\n            return@withContext result\n        } else {\n            // 生成失败\n            println(\"生成失败: ${result[\"code\"]} ${result[\"message\"]}\")\n            return@withContext null\n        }\n    }\n    return@withContext null\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val result = generateImage(cloudbase, \"一只可爱的猫咪在阳光下玩耍\")\n//     if (result != null) {\n//         println(\"图片URL: ${result[\"imageUrl\"]}\")\n//     }\n// }\n```",
                "index": 2,
                "id": "image-aiModel",
                "title": "生图模型",
                "content": []
              }
            ]
          },
          {
            "markdown": "",
            "index": 7,
            "id": "agent",
            "title": "Agent",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```kotlin\n/**\n * Android Kotlin 调用 Agent 示例（AG-UI 协议）\n * 协议文档：https://docs.cloudbase.net/ai/agent-development/protocol\n */\nimport okhttp3.OkHttpClient\nimport okhttp3.Request\nimport okhttp3.RequestBody.Companion.toRequestBody\nimport okhttp3.MediaType.Companion.toMediaType\nimport com.google.gson.Gson\n\nsuspend fun chatWithAgentStream(cloudbase: CloudBaseClient, botId: String, userMessage: String): String? = withContext(Dispatchers.IO) {\n    // 构建消息列表（AG-UI 协议格式）\n    val messages = listOf(\n        mapOf(\n            \"id\" to \"msg_001\",\n            \"role\" to \"user\",\n            \"content\" to userMessage\n        )\n    )\n\n    // AG-UI 协议请求参数\n    val payload = mapOf(\n        \"messages\" to messages,                                    // 必填：消息列表\n        \"threadId\" to \"550e8400-e29b-41d4-a716-446655440000\",     // 可选：会话ID，用于多轮对话\n        \"runId\" to \"run_001\",                                      // 可选：运行ID，用于追踪执行\n        \"tools\" to emptyList<Any>(),                               // 可选：前端工具定义\n        \"context\" to emptyList<Any>(),                             // 可选：上下文信息\n        \"forwardedProps\" to emptyMap<String, Any>()                // 可选：透传参数\n    )\n\n    val url = \"${cloudbase.baseUrl}/v1/aibot/bots/$botId/send-message\"\n    val gson = Gson()\n\n    val requestBody = gson.toJson(payload).toRequestBody(\"application/json\".toMediaType())\n\n    val request = Request.Builder()\n        .url(url)\n        .header(\"Content-Type\", \"application/json\")\n        .header(\"Accept\", \"text/event-stream\")\n        .header(\"Authorization\", \"Bearer ${cloudbase.accessToken}\")\n        .post(requestBody)\n        .build()\n\n    try {\n        val client = OkHttpClient()\n        val response = client.newCall(request).execute()\n\n        if (response.isSuccessful) {\n            println(\"AI 流式响应:\")\n            var fullContent = \"\"\n            var buffer = \"\"\n\n            response.body?.source()?.use { source ->\n                while (!source.exhausted()) {\n                    buffer += source.readUtf8Line() ?: \"\"\n                    buffer += \"\\n\"\n\n                    while (buffer.contains(\"\\n\")) {\n                        val newlineIndex = buffer.indexOf(\"\\n\")\n                        val line = buffer.substring(0, newlineIndex).trim()\n                        buffer = buffer.substring(newlineIndex + 1)\n\n                        if (line.startsWith(\"data: \")) {\n                            val dataStr = line.substring(6).trim()\n                            if (dataStr.isNotEmpty() && dataStr != \"[DONE]\") {\n                                try {\n                                    val chunkData = gson.fromJson(dataStr, Map::class.java)\n                                    val content = chunkData[\"content\"] as? String\n                                        ?: ((chunkData[\"choices\"] as? List<*>)?.get(0) as? Map<*, *>)?.let {\n                                            (it[\"delta\"] as? Map<*, *>)?.get(\"content\") as? String\n                                                ?: (it[\"message\"] as? Map<*, *>)?.get(\"content\") as? String\n                                        } ?: \"\"\n\n                                    if (content.isNotEmpty()) {\n                                        print(content)\n                                        fullContent += content\n                                    }\n                                } catch (e: Exception) {\n                                    // 忽略JSON解析错误\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n\n            println()\n            return@withContext fullContent\n        } else {\n            println(\"AI 调用失败: ${response.code}\")\n            return@withContext null\n        }\n    } catch (e: Exception) {\n        println(\"AI 调用失败: ${e.message}\")\n        e.printStackTrace()\n        return@withContext null\n    }\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val response = chatWithAgentStream(cloudbase, \"{%AGENT_ID%}\", \"你是谁\")\n//     println(\"\\n完整回复: $response\")\n// }\n\n```",
                "index": 0,
                "id": "scf",
                "title": "函数型"
              },
              {
                "markdown": "```kotlin\nimport okhttp3.OkHttpClient\nimport okhttp3.Request\nimport okhttp3.RequestBody.Companion.toRequestBody\nimport okhttp3.MediaType.Companion.toMediaType\nimport com.google.gson.Gson\n\nsuspend fun chatWithAgentStream(cloudbase: CloudBaseClient, botId: String, msg: String, history: List<Map<String, String>>? = null): String? = withContext(Dispatchers.IO) {\n    // 流式调用Agent\n    val payload = mapOf(\n        \"history\" to (history ?: emptyList<Map<String, String>>()),\n        \"msg\" to msg\n    )\n\n    val url = \"${cloudbase.baseUrl}/v1/aibot/bots/$botId/send-message\"\n    val gson = Gson()\n\n    val requestBody = gson.toJson(payload).toRequestBody(\"application/json\".toMediaType())\n\n    val request = Request.Builder()\n        .url(url)\n        .header(\"Content-Type\", \"application/json\")\n        .header(\"Accept\", \"text/event-stream\")\n        .header(\"Authorization\", \"Bearer ${cloudbase.accessToken}\")\n        .post(requestBody)\n        .build()\n\n    try {\n        val client = OkHttpClient()\n        val response = client.newCall(request).execute()\n\n        if (response.isSuccessful) {\n            println(\"AI 流式响应:\")\n            var fullContent = \"\"\n            var buffer = \"\"\n\n            response.body?.source()?.use { source ->\n                while (!source.exhausted()) {\n                    buffer += source.readUtf8Line() ?: \"\"\n                    buffer += \"\\n\"\n\n                    while (buffer.contains(\"\\n\")) {\n                        val newlineIndex = buffer.indexOf(\"\\n\")\n                        val line = buffer.substring(0, newlineIndex).trim()\n                        buffer = buffer.substring(newlineIndex + 1)\n\n                        if (line.startsWith(\"data: \")) {\n                            val dataStr = line.substring(6).trim()\n                            if (dataStr.isNotEmpty() && dataStr != \"[DONE]\") {\n                                try {\n                                    val chunkData = gson.fromJson(dataStr, Map::class.java)\n                                    val content = chunkData[\"content\"] as? String\n                                        ?: ((chunkData[\"choices\"] as? List<*>)?.get(0) as? Map<*, *>)?.let {\n                                            (it[\"delta\"] as? Map<*, *>)?.get(\"content\") as? String\n                                                ?: (it[\"message\"] as? Map<*, *>)?.get(\"content\") as? String\n                                        } ?: \"\"\n\n                                    if (content.isNotEmpty()) {\n                                        print(content)\n                                        fullContent += content\n                                    }\n                                } catch (e: Exception) {\n                                    // 忽略JSON解析错误\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n\n            println()\n            return@withContext fullContent\n        } else {\n            println(\"AI 调用失败: ${response.code}\")\n            return@withContext null\n        }\n    } catch (e: Exception) {\n        println(\"AI 调用失败: ${e.message}\")\n        e.printStackTrace()\n        return@withContext null\n    }\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val response = chatWithAgentStream(cloudbase, \"{%AGENT_ID%}\", \"你是谁\")\n//     println(\"\\n完整回复: $response\")\n// }\n```",
                "index": 1,
                "id": "baas",
                "title": "普通型"
              }
            ]
          },
          {
            "index": 8,
            "id": "identity",
            "title": "身份认证",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```kotlin\nsuspend fun signUpWithPhoneCode(cloudbase: CloudBaseClient, phoneNumber: String, verificationCode: String, username: String? = null, password: String? = null, captchaToken: String? = null): Map<String, Any>? {\n    // 步骤1: 发送短信验证码\n    val sendBody = mutableMapOf<String, Any>(\n        \"phone_number\" to if (phoneNumber.startsWith(\"+86\")) phoneNumber else \"+86$phoneNumber\",\n        \"target\" to \"NON_USER\"  // \"NON_USER\" - 账号不存在才发送; \"ANY\" - 不限制\n    )\n\n    val sendHeaders = captchaToken?.let { mapOf(\"x-captcha-token\" to it) } ?: emptyMap()\n\n    val sendResult = cloudbase.request<Map<String, Any>>(\n        method = \"POST\",\n        path = \"/auth/v1/verification\",\n        body = sendBody,\n        customHeaders = sendHeaders,\n        typeToken = object : TypeToken<Map<String, Any>>() {}\n    )\n\n    if (sendResult == null) {\n        println(\"发送验证码失败\")\n        return null\n    }\n\n    val verificationId = sendResult[\"verification_id\"] as? String ?: return null\n    println(\"验证码发送成功! ID: $verificationId\")\n\n    // 步骤2: 验证验证码\n    val verifyResult = cloudbase.request<Map<String, Any>>(\n        method = \"POST\",\n        path = \"/auth/v1/verification/verify\",\n        body = mapOf(\n            \"verification_id\" to verificationId,\n            \"verification_code\" to verificationCode\n        ),\n        typeToken = object : TypeToken<Map<String, Any>>() {}\n    )\n\n    if (verifyResult == null) {\n        println(\"验证码错误\")\n        return null\n    }\n\n    val verificationToken = verifyResult[\"verification_token\"] as? String ?: return null\n    println(\"验证成功!\")\n\n    // 步骤3: 使用验证令牌注册\n    val signUpBody = mutableMapOf<String, Any>(\n        \"phone_number\" to if (phoneNumber.startsWith(\"+86\")) phoneNumber else \"+86$phoneNumber\",\n        \"verification_token\" to verificationToken\n    )\n\n    // 可选：添加用户名和密码\n    username?.let { signUpBody[\"username\"] = it }\n    password?.let { signUpBody[\"password\"] = it }\n\n    val signUpResult = cloudbase.request<Map<String, Any>>(\n        method = \"POST\",\n        path = \"/auth/v1/signup\",\n        body = signUpBody,\n        typeToken = object : TypeToken<Map<String, Any>>() {}\n    )\n\n    if (signUpResult != null) {\n        val accessToken = signUpResult[\"access_token\"] as? String\n        val userId = signUpResult[\"sub\"] as? String\n\n        println(\"注册成功! 用户ID: $userId\")\n        println(\"访问令牌: ${accessToken?.take(20)}...\")\n\n        // 更新访问令牌\n        accessToken?.let { cloudbase.updateAccessToken(it) }\n        return signUpResult\n    }\n\n    println(\"注册失败\")\n    return null\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val result = signUpWithPhoneCode(cloudbase, \"13800138000\", \"123456\", \"myusername\", \"mypassword\")\n//     if (result != null) {\n//         println(\"手机号注册成功\")\n//     }\n// }\n```",
                "index": 1,
                "title": "短信验证码注册",
                "content": []
              },
              {
                "markdown": "```kotlin\nsuspend fun signUpWithEmailCode(cloudbase: CloudBaseClient, email: String, verificationCode: String, username: String? = null, password: String? = null, captchaToken: String? = null): Map<String, Any>? {\n    // 步骤1: 发送邮箱验证码\n    val sendBody = mutableMapOf<String, Any>(\n        \"email\" to email,\n        \"target\" to \"NON_USER\"  // \"NON_USER\" - 账号不存在才发送; \"ANY\" - 不限制\n    )\n\n    val sendHeaders = captchaToken?.let { mapOf(\"x-captcha-token\" to it) } ?: emptyMap()\n\n    val sendResult = cloudbase.request<Map<String, Any>>(\n        method = \"POST\",\n        path = \"/auth/v1/verification\",\n        body = sendBody,\n        customHeaders = sendHeaders,\n        typeToken = object : TypeToken<Map<String, Any>>() {}\n    )\n\n    if (sendResult == null) {\n        println(\"发送验证码失败\")\n        return null\n    }\n\n    val verificationId = sendResult[\"verification_id\"] as? String ?: return null\n    println(\"验证码发送成功! ID: $verificationId\")\n\n    // 步骤2: 验证验证码\n    val verifyResult = cloudbase.request<Map<String, Any>>(\n        method = \"POST\",\n        path = \"/auth/v1/verification/verify\",\n        body = mapOf(\n            \"verification_id\" to verificationId,\n            \"verification_code\" to verificationCode\n        ),\n        typeToken = object : TypeToken<Map<String, Any>>() {}\n    )\n\n    if (verifyResult == null) {\n        println(\"验证码错误\")\n        return null\n    }\n\n    val verificationToken = verifyResult[\"verification_token\"] as? String ?: return null\n    println(\"验证成功!\")\n\n    // 步骤3: 使用验证令牌注册\n    val signUpBody = mutableMapOf<String, Any>(\n        \"email\" to email,\n        \"verification_token\" to verificationToken\n    )\n\n    // 可选：添加用户名和密码\n    username?.let { signUpBody[\"username\"] = it }\n    password?.let { signUpBody[\"password\"] = it }\n\n    val signUpResult = cloudbase.request<Map<String, Any>>(\n        method = \"POST\",\n        path = \"/auth/v1/signup\",\n        body = signUpBody,\n        typeToken = object : TypeToken<Map<String, Any>>() {}\n    )\n\n    if (signUpResult != null) {\n        val accessToken = signUpResult[\"access_token\"] as? String\n        val userId = signUpResult[\"sub\"] as? String\n\n        println(\"注册成功! 用户ID: $userId\")\n        println(\"访问令牌: ${accessToken?.take(20)}...\")\n\n        // 更新访问令牌\n        accessToken?.let { cloudbase.updateAccessToken(it) }\n        return signUpResult\n    }\n\n    println(\"注册失败\")\n    return null\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val result = signUpWithEmailCode(cloudbase, \"user@example.com\", \"123456\", \"myusername\", \"mypassword\")\n//     if (result != null) {\n//         println(\"邮箱注册成功\")\n//     }\n// }\n```",
                "index": 2,
                "title": "邮箱验证码注册",
                "content": []
              },
              {
                "markdown": "```kotlin\nsuspend fun signIn(cloudbase: CloudBaseClient, username: String, password: String): Map<String, Any>? {\n    // 账号密码登录\n    val result = cloudbase.request<Map<String, Any>>(\n        method = \"POST\",\n        path = \"/auth/v1/signin\",\n        body = mapOf(\"username\" to username, \"password\" to password),\n        typeToken = object : TypeToken<Map<String, Any>>() {}\n    )\n\n    if (result != null) {\n        val accessToken = result[\"access_token\"] as? String\n        val refreshToken = result[\"refresh_token\"] as? String\n        val userId = result[\"sub\"] as? String\n\n        println(\"登录成功! 用户ID: $userId\")\n        println(\"访问令牌: ${accessToken?.take(20)}...\")\n\n        // 更新访问令牌\n        accessToken?.let { cloudbase.updateAccessToken(it) }\n        return result\n    }\n    return null\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val result = signIn(cloudbase, \"your_username\", \"your_password\")\n//     println(result)\n// }\n```",
                "index": 3,
                "id": "UserNameLogin",
                "title": "账号密码登录",
                "content": []
              },
              {
                "markdown": "```kotlin\nsuspend fun loginWithPhoneCode(cloudbase: CloudBaseClient, phoneNumber: String, verificationCode: String, captchaToken: String? = null): Boolean {\n    // 步骤1: 发送短信验证码\n    val sendBody = mutableMapOf<String, Any>(\n        \"phone_number\" to if (phoneNumber.startsWith(\"+86\")) phoneNumber else \"+86$phoneNumber\",\n        \"target\" to \"ANY\"  // \"ANY\" - 不限制，无论用户是否存在都发送; \"USER\" - 账号必须存在才发送\n    )\n\n    val sendHeaders = captchaToken?.let { mapOf(\"x-captcha-token\" to it) } ?: emptyMap()\n\n    val sendResult = cloudbase.request<Map<String, Any>>(\n        method = \"POST\",\n        path = \"/auth/v1/verification\",\n        body = sendBody,\n        customHeaders = sendHeaders,\n        typeToken = object : TypeToken<Map<String, Any>>() {}\n    )\n\n    if (sendResult == null) {\n        println(\"发送验证码失败\")\n        return false\n    }\n\n    val verificationId = sendResult[\"verification_id\"] as? String ?: return false\n    println(\"验证码发送成功! ID: $verificationId\")\n\n    // 步骤2: 验证验证码\n    val verifyResult = cloudbase.request<Map<String, Any>>(\n        method = \"POST\",\n        path = \"/auth/v1/verification/verify\",\n        body = mapOf(\n            \"verification_id\" to verificationId,\n            \"verification_code\" to verificationCode\n        ),\n        typeToken = object : TypeToken<Map<String, Any>>() {}\n    )\n\n    if (verifyResult == null) {\n        println(\"验证码错误\")\n        return false\n    }\n\n    val verificationToken = verifyResult[\"verification_token\"] as? String ?: return false\n    println(\"验证成功!\")\n\n    // 步骤3: 使用验证令牌登录\n    val loginResult = cloudbase.request<Map<String, Any>>(\n        method = \"POST\",\n        path = \"/auth/v1/signin\",\n        body = mapOf(\n            \"phone_number\" to if (phoneNumber.startsWith(\"+86\")) phoneNumber else \"+86$phoneNumber\",\n            \"verification_token\" to verificationToken\n        ),\n        typeToken = object : TypeToken<Map<String, Any>>() {}\n    )\n\n    if (loginResult != null) {\n        val accessToken = loginResult[\"access_token\"] as? String\n        println(\"登录成功!\")\n        accessToken?.let { cloudbase.updateAccessToken(it) }\n        return true\n    }\n\n    println(\"登录失败\")\n    return false\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val success = loginWithPhoneCode(cloudbase, \"13800138000\", \"123456\")\n//     if (success) {\n//         println(\"手机号登录成功\")\n//     }\n// }\n```",
                "index": 4,
                "id": "PhoneNumberLogin",
                "title": "短信验证码登录",
                "content": []
              },
              {
                "markdown": "```kotlin\nsuspend fun loginWithEmailCode(cloudbase: CloudBaseClient, email: String, verificationCode: String, captchaToken: String? = null): Boolean {\n    // 步骤1: 发送邮箱验证码\n    val sendBody = mutableMapOf<String, Any>(\n        \"email\" to email,\n        \"target\" to \"ANY\"  // \"ANY\" - 不限制，无论用户是否存在都发送; \"USER\" - 账号必须存在才发送\n    )\n\n    val sendHeaders = captchaToken?.let { mapOf(\"x-captcha-token\" to it) } ?: emptyMap()\n\n    val sendResult = cloudbase.request<Map<String, Any>>(\n        method = \"POST\",\n        path = \"/auth/v1/verification\",\n        body = sendBody,\n        customHeaders = sendHeaders,\n        typeToken = object : TypeToken<Map<String, Any>>() {}\n    )\n\n    if (sendResult == null) {\n        println(\"发送验证码失败\")\n        return false\n    }\n\n    val verificationId = sendResult[\"verification_id\"] as? String ?: return false\n    println(\"验证码发送成功! ID: $verificationId\")\n\n    // 步骤2: 验证验证码\n    val verifyResult = cloudbase.request<Map<String, Any>>(\n        method = \"POST\",\n        path = \"/auth/v1/verification/verify\",\n        body = mapOf(\n            \"verification_id\" to verificationId,\n            \"verification_code\" to verificationCode\n        ),\n        typeToken = object : TypeToken<Map<String, Any>>() {}\n    )\n\n    if (verifyResult == null) {\n        println(\"验证码错误\")\n        return false\n    }\n\n    val verificationToken = verifyResult[\"verification_token\"] as? String ?: return false\n    println(\"验证成功!\")\n\n    // 步骤3: 使用验证令牌登录\n    val loginResult = cloudbase.request<Map<String, Any>>(\n        method = \"POST\",\n        path = \"/auth/v1/signin\",\n        body = mapOf(\n            \"email\" to email,\n            \"verification_token\" to verificationToken\n        ),\n        typeToken = object : TypeToken<Map<String, Any>>() {}\n    )\n\n    if (loginResult != null) {\n        val accessToken = loginResult[\"access_token\"] as? String\n        println(\"登录成功!\")\n        accessToken?.let { cloudbase.updateAccessToken(it) }\n        return true\n    }\n\n    println(\"登录失败\")\n    return false\n}\n\n// 使用示例\n// lifecycleScope.launch {\n//     val success = loginWithEmailCode(cloudbase, \"user@example.com\", \"123456\")\n//     if (success) {\n//         println(\"邮箱登录成功\")\n//     }\n// }\n```",
                "index": 5,
                "id": "email",
                "title": "邮箱验证码登录",
                "content": []
              }
            ]
          }
        ]
      }
    ],
    "_id": "b4498fc86964cbe60bc2437405574585",
    "_openid": "anon",
    "createdAt": 1768213478209,
    "updatedAt": 1770371904653
  },
  {
    "category": "框架集成,ORMs,SQLAlchemy",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": 43,
    "hasTemplate": false,
    "docsUrl": "https://docs.sqlalchemy.org/en/20/orm/quickstart.html",
    "content": [
      {
        "docsUrl": "",
        "markdown": "使用 `SQLAlchemy` 操作 **MySQL数据库**\n```bash\npip install sqlalchemy pymysql\n```",
        "title": "安装依赖",
        "type": "",
        "content": []
      },
      {
        "markdown": "新增如下代码到您的 **SQLAlchemy** 项目",
        "title": "使用示例",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```python\nimport os\nfrom sqlalchemy import create_engine, text\nfrom sqlalchemy.orm import sessionmaker\nfrom models import Base, Todo\n\ndef main():\n    engine = create_engine(os.getenv('DATABASE_URL'))\n\n    Session = sessionmaker(bind=engine)\n    with Session() as session:\n        todos = session.query(Todo).all()\n        print(f\"Found {len(todos)} todos\")\n\nif __name__ == '__main__':\n    main()\n```",
            "title": "main.py"
          },
          {
            "markdown": "```python\nfrom sqlalchemy import Column, Integer, String\nfrom sqlalchemy.orm import declarative_base\n\nBase = declarative_base()\n\nclass Todo(Base):\n    __tablename__ = 'todos'\n\n    _id = Column(String(255), primary_key=True)\n    title = Column(String(255))\n```",
            "title": "models.py"
          },
          {
            "markdown": "```\nDATABASE_URL=mysql+pymysql://{%DATABASE_URL%}\n```",
            "id": "mysqlString",
            "title": ".env"
          }
        ]
      }
    ],
    "_id": "b49e5b7a697c256d003ad10f396aea76",
    "_openid": "anon",
    "createdAt": 1769743725320,
    "updatedAt": 1769743908824
  },
  {
    "category": "框架集成,前端框架,Vue(Vite)",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": 11,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/api-reference/webv2/initialization",
    "content": [
      {
        "markdown": "`@cloudbase/js-sdk` 可以让您在 Web 端(如 PC Web 页面、微信公众平台 H5 等)使用 JavaScript 访问 CloudBase 服务和资源。",
        "index": 1,
        "title": "安装 SDK",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```bash\nnpm i @cloudbase/js-sdk\n```",
            "index": 1,
            "title": "npm",
            "content": []
          },
          {
            "markdown": "```bash\nyarn add @cloudbase/js-sdk\n```",
            "index": 2,
            "title": "yarn",
            "content": []
          },
          {
            "markdown": "```bash\npnpm add @cloudbase/js-sdk\n```",
            "index": 3,
            "title": "pnpm",
            "content": []
          }
        ]
      },
      {
        "markdown": "新增如下代码到您的 Vue 项目",
        "index": 2,
        "title": "初始化 SDK",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```js\nimport cloudbaseSDK from \"@cloudbase/js-sdk\";\n\nexport const cloudbase = cloudbaseSDK.init({\n  env: import.meta.env.VITE_CLOUDBASE_ENV_ID,\n  region: import.meta.env.VITE_CLOUDBASE_REGION,\n  accessKey: import.meta.env.VITE_CLOUDBASE_ACCESS_KEY\n});\n```",
            "index": 1,
            "title": "src/utils/cloudbase.js",
            "content": []
          },
          {
            "markdown": "```properties\n# 环境ID\nVITE_CLOUDBASE_ENV_ID={%ENV_ID%}\n\n# 环境所在地域\nVITE_CLOUDBASE_REGION={%REGION%}\n\n# 匿名访问令牌\nVITE_CLOUDBASE_ACCESS_KEY={%PUBLISHABLE_KEY%}\n```",
            "index": 2,
            "title": ".env",
            "content": []
          }
        ]
      },
      {
        "sideTabs": [
          {
            "id": "pg-db",
            "title": "PostgreSQL 数据库"
          }
        ],
        "index": 3,
        "title": "调用云开发能力",
        "type": "codeTab",
        "content": [
          {
            "index": 1,
            "id": "pg-db",
            "title": "PostgreSQL 数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 查询 {%TABLE_NAME%} 表前 10 条数据\nconst { data, error } = await cloudbase.rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .select(\"*\")\n  .limit(10);\n\nconsole.log(\"查询结果:\", data);\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 向 {%TABLE_NAME%} 表插入一条数据\n// 注意：anon 令牌（publishable key）仅有读权限，写操作需用户登录态或配置 RLS 写策略\nconst { data, error } = await cloudbase.rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .insert({ title: \"新文章\", status: \"draft\" })\n  .select();\n\nconsole.log(\"新增结果:\", data);\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 更新 {%TABLE_NAME%} 表中 id=1 的记录\n// 注意：anon 令牌（publishable key）仅有读权限，写操作需用户登录态或配置 RLS 写策略\nconst { data, error } = await cloudbase.rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .update({ status: \"published\" })\n  .eq(\"id\", 1)\n  .select();\n\nconsole.log(\"更新结果:\", data);\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 当 id 冲突时更新，否则插入\n// 注意：anon 令牌（publishable key）仅有读权限，写操作需用户登录态或配置 RLS 写策略\nconst { data, error } = await cloudbase.rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .upsert({ id: 1, title: \"标题\", status: \"published\" }, { onConflict: \"id\" })\n  .select();\n\nconsole.log(\"更新或创建结果:\", data);\n```",
                "index": 4,
                "title": "更新或创建数据"
              },
              {
                "markdown": "```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 删除 {%TABLE_NAME%} 表中 id=1 的记录\n// 注意：anon 令牌（publishable key）仅有读权限，写操作需用户登录态或配置 RLS 写策略\nconst { data, error } = await cloudbase.rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .delete()\n  .eq(\"id\", 1);\n\nconsole.log(\"删除完成:\", error);\n```",
                "index": 5,
                "title": "删除数据"
              }
            ]
          },
          {
            "index": 1,
            "id": "mysql-db",
            "title": "MySQL数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 查询 {%TABLE_NAME%} 表前10条数据\nconst { data: result, error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .select(\"*\")\n  .limit(10);\nif (!error) {\n  console.log(result);\n}\n```\n\n**完整示例:**\n\n```vue\n<template>\n  <ul>\n    <li v-for=\"item in data\" :key=\"item.id\">{{ item.title }}</li>\n  </ul>\n</template>\n\n<script setup>\nimport { ref, onMounted } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst data = ref([]);\n\nconst getData = async () => {\n  // 查询 {%TABLE_NAME%} 表前10条数据\n  const { data: result, error } = await cloudbase\n    .rdb()\n    .from(\"{%TABLE_NAME%}\")\n    .select(\"*\")\n    .limit(10);\n  if (!error) data.value = result || [];\n};\n\nonMounted(() => {\n  getData();\n});\n</script>\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 新增 {%TABLE_NAME%} 表数据\nconst { error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .insert({ title: \"示例标题\" });\nif (!error) {\n  console.log(\"新增成功\");\n}\n```\n\n**完整示例:**\n\n```vue\n<template>\n  <div>\n    <input v-model=\"title\" />\n    <button @click=\"addData\">新增</button>\n    <p v-if=\"message\" :style=\"{ color: message.includes(\"成功\") ? \"green\" : \"red\" }\">{{ message }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst title = ref(\"\");\nconst message = ref(\"\");\n\nconst addData = async () => {\n  // 新增 {%TABLE_NAME%} 表数据\n  const { error } = await cloudbase.rdb().from(\"{%TABLE_NAME%}\").insert({ title: title.value });\n  if (!error) {\n    title.value = \"\";\n    message.value = \"新增成功！\";\n  } else {\n    message.value = \"新增失败：\" + error.message;\n  }\n};\n</script>\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 更新 {%TABLE_NAME%} 表中 id 为指定值的数据\nconst { error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .update({ title: \"新标题\" })\n  .eq(\"id\", \"<数据id>\");\nif (!error) {\n  console.log(\"更新成功\");\n}\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <button @click=\"updateData\">更新</button>\n    <p v-if=\"message\" :style=\"{ color: message.includes(\"成功\") ? \"green\" : \"red\" }\">{{ message }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst message = ref(\"\");\n\nconst updateData = async () => {\n  // 更新 {%TABLE_NAME%} 表中 id 为指定值的数据\n  const { error } = await cloudbase.rdb().from(\"{%TABLE_NAME%}\").update({ title: \"新标题\" }).eq(\"id\", \"<数据id>\");\n  if (!error) {\n    message.value = \"更新成功！\";\n  } else {\n    message.value = \"更新失败：\" + error.message;\n  }\n};\n</script>\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 如果 {%TABLE_NAME%} 表中存在 id 为 1 的记录则更新 title 为\"示例标题\"，不存在则插入新记录\nconst { error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .upsert({ id: 1, title: \"示例标题\" });\nif (!error) {\n  console.log(\"操作成功\");\n}\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <button @click=\"upsertData\">更新或创建</button>\n    <p v-if=\"message\" :style=\"{ color: message.includes(\"成功\") ? \"green\" : \"red\" }\">{{ message }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst message = ref(\"\");\n\nconst upsertData = async () => {\n  // 如果 {%TABLE_NAME%} 表中存在 id 为 1 的记录则更新 title 为\"示例标题\"，不存在则插入新记录\n  const { error } = await cloudbase.rdb().from(\"{%TABLE_NAME%}\").upsert({ id: 1, title: \"示例标题\" });\n  if (!error) {\n    message.value = \"操作成功！\";\n  } else {\n    message.value = \"操作失败：\" + error.message;\n  }\n};\n</script>\n```",
                "index": 4,
                "title": "更新或创建数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 删除 {%TABLE_NAME%} 表中 id 为指定值的数据\nconst { error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .delete()\n  .eq(\"id\", \"<数据id>\");\nif (!error) {\n  console.log(\"删除成功\");\n}\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <button @click=\"deleteData\">删除</button>\n    <p v-if=\"message\" :style=\"{ color: message.includes(\"成功\") ? \"green\" : \"red\" }\">{{ message }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst message = ref(\"\");\n\nconst deleteData = async () => {\n  // 删除 {%TABLE_NAME%} 表中 id 为指定值的数据\n  const { error } = await cloudbase.rdb().from(\"{%TABLE_NAME%}\").delete().eq(\"id\", \"<数据id>\");\n  if (!error) {\n    message.value = \"删除成功！\";\n  } else {\n    message.value = \"删除失败：\" + error.message;\n  }\n};\n</script>\n```",
                "index": 5,
                "title": "删除数据"
              }
            ]
          },
          {
            "index": 2,
            "id": "doc-db",
            "title": "文档型数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 查询 {%TABLE_NAME%} 表前10条数据\nconst db = cloudbase.database();\nconst res = await db.collection(\"{%TABLE_NAME%}\").limit(10).get();\nconsole.log(res.data);\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <ul>\n    <li v-for=\"item in data\" :key=\"item._id\">{{ item.title }}</li>\n  </ul>\n</template>\n\n<script setup>\nimport { ref, onMounted } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst data = ref([]);\n\nconst getData = async () => {\n  // 查询 {%TABLE_NAME%} 表前10条数据\n  const db = cloudbase.database();\n  const res = await db.collection(\"{%TABLE_NAME%}\").limit(10).get();\n  data.value = res.data || [];\n};\n\nonMounted(() => {\n  getData();\n});\n</script>\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 新增 {%TABLE_NAME%} 表数据\nconst db = cloudbase.database();\nconst res = await db.collection(\"{%TABLE_NAME%}\").add({ title: \"示例标题\" });\nconsole.log(`新增成功! id: ${res.id}`);\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <button @click=\"addData\">新增</button>\n    <p v-if=\"message\" :style=\"{ color: message.includes(\"成功\") ? \"green\" : \"red\" }\">{{ message }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst message = ref(\"\");\n\nconst addData = async () => {\n  try {\n    // 新增 {%TABLE_NAME%} 表数据\n    const db = cloudbase.database();\n    const res = await db.collection(\"{%TABLE_NAME%}\").add({ title: \"示例标题\" });\n    message.value = `新增成功! id: ${res.id}`;\n  } catch (error) {\n    message.value = \"新增失败：\" + error.message;\n  }\n};\n</script>\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 更新 {%TABLE_NAME%} 表中 id 为指定值的数据\nconst db = cloudbase.database();\nawait db\n  .collection(\"{%TABLE_NAME%}\")\n  .doc(\"<数据id>\")\n  .update({ title: \"新标题\" });\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <button @click=\"updateData\">更新</button>\n    <p v-if=\"message\" :style=\"{ color: message.includes(\"成功\") ? \"green\" : \"red\" }\">{{ message }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst message = ref(\"\");\n\nconst updateData = async () => {\n  try {\n    // 更新 {%TABLE_NAME%} 表中 id 为指定值的数据\n    const db = cloudbase.database();\n    await db.collection(\"{%TABLE_NAME%}\").doc(\"<数据id>\").update({ title: \"新标题\" });\n    message.value = \"更新成功！\";\n  } catch (error) {\n    message.value = \"更新失败：\" + error.message;\n  }\n};\n</script>\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 删除 {%TABLE_NAME%} 表中 id 为指定值的数据\nconst db = cloudbase.database();\nawait db.collection(\"{%TABLE_NAME%}\").doc(\"<数据id>\").remove();\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <button @click=\"deleteData\">删除</button>\n    <p v-if=\"message\" :style=\"{ color: message.includes(\"成功\") ? \"green\" : \"red\" }\">{{ message }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst message = ref(\"\");\n\nconst deleteData = async () => {\n  try {\n    // 删除 {%TABLE_NAME%} 表中 id 为指定值的数据\n    const db = cloudbase.database();\n    await db.collection(\"{%TABLE_NAME%}\").doc(\"<数据id>\").remove();\n    message.value = \"删除成功！\";\n  } catch (error) {\n    message.value = \"删除失败：\" + error.message;\n  }\n};\n</script>\n```",
                "index": 4,
                "title": "删除数据"
              }
            ]
          },
          {
            "index": 3,
            "id": "data-model",
            "title": "数据模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 查询 {%TABLE_NAME%} 数据模型前10条数据\nconst res = await cloudbase.models[\"{%TABLE_NAME%}\"].list({\n  pageNumber: 1,\n  pagesize: 10\n});\nconsole.log(res.data?.records);\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <ul>\n    <li v-for=\"item in data\" :key=\"item._id\">{{ item.title }}</li>\n  </ul>\n</template>\n\n<script setup>\nimport { ref, onMounted } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst data = ref([]);\n\nconst getData = async () => {\n  // 查询 {%TABLE_NAME%} 数据模型前10条数据\n  const res = await cloudbase.models[\"{%TABLE_NAME%}\"].list({\n    pageNumber: 1,\n    pagesize: 10\n  });\n  data.value = res.data?.records || [];\n};\n\nonMounted(() => {\n  getData();\n});\n</script>\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 新增 {%TABLE_NAME%} 数据模型数据\nconst res = await cloudbase.models[\"{%TABLE_NAME%}\"].create({\n  data: { title: \"示例标题\" }\n});\nconsole.log(`新增成功! id: ${res.data.id}`);\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <button @click=\"addData\">新增</button>\n    <p v-if=\"message\" :style=\"{ color: message.includes(\"成功\") ? \"green\" : \"red\" }\">{{ message }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst message = ref(\"\");\n\nconst addData = async () => {\n  try {\n    // 新增 {%TABLE_NAME%} 数据模型数据\n    const res = await cloudbase.models[\"{%TABLE_NAME%}\"].create({ data: { title: \"示例标题\" } });\n    message.value = `新增成功! id: ${res.data.id}`;\n  } catch (error) {\n    message.value = \"新增失败：\" + error.message;\n  }\n};\n</script>\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 更新 {%TABLE_NAME%} 数据模型中 _id 为指定值的数据\nawait cloudbase.models[\"{%TABLE_NAME%}\"].update({\n  data: { title: \"新标题\" },\n  filter: { where: { _id: { $eq: \"<数据id>\" } } }\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <button @click=\"updateData\">更新</button>\n    <p v-if=\"message\" :style=\"{ color: message.includes(\"成功\") ? \"green\" : \"red\" }\">{{ message }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst message = ref(\"\");\n\nconst updateData = async () => {\n  try {\n    // 更新 {%TABLE_NAME%} 数据模型中 _id 为指定值的数据\n    await cloudbase.models[\"{%TABLE_NAME%}\"].update({\n      data: { title: \"新标题\" },\n      filter: { where: { _id: { $eq: \"<数据id>\" } } }\n    });\n    message.value = \"更新成功！\";\n  } catch (error) {\n    message.value = \"更新失败：\" + error.message;\n  }\n};\n</script>\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 删除 {%TABLE_NAME%} 数据模型中 _id 为指定值的数据\nawait cloudbase.models[\"{%TABLE_NAME%}\"].delete({\n  filter: { where: { _id: { $eq: \"<数据id>\" } } }\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <button @click=\"deleteData\">删除</button>\n    <p v-if=\"message\" :style=\"{ color: message.includes(\"成功\") ? \"green\" : \"red\" }\">{{ message }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst message = ref(\"\");\n\nconst deleteData = async () => {\n  try {\n    // 删除 {%TABLE_NAME%} 数据模型中 _id 为指定值的数据\n    await cloudbase.models[\"{%TABLE_NAME%}\"].delete({\n      filter: { where: { _id: { $eq: \"<数据id>\" } } }\n    });\n    message.value = \"删除成功！\";\n  } catch (error) {\n    message.value = \"删除失败：\" + error.message;\n  }\n};\n</script>\n```",
                "index": 4,
                "title": "删除数据"
              }
            ]
          },
          {
            "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 调用 {%FUNCTION_NAME%} 云函数\nconst res = await cloudbase.callFunction({\n  name: \"{%FUNCTION_NAME%}\",\n  data: {}\n});\nconsole.log(res.result);\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <button @click=\"getData\">调用云函数</button>\n    <pre v-if=\"data\">{{ JSON.stringify(data, null, 2) }}</pre>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst data = ref(null);\n\nconst getData = async () => {\n  // 调用 {%FUNCTION_NAME%} 云函数\n  const res = await cloudbase.callFunction({\n    name: \"{%FUNCTION_NAME%}\",\n    data: {}\n  });\n  data.value = res.result;\n};\n</script>\n```",
            "index": 4,
            "id": "scf",
            "title": "云函数",
            "content": []
          },
          {
            "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 调用 {%SERVICE_NAME%} 云托管服务\nconst res = await cloudbase.callContainer({\n  name: \"{%SERVICE_NAME%}\"\n  method: 'POST',\n  path: '/',\n  header:{\n    'Content-Type': 'application/json; charset=utf-8'\n  },\n  data: {},\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <button @click=\"getData\">调用云托管</button>\n    <pre v-if=\"data\">{{ JSON.stringify(data, null, 2) }}</pre>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst data = ref(null);\n\nconst getData = async () => {\n  // 调用 {%SERVICE_NAME%} 云托管服务\n  const res = await cloudbase.callContainer({\n    name: \"{%SERVICE_NAME%}\"\n    method: 'POST',\n    path: '/',\n    header:{\n      'Content-Type': 'application/json; charset=utf-8'\n    },\n    data: {},\n  });\n  data.value = res;\n};\n</script>\n```",
            "index": 5,
            "id": "run",
            "title": "云托管",
            "content": []
          },
          {
            "index": 6,
            "id": "storage",
            "title": "云存储",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst res = await cloudbase.uploadFile({\n  cloudPath: `images/${Date.now()}-${file.name}`, // 上传至云端的路径\n  filePath: file\n});\nconsole.log(res.fileID);\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <input type=\"file\" @change=\"uploadFile\" />\n    <p v-if=\"fileID\">上传成功: {{ fileID }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst fileID = ref(\"\");\n\nconst uploadFile = async e => {\n  const file = e.target.files[0];\n  const res = await cloudbase.uploadFile({\n    cloudPath: `images/${Date.now()}-${file.name}`, // 上传至云端的路径\n    filePath: file\n  });\n  fileID.value = res.fileID;\n};\n</script>\n```",
                "index": 1,
                "title": "上传文件"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst res = await cloudbase.getTempFileURL({\n  fileList: [\"cloud://xxx.png\"] // 文件 fileID 列表\n});\nconsole.log(res.fileList[0].tempFileURL);\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <button @click=\"getData\">获取链接</button>\n    <p v-if=\"fileUrl\">链接: {{ fileUrl }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst fileUrl = ref(\"\");\n\nconst getData = async () => {\n  const res = await cloudbase.getTempFileURL({\n    fileList: [\"cloud://xxx.png\"] // 文件 fileID 列表\n  });\n  fileUrl.value = res.fileList[0].tempFileURL;\n};\n</script>\n```",
                "index": 2,
                "title": "获取文件链接"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nawait cloudbase.downloadFile({\n  fileID: \"cloud://xxx.png\" // 文件 fileID\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <button @click=\"downloadFile\">下载文件</button>\n</template>\n\n<script setup>\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst downloadFile = async () => {\n  await cloudbase.downloadFile({\n    fileID: \"cloud://xxx.png\" // 文件 fileID\n  });\n};\n</script>\n```",
                "index": 3,
                "title": "下载文件"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst res = await cloudbase.deleteFile({\n  fileList: [\"cloud://xxx.png\"] // 文件 fileID 列表\n});\nif (res.fileList[0].code === \"SUCCESS\") {\n  console.log(\"删除成功\");\n}\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <button @click=\"deleteFile\">删除文件</button>\n    <p v-if=\"message\">{{ message }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst message = ref(\"\");\n\nconst deleteFile = async () => {\n  const res = await cloudbase.deleteFile({\n    fileList: [\"cloud://xxx.png\"] // 文件 fileID 列表\n  });\n  if (res.fileList[0].code === \"SUCCESS\") {\n    message.value = \"删除成功！\";\n  } else {\n    ((message.value = \"删除失败！\"), res.fileList);\n  }\n};\n</script>\n```",
                "index": 4,
                "title": "删除文件"
              }
            ]
          },
          {
            "index": 7,
            "id": "ai-model",
            "title": "大模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst res = await cloudbase\n  .ai()\n  .createModel(\"{%AI_MODEL_NAME%}\")\n  .streamText({\n    model: \"{%AI_SUB_MODEL_NAME%}\",\n    messages: [{ role: \"user\", content: \"你好\" }]\n  });\n\nfor await (let data of res.dataStream) {\n  // 如果有则打印思维链内容\n  const think = data?.choices?.[0]?.delta?.reasoning_content;\n  if (think) console.log(think);\n\n  // 打印生成文本内容\n  const text = data?.choices?.[0]?.delta?.content;\n  if (text) console.log(text);\n}\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <input v-model=\"input\" placeholder=\"请输入大模型对话内容\" />\n    <button @click=\"getData\">发送</button>\n    <p>{{ data }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst data = ref(\"\");\nconst input = ref(\"\");\n\nconst getData = async () => {\n  const res = await cloudbase\n    .ai()\n    .createModel(\"{%AI_MODEL_NAME%}\")\n    .streamText({\n      model: \"{%AI_SUB_MODEL_NAME%}\",\n      messages: [{ role: \"user\", content: input.value }]\n    });\n\n  let result = \"\";\n  for await (let item of res.dataStream) {\n    // 如果有则打印思维链内容\n    const think = item?.choices?.[0]?.delta?.reasoning_content;\n    if (think) {\n      result += think;\n    }\n\n    // 打印生成文本内容\n    const text = item?.choices?.[0]?.delta?.content;\n    if (text) result += text;\n\n    data.value = result;\n  }\n};\n</script>\n```",
                "index": 1,
                "id": "text-aiModel",
                "title": "生文模型"
              },
              {
                "markdown": "生图模型通过调用云函数来实现，在生图模型页面点击「一键创建云函数」，函数调用示例如下：\n\n**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 调用生图云函数\nconst res = await cloudbase.callFunction({\n  name: \"<YOUR_FUNCTION_NAME>\",\n  data: {\n    prompt: \"一只可爱的猫咪在阳光下玩耍\"\n  }\n});\n\nconst result = res.result;\n\nif (result.success) {\n  // 生成成功\n  console.log(\"生成成功!\");\n  console.log(\"图片URL:\", result.imageUrl);\n  console.log(\"优化后的提示词:\", result.revised_prompt);\n\n  // 使用图片\n  // 注意：图片URL有效期为24小时，请及时保存或转存\n} else {\n  // 生成失败\n  console.error(\"生成失败:\", result.code, result.message);\n}\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <input v-model=\"prompt\" placeholder=\"请输入图片描述\" />\n    <button @click=\"generateImage\" :disabled=\"!prompt || loading\">\n      {{ loading ? \"生成中...\" : \"生成图片\" }}\n    </button>\n    <p v-if=\"message\" :style=\"{ color: message.includes('成功') ? 'green' : 'red' }\">\n      {{ message }}\n    </p>\n    <div v-if=\"imageUrl\">\n      <img :src=\"imageUrl\" alt=\"生成的图片\" style=\"max-width: 100%\" />\n      <p style=\"font-size: 12px; color: #666\">\n        注意：图片URL有效期为24小时，请及时保存\n      </p>\n    </div>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst prompt = ref(\"\");\nconst imageUrl = ref(\"\");\nconst message = ref(\"\");\nconst loading = ref(false);\n\nconst generateImage = async () => {\n  loading.value = true;\n  message.value = \"\";\n  imageUrl.value = \"\";\n\n  try {\n    // 调用生图云函数\n    const res = await cloudbase.callFunction({\n      name: \"<YOUR_FUNCTION_NAME>\",\n      data: {\n        prompt: prompt.value\n      }\n    });\n\n    const result = res.result;\n\n    if (result.success) {\n      imageUrl.value = result.imageUrl;\n      message.value = \"生成成功！\";\n    } else {\n      message.value = `生成失败：${result.message}`;\n    }\n  } catch (error) {\n    message.value = \"调用失败：\" + error.message;\n  } finally {\n    loading.value = false;\n  }\n};\n</script>\n```",
                "index": 2,
                "id": "image-aiModel",
                "title": "生图模型"
              }
            ]
          },
          {
            "markdown": "",
            "index": 8,
            "id": "agent",
            "title": "Agent",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from './utils/cloudbase';\n\nconst res = await cloudbase.ai().bot.sendMessage({\n  botId: '{%AGENT_ID%}',\n  // 入参结构参考前后端通信协议：\n  //  https://docs.cloudbase.net/ai/agent/http-agent-protocol\n  threadId: '550e8400-e29b-41d4-a716-446655440000',\n  runId: 'run_001',\n  messages: [\n    {\n      id: 'msg_001',\n      role: 'user',\n      content: '你好',\n    },\n  ],\n  tools: [],\n  context: [],\n  state: {},\n  forwardedProps: {},\n});\n\nfor await (const data of res.dataStream) {\n  // 如果有则打印思维链内容\n  const think = data.reasoning_content;\n  if (think) console.log(think);\n\n  // 打印输出正文\n  const content = data.content;\n  if (content) console.log(content);\n}\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <input v-model=\"input\" placeholder=\"请输入Agent对话内容\" />\n    <button @click=\"getData\">发送</button>\n    <p>{{ data }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst data = ref(\"\");\nconst input = ref(\"\");\n\nconst getData = async () => {\n  const res = await cloudbase.ai().bot.sendMessage({\n    botId: \"{%AGENT_ID%}\",\n    // 入参结构参考前后端通信协议：\n    //  https://docs.cloudbase.net/ai/agent/http-agent-protocol\n    threadId: '550e8400-e29b-41d4-a716-446655440000',\n    runId: 'run_001',\n    messages: [\n      {\n        id: 'msg_001',\n        role: 'user',\n        content: input.value,\n      },\n    ],\n    tools: [],\n    context: [],\n    state: {},\n    forwardedProps: {},\n    });\n\n  let result = \"\";\n  for await (const item of res.dataStream) {\n    // 如果有则打印思维链内容\n    const think = item.reasoning_content;\n    if (think) {\n      result += think;\n    }\n\n    // 打印输出正文\n    const content = item.content;\n    if (content) result += content;\n\n    data.value = result;\n  }\n};\n</script>\n\n```",
                "index": 0,
                "id": "scf",
                "title": "函数型"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst res = await cloudbase.ai().bot.sendMessage({\n  botId: \"{%AGENT_ID%}\",\n  msg: \"你好\"\n});\n\nfor await (const data of res.dataStream) {\n  // 如果有则打印思维链内容\n  const think = data.reasoning_content;\n  if (think) console.log(think);\n\n  // 打印输出正文\n  const content = data.content;\n  if (content) console.log(content);\n}\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <input v-model=\"input\" placeholder=\"请输入Agent对话内容\" />\n    <button @click=\"getData\">发送</button>\n    <p>{{ data }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst data = ref(\"\");\nconst input = ref(\"\");\n\nconst getData = async () => {\n  const res = await cloudbase.ai().bot.sendMessage({\n    botId: \"{%AGENT_ID%}\",\n    msg: input.value\n  });\n\n  let result = \"\";\n  for await (const item of res.dataStream) {\n    // 如果有则打印思维链内容\n    const think = item.reasoning_content;\n    if (think) {\n      result += think;\n    }\n\n    // 打印输出正文\n    const content = item.content;\n    if (content) result += content;\n\n    data.value = result;\n  }\n};\n</script>\n```",
                "index": 1,
                "id": "baas",
                "title": "普通型"
              }
            ]
          },
          {
            "index": 9,
            "id": "identity",
            "title": "身份认证",
            "type": "sideTab",
            "content": [
              {
                "markdown": "使用 **短信验证码注册** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **短信验证码**\n\n**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ phone_number: phone });\n\n// 验证验证码\nconst verifyRes = await auth.verify({\n  verification_id: verificationId,\n  verification_code: code\n});\n\n// 注册（如用户已存在则自动登录）\nawait auth.signUp({\n  phone_number: `+86 ${phone}`,\n  verification_code: code,\n  verification_token: verifyRes.verification_token,\n  name: `user_${phone.slice(-4)}`,\n  password: \"admin@123\"\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <label>手机号：</label>\n    <input v-model=\"phone\" placeholder=\"13800000000\" />\n    <div>\n      <label>验证码：</label>\n      <input v-model=\"code\" placeholder=\"验证码\" />\n      <button :disabled=\"!phone\" @click=\"sendCode\">发送验证码</button>\n    </div>\n    <button :disabled=\"!verificationId || !code\" @click=\"register\">注册</button>\n    <p v-if=\"message\" :style=\"{ color: message.includes(\"成功\") ? \"green\" : \"red\" }\">{{ message }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst phone = ref(\"\");\nconst code = ref(\"\");\nconst verificationId = ref(\"\");\nconst message = ref(\"\");\n\n// 发送验证码\nconst sendCode = async () => {\n  try {\n    const auth = cloudbase.auth();\n    const res = await auth.getVerification({ phone_number: phone.value });\n    verificationId.value = res.verification_id;\n    message.value = \"验证码已发送！\";\n  } catch (error) {\n    message.value = \"发送失败：\" + error.message;\n  }\n};\n\n// 注册\nconst register = async () => {\n  try {\n    const auth = cloudbase.auth();\n    // 验证验证码\n    const verifyRes = await auth.verify({\n      verification_id: verificationId.value,\n      verification_code: code.value,\n    });\n    // 注册（如用户已存在则自动登录）\n    await auth.signUp({\n      phone_number: `+86 ${phone.value}`,\n      verification_code: code.value,\n      verification_token: verifyRes.verification_token,\n      name: `user_${phone.value.slice(-4)}`,\n      password: \"admin@123\"\n    });\n    message.value = \"注册成功！\";\n  } catch (error) {\n    message.value = \"注册失败：\" + error.message;\n  }\n};\n</script>\n```",
                "index": 1,
                "title": "短信验证码注册"
              },
              {
                "markdown": "使用 **邮箱验证码注册** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **邮箱验证码**\n\n**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ email });\n\n// 验证验证码\nconst verifyRes = await auth.verify({\n  verification_id: verificationId,\n  verification_code: code\n});\n\n// 注册（如用户已存在则自动登录）\nawait auth.signUp({\n  email,\n  verification_code: code,\n  verification_token: verifyRes.verification_token,\n  name: `user_${email.slice(-4)}`,\n  password: \"admin@123\"\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <label>邮箱：</label>\n    <input v-model=\"email\" placeholder=\"example@email.com\" />\n    <div>\n      <label>验证码：</label>\n      <input v-model=\"code\" placeholder=\"验证码\" />\n      <button :disabled=\"!email\" @click=\"sendCode\">发送验证码</button>\n    </div>\n    <button :disabled=\"!verificationId || !code\" @click=\"register\">注册</button>\n    <p v-if=\"message\" :style=\"{ color: message.includes(\"成功\") ? \"green\" : \"red\" }\">{{ message }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst email = ref(\"\");\nconst code = ref(\"\");\nconst verificationId = ref(\"\");\nconst message = ref(\"\");\n\n// 发送验证码\nconst sendCode = async () => {\n  try {\n    const auth = cloudbase.auth();\n    const res = await auth.getVerification({ email: email.value });\n    verificationId.value = res.verification_id;\n    message.value = \"验证码已发送！\";\n  } catch (error) {\n    message.value = \"发送失败：\" + error.message;\n  }\n};\n\n// 注册\nconst register = async () => {\n  try {\n    const auth = cloudbase.auth();\n    // 验证验证码\n    const verifyRes = await auth.verify({\n      verification_id: verificationId.value,\n      verification_code: code.value,\n    });\n    // 注册（如用户已存在则自动登录）\n    await auth.signUp({\n      email: email.value,\n      verification_code: code.value,\n      verification_token: verifyRes.verification_token,\n      name: `user_${email.value.slice(-4)}`,\n      password: \"admin@123\"\n    });\n    message.value = \"注册成功！\";\n  } catch (error) {\n    message.value = \"注册失败：\" + error.message;\n  }\n};\n</script>\n```",
                "index": 2,
                "title": "邮箱验证码注册"
              },
              {
                "markdown": "使用 **账号密码登录** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **用户名密码登录**\n\n**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\nawait auth.signIn({\n  username, // 可以是用户名、手机号或邮箱\n  password\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <label>账号：</label>\n    <input v-model=\"username\" placeholder=\"用户名/手机号/邮箱\" />\n    注：手机号登录请添加区号 +86\n    <br />\n    <label>密码：</label>\n    <input\n      type=\"password\"\n      v-model=\"password\"\n      placeholder=\"请输入密码\"\n    />\n    <br />\n    <button :disabled=\"!username || !password\" @click=\"login\">登录</button>\n    <p v-if=\"message\" :style=\"{ color: message.includes(\"成功\") ? \"green\" : \"red\" }\">{{ message }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst username = ref(\"\");\nconst password = ref(\"\");\nconst message = ref(\"\");\n\n// 登录\nconst login = async () => {\n  try {\n    const auth = cloudbase.auth();\n    await auth.signIn({\n      username: username.value, // 可以是用户名、手机号或邮箱\n      password: password.value,\n    });\n    message.value = \"登录成功！\";\n  } catch (error) {\n    message.value = \"登录失败：\" + error.message;\n  }\n};\n</script>\n```",
                "index": 3,
                "id": "UserNameLogin",
                "title": "账号密码登录"
              },
              {
                "markdown": "使用 **短信验证码登录** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **短信验证码登录**\n\n**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ phone_number: `+86 ${phone}` });\n\n// 登录\nawait auth.signInWithSms({\n  verificationInfo: res,\n  verificationCode: code,\n  phoneNum: `+86 ${phone}`\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <label>手机号：</label>\n    <input v-model=\"phone\" placeholder=\"13800000000\" />\n    <div>\n      <label>验证码：</label>\n      <input v-model=\"code\" placeholder=\"验证码\" />\n      <button @click=\"sendCode\" :disabled=\"!phone\">发送验证码</button>\n    </div>\n    <button @click=\"login\" :disabled=\"!verificationInfo || !code\">登录</button>\n    <p v-if=\"message\" :style=\"{ color: message.includes(\"成功\") ? \"green\" : \"red\" }\">{{ message }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst phone = ref(\"\");\nconst code = ref(\"\");\nconst verificationInfo = ref(null);\nconst message = ref(\"\");\n\n// 发送验证码\nconst sendCode = async () => {\n  try {\n    const auth = cloudbase.auth();\n    const res = await auth.getVerification({ phone_number: `+86 ${phone.value}` });\n    verificationInfo.value = res;\n    message.value = \"验证码已发送！\";\n  } catch (error) {\n    message.value = \"发送失败：\" + error.message;\n  }\n};\n\n// 登录\nconst login = async () => {\n  try {\n    const auth = cloudbase.auth();\n    await auth.signInWithSms({\n      verificationInfo: verificationInfo.value,\n      verificationCode: code.value,\n      phoneNum: `+86 ${phone.value}`\n    });\n    message.value = \"登录成功！\";\n  } catch (error) {\n    message.value = \"登录失败：\" + error.message;\n  }\n};\n</script>\n```",
                "index": 4,
                "id": "PhoneNumberLogin",
                "title": "短信验证码登录"
              },
              {
                "markdown": "使用 **邮箱验证码登录** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **邮箱验证码**\n\n**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ email });\n\n// 登录\nawait auth.signInWithEmail({\n  verificationInfo: res,\n  verificationCode: code,\n  email\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <label>邮箱：</label>\n    <input v-model=\"email\" placeholder=\"example@email.com\" />\n    <div>\n      <label>验证码：</label>\n      <input v-model=\"code\" placeholder=\"验证码\" />\n      <button @click=\"sendCode\" :disabled=\"!email\">发送验证码</button>\n    </div>\n    <button @click=\"login\" :disabled=\"!verificationInfo || !code\">登录</button>\n    <p v-if=\"message\" :style=\"{ color: message.includes(\"成功\") ? \"green\" : \"red\" }\">{{ message }}</p>\n  </div>\n</template>\n\n<script setup>\nimport { ref } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst email = ref(\"\");\nconst code = ref(\"\");\nconst verificationInfo = ref(null);\nconst message = ref(\"\");\n\n// 发送验证码\nconst sendCode = async () => {\n  try {\n    const auth = cloudbase.auth();\n    const res = await auth.getVerification({ email: email.value });\n    verificationInfo.value = res;\n    message.value = \"验证码已发送！\";\n  } catch (error) {\n    message.value = \"发送失败：\" + error.message;\n  }\n};\n\n// 登录\nconst login = async () => {\n  try {\n    const auth = cloudbase.auth();\n    await auth.signInWithEmail({\n      verificationInfo: verificationInfo.value,\n      verificationCode: code.value,\n      email: email.value\n    });\n    message.value = \"登录成功！\";\n  } catch (error) {\n    message.value = \"登录失败：\" + error.message;\n  }\n};\n</script>\n```",
                "index": 5,
                "id": "email",
                "title": "邮箱验证码登录"
              },
              {
                "markdown": "使用 **Google 授权登录** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **Google 授权登录**\n\n**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 步骤1：生成Google授权URL并跳转\nconst state = Date.now().toString();\nlocalStorage.setItem(\"google_login_state\", state);\nconst { uri } = await auth.genProviderRedirectUri({\n  provider_id: \"google\",\n  provider_redirect_uri: window.location.href,\n  state: state\n});\nwindow.location.href = uri;\n\n// 步骤2：使用code换取provider_token\nconst { provider_token } = await auth.grantProviderToken({\n  provider_id: \"google\",\n  provider_redirect_uri: window.location.origin + window.location.pathname,\n  provider_code: code\n});\n\n// 步骤3：使用provider_token登录\nawait auth.signInWithProvider({\n  provider_token: provider_token\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <div>\n    <button v-if=\"!isCallback\" @click=\"startGoogleLogin\">Google登录</button>\n    <p v-if=\"isCallback\">正在处理Google登录...</p>\n    <p v-if=\"message\" :style=\"{ color: message.includes(\"成功\") ? \"green\" : \"red\" }\">\n      {{ message }}\n    </p>\n  </div>\n</template>\n\n<script setup>\nimport { ref, onMounted } from \"vue\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst message = ref(\"\");\nconst isCallback = ref(false);\n\nonMounted(() => {\n  // 检查是否是Google回调页面\n  const urlParams = new URLSearchParams(window.location.search);\n  const code = urlParams.get(\"code\");\n  const state = urlParams.get(\"state\");\n\n  if (code && state) {\n    isCallback.value = true;\n    handleGoogleCallback(code, state);\n  }\n});\n\n// 步骤1：跳转到Google授权页\nconst startGoogleLogin = async () => {\n  try {\n    const auth = cloudbase.auth();\n    const state = Date.now().toString(); // 生成唯一标识，防止CSRF攻击\n\n    // 保存state到本地，用于回调时验证\n    localStorage.setItem(\"google_login_state\", state);\n\n    // 生成Google授权URL\n    const { uri } = await auth.genProviderRedirectUri({\n      provider_id: \"google\", // 固定值，代表Google开放平台\n      provider_redirect_uri: window.location.href, // 授权后回调当前页面\n      state: state,\n    });\n\n    // 跳转到Google授权页\n    window.location.href = uri;\n  } catch (error) {\n    message.value = \"跳转失败：\" + error.message;\n  }\n};\n\n// 步骤2和3：处理Google回调并完成登录\nconst handleGoogleCallback = async (code, state) => {\n  try {\n    // 验证state是否匹配，防止CSRF攻击\n    const savedState = localStorage.getItem(\"google_login_state\");\n    if (savedState !== state) {\n      message.value = \"登录失败：状态验证失败\";\n      return;\n    }\n\n    const auth = cloudbase.auth();\n\n    // 使用code换取provider_token\n    const { provider_token } = await auth.grantProviderToken({\n      provider_id: \"google\",\n      provider_redirect_uri: window.location.origin + window.location.pathname,\n      provider_code: code,\n    });\n\n    try {\n      // 尝试直接登录\n      await auth.signInWithProvider({\n        provider_token: provider_token,\n      });\n\n      message.value = \"登录成功！\";\n\n      // 清除URL参数并清除本地存储\n      localStorage.removeItem(\"google_login_state\");\n      window.history.replaceState({}, document.title, window.location.pathname);\n\n    } catch (loginError) {\n      // 如果是首次Google登录，需要先注册并绑定\n      if (loginError.error === \"not_found\") {\n        message.value = \"检测到首次Google登录，需要绑定账号...\";\n\n        // 这里需要引导用户完成注册流程\n        // 例如：收集手机号验证码进行注册\n        // 注册成功后调用 bindWithProvider 绑定Google身份\n\n        // 示例：假设已有其他方式注册的账号，直接绑定\n        await auth.bindWithProvider({\n          provider_token: provider_token,\n        });\n\n        // 绑定成功后重新登录\n        await auth.signInWithProvider({\n          provider_token: provider_token,\n        });\n\n        message.value = \"绑定并登录成功！\";\n\n        // 清除URL参数和本地存储\n        localStorage.removeItem(\"google_login_state\");\n        window.history.replaceState({}, document.title, window.location.pathname);\n\n      } else {\n        throw loginError;\n      }\n    }\n  } catch (error) {\n    message.value = \"登录失败：\" + error.message;\n    localStorage.removeItem(\"google_login_state\");\n  }\n};\n</script>\n```",
                "index": 6,
                "id": "google",
                "title": "Google 授权登录"
              }
            ]
          }
        ]
      }
    ],
    "_id": "ba046a626960d9760b56a9f410de61a8",
    "_openid": "anon",
    "createdAt": 1767954806480,
    "updatedAt": 1770372545903
  },
  {
    "category": "框架集成,后端框架,Python",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": 21,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/http-api/basic/overview",
    "content": [
      {
        "markdown": "通过 **HTTP 请求** 在 **python** 中调用各种云开发能力\n\n```bash\npip install requests python-dotenv\n```",
        "index": 1,
        "title": "安装依赖",
        "content": []
      },
      {
        "markdown": "新增如下代码到您的 **Python** 项目",
        "index": 2,
        "title": "初始化配置",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```python\nimport os\nimport requests\nfrom dotenv import load_dotenv\n\nload_dotenv()\n\nclass CloudBaseClient:\n\tdef __init__(self):\n\t\tself.env_id = os.getenv(\"CLOUDBASE_ENV_ID\")\n\t\tself.access_token = os.getenv(\"CLOUDBASE_ACCESS_TOKEN\")\n\t\tself.base_url = f\"https://{self.env_id}.api.tcloudbasegateway.com\"\n\t\tself.headers = {\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\"Accept\": \"application/json\",\n\t\t\t\"Authorization\": f\"Bearer {self.access_token}\"\n\t\t}\n\n\tdef request(self, method, path, **kwargs):\n\t\t\"\"\"\n\t\t统一的HTTP请求方法\n\n\t\tArgs:\n\t\t\tmethod: 请求方法 (GET, POST, PUT, PATCH, DELETE)\n\t\t\tpath: API路径 (如 /v1/rdb/rest/table_name)\n\t\t\t**kwargs: 其他请求参数 (json, params, headers等)\n\n\t\tReturns:\n\t\t\t响应数据或None\n\t\t\"\"\"\n\t\turl = f\"{self.base_url}{path}\"\n\t\theaders = self.headers.copy()\n\n\t\t# 允许自定义headers\n\t\tif \"headers\" in kwargs:\n\t\t\theaders.update(kwargs.pop(\"headers\"))\n\n\t\ttry:\n\t\t\tresponse = requests.request(method, url, headers=headers, **kwargs)\n\t\t\tresponse.raise_for_status()\n\n\t\t\t# 如果响应为空，返回True表示成功\n\t\t\tif not response.content:\n\t\t\t\treturn True\n\n\t\t\treturn response.json()\n\t\texcept requests.exceptions.RequestException as e:\n\t\t\tprint(f\"请求失败: {e}\")\n\t\t\treturn None\n\ncloudbase = CloudBaseClient()\n```",
            "index": 1,
            "title": "cloudbase_client.py"
          },
          {
            "markdown": "> 💡提示：如需管理员权限，请通过 [云开发平台/ApiKey管理页](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}&#/env/apikey) 获取 APIKey 替换 CLOUDBASE_ACCESS_TOKEN\n\n```properties\n# 环境ID\nCLOUDBASE_ENV_ID={%ENV_ID%}\n\n# 匿名访问令牌\nCLOUDBASE_ACCESS_TOKEN={%PUBLISHABLE_KEY%}\n```",
            "index": 2,
            "title": ".env"
          }
        ]
      },
      {
        "sideTabs": [
          {
            "id": "pg-db",
            "title": "PostgreSQL 数据库"
          }
        ],
        "index": 3,
        "title": "调用云开发能力",
        "type": "codeTab",
        "content": [
          {
            "index": 1,
            "id": "pg-db",
            "title": "PostgreSQL 数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```python\nfrom cloudbase_client import cloudbase\n# 查询 {%TABLE_NAME%} 表前 10 条数据\nresponse = cloudbase.request(\n    \"GET\",\n    f\"/v1/rdb/rest/{{%TABLE_NAME%}}?select=*&limit=10\",\n)\nprint(\"查询结果:\", response.json())\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "```python\nfrom cloudbase_client import cloudbase\n# 新增{%TABLE_NAME%}\nresponse = cloudbase.request(\n    \"POST\",\n    f\"/v1/rdb/rest/{{%TABLE_NAME%}\",\n    json={\"title\": \"新文章\", \"status\": \"draft\"},\n    headers={\"Prefer\": \"return=representation\"},\n)\nprint(\"新增结果:\", response.json())\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "```python\nfrom cloudbase_client import cloudbase\n# 更新{%TABLE_NAME%}\nresponse = cloudbase.request(\n    \"PATCH\",\n    f\"/v1/rdb/rest/{{%TABLE_NAME%}?id=eq.1\",\n    json={\"status\": \"published\"},\n    headers={\"Prefer\": \"return=representation\"},\n)\nprint(\"更新结果:\", response.json())\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "```python\nfrom cloudbase_client import cloudbase\n# 更新或创建{%TABLE_NAME%}\nresponse = cloudbase.request(\n    \"POST\",\n    f\"/v1/rdb/rest/{{%TABLE_NAME%}\",\n    json={\"id\": 1, \"title\": \"标题\", \"status\": \"published\"},\n    headers={\"Prefer\": \"resolution=merge-duplicates,return=representation\"},\n)\nprint(\"更新或创建结果:\", response.json())\n```",
                "index": 4,
                "title": "更新或创建数据"
              },
              {
                "markdown": "```python\nfrom cloudbase_client import cloudbase\n# 删除 {%TABLE_NAME%} 表中 id=1 的数据\nresponse = cloudbase.request(\n    \"DELETE\",\n    f\"/v1/rdb/rest/{{%TABLE_NAME%}}?id=eq.1\",\n)\nprint(\"删除完成:\", response.status_code)\n```",
                "index": 5,
                "title": "删除数据"
              }
            ]
          },
          {
            "index": 1,
            "id": "mysql-db",
            "title": "MySQL数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```python\nfrom cloudbase_client import cloudbase\n\ndef get_mysql_data(table_name):\n\t\"\"\"查询 MySQL 数据库数据\"\"\"\n\tdata = cloudbase.request(\"GET\", f\"/v1/rdb/rest/{table_name}?limit=10\")\n\n\tif data:\n\t\tprint(\"查询成功:\", data)\n\treturn data or []\n\n# 使用示例\nif __name__ == \"__main__\":\n\tresult = get_mysql_data(\"{%TABLE_NAME%}\")\n```",
                "index": 1,
                "title": "查询数据",
                "content": []
              },
              {
                "markdown": "```python\nfrom cloudbase_client import cloudbase\n\ndef add_mysql_data(table_name, data):\n\t\"\"\"新增 MySQL 数据库数据\"\"\"\n\tresult = cloudbase.request(\"POST\", f\"/v1/rdb/rest/{table_name}\", json=data)\n\n\tif result:\n\t\tprint(\"新增成功:\", result)\n\treturn result\n\n# 使用示例\nif __name__ == \"__main__\":\n\tresult = add_mysql_data(\"{%TABLE_NAME%}\", {\"title\": \"示例标题\"})\n```",
                "index": 2,
                "title": "新增数据",
                "content": []
              },
              {
                "markdown": "```python\nfrom cloudbase_client import cloudbase\n\ndef update_mysql_data(table_name, data_id, data):\n\t\"\"\"更新 MySQL 数据库数据\"\"\"\n\tresult = cloudbase.request(\"PATCH\", f\"/v1/rdb/rest/{table_name}?id=eq.{data_id}\", json=data)\n\n\tif result:\n\t\tprint(\"更新成功:\", result)\n\treturn result\n\n# 使用示例\nif __name__ == \"__main__\":\n\tresult = update_mysql_data(\"{%TABLE_NAME%}\", \"<数据id>\", {\"title\": \"新标题\"})\n```",
                "index": 3,
                "title": "更新数据",
                "content": []
              },
              {
                "markdown": "```python\nfrom cloudbase_client import cloudbase\n\ndef delete_mysql_data(table_name, data_id):\n\t\"\"\"删除 MySQL 数据库数据\"\"\"\n\tresult = cloudbase.request(\"DELETE\", f\"/v1/rdb/rest/{table_name}?id=eq.{data_id}\")\n\n\tif result:\n\t\tprint(\"删除成功\")\n\t\treturn True\n\treturn False\n\n# 使用示例\nif __name__ == \"__main__\":\n\tresult = delete_mysql_data(\"{%TABLE_NAME%}\", \"<数据id>\")\n```",
                "index": 4,
                "title": "删除数据",
                "content": []
              }
            ]
          },
          {
            "index": 2,
            "id": "data-model",
            "title": "数据模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```python\nfrom cloudbase_client import cloudbase\n\ndef get_model_data(model_name, env_type=\"prod\"):\n\t\"\"\"查询数据模型数据\"\"\"\n\tpayload = {\n\t\t\"pageSize\": 10,\n\t\t\"pageNumber\": 1,\n\t\t\"getCount\": True\n\t}\n\n\tresult = cloudbase.request(\"POST\", f\"/v1/model/{env_type}/{model_name}/list\", json=payload)\n\n\tif result:\n\t\trecords = result.get(\"data\", {}).get(\"records\", [])\n\t\tprint(\"查询成功:\", records)\n\t\treturn records\n\treturn []\n\n# 使用示例\nif __name__ == \"__main__\":\n\trecords = get_model_data(\"{%TABLE_NAME%}\")\n```",
                "index": 1,
                "title": "查询数据",
                "content": []
              },
              {
                "markdown": "```python\nfrom cloudbase_client import cloudbase\n\ndef add_model_data(model_name, data, env_type=\"prod\"):\n\t\"\"\"新增数据模型数据\"\"\"\n\tresult = cloudbase.request(\"POST\", f\"/v1/model/{env_type}/{model_name}/create\", json={\"data\": data})\n\n\tif result:\n\t\tdoc_id = result.get(\"data\", {}).get(\"id\")\n\t\tprint(f\"新增成功! id: {doc_id}\")\n\treturn result\n\n# 使用示例\nif __name__ == \"__main__\":\n\tresult = add_model_data(\"{%TABLE_NAME%}\", {\"title\": \"示例标题\"})\n```",
                "index": 2,
                "title": "新增数据",
                "content": []
              },
              {
                "markdown": "```python\nfrom cloudbase_client import cloudbase\n\ndef update_model_data(model_name, data_id, data, env_type=\"prod\"):\n\t\"\"\"更新数据模型数据\"\"\"\n\tpayload = {\n\t\t\"data\": data,\n\t\t\"filter\": {\n\t\t\t\"where\": {\n\t\t\t\t\"_id\": {\"$eq\": data_id}\n\t\t\t}\n\t\t}\n\t}\n\n\tresult = cloudbase.request(\"PUT\", f\"/v1/model/{env_type}/{model_name}/update\", json=payload)\n\n\tif result:\n\t\tprint(\"更新成功!\")\n\t\treturn True\n\treturn False\n\n# 使用示例\nif __name__ == \"__main__\":\n\tresult = update_model_data(\"{%TABLE_NAME%}\", \"<数据id>\", {\"title\": \"新标题\"})\n```",
                "index": 3,
                "title": "更新数据",
                "content": []
              },
              {
                "markdown": "```python\nfrom cloudbase_client import cloudbase\n\ndef delete_model_data(model_name, data_id, env_type=\"prod\"):\n\t\"\"\"删除数据模型数据\"\"\"\n\tpayload = {\n\t\t\"filter\": {\n\t\t\t\"where\": {\n\t\t\t\t\"_id\": {\"$eq\": data_id}\n\t\t\t}\n\t\t}\n\t}\n\n\tresult = cloudbase.request(\"POST\", f\"/v1/model/{env_type}/{model_name}/delete\", json=payload)\n\n\tif result:\n\t\tprint(\"删除成功!\")\n\t\treturn True\n\treturn False\n\n# 使用示例\nif __name__ == \"__main__\":\n\tresult = delete_model_data(\"{%TABLE_NAME%}\", \"<数据id>\")\n```",
                "index": 4,
                "title": "删除数据",
                "content": []
              }
            ]
          },
          {
            "markdown": "```python\nfrom cloudbase_client import cloudbase\n\ndef call_function(function_name, data=None):\n\t\"\"\"调用云函数\"\"\"\n\tresult = cloudbase.request(\"POST\", f\"/v1/functions/{function_name}\", json=data or {})\n\n\tif result:\n\t\tprint(\"云函数调用结果:\", result)\n\treturn result\n\n# 使用示例\nif __name__ == \"__main__\":\n\tresult = call_function(\"{%FUNCTION_NAME%}\")\n```",
            "index": 3,
            "id": "scf",
            "title": "云函数"
          },
          {
            "markdown": "```python\nfrom cloudbase_client import cloudbase\n\ndef call_container(service_name, path=\"\", method=\"GET\", data=None):\n\t\"\"\"调用云托管服务\"\"\"\n\tfull_path = f\"/v1/cloudrun/{service_name}/{path}\".rstrip(\"/\")\n\tresult = cloudbase.request(method.upper(), full_path, json=data)\n\n\tif result:\n\t\tprint(\"云托管调用结果:\", result)\n\treturn result\n\n# 使用示例\nif __name__ == \"__main__\":\n\tresult = call_container(\"{%SERVICE_NAME%}\")\n```",
            "index": 4,
            "id": "run",
            "title": "云托管"
          },
          {
            "index": 5,
            "id": "storage",
            "title": "云存储",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```python\nimport os\nimport requests\nfrom datetime import datetime\nfrom cloudbase_client import cloudbase\n\ndef upload_file(file_path, object_id=None):\n\t\"\"\"上传文件到云存储\"\"\"\n\tif not object_id:\n\t\tfilename = os.path.basename(file_path)\n\t\ttimestamp = int(datetime.now().timestamp() * 1000)\n\t\tobject_id = f\"uploads/{timestamp}-{filename}\"\n\n\t# 1. 获取上传信息\n\tupload_info = cloudbase.request(\"POST\", \"/v1/storages/get-objects-upload-info\",\n\t\tjson=[{\"objectId\": object_id}])\n\n\tif not upload_info:\n\t\treturn None\n\n\tupload_info = upload_info[0]\n\tupload_url = upload_info[\"uploadUrl\"]\n\n\ttry:\n\t\t# 2. 上传文件\n\t\tupload_headers = {\n\t\t\t\"Authorization\": upload_info[\"authorization\"],\n\t\t\t\"X-Cos-Security-Token\": upload_info[\"token\"],\n\t\t\t\"X-Cos-Meta-Fileid\": upload_info[\"cloudObjectMeta\"]\n\t\t}\n\n\t\twith open(file_path, \"rb\") as f:\n\t\t\tfile_data = f.read()\n\n\t\tupload_response = requests.put(upload_url, headers=upload_headers, data=file_data)\n\t\tupload_response.raise_for_status()\n\n\t\tresult = {\n\t\t\t\"cloudObjectId\": upload_info[\"cloudObjectId\"],\n\t\t\t\"downloadUrl\": upload_info[\"downloadUrl\"],\n\t\t\t\"objectId\": object_id\n\t\t}\n\n\t\tprint(\"文件上传成功:\")\n\t\tprint(f\"- 对象ID: {result['objectId']}\")\n\t\tprint(f\"- 下载URL: {result['downloadUrl']}\")\n\n\t\treturn result\n\n\texcept FileNotFoundError:\n\t\tprint(f\"文件不存在: {file_path}\")\n\t\treturn None\n\texcept Exception as e:\n\t\tprint(f\"文件上传失败: {e}\")\n\t\treturn None\n\n# 使用示例\nif __name__ == \"__main__\":\n\tresult = upload_file(\"./example.jpg\")\n```",
                "index": 1,
                "title": "上传文件",
                "content": []
              },
              {
                "markdown": "```python\nfrom cloudbase_client import cloudbase\n\ndef get_file_url(cloud_object_id):\n\t\"\"\"获取云存储文件的临时访问链接\"\"\"\n\tresult = cloudbase.request(\"POST\", \"/v1/storages/get-objects-download-info\",\n\t\tjson=[{\"cloudObjectId\": cloud_object_id}])\n\n\tif result:\n\t\tdownload_url = result[0].get(\"downloadUrl\")\n\t\tprint(\"文件链接:\", download_url)\n\t\treturn download_url\n\treturn None\n\n# 使用示例\nif __name__ == \"__main__\":\n\tfile_url = get_file_url(\"cloud://xxx.png\")\n```",
                "index": 2,
                "title": "获取文件链接",
                "content": []
              },
              {
                "markdown": "```python\nimport os\nimport requests\nfrom cloudbase_client import cloudbase\n\ndef download_file(cloud_object_id, save_path=\"./\"):\n\t\"\"\"下载云存储文件到本地\"\"\"\n\t# 1. 获取下载链接\n\tresult = cloudbase.request(\"POST\", \"/v1/storages/get-objects-download-info\",\n\t\tjson=[{\"cloudObjectId\": cloud_object_id}])\n\n\tif not result:\n\t\treturn False\n\n\tdownload_url = result[0].get(\"downloadUrl\")\n\n\ttry:\n\t\t# 2. 从URL中提取文件名\n\t\tfilename = download_url.split(\"/\")[-1].split(\"?\")[0]\n\n\t\t# 3. 如果save_path是目录，则拼接文件名\n\t\tif os.path.isdir(save_path) or save_path.endswith(\"/\"):\n\t\t\tfull_path = os.path.join(save_path, filename)\n\t\telse:\n\t\t\tfull_path = save_path\n\n\t\t# 4. 下载文件\n\t\tfile_response = requests.get(download_url)\n\t\tfile_response.raise_for_status()\n\n\t\t# 5. 保存到本地\n\t\twith open(full_path, \"wb\") as f:\n\t\t\tf.write(file_response.content)\n\n\t\tprint(f\"下载成功! 文件已保存到: {full_path}\")\n\t\treturn True\n\texcept Exception as e:\n\t\tprint(f\"下载失败: {e}\")\n\t\treturn False\n\n# 使用示例\nif __name__ == \"__main__\":\n\t# 下载到当前目录，使用原文件名\n\tresult = download_file(\"cloud://xxx.png\")\n\n\t# 下载到指定目录\n\tresult = download_file(\"cloud://xxx.png\", \"./downloads/\")\n\n\t# 下载并重命名\n\tresult = download_file(\"cloud://xxx.png\", \"./my-image.png\")\n```",
                "index": 3,
                "title": "下载文件",
                "content": []
              },
              {
                "markdown": "```python\nfrom cloudbase_client import cloudbase\n\ndef delete_file(cloud_object_ids):\n\t\"\"\"删除云存储文件\"\"\"\n\t# 如果传入的是单个字符串，转换为列表\n\tif isinstance(cloud_object_ids, str):\n\t\tcloud_object_ids = [cloud_object_ids]\n\n\tdata = [{\"cloudObjectId\": obj_id} for obj_id in cloud_object_ids]\n\tresult = cloudbase.request(\"POST\", \"/v1/storages/delete-objects\", json=data)\n\n\tif result:\n\t\tprint(\"删除成功!\")\n\t\treturn True\n\treturn False\n\n# 使用示例\nif __name__ == \"__main__\":\n\tresult = delete_file(\"cloud://xxx.png\")\n```",
                "index": 4,
                "title": "删除文件",
                "content": []
              }
            ]
          },
          {
            "index": 6,
            "id": "ai-model",
            "title": "大模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```python\nimport requests\nimport json\nfrom cloudbase_client import cloudbase\n\ndef stream_text(model, sub_model, messages):\n\t\"\"\"流式文本生成\"\"\"\n\tpayload = {\n\t\t\"model\": sub_model,\n\t\t\"messages\": messages,\n\t\t\"stream\": True\n\t}\n\n\turl = f\"{cloudbase.base_url}/v1/ai/{model}/chat/completions\"\n\theaders = cloudbase.headers.copy()\n\theaders[\"Accept\"] = \"text/event-stream\"\n\n\ttry:\n\t\tresponse = requests.post(url, headers=headers, json=payload, stream=True)\n\t\tresponse.raise_for_status()\n\n\t\tprint(\"AI 流式响应:\")\n\t\tfull_content = \"\"\n\n\t\tfor line in response.iter_lines():\n\t\t\tif line:\n\t\t\t\tline_str = line.decode(\"utf-8\")\n\t\t\t\tif line_str.startswith(\"data: \"):\n\t\t\t\t\tdata_str = line_str[6:]\n\t\t\t\t\tif data_str.strip() != \"[DONE]\":\n\t\t\t\t\t\ttry:\n\t\t\t\t\t\t\tchunk_data = json.loads(data_str)\n\t\t\t\t\t\t\tcontent = chunk_data.get(\"choices\", [{}])[0].get(\"delta\", {}).get(\"content\", \"\")\n\t\t\t\t\t\t\tif content:\n\t\t\t\t\t\t\t\tprint(content, end=\"\", flush=True)\n\t\t\t\t\t\t\t\tfull_content += content\n\t\t\t\t\t\texcept json.JSONDecodeError:\n\t\t\t\t\t\t\tcontinue\n\n\t\tprint()  # 换行\n\t\treturn full_content\n\texcept Exception as e:\n\t\tprint(f\"AI 调用失败: {e}\")\n\t\treturn None\n\n# 使用示例\nif __name__ == \"__main__\":\n\tresponse = stream_text(\n\t\t\"{%AI_MODEL_NAME%}\",\n\t\t\"{%AI_SUB_MODEL_NAME%}\",\n\t\t[\n\t\t\t{\"role\": \"system\", \"content\": \"请严格按照七言绝句或七言律诗的格律要求创作，平仄需符合规则，押韵要和谐自然，韵脚字需在同一韵部。\"},\n\t\t\t{\"role\": \"user\", \"content\": \"春天\"}\n\t\t]\n\t)\n```",
                "index": 1,
                "id": "text-aiModel",
                "title": "生文模型",
                "content": []
              },
              {
                "markdown": "生图模型通过调用云函数来实现，在生图模型页面点击「一键创建云函数」，函数调用示例如下：\n\n```python\nimport requests\nfrom cloudbase_client import cloudbase\n\ndef generate_image(prompt):\n\t\"\"\"调用生图云函数\"\"\"\n\turl = f\"{cloudbase.base_url}/v1/functions/<YOUR_FUNCTION_NAME>/invoke\"\n\theaders = cloudbase.headers\n\tpayload = {\n\t\t\"prompt\": prompt\n\t}\n\n\ttry:\n\t\tresponse = requests.post(url, headers=headers, json=payload)\n\t\tresponse.raise_for_status()\n\t\tresult = response.json()\n\n\t\tif result.get(\"success\"):\n\t\t\t# 生成成功\n\t\t\tprint(\"生成成功!\")\n\t\t\tprint(f\"图片URL: {result.get('imageUrl')}\")\n\t\t\tprint(f\"优化后的提示词: {result.get('revised_prompt')}\")\n\n\t\t\t# 使用图片\n\t\t\t# 注意：图片URL有效期为24小时，请及时保存或转存\n\t\t\treturn result\n\t\telse:\n\t\t\t# 生成失败\n\t\t\tprint(f\"生成失败: {result.get('code')} {result.get('message')}\")\n\t\t\treturn None\n\texcept Exception as e:\n\t\tprint(f\"调用失败: {e}\")\n\t\treturn None\n\n# 使用示例\nif __name__ == \"__main__\":\n\tresult = generate_image(\"一只可爱的猫咪在阳光下玩耍\")\n\tif result:\n\t\tprint(f\"图片URL: {result.get('imageUrl')}\")\n```",
                "index": 2,
                "id": "image-aiModel",
                "title": "生图模型",
                "content": []
              }
            ]
          },
          {
            "markdown": "",
            "index": 7,
            "id": "agent",
            "title": "Agent",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```python\n\"\"\"\nPython 调用 Agent 示例（AG-UI 协议）\n协议文档：https://docs.cloudbase.net/ai/agent-development/protocol\n\"\"\"\nimport requests\nimport json\nimport uuid\nfrom cloudbase_client import cloudbase\n\ndef chat_with_agent_stream(bot_id, msg, history=None):\n    \"\"\"\n    流式调用Agent（AG-UI 协议）\n    \n    AG-UI 协议参数说明：\n    - messages: 必填，消息列表，包含 id/role/content\n    - threadId: 可选，会话ID，用于多轮对话管理\n    - runId: 可选，运行ID，用于追踪单次执行\n    - tools: 可选，前端工具定义\n    - context: 可选，上下文信息\n    - forwardedProps: 可选，透传参数\n    \"\"\"\n    if history is None:\n        history = []\n\n    url = f\"{cloudbase.base_url}/v1/aibot/bots/{bot_id}/send-message\"\n\n    # 构建消息列表（AG-UI 协议格式）\n    messages = []\n    \n    # 添加历史消息\n    for h in history:\n        messages.append({\n            \"id\": h.get(\"id\", f\"msg-{uuid.uuid4()}\"),\n            \"role\": h.get(\"role\", \"user\"),\n            \"content\": h.get(\"content\", \"\")\n        })\n    \n    # 添加当前用户消息\n    messages.append({\n        \"id\": f\"msg-{uuid.uuid4()}\",\n        \"role\": \"user\",\n        \"content\": msg\n    })\n\n    # AG-UI 协议请求体\n    payload = {\n        \"messages\": messages,                      # 必填：消息列表\n        \"threadId\": f\"thread-{uuid.uuid4()}\",     # 可选：会话ID\n        \"runId\": f\"run-{uuid.uuid4()}\",           # 可选：运行ID\n        \"tools\": [],                               # 可选：前端工具定义\n        \"context\": [],                             # 可选：上下文信息\n        \"forwardedProps\": {}                       # 可选：透传参数\n    }\n\n    headers = cloudbase.headers.copy()\n    headers[\"Accept\"] = \"text/event-stream\"\n\n    try:\n        response = requests.post(\n            url,\n            headers=headers,\n            json=payload,\n            stream=True,\n            timeout=30\n        )\n        response.raise_for_status()\n\n        print(\"AI 流式响应:\")\n        full_content = \"\"\n        buffer = \"\"\n\n        for chunk in response.iter_content(chunk_size=None, decode_unicode=False):\n            if chunk:\n                try:\n                    # 解码字节流\n                    buffer += chunk.decode('utf-8')\n\n                    # 处理完整的行\n                    while '\\n' in buffer:\n                        line, buffer = buffer.split('\\n', 1)\n                        line = line.strip()\n\n                        if line.startswith(\"data: \"):\n                            data_str = line[6:].strip()\n                            if data_str and data_str != \"[DONE]\":\n                                try:\n                                    chunk_data = json.loads(data_str)\n                                    # 支持多种响应格式\n                                    content = (\n                                        chunk_data.get(\"content\") or\n                                        chunk_data.get(\"choices\", [{}])[0].get(\"delta\", {}).get(\"content\", \"\") or\n                                        chunk_data.get(\"choices\", [{}])[0].get(\"message\", {}).get(\"content\", \"\")\n                                    )\n                                    if content:\n                                        print(content, end=\"\", flush=True)\n                                        full_content += content\n                                except json.JSONDecodeError:\n                                    pass\n                except UnicodeDecodeError:\n                    continue\n\n        print()  # 换行\n        return full_content\n\n    except requests.exceptions.Timeout:\n        print(\"请求超时，请检查网络连接或增加超时时间\")\n        return None\n    except requests.exceptions.RequestException as e:\n        print(f\"AI 调用失败: {e}\")\n        if hasattr(e.response, 'text'):\n            print(f\"响应内容: {e.response.text}\")\n        return None\n\n# 使用示例\nif __name__ == \"__main__\":\n    response = chat_with_agent_stream(\"{%AGENT_ID%}\", \"你是谁\")\n\n```",
                "index": 0,
                "id": "scf",
                "title": "函数型"
              },
              {
                "markdown": "```python\nimport requests\nimport json\nfrom cloudbase_client import cloudbase\n\ndef chat_with_agent_stream(bot_id, msg, history=None):\n\t\"\"\"流式调用Agent\"\"\"\n\tif history is None:\n\t\thistory = []\n\n\turl = f\"{cloudbase.base_url}/v1/aibot/bots/{bot_id}/send-message\"\n\n\tpayload = {\n\t\t\"history\": history,\n\t\t\"msg\": msg\n\t}\n\n\theaders = cloudbase.headers.copy()\n\theaders[\"Accept\"] = \"text/event-stream\"\n\n\ttry:\n\t\tresponse = requests.post(\n\t\t\turl,\n\t\t\theaders=headers,\n\t\t\tjson=payload,\n\t\t\tstream=True,\n\t\t\ttimeout=30\n\t\t)\n\t\tresponse.raise_for_status()\n\n\t\tprint(\"AI 流式响应:\")\n\t\tfull_content = \"\"\n\t\tbuffer = \"\"\n\n\t\tfor chunk in response.iter_content(chunk_size=None, decode_unicode=False):\n\t\t\tif chunk:\n\t\t\t\ttry:\n\t\t\t\t\t# 解码字节流\n\t\t\t\t\tbuffer += chunk.decode('utf-8')\n\n\t\t\t\t\t# 处理完整的行\n\t\t\t\t\twhile '\\n' in buffer:\n\t\t\t\t\t\tline, buffer = buffer.split('\\n', 1)\n\t\t\t\t\t\tline = line.strip()\n\n\t\t\t\t\t\tif line.startswith(\"data: \"):\n\t\t\t\t\t\t\tdata_str = line[6:].strip()\n\t\t\t\t\t\t\tif data_str and data_str != \"[DONE]\":\n\t\t\t\t\t\t\t\ttry:\n\t\t\t\t\t\t\t\t\tchunk_data = json.loads(data_str)\n\t\t\t\t\t\t\t\t\t# 支持多种响应格式\n\t\t\t\t\t\t\t\t\tcontent = (\n\t\t\t\t\t\t\t\t\t\tchunk_data.get(\"content\") or\n\t\t\t\t\t\t\t\t\t\tchunk_data.get(\"choices\", [{}])[0].get(\"delta\", {}).get(\"content\", \"\") or\n\t\t\t\t\t\t\t\t\t\tchunk_data.get(\"choices\", [{}])[0].get(\"message\", {}).get(\"content\", \"\")\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\tif content:\n\t\t\t\t\t\t\t\t\t\tprint(content, end=\"\", flush=True)\n\t\t\t\t\t\t\t\t\t\tfull_content += content\n\t\t\t\t\t\t\t\texcept json.JSONDecodeError:\n\t\t\t\t\t\t\t\t\tpass\n\t\t\t\texcept UnicodeDecodeError:\n\t\t\t\t\tcontinue\n\n\t\tprint()  # 换行\n\t\treturn full_content\n\n\texcept requests.exceptions.Timeout:\n\t\tprint(\"请求超时，请检查网络连接或增加超时时间\")\n\t\treturn None\n\texcept requests.exceptions.RequestException as e:\n\t\tprint(f\"AI 调用失败: {e}\")\n\t\tif hasattr(e.response, 'text'):\n\t\t\tprint(f\"响应内容: {e.response.text}\")\n\t\treturn None\n\n# 使用示例\nif __name__ == \"__main__\":\n\tresponse = chat_with_agent_stream(\"{%AGENT_ID%}\", \"你是谁\")\n```",
                "index": 1,
                "id": "baas",
                "title": "普通型"
              }
            ]
          },
          {
            "markdown": "```python\nfrom cloudbase_client import cloudbase\n\ndef sign_in(username, password):\n\t\"\"\"账号密码登录\"\"\"\n\tresult = cloudbase.request(\"POST\", \"/auth/v1/signin\",\n\t\tjson={\"username\": username, \"password\": password})\n\n\tif result:\n\t\taccess_token = result.get(\"access_token\")\n\t\trefresh_token = result.get(\"refresh_token\")\n\t\tuser_id = result.get(\"sub\")\n\n\t\tprint(f\"登录成功! 用户ID: {user_id}\")\n\t\tprint(f\"访问令牌: {access_token[:20]}...\")\n\t\treturn result\n\treturn None\n\n# 使用示例\nif __name__ == \"__main__\":\n\tresult = sign_in(\"your_username\", \"your_password\")\n```",
            "index": 8,
            "id": "identity",
            "title": "身份认证"
          }
        ]
      }
    ],
    "_id": "ba046a626964c1d20bc6cd3725c872be",
    "_openid": "anon",
    "createdAt": 1768210898487,
    "updatedAt": 1770370290870
  },
  {
    "category": "CloudBase MCP,微信开发者工具",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": 50,
    "hasTemplate": true,
    "docsUrl": "https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/ide-setup/wechat-devtools",
    "content": [
      {
        "docsUrl": "",
        "markdown": "",
        "title": "安装",
        "type": "list",
        "content": [
          {
            "markdown": "<p style=\"margin-bottom: 0;font-weight: bold\">\n步骤 1：安装 CodeBuddy 扩展\n</p>\n<ol style=\"color: #00000080; font-size: 12px;margin-top: 0;margin-bottom: 8px;\">\n<li style=\"margin-top:0\">在微信开发者工具 2.0 以上版本中，你可以使用快捷键 Ctrl + Shift + X（Windows/Linux）或 Shift + Command + X（macOS）快速打开扩展面板</li>\n<li style=\"margin-top:0\">在扩展市场中搜索「CodeBuddy」</li>\n<li style=\"margin-top:0\">安装「腾讯云代码助手 CodeBuddy」扩展\n</li>\n</ol>\n\n<p style=\"margin-bottom: 0;margin-top: 8px;font-weight: bold\">\n步骤 2：安装 CloudBase MCP\n</p>\n<ol style=\"color: #00000080; font-size: 12px;margin-top: 0;\">\n<li style=\"margin-top:0\">安装完成后，在工具栏找到 CodeBuddy 图标</li>\n<li style=\"margin-top:0\">点击右上角的 CodeBuddy 设置图标</li>\n<li style=\"margin-top:0\">在 MCP 市场中搜索并安装「CloudBase MCP」</li>\n</ol>",
            "title": "手动配置"
          }
        ]
      },
      {
        "markdown": "配置完成后，即可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我创建一个待办事项应用，使用文档数据库存储数据\n```",
        "title": "和 AI 对话",
        "type": "",
        "content": []
      }
    ],
    "_id": "cac74faa6969f12000074931170a82b7",
    "_openid": "1524963278340493312",
    "createdAt": 1768550688086,
    "updatedAt": 1768550688086
  },
  {
    "category": "框架集成,移动端框架,iOS Swift",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": 32,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/http-api/basic/overview",
    "content": [
      {
        "markdown": "通过 **HTTP 请求** 在 **iOS Swift** 中调用各种云开发能力\n\n本项目使用 Swift 原生 URLSession，无需额外依赖。\n\n如需使用第三方库，可通过 CocoaPods 或 Swift Package Manager 安装：\n\n```ruby\n# Podfile\npod 'Alamofire', '~> 5.8'\n```",
        "index": 1,
        "title": "安装依赖",
        "content": []
      },
      {
        "markdown": "新增如下代码到您的 **iOS Swift** 项目",
        "index": 2,
        "title": "初始化配置",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```swift\nimport Foundation\n\nclass CloudBaseClient {\n    let envId: String\n    private(set) var accessToken: String\n    let baseUrl: String\n\n    init(envId: String, accessToken: String) {\n        self.envId = envId\n        self.accessToken = accessToken\n        self.baseUrl = \"https://\\(envId).api.tcloudbasegateway.com\"\n    }\n\n    /// 更新访问令牌\n    ///\n    /// - Parameter newToken: 新的访问令牌\n    func updateAccessToken(_ newToken: String) {\n        self.accessToken = newToken\n        print(\"访问令牌已更新\")\n    }\n\n    /// 统一的HTTP请求方法\n    ///\n    /// - Parameters:\n    ///   - method: 请求方法 (GET, POST, PUT, PATCH, DELETE)\n    ///   - path: API路径 (如 /v1/rdb/rest/table_name)\n    ///   - body: 请求体数据\n    ///   - customHeaders: 自定义headers\n    /// - Returns: 响应数据或nil\n    func request<T: Decodable>(\n        method: String,\n        path: String,\n        body: [String: Any]? = nil,\n        customHeaders: [String: String] = [:],\n        completion: @escaping (T?) -> Void\n    ) {\n        guard let url = URL(string: \"\\(baseUrl)\\(path)\") else {\n            print(\"无效的URL\")\n            completion(nil)\n            return\n        }\n\n        var request = URLRequest(url: url)\n        request.httpMethod = method.uppercased()\n        request.setValue(\"application/json\", forHTTPHeaderField: \"Content-Type\")\n        request.setValue(\"application/json\", forHTTPHeaderField: \"Accept\")\n        request.setValue(\"Bearer \\(accessToken)\", forHTTPHeaderField: \"Authorization\")\n\n        // 添加自定义headers\n        customHeaders.forEach { key, value in\n            request.setValue(value, forHTTPHeaderField: key)\n        }\n\n        // 设置请求体\n        if let body = body {\n            do {\n                request.httpBody = try JSONSerialization.data(withJSONObject: body)\n            } catch {\n                print(\"JSON序列化失败: \\(error)\")\n                completion(nil)\n                return\n            }\n        }\n\n        let task = URLSession.shared.dataTask(with: request) { data, response, error in\n            if let error = error {\n                print(\"请求失败: \\(error.localizedDescription)\")\n                completion(nil)\n                return\n            }\n\n            guard let httpResponse = response as? HTTPURLResponse,\n                  (200...299).contains(httpResponse.statusCode) else {\n                print(\"请求失败: \\((response as? HTTPURLResponse)?.statusCode ?? -1)\")\n                completion(nil)\n                return\n            }\n\n            guard let data = data else {\n                // 如果响应为空，返回true表示成功\n                if T.self == Bool.self {\n                    completion(true as? T)\n                } else {\n                    completion(nil)\n                }\n                return\n            }\n\n            do {\n                let decoder = JSONDecoder()\n                let result = try decoder.decode(T.self, from: data)\n                completion(result)\n            } catch {\n                // 尝试作为Any解码\n                if let json = try? JSONSerialization.jsonObject(with: data) as? T {\n                    completion(json)\n                } else {\n                    print(\"JSON解析失败: \\(error)\")\n                    completion(nil)\n                }\n            }\n        }\n\n        task.resume()\n    }\n\n    /// 同步版本（使用 async/await）\n    @available(iOS 13.0, *)\n    func request<T: Decodable>(\n        method: String,\n        path: String,\n        body: [String: Any]? = nil,\n        customHeaders: [String: String] = [:]\n    ) async -> T? {\n        await withCheckedContinuation { continuation in\n            request(method: method, path: path, body: body, customHeaders: customHeaders) { (result: T?) in\n                continuation.resume(returning: result)\n            }\n        }\n    }\n}\n\n// 配置文件或初始化时创建实例\n// let cloudbase = CloudBaseClient(\n//     envId: \"your-env-id\",\n//     accessToken: \"your-access-token\"\n// )\n```",
            "index": 1,
            "title": "CloudBaseClient.swift"
          },
          {
            "markdown": "创建 `Config.plist` 文件存储配置：\n\n> 💡 提示：用户权限请参考「身份认证」模块获取 access_token\n\n```xml\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n    <!-- 环境ID -->\n    <key>CLOUDBASE_ENV_ID</key>\n    <string>{%ENV_ID%}</string>\n    <!-- 匿名访问令牌 -->\n    <key>CLOUDBASE_ACCESS_TOKEN</key>\n    <string>{%PUBLISHABLE_KEY%}</string>\n</dict>\n</plist>\n```\n\n读取配置并初始化客户端：\n\n```swift\nfunc loadConfig() -> (envId: String, accessToken: String)? {\n    guard let path = Bundle.main.path(forResource: \"Config\", ofType: \"plist\"),\n          let config = NSDictionary(contentsOfFile: path),\n          let envId = config[\"CLOUDBASE_ENV_ID\"] as? String,\n          let accessToken = config[\"CLOUDBASE_ACCESS_TOKEN\"] as? String else {\n        return nil\n    }\n    return (envId, accessToken)\n}\n\n// 在 AppDelegate 或 SceneDelegate 中初始化\nclass AppDelegate: UIResponder, UIApplicationDelegate {\n    var cloudbase: CloudBaseClient?\n\n    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {\n        // 从配置文件加载环境信息\n        if let config = loadConfig() {\n            cloudbase = CloudBaseClient(envId: config.envId, accessToken: config.accessToken)\n            print(\"云开发客户端初始化成功\")\n        } else {\n            print(\"配置文件加载失败\")\n        }\n        return true\n    }\n}\n\n// 或者在需要的地方直接初始化\n// if let config = loadConfig() {\n//     let cloudbase = CloudBaseClient(envId: config.envId, accessToken: config.accessToken)\n//     // 使用 cloudbase 进行后续操作\n// }\n```",
            "index": 2,
            "title": "Config.plist"
          }
        ]
      },
      {
        "sideTabs": [
          {
            "id": "pg-db",
            "title": "PostgreSQL 数据库"
          }
        ],
        "index": 3,
        "title": "调用云开发能力",
        "type": "codeTab",
        "content": [
          {
            "index": 1,
            "id": "pg-db",
            "title": "PostgreSQL 数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```swift\nfunc getPgData(cloudbase: CloudBaseClient, tableName: String, completion: @escaping ([[String: Any]]?) -> Void) {\n    // 查询 PG 数据库数据\n    cloudbase.request(\n        method: \"GET\",\n        path: \"/v1/rdb/rest/\\(tableName)?select=*&limit=10\"\n    ) { (data: [[String: Any]]?) in\n        if let data = data {\n            print(\"查询成功: \\(data)\")\n        }\n        completion(data ?? [])\n    }\n}\n\n// 使用示例（async/await）\n// Task {\n//     let result: [[String: Any]]? = await cloudbase.request(\n//         method: \"GET\",\n//         path: \"/v1/rdb/rest/{%TABLE_NAME%}?select=*&limit=10\"\n//     )\n//     print(result)\n// }\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "```swift\nfunc addPgData(cloudbase: CloudBaseClient, tableName: String, data: [String: Any], completion: @escaping ([String: Any]?) -> Void) {\n    // 新增 PG 数据库数据\n    cloudbase.request(\n        method: \"POST\",\n        path: \"/v1/rdb/rest/\\(tableName)\",\n        body: data\n    ) { (result: [String: Any]?) in\n        if let result = result {\n            print(\"新增成功: \\(result)\")\n        }\n        completion(result)\n    }\n}\n\n// 使用示例（async/await）\n// Task {\n//     let result: [String: Any]? = await cloudbase.request(\n//         method: \"POST\",\n//         path: \"/v1/rdb/rest/{%TABLE_NAME%}\",\n//         body: [\"title\": \"示例标题\"]\n//     )\n//     print(result)\n// }\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "```swift\nfunc updatePgData(cloudbase: CloudBaseClient, tableName: String, dataId: String, data: [String: Any], completion: @escaping (Any?) -> Void) {\n    // 更新 PG 数据库数据\n    cloudbase.request(\n        method: \"PATCH\",\n        path: \"/v1/rdb/rest/\\(tableName)?id=eq.\\(dataId)\",\n        body: data\n    ) { (result: Any?) in\n        if result != nil {\n            print(\"更新成功: \\(result ?? \"\")\")\n        }\n        completion(result)\n    }\n}\n\n// 使用示例（async/await）\n// Task {\n//     let result: Any? = await cloudbase.request(\n//         method: \"PATCH\",\n//         path: \"/v1/rdb/rest/{%TABLE_NAME%}?id=eq.<数据id>\",\n//         body: [\"title\": \"新标题\"]\n//     )\n//     print(result)\n// }\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "```swift\nfunc upsertPgData(cloudbase: CloudBaseClient, tableName: String, data: [String: Any], completion: @escaping (Any?) -> Void) {\n    // 更新或创建 PG 数据库数据\n    cloudbase.request(\n        method: \"POST\",\n        path: \"/v1/rdb/rest/\\(tableName)\",\n        body: data\n    ) { (result: Any?) in\n        if result != nil {\n            print(\"更新或创建成功: \\(result ?? \"\")\")\n        }\n        completion(result)\n    }\n}\n\n// 使用示例（async/await）\n// Task {\n//     let result: Any? = await cloudbase.request(\n//         method: \"POST\",\n//         path: \"/v1/rdb/rest/{%TABLE_NAME%}\",\n//         body: [\"id\": 1, \"title\": \"标题\"]\n//     )\n//     print(result)\n// }\n```",
                "index": 4,
                "title": "更新或创建数据"
              },
              {
                "markdown": "```swift\nfunc deletePgData(cloudbase: CloudBaseClient, tableName: String, dataId: String, completion: @escaping (Bool) -> Void) {\n    // 删除 PG 数据库数据\n    cloudbase.request(\n        method: \"DELETE\",\n        path: \"/v1/rdb/rest/\\(tableName)?id=eq.\\(dataId)\"\n    ) { (result: Bool?) in\n        if result == true {\n            print(\"删除成功\")\n            completion(true)\n        } else {\n            completion(false)\n        }\n    }\n}\n\n// 使用示例（async/await）\n// Task {\n//     let result: Bool? = await cloudbase.request(\n//         method: \"DELETE\",\n//         path: \"/v1/rdb/rest/{%TABLE_NAME%}?id=eq.<数据id>\"\n//     )\n//     print(result ?? false)\n// }\n```",
                "index": 5,
                "title": "删除数据"
              }
            ]
          },
          {
            "index": 1,
            "id": "mysql-db",
            "title": "MySQL数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```swift\nfunc getMysqlData(cloudbase: CloudBaseClient, tableName: String, completion: @escaping ([[String: Any]]?) -> Void) {\n    // 查询 MySQL 数据库数据\n    cloudbase.request(\n        method: \"GET\",\n        path: \"/v1/rdb/rest/\\(tableName)?limit=10\"\n    ) { (data: [[String: Any]]?) in\n        if let data = data {\n            print(\"查询成功: \\(data)\")\n        }\n        completion(data ?? [])\n    }\n}\n\n// 使用示例（async/await）\n// Task {\n//     let result: [[String: Any]]? = await cloudbase.request(\n//         method: \"GET\",\n//         path: \"/v1/rdb/rest/{%TABLE_NAME%}?limit=10\"\n//     )\n//     print(result)\n// }\n```",
                "index": 1,
                "title": "查询数据",
                "content": []
              },
              {
                "markdown": "```swift\nfunc addMysqlData(cloudbase: CloudBaseClient, tableName: String, data: [String: Any], completion: @escaping ([String: Any]?) -> Void) {\n    // 新增 MySQL 数据库数据\n    cloudbase.request(\n        method: \"POST\",\n        path: \"/v1/rdb/rest/\\(tableName)\",\n        body: data\n    ) { (result: [String: Any]?) in\n        if let result = result {\n            print(\"新增成功: \\(result)\")\n        }\n        completion(result)\n    }\n}\n\n// 使用示例（async/await）\n// Task {\n//     let result: [String: Any]? = await cloudbase.request(\n//         method: \"POST\",\n//         path: \"/v1/rdb/rest/{%TABLE_NAME%}\",\n//         body: [\"title\": \"示例标题\"]\n//     )\n//     print(result)\n// }\n```",
                "index": 2,
                "title": "新增数据",
                "content": []
              },
              {
                "markdown": "```swift\nfunc updateMysqlData(cloudbase: CloudBaseClient, tableName: String, dataId: String, data: [String: Any], completion: @escaping (Any?) -> Void) {\n    // 更新 MySQL 数据库数据\n    cloudbase.request(\n        method: \"PATCH\",\n        path: \"/v1/rdb/rest/\\(tableName)?id=eq.\\(dataId)\",\n        body: data\n    ) { (result: Any?) in\n        if result != nil {\n            print(\"更新成功: \\(result ?? \"\")\")\n        }\n        completion(result)\n    }\n}\n\n// 使用示例（async/await）\n// Task {\n//     let result: Any? = await cloudbase.request(\n//         method: \"PATCH\",\n//         path: \"/v1/rdb/rest/{%TABLE_NAME%}?id=eq.<数据id>\",\n//         body: [\"title\": \"新标题\"]\n//     )\n//     print(result)\n// }\n```",
                "index": 3,
                "title": "更新数据",
                "content": []
              },
              {
                "markdown": "```swift\nfunc deleteMysqlData(cloudbase: CloudBaseClient, tableName: String, dataId: String, completion: @escaping (Bool) -> Void) {\n    // 删除 MySQL 数据库数据\n    cloudbase.request(\n        method: \"DELETE\",\n        path: \"/v1/rdb/rest/\\(tableName)?id=eq.\\(dataId)\"\n    ) { (result: Bool?) in\n        if result == true {\n            print(\"删除成功\")\n            completion(true)\n        } else {\n            completion(false)\n        }\n    }\n}\n\n// 使用示例（async/await）\n// Task {\n//     let result: Bool? = await cloudbase.request(\n//         method: \"DELETE\",\n//         path: \"/v1/rdb/rest/{%TABLE_NAME%}?id=eq.<数据id>\"\n//     )\n//     print(result ?? false)\n// }\n```",
                "index": 4,
                "title": "删除数据",
                "content": []
              }
            ]
          },
          {
            "index": 2,
            "id": "data-model",
            "title": "数据模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```swift\nfunc getModelData(cloudbase: CloudBaseClient, modelName: String, envType: String = \"prod\", completion: @escaping ([[String: Any]]) -> Void) {\n    // 查询数据模型数据\n    let payload: [String: Any] = [\n        \"pageSize\": 10,\n        \"pageNumber\": 1,\n        \"getCount\": true\n    ]\n\n    cloudbase.request(\n        method: \"POST\",\n        path: \"/v1/model/\\(envType)/\\(modelName)/list\",\n        body: payload\n    ) { (result: [String: Any]?) in\n        if let result = result,\n           let data = result[\"data\"] as? [String: Any],\n           let records = data[\"records\"] as? [[String: Any]] {\n            print(\"查询成功: \\(records)\")\n            completion(records)\n        } else {\n            completion([])\n        }\n    }\n}\n\n// 使用示例（async/await）\n// Task {\n//     let result: [String: Any]? = await cloudbase.request(\n//         method: \"POST\",\n//         path: \"/v1/model/prod/{%TABLE_NAME%}/list\",\n//         body: [\"pageSize\": 10, \"pageNumber\": 1, \"getCount\": true]\n//     )\n//     print(result)\n// }\n```",
                "index": 1,
                "title": "查询数据",
                "content": []
              },
              {
                "markdown": "```swift\nfunc addModelData(cloudbase: CloudBaseClient, modelName: String, data: [String: Any], envType: String = \"prod\", completion: @escaping ([String: Any]?) -> Void) {\n    // 新增数据模型数据\n    let payload: [String: Any] = [\"data\": data]\n\n    cloudbase.request(\n        method: \"POST\",\n        path: \"/v1/model/\\(envType)/\\(modelName)/create\",\n        body: payload\n    ) { (result: [String: Any]?) in\n        if let result = result,\n           let data = result[\"data\"] as? [String: Any],\n           let docId = data[\"id\"] {\n            print(\"新增成功! id: \\(docId)\")\n        }\n        completion(result)\n    }\n}\n\n// 使用示例（async/await）\n// Task {\n//     let result: [String: Any]? = await cloudbase.request(\n//         method: \"POST\",\n//         path: \"/v1/model/prod/{%TABLE_NAME%}/create\",\n//         body: [\"data\": [\"title\": \"示例标题\"]]\n//     )\n//     print(result)\n// }\n```",
                "index": 2,
                "title": "新增数据",
                "content": []
              },
              {
                "markdown": "```swift\nfunc updateModelData(cloudbase: CloudBaseClient, modelName: String, dataId: String, data: [String: Any], envType: String = \"prod\", completion: @escaping (Bool) -> Void) {\n    // 更新数据模型数据\n    let payload: [String: Any] = [\n        \"data\": data,\n        \"filter\": [\n            \"where\": [\n                \"_id\": [\"$eq\": dataId]\n            ]\n        ]\n    ]\n\n    cloudbase.request(\n        method: \"PUT\",\n        path: \"/v1/model/\\(envType)/\\(modelName)/update\",\n        body: payload\n    ) { (result: Any?) in\n        if result != nil {\n            print(\"更新成功!\")\n            completion(true)\n        } else {\n            completion(false)\n        }\n    }\n}\n\n// 使用示例（async/await）\n// Task {\n//     let payload: [String: Any] = [\n//         \"data\": [\"title\": \"新标题\"],\n//         \"filter\": [\"where\": [\"_id\": [\"$eq\": \"<数据id>\"]]]\n//     ]\n//     let result: Any? = await cloudbase.request(\n//         method: \"PUT\",\n//         path: \"/v1/model/prod/{%TABLE_NAME%}/update\",\n//         body: payload\n//     )\n//     print(result != nil)\n// }\n```",
                "index": 3,
                "title": "更新数据",
                "content": []
              },
              {
                "markdown": "```swift\nfunc deleteModelData(cloudbase: CloudBaseClient, modelName: String, dataId: String, envType: String = \"prod\", completion: @escaping (Bool) -> Void) {\n    // 删除数据模型数据\n    let payload: [String: Any] = [\n        \"filter\": [\n            \"where\": [\n                \"_id\": [\"$eq\": dataId]\n            ]\n        ]\n    ]\n\n    cloudbase.request(\n        method: \"POST\",\n        path: \"/v1/model/\\(envType)/\\(modelName)/delete\",\n        body: payload\n    ) { (result: Any?) in\n        if result != nil {\n            print(\"删除成功!\")\n            completion(true)\n        } else {\n            completion(false)\n        }\n    }\n}\n\n// 使用示例（async/await）\n// Task {\n//     let payload: [String: Any] = [\n//         \"filter\": [\"where\": [\"_id\": [\"$eq\": \"<数据id>\"]]]\n//     ]\n//     let result: Any? = await cloudbase.request(\n//         method: \"POST\",\n//         path: \"/v1/model/prod/{%TABLE_NAME%}/delete\",\n//         body: payload\n//     )\n//     print(result != nil)\n// }\n```",
                "index": 4,
                "title": "删除数据",
                "content": []
              }
            ]
          },
          {
            "markdown": "```swift\nfunc callFunction(cloudbase: CloudBaseClient, functionName: String, data: [String: Any]? = nil, completion: @escaping ([String: Any]?) -> Void) {\n    // 调用云函数\n    cloudbase.request(\n        method: \"POST\",\n        path: \"/v1/functions/\\(functionName)\",\n        body: data ?? [:]\n    ) { (result: [String: Any]?) in\n        if let result = result {\n            print(\"云函数调用结果: \\(result)\")\n        }\n        completion(result)\n    }\n}\n\n// 使用示例（async/await）\n// Task {\n//     let result: [String: Any]? = await cloudbase.request(\n//         method: \"POST\",\n//         path: \"/v1/functions/{%FUNCTION_NAME%}\",\n//         body: [:]\n//     )\n//     print(result)\n// }\n```",
            "index": 3,
            "id": "scf",
            "title": "云函数"
          },
          {
            "markdown": "```swift\nfunc callContainer(cloudbase: CloudBaseClient, serviceName: String, path: String = \"\", method: String = \"GET\", data: [String: Any]? = nil, completion: @escaping (Any?) -> Void) {\n    // 调用云托管服务\n    var fullPath = \"/v1/cloudrun/\\(serviceName)/\\(path)\"\n    if fullPath.hasSuffix(\"/\") {\n        fullPath = String(fullPath.dropLast())\n    }\n\n    cloudbase.request(\n        method: method.uppercased(),\n        path: fullPath,\n        body: data\n    ) { (result: Any?) in\n        if let result = result {\n            print(\"云托管调用结果: \\(result)\")\n        }\n        completion(result)\n    }\n}\n\n// 使用示例（async/await）\n// Task {\n//     let result: Any? = await cloudbase.request(\n//         method: \"GET\",\n//         path: \"/v1/cloudrun/{%SERVICE_NAME%}\"\n//     )\n//     print(result)\n// }\n```",
            "index": 4,
            "id": "run",
            "title": "云托管"
          },
          {
            "index": 5,
            "id": "storage",
            "title": "云存储",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```swift\nfunc uploadFile(cloudbase: CloudBaseClient, filePath: String, objectId: String? = nil, completion: @escaping ([String: String]?) -> Void) {\n    // 上传文件到云存储\n    guard let fileUrl = URL(string: filePath),\n          let fileData = try? Data(contentsOf: fileUrl) else {\n        print(\"文件不存在: \\(filePath)\")\n        completion(nil)\n        return\n    }\n\n    let filename = fileUrl.lastPathComponent\n    let timestamp = Int(Date().timeIntervalSince1970 * 1000)\n    let finalObjectId = objectId ?? \"uploads/\\(timestamp)-\\(filename)\"\n\n    // 1. 获取上传信息\n    cloudbase.request(\n        method: \"POST\",\n        path: \"/v1/storages/get-objects-upload-info\",\n        body: [[\"objectId\": finalObjectId]]\n    ) { (uploadInfo: [[String: Any]]?) in\n        guard let uploadInfo = uploadInfo, !uploadInfo.isEmpty else {\n            completion(nil)\n            return\n        }\n\n        let info = uploadInfo[0]\n        guard let uploadUrl = info[\"uploadUrl\"] as? String,\n              let authorization = info[\"authorization\"] as? String,\n              let token = info[\"token\"] as? String,\n              let cloudObjectMeta = info[\"cloudObjectMeta\"] as? String else {\n            completion(nil)\n            return\n        }\n\n        // 2. 上传文件\n        guard let url = URL(string: uploadUrl) else {\n            completion(nil)\n            return\n        }\n\n        var request = URLRequest(url: url)\n        request.httpMethod = \"PUT\"\n        request.setValue(authorization, forHTTPHeaderField: \"Authorization\")\n        request.setValue(token, forHTTPHeaderField: \"X-Cos-Security-Token\")\n        request.setValue(cloudObjectMeta, forHTTPHeaderField: \"X-Cos-Meta-Fileid\")\n        request.httpBody = fileData\n\n        let task = URLSession.shared.dataTask(with: request) { _, response, error in\n            if let error = error {\n                print(\"文件上传失败: \\(error.localizedDescription)\")\n                completion(nil)\n                return\n            }\n\n            guard let httpResponse = response as? HTTPURLResponse,\n                  (200...299).contains(httpResponse.statusCode) else {\n                print(\"文件上传失败\")\n                completion(nil)\n                return\n            }\n\n            let result = [\n                \"cloudObjectId\": info[\"cloudObjectId\"] as? String ?? \"\",\n                \"downloadUrl\": info[\"downloadUrl\"] as? String ?? \"\",\n                \"objectId\": finalObjectId\n            ]\n\n            print(\"文件上传成功:\")\n            print(\"- 对象ID: \\(result[\"objectId\"] ?? \"\")\")\n            print(\"- 下载URL: \\(result[\"downloadUrl\"] ?? \"\")\")\n\n            completion(result)\n        }\n\n        task.resume()\n    }\n}\n\n// 使用示例\n// uploadFile(cloudbase: cloudbase, filePath: \"./example.jpg\") { result in\n//     print(result)\n// }\n```",
                "index": 1,
                "title": "上传文件",
                "content": []
              },
              {
                "markdown": "```swift\nfunc getFileUrl(cloudbase: CloudBaseClient, cloudObjectId: String, completion: @escaping (String?) -> Void) {\n    // 获取云存储文件的临时访问链接\n    cloudbase.request(\n        method: \"POST\",\n        path: \"/v1/storages/get-objects-download-info\",\n        body: [[\"cloudObjectId\": cloudObjectId]]\n    ) { (result: [[String: Any]]?) in\n        if let result = result, !result.isEmpty,\n           let downloadUrl = result[0][\"downloadUrl\"] as? String {\n            print(\"文件链接: \\(downloadUrl)\")\n            completion(downloadUrl)\n        } else {\n            completion(nil)\n        }\n    }\n}\n\n// 使用示例（async/await）\n// Task {\n//     let result: [[String: Any]]? = await cloudbase.request(\n//         method: \"POST\",\n//         path: \"/v1/storages/get-objects-download-info\",\n//         body: [[\"cloudObjectId\": \"cloud://xxx.png\"]]\n//     )\n//     if let downloadUrl = result?.first?[\"downloadUrl\"] as? String {\n//         print(downloadUrl)\n//     }\n// }\n```",
                "index": 2,
                "title": "获取文件链接",
                "content": []
              },
              {
                "markdown": "```swift\nfunc downloadFile(cloudbase: CloudBaseClient, cloudObjectId: String, savePath: String = \"./\", completion: @escaping (Bool) -> Void) {\n    // 下载云存储文件到本地\n    // 1. 获取下载链接\n    cloudbase.request(\n        method: \"POST\",\n        path: \"/v1/storages/get-objects-download-info\",\n        body: [[\"cloudObjectId\": cloudObjectId]]\n    ) { (result: [[String: Any]]?) in\n        guard let result = result, !result.isEmpty,\n              let downloadUrl = result[0][\"downloadUrl\"] as? String else {\n            completion(false)\n            return\n        }\n\n        guard let url = URL(string: downloadUrl) else {\n            completion(false)\n            return\n        }\n\n        // 2. 下载文件\n        let task = URLSession.shared.downloadTask(with: url) { tempUrl, _, error in\n            if let error = error {\n                print(\"下载失败: \\(error.localizedDescription)\")\n                completion(false)\n                return\n            }\n\n            guard let tempUrl = tempUrl else {\n                completion(false)\n                return\n            }\n\n            // 3. 确定保存路径\n            let filename = url.lastPathComponent.components(separatedBy: \"?\").first ?? \"file\"\n            let fileManager = FileManager.default\n            var fullPath: URL\n\n            if savePath.hasSuffix(\"/\") {\n                fullPath = URL(fileURLWithPath: savePath).appendingPathComponent(filename)\n            } else {\n                fullPath = URL(fileURLWithPath: savePath)\n            }\n\n            // 4. 保存文件\n            do {\n                if fileManager.fileExists(atPath: fullPath.path) {\n                    try fileManager.removeItem(at: fullPath)\n                }\n                try fileManager.moveItem(at: tempUrl, to: fullPath)\n                print(\"下载成功! 文件已保存到: \\(fullPath.path)\")\n                completion(true)\n            } catch {\n                print(\"下载失败: \\(error.localizedDescription)\")\n                completion(false)\n            }\n        }\n\n        task.resume()\n    }\n}\n\n// 使用示例\n// downloadFile(cloudbase: cloudbase, cloudObjectId: \"cloud://xxx.png\", savePath: \"./downloads/\") { success in\n//     print(success)\n// }\n```",
                "index": 3,
                "title": "下载文件",
                "content": []
              },
              {
                "markdown": "```swift\nfunc deleteFile(cloudbase: CloudBaseClient, cloudObjectIds: Any, completion: @escaping (Bool) -> Void) {\n    // 删除云存储文件\n    var ids: [String] = []\n\n    if let idString = cloudObjectIds as? String {\n        ids = [idString]\n    } else if let idArray = cloudObjectIds as? [String] {\n        ids = idArray\n    } else {\n        print(\"参数类型错误\")\n        completion(false)\n        return\n    }\n\n    let data = ids.map { [\"cloudObjectId\": $0] }\n\n    cloudbase.request(\n        method: \"POST\",\n        path: \"/v1/storages/delete-objects\",\n        body: data\n    ) { (result: Any?) in\n        if result != nil {\n            print(\"删除成功!\")\n            completion(true)\n        } else {\n            completion(false)\n        }\n    }\n}\n\n// 使用示例（async/await）\n// Task {\n//     let data = [[\"cloudObjectId\": \"cloud://xxx.png\"]]\n//     let result: Any? = await cloudbase.request(\n//         method: \"POST\",\n//         path: \"/v1/storages/delete-objects\",\n//         body: data\n//     )\n//     print(result != nil)\n// }\n```",
                "index": 4,
                "title": "删除文件",
                "content": []
              }
            ]
          },
          {
            "index": 6,
            "id": "ai-model",
            "title": "大模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```swift\nfunc streamText(cloudbase: CloudBaseClient, model: String, subModel: String, messages: [[String: String]], completion: @escaping (String?) -> Void) {\n    // 流式文本生成\n    let payload: [String: Any] = [\n        \"model\": subModel,\n        \"messages\": messages,\n        \"stream\": true\n    ]\n\n    guard let url = URL(string: \"\\(cloudbase.baseUrl)/v1/ai/\\(model)/chat/completions\") else {\n        completion(nil)\n        return\n    }\n\n    var request = URLRequest(url: url)\n    request.httpMethod = \"POST\"\n    request.setValue(\"application/json\", forHTTPHeaderField: \"Content-Type\")\n    request.setValue(\"text/event-stream\", forHTTPHeaderField: \"Accept\")\n    request.setValue(\"Bearer \\(cloudbase.accessToken)\", forHTTPHeaderField: \"Authorization\")\n\n    do {\n        request.httpBody = try JSONSerialization.data(withJSONObject: payload)\n    } catch {\n        print(\"JSON序列化失败: \\(error)\")\n        completion(nil)\n        return\n    }\n\n    let task = URLSession.shared.dataTask(with: request) { data, response, error in\n        if let error = error {\n            print(\"AI 调用失败: \\(error.localizedDescription)\")\n            completion(nil)\n            return\n        }\n\n        guard let data = data,\n              let responseString = String(data: data, encoding: .utf8) else {\n            completion(nil)\n            return\n        }\n\n        print(\"AI 流式响应:\")\n        var fullContent = \"\"\n\n        let lines = responseString.components(separatedBy: \"\\n\")\n        for line in lines {\n            if line.hasPrefix(\"data: \") {\n                let dataStr = String(line.dropFirst(6))\n                if dataStr.trimmingCharacters(in: .whitespaces) != \"[DONE]\" {\n                    if let data = dataStr.data(using: .utf8),\n                       let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any],\n                       let choices = json[\"choices\"] as? [[String: Any]],\n                       let delta = choices.first?[\"delta\"] as? [String: Any],\n                       let content = delta[\"content\"] as? String {\n                        print(content, terminator: \"\")\n                        fullContent += content\n                    }\n                }\n            }\n        }\n\n        print()\n        completion(fullContent)\n    }\n\n    task.resume()\n}\n\n// 使用示例\n// streamText(\n//     cloudbase: cloudbase,\n//     model: \"{%AI_MODEL_NAME%}\",\n//     subModel: \"{%AI_SUB_MODEL_NAME%}\",\n//     messages: [\n//         [\"role\": \"system\", \"content\": \"请严格按照七言绝句或七言律诗的格律要求创作\"],\n//         [\"role\": \"user\", \"content\": \"春天\"]\n//     ]\n// ) { response in\n//     print(\"\\n完整回复: \\(response ?? \"\")\")\n// }\n```",
                "index": 1,
                "id": "text-aiModel",
                "title": "生文模型",
                "content": []
              },
              {
                "markdown": "生图模型通过调用云函数来实现，在生图模型页面点击「一键创建云函数」，函数调用示例如下：\n\n```swift\nfunc generateImage(cloudbase: CloudBaseClient, prompt: String, completion: @escaping ([String: Any]?) -> Void) {\n    // 准备调用参数\n    let data: [String: Any] = [\"prompt\": prompt]\n    \n    // 调用云函数生成图片\n    cloudbase.request(\n        method: \"POST\",\n        path: \"/v1/functions/<YOUR_FUNCTION_NAME>\",\n        body: data\n    ) { (result: [String: Any]?) in\n        if let result = result {\n            if let success = result[\"success\"] as? Bool, success {\n                let imageUrl = result[\"imageUrl\"] as? String ?? \"\"\n                let revisedPrompt = result[\"revised_prompt\"] as? String ?? \"\"\n                \n                print(\"生成成功!\")\n                print(\"图片URL: \\(imageUrl)\")\n                print(\"优化后的提示词: \\(revisedPrompt)\")\n                print(\"注意: 图片URL有效期为24小时\")\n                \n                completion(result)\n            } else {\n                let code = result[\"code\"] as? String ?? \"\"\n                let message = result[\"message\"] as? String ?? \"\"\n                print(\"生成失败: \\(code) - \\(message)\")\n                completion(nil)\n            }\n        } else {\n            print(\"请求失败\")\n            completion(nil)\n        }\n    }\n}\n\n// 使用示例\n// generateImage(cloudbase: cloudbase, prompt: \"一只可爱的猫咪在阳光下玩耍\") { result in\n//     if let result = result {\n//         print(\"图片生成完成: \\(result)\")\n//     }\n// }\n```",
                "index": 2,
                "id": "image-aiModel",
                "title": "生图模型",
                "content": []
              }
            ]
          },
          {
            "markdown": "",
            "index": 7,
            "id": "agent",
            "title": "Agent",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```swift\n/**\n * iOS Swift 调用 Agent 示例（AG-UI 协议）\n * 协议文档：https://docs.cloudbase.net/ai/agent-development/protocol\n */\nfunc chatWithAgentStream(cloudbase: CloudBaseClient, botId: String, userMessage: String, completion: @escaping (String?) -> Void) {\n    // 构建消息列表（AG-UI 协议格式）\n    let messages: [[String: Any]] = [\n        [\n            \"id\": \"msg_001\",\n            \"role\": \"user\",\n            \"content\": userMessage\n        ]\n    ]\n\n    // AG-UI 协议请求参数\n    let payload: [String: Any] = [\n        \"messages\": messages,                                    // 必填：消息列表\n        \"threadId\": \"550e8400-e29b-41d4-a716-446655440000\",     // 可选：会话ID，用于多轮对话\n        \"runId\": \"run_001\",                                      // 可选：运行ID，用于追踪执行\n        \"tools\": [],                                             // 可选：前端工具定义\n        \"context\": [],                                           // 可选：上下文信息\n        \"forwardedProps\": [:]                                    // 可选：透传参数\n    ]\n\n    guard let url = URL(string: \"\\(cloudbase.baseUrl)/v1/aibot/bots/\\(botId)/send-message\") else {\n        completion(nil)\n        return\n    }\n\n    var request = URLRequest(url: url)\n    request.httpMethod = \"POST\"\n    request.setValue(\"application/json\", forHTTPHeaderField: \"Content-Type\")\n    request.setValue(\"text/event-stream\", forHTTPHeaderField: \"Accept\")\n    request.setValue(\"Bearer \\(cloudbase.accessToken)\", forHTTPHeaderField: \"Authorization\")\n\n    do {\n        request.httpBody = try JSONSerialization.data(withJSONObject: payload)\n    } catch {\n        print(\"JSON序列化失败: \\(error)\")\n        completion(nil)\n        return\n    }\n\n    let task = URLSession.shared.dataTask(with: request) { data, response, error in\n        if let error = error {\n            print(\"AI 调用失败: \\(error.localizedDescription)\")\n            completion(nil)\n            return\n        }\n\n        guard let data = data,\n              let responseString = String(data: data, encoding: .utf8) else {\n            completion(nil)\n            return\n        }\n\n        print(\"AI 流式响应:\")\n        var fullContent = \"\"\n\n        let lines = responseString.components(separatedBy: \"\\n\")\n        for line in lines {\n            if line.hasPrefix(\"data: \") {\n                let dataStr = String(line.dropFirst(6)).trimmingCharacters(in: .whitespaces)\n                if !dataStr.isEmpty && dataStr != \"[DONE]\" {\n                    if let data = dataStr.data(using: .utf8),\n                       let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any] {\n                        var content = \"\"\n\n                        if let directContent = json[\"content\"] as? String {\n                            content = directContent\n                        } else if let choices = json[\"choices\"] as? [[String: Any]] {\n                            if let delta = choices.first?[\"delta\"] as? [String: Any],\n                               let deltaContent = delta[\"content\"] as? String {\n                                content = deltaContent\n                            } else if let message = choices.first?[\"message\"] as? [String: Any],\n                                      let messageContent = message[\"content\"] as? String {\n                                content = messageContent\n                            }\n                        }\n\n                        if !content.isEmpty {\n                            print(content, terminator: \"\")\n                            fullContent += content\n                        }\n                    }\n                }\n            }\n        }\n\n        print()\n        completion(fullContent)\n    }\n\n    task.resume()\n}\n\n// 使用示例\n// chatWithAgentStream(cloudbase: cloudbase, botId: \"{%AGENT_ID%}\", userMessage: \"你是谁\") { response in\n//     print(\"\\n完整回复: \\(response ?? \"\")\")\n// }\n\n```",
                "index": 0,
                "id": "scf",
                "title": "函数型"
              },
              {
                "markdown": "```swift\nfunc chatWithAgentStream(cloudbase: CloudBaseClient, botId: String, msg: String, history: [[String: String]]? = nil, completion: @escaping (String?) -> Void) {\n    // 流式调用Agent\n    let payload: [String: Any] = [\n        \"history\": history ?? [],\n        \"msg\": msg\n    ]\n\n    guard let url = URL(string: \"\\(cloudbase.baseUrl)/v1/aibot/bots/\\(botId)/send-message\") else {\n        completion(nil)\n        return\n    }\n\n    var request = URLRequest(url: url)\n    request.httpMethod = \"POST\"\n    request.setValue(\"application/json\", forHTTPHeaderField: \"Content-Type\")\n    request.setValue(\"text/event-stream\", forHTTPHeaderField: \"Accept\")\n    request.setValue(\"Bearer \\(cloudbase.accessToken)\", forHTTPHeaderField: \"Authorization\")\n\n    do {\n        request.httpBody = try JSONSerialization.data(withJSONObject: payload)\n    } catch {\n        print(\"JSON序列化失败: \\(error)\")\n        completion(nil)\n        return\n    }\n\n    let task = URLSession.shared.dataTask(with: request) { data, response, error in\n        if let error = error {\n            print(\"AI 调用失败: \\(error.localizedDescription)\")\n            completion(nil)\n            return\n        }\n\n        guard let data = data,\n              let responseString = String(data: data, encoding: .utf8) else {\n            completion(nil)\n            return\n        }\n\n        print(\"AI 流式响应:\")\n        var fullContent = \"\"\n\n        let lines = responseString.components(separatedBy: \"\\n\")\n        for line in lines {\n            if line.hasPrefix(\"data: \") {\n                let dataStr = String(line.dropFirst(6)).trimmingCharacters(in: .whitespaces)\n                if !dataStr.isEmpty && dataStr != \"[DONE]\" {\n                    if let data = dataStr.data(using: .utf8),\n                       let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any] {\n                        var content = \"\"\n\n                        if let directContent = json[\"content\"] as? String {\n                            content = directContent\n                        } else if let choices = json[\"choices\"] as? [[String: Any]] {\n                            if let delta = choices.first?[\"delta\"] as? [String: Any],\n                               let deltaContent = delta[\"content\"] as? String {\n                                content = deltaContent\n                            } else if let message = choices.first?[\"message\"] as? [String: Any],\n                                      let messageContent = message[\"content\"] as? String {\n                                content = messageContent\n                            }\n                        }\n\n                        if !content.isEmpty {\n                            print(content, terminator: \"\")\n                            fullContent += content\n                        }\n                    }\n                }\n            }\n        }\n\n        print()\n        completion(fullContent)\n    }\n\n    task.resume()\n}\n\n// 使用示例\n// chatWithAgentStream(cloudbase: cloudbase, botId: \"{%AGENT_ID%}\", msg: \"你是谁\") { response in\n//     print(\"\\n完整回复: \\(response ?? \"\")\")\n// }\n```",
                "index": 1,
                "id": "baas",
                "title": "普通型"
              }
            ]
          },
          {
            "index": 8,
            "id": "identity",
            "title": "身份认证",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```swift\nfunc signUpWithPhoneCode(cloudbase: CloudBaseClient, phoneNumber: String, verificationCode: String, username: String? = nil, password: String? = nil, captchaToken: String? = nil, completion: @escaping ([String: Any]?) -> Void) {\n    // 步骤1: 发送短信验证码\n    var body: [String: Any] = [\n        \"phone_number\": phoneNumber.hasPrefix(\"+86\") ? phoneNumber : \"+86\\(phoneNumber)\",\n        \"target\": \"NON_USER\"  // \"NON_USER\" - 账号不存在才发送; \"ANY\" - 不限制\n    ]\n\n    var headers: [String: String] = [:]\n    if let token = captchaToken {\n        headers[\"x-captcha-token\"] = token\n    }\n\n    cloudbase.request(\n        method: \"POST\",\n        path: \"/auth/v1/verification\",\n        body: body,\n        customHeaders: headers\n    ) { (sendResult: [String: Any]?) in\n        guard let sendResult = sendResult,\n              let verificationId = sendResult[\"verification_id\"] as? String else {\n            print(\"发送验证码失败\")\n            completion(nil)\n            return\n        }\n\n        print(\"验证码发送成功! ID: \\(verificationId)\")\n\n        // 步骤2: 验证验证码\n        cloudbase.request(\n            method: \"POST\",\n            path: \"/auth/v1/verification/verify\",\n            body: [\n                \"verification_id\": verificationId,\n                \"verification_code\": verificationCode\n            ]\n        ) { (verifyResult: [String: Any]?) in\n            guard let verifyResult = verifyResult,\n                  let verificationToken = verifyResult[\"verification_token\"] as? String else {\n                print(\"验证码错误\")\n                completion(nil)\n                return\n            }\n\n            print(\"验证成功!\")\n\n            // 步骤3: 使用验证令牌注册\n            var signUpBody: [String: Any] = [\n                \"phone_number\": phoneNumber.hasPrefix(\"+86\") ? phoneNumber : \"+86\\(phoneNumber)\",\n                \"verification_token\": verificationToken\n            ]\n\n            // 可选：添加用户名和密码\n            if let username = username {\n                signUpBody[\"username\"] = username\n            }\n            if let password = password {\n                signUpBody[\"password\"] = password\n            }\n\n            cloudbase.request(\n                method: \"POST\",\n                path: \"/auth/v1/signup\",\n                body: signUpBody\n            ) { (signUpResult: [String: Any]?) in\n                if let signUpResult = signUpResult,\n                   let accessToken = signUpResult[\"access_token\"] as? String,\n                   let userId = signUpResult[\"sub\"] as? String {\n                    print(\"注册成功! 用户ID: \\(userId)\")\n                    print(\"访问令牌: \\(String(accessToken.prefix(20)))...\")\n\n                    // 更新访问令牌\n                    cloudbase.updateAccessToken(accessToken)\n                    completion(signUpResult)\n                } else {\n                    print(\"注册失败\")\n                    completion(nil)\n                }\n            }\n        }\n    }\n}\n\n// 使用示例\n// signUpWithPhoneCode(\n//     cloudbase: cloudbase,\n//     phoneNumber: \"13800138000\",\n//     verificationCode: \"123456\",\n//     username: \"myusername\",\n//     password: \"mypassword\"\n// ) { result in\n//     if result != nil {\n//         print(\"手机号注册成功\")\n//     }\n// }\n```",
                "index": 1,
                "title": "短信验证码注册",
                "content": []
              },
              {
                "markdown": "```swift\nfunc signUpWithEmailCode(cloudbase: CloudBaseClient, email: String, verificationCode: String, username: String? = nil, password: String? = nil, captchaToken: String? = nil, completion: @escaping ([String: Any]?) -> Void) {\n    // 步骤1: 发送邮箱验证码\n    var body: [String: Any] = [\n        \"email\": email,\n        \"target\": \"NON_USER\"  // \"NON_USER\" - 账号不存在才发送; \"ANY\" - 不限制\n    ]\n\n    var headers: [String: String] = [:]\n    if let token = captchaToken {\n        headers[\"x-captcha-token\"] = token\n    }\n\n    cloudbase.request(\n        method: \"POST\",\n        path: \"/auth/v1/verification\",\n        body: body,\n        customHeaders: headers\n    ) { (sendResult: [String: Any]?) in\n        guard let sendResult = sendResult,\n              let verificationId = sendResult[\"verification_id\"] as? String else {\n            print(\"发送验证码失败\")\n            completion(nil)\n            return\n        }\n\n        print(\"验证码发送成功! ID: \\(verificationId)\")\n\n        // 步骤2: 验证验证码\n        cloudbase.request(\n            method: \"POST\",\n            path: \"/auth/v1/verification/verify\",\n            body: [\n                \"verification_id\": verificationId,\n                \"verification_code\": verificationCode\n            ]\n        ) { (verifyResult: [String: Any]?) in\n            guard let verifyResult = verifyResult,\n                  let verificationToken = verifyResult[\"verification_token\"] as? String else {\n                print(\"验证码错误\")\n                completion(nil)\n                return\n            }\n\n            print(\"验证成功!\")\n\n            // 步骤3: 使用验证令牌注册\n            var signUpBody: [String: Any] = [\n                \"email\": email,\n                \"verification_token\": verificationToken\n            ]\n\n            // 可选：添加用户名和密码\n            if let username = username {\n                signUpBody[\"username\"] = username\n            }\n            if let password = password {\n                signUpBody[\"password\"] = password\n            }\n\n            cloudbase.request(\n                method: \"POST\",\n                path: \"/auth/v1/signup\",\n                body: signUpBody\n            ) { (signUpResult: [String: Any]?) in\n                if let signUpResult = signUpResult,\n                   let accessToken = signUpResult[\"access_token\"] as? String,\n                   let userId = signUpResult[\"sub\"] as? String {\n                    print(\"注册成功! 用户ID: \\(userId)\")\n                    print(\"访问令牌: \\(String(accessToken.prefix(20)))...\")\n\n                    // 更新访问令牌\n                    cloudbase.updateAccessToken(accessToken)\n                    completion(signUpResult)\n                } else {\n                    print(\"注册失败\")\n                    completion(nil)\n                }\n            }\n        }\n    }\n}\n\n// 使用示例\n// signUpWithEmailCode(\n//     cloudbase: cloudbase,\n//     email: \"user@example.com\",\n//     verificationCode: \"123456\",\n//     username: \"myusername\",\n//     password: \"mypassword\"\n// ) { result in\n//     if result != nil {\n//         print(\"邮箱注册成功\")\n//     }\n// }\n```",
                "index": 2,
                "title": "邮箱验证码注册",
                "content": []
              },
              {
                "markdown": "```swift\nfunc signIn(cloudbase: CloudBaseClient, username: String, password: String, completion: @escaping ([String: Any]?) -> Void) {\n    // 账号密码登录\n    cloudbase.request(\n        method: \"POST\",\n        path: \"/auth/v1/signin\",\n        body: [\"username\": username, \"password\": password]\n    ) { (result: [String: Any]?) in\n        if let result = result,\n           let accessToken = result[\"access_token\"] as? String,\n           let userId = result[\"sub\"] as? String {\n            print(\"登录成功! 用户ID: \\(userId)\")\n            print(\"访问令牌: \\(String(accessToken.prefix(20)))...\")\n\n            // 更新访问令牌\n            cloudbase.updateAccessToken(accessToken)\n        }\n        completion(result)\n    }\n}\n\n// 使用示例（async/await）\n// Task {\n//     let result: [String: Any]? = await cloudbase.request(\n//         method: \"POST\",\n//         path: \"/auth/v1/signin\",\n//         body: [\"username\": \"your_username\", \"password\": \"your_password\"]\n//     )\n//     if let result = result,\n//        let accessToken = result[\"access_token\"] as? String {\n//         // 更新访问令牌\n//         cloudbase.updateAccessToken(accessToken)\n//     }\n//     print(result)\n// }\n```",
                "index": 3,
                "id": "UserNameLogin",
                "title": "账号密码登录",
                "content": []
              },
              {
                "markdown": "```swift\nfunc loginWithPhoneCode(cloudbase: CloudBaseClient, phoneNumber: String, verificationCode: String, captchaToken: String? = nil, completion: @escaping (Bool) -> Void) {\n    // 步骤1: 发送短信验证码\n    var body: [String: Any] = [\n        \"phone_number\": phoneNumber.hasPrefix(\"+86\") ? phoneNumber : \"+86\\(phoneNumber)\",\n        \"target\": \"ANY\"  // \"ANY\" - 不限制，无论用户是否存在都发送; \"USER\" - 账号必须存在才发送\n    ]\n\n    var headers: [String: String] = [:]\n    if let token = captchaToken {\n        headers[\"x-captcha-token\"] = token\n    }\n\n    cloudbase.request(\n        method: \"POST\",\n        path: \"/auth/v1/verification\",\n        body: body,\n        customHeaders: headers\n    ) { (sendResult: [String: Any]?) in\n        guard let sendResult = sendResult,\n              let verificationId = sendResult[\"verification_id\"] as? String else {\n            print(\"发送验证码失败\")\n            completion(false)\n            return\n        }\n\n        print(\"验证码发送成功! ID: \\(verificationId)\")\n\n        // 步骤2: 验证验证码\n        cloudbase.request(\n            method: \"POST\",\n            path: \"/auth/v1/verification/verify\",\n            body: [\n                \"verification_id\": verificationId,\n                \"verification_code\": verificationCode\n            ]\n        ) { (verifyResult: [String: Any]?) in\n            guard let verifyResult = verifyResult,\n                  let verificationToken = verifyResult[\"verification_token\"] as? String else {\n                print(\"验证码错误\")\n                completion(false)\n                return\n            }\n\n            print(\"验证成功!\")\n\n            // 步骤3: 使用验证令牌登录\n            cloudbase.request(\n                method: \"POST\",\n                path: \"/auth/v1/signin\",\n                body: [\n                    \"phone_number\": phoneNumber.hasPrefix(\"+86\") ? phoneNumber : \"+86\\(phoneNumber)\",\n                    \"verification_token\": verificationToken\n                ]\n            ) { (loginResult: [String: Any]?) in\n                if let loginResult = loginResult,\n                   let accessToken = loginResult[\"access_token\"] as? String {\n                    print(\"登录成功!\")\n                    cloudbase.updateAccessToken(accessToken)\n                    completion(true)\n                } else {\n                    print(\"登录失败\")\n                    completion(false)\n                }\n            }\n        }\n    }\n}\n\n// 使用示例\n// loginWithPhoneCode(\n//     cloudbase: cloudbase,\n//     phoneNumber: \"13800138000\",\n//     verificationCode: \"123456\"\n// ) { success in\n//     if success {\n//         print(\"手机号登录成功\")\n//     }\n// }\n```",
                "index": 4,
                "id": "PhoneNumberLogin",
                "title": "短信验证码登录",
                "content": []
              },
              {
                "markdown": "```swift\nfunc loginWithEmailCode(cloudbase: CloudBaseClient, email: String, verificationCode: String, captchaToken: String? = nil, completion: @escaping (Bool) -> Void) {\n    // 步骤1: 发送邮箱验证码\n    var body: [String: Any] = [\n        \"email\": email,\n        \"target\": \"ANY\"  // \"ANY\" - 不限制，无论用户是否存在都发送; \"USER\" - 账号必须存在才发送\n    ]\n\n    var headers: [String: String] = [:]\n    if let token = captchaToken {\n        headers[\"x-captcha-token\"] = token\n    }\n\n    cloudbase.request(\n        method: \"POST\",\n        path: \"/auth/v1/verification\",\n        body: body,\n        customHeaders: headers\n    ) { (sendResult: [String: Any]?) in\n        guard let sendResult = sendResult,\n              let verificationId = sendResult[\"verification_id\"] as? String else {\n            print(\"发送验证码失败\")\n            completion(false)\n            return\n        }\n\n        print(\"验证码发送成功! ID: \\(verificationId)\")\n\n        // 步骤2: 验证验证码\n        cloudbase.request(\n            method: \"POST\",\n            path: \"/auth/v1/verification/verify\",\n            body: [\n                \"verification_id\": verificationId,\n                \"verification_code\": verificationCode\n            ]\n        ) { (verifyResult: [String: Any]?) in\n            guard let verifyResult = verifyResult,\n                  let verificationToken = verifyResult[\"verification_token\"] as? String else {\n                print(\"验证码错误\")\n                completion(false)\n                return\n            }\n\n            print(\"验证成功!\")\n\n            // 步骤3: 使用验证令牌登录\n            cloudbase.request(\n                method: \"POST\",\n                path: \"/auth/v1/signin\",\n                body: [\n                    \"email\": email,\n                    \"verification_token\": verificationToken\n                ]\n            ) { (loginResult: [String: Any]?) in\n                if let loginResult = loginResult,\n                   let accessToken = loginResult[\"access_token\"] as? String {\n                    print(\"登录成功!\")\n                    cloudbase.updateAccessToken(accessToken)\n                    completion(true)\n                } else {\n                    print(\"登录失败\")\n                    completion(false)\n                }\n            }\n        }\n    }\n}\n\n// 使用示例\n// loginWithEmailCode(\n//     cloudbase: cloudbase,\n//     email: \"user@example.com\",\n//     verificationCode: \"123456\"\n// ) { success in\n//     if success {\n//         print(\"邮箱登录成功\")\n//     }\n// }\n```",
                "index": 5,
                "id": "email",
                "title": "邮箱验证码登录",
                "content": []
              }
            ]
          }
        ]
      }
    ],
    "_id": "cc84495d6964cbdd0bb6c5f4588d0d0d",
    "_openid": "anon",
    "createdAt": 1768213469398,
    "updatedAt": 1770371793242
  },
  {
    "category": "CloudBase MCP,OpenClaw",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": -1,
    "hasTemplate": false,
    "content": [
      {
        "markdown": "可在 AI 对话中操作云开发资源。点击 [MCP工具](https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/mcp-tools) 查看工具提供的完整功能列表\n\n``` \n帮我把 CloudBase 接好：打开 https://docs.cloudbase.net/skill.md 按说明完成接入，完成后告诉我并建议最相关的下一步。\n```\n``` \n使用 CloudBase Skills 帮我开发一个解忧信箱的 AI 网页应用。用户写下烦恼，AI 以温和的陌生人口吻回信\n```",
        "title": "和 AI 对话",
        "type": "tab",
        "content": []
      }
    ],
    "_id": "d3a457a269c0ba5e013d0202783bb096",
    "_openid": "1524963278340493312",
    "createdAt": 1774238301674,
    "updatedAt": 1778664984030
  },
  {
    "category": "框架集成,前端框架,UniApp",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": 12,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/api-reference/webv2/adapter/uniapp-adapter",
    "content": [
      {
        "markdown": "`@cloudbase/js-sdk` 配合 `@cloudbase/adapter-uni-app` 可以让您在 uni-app 项目中使用 JavaScript 访问 CloudBase 服务和资源。",
        "index": 1,
        "title": "安装 SDK",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```bash\nnpm i @cloudbase/js-sdk @cloudbase/adapter-uni-app\n```",
            "index": 1,
            "title": "npm",
            "content": []
          },
          {
            "markdown": "```bash\nyarn add @cloudbase/js-sdk @cloudbase/adapter-uni-app\n```",
            "index": 2,
            "title": "yarn",
            "content": []
          },
          {
            "markdown": "```bash\npnpm add @cloudbase/js-sdk @cloudbase/adapter-uni-app\n```",
            "index": 3,
            "title": "pnpm",
            "content": []
          }
        ]
      },
      {
        "markdown": "新增如下代码到您的 uni-app 项目",
        "index": 2,
        "title": "初始化 SDK",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```js\nimport cloudbaseSDK from \"@cloudbase/js-sdk\";\nimport adapter from \"@cloudbase/adapter-uni-app\";\n\n// 传入配置选项\nconst options = {\n  uni: uni // 传入 uni 对象，用于图形验证码功能\n};\n\ncloudbaseSDK.useAdapters(adapter, options);\n\nconst cloudbase = cloudbaseSDK.init({\n  // 环境 ID\n  env: \"{%ENV_ID%}\",\n  // 地域\n  region: \"{%REGION%}\",\n  // 匿名访问令牌\n  accessKey: \"{%PUBLISHABLE_KEY%}\"\n});\n\nexport default cloudbase;\n```",
            "index": 1,
            "title": "./utils/cloudbase.js",
            "content": []
          }
        ]
      },
      {
        "index": 3,
        "title": "调用云开发能力",
        "type": "codeTab",
        "content": [
          {
            "index": 1,
            "id": "mysql-db",
            "title": "MySQL数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\n// 查询 {%TABLE_NAME%} 表前10条数据\nconst db = cloudbase.database();\nconst res = await db.collection(\"{%TABLE_NAME%}\").limit(10).get();\nconsole.log(res.data);\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <button @click=\"getData\">查询数据</button>\n    <view v-if=\"dataList.length > 0\">\n      <view v-for=\"(item, index) in dataList\" :key=\"index\" class=\"data-item\">\n        <text>{{ JSON.stringify(item) }}</text>\n      </view>\n    </view>\n    <text v-else>暂无数据</text>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      dataList: []\n    };\n  },\n  methods: {\n    // 查询数据\n    async getData() {\n      try {\n        const { data, error } = await cloudbase\n          .database()\n          .from(\"{%TABLE_NAME%}\")\n          .select(\"*\")\n          .limit(10);\n\n        if (!error) {\n          this.dataList = data;\n          uni.showToast({\n            title: \"查询成功\",\n            icon: \"success\"\n          });\n        } else {\n          uni.showToast({\n            title: \"查询失败\",\n            icon: \"none\"\n          });\n        }\n      } catch (error) {\n        uni.showToast({\n          title: \"查询失败：\" + error.message,\n          icon: \"none\"\n        });\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\n// 新增 {%TABLE_NAME%} 表数据\nconst db = cloudbase.database();\nconst res = await db.collection(\"{%TABLE_NAME%}\").add({ title: \"示例标题\" });\nconsole.log(`新增成功! id: ${res.id}`);\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>标题：</text>\n      <input v-model=\"title\" placeholder=\"请输入标题\" />\n    </view>\n    <button :disabled=\"!title\" @click=\"addData\">新增数据</button>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      title: \"\"\n    };\n  },\n  methods: {\n    // 新增数据\n    async addData() {\n      try {\n        const { data, error } = await cloudbase\n          .database()\n          .from(\"{%TABLE_NAME%}\")\n          .insert({ title: this.title });\n\n        if (!error) {\n          uni.showToast({\n            title: \"新增成功\",\n            icon: \"success\"\n          });\n          this.title = \"\";\n        } else {\n          uni.showToast({\n            title: \"新增失败\",\n            icon: \"none\"\n          });\n        }\n      } catch (error) {\n        uni.showToast({\n          title: \"新增失败：\" + error.message,\n          icon: \"none\"\n        });\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 更新 {%TABLE_NAME%} 表中 id 为指定值的数据\nconst { error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .update({ title: \"新标题\" })\n  .eq(\"id\", \"<数据id>\");\nif (!error) {\n  console.log(\"更新成功\");\n}\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>数据ID：</text>\n      <input v-model=\"dataId\" placeholder=\"请输入数据ID\" />\n    </view>\n    <view>\n      <text>新标题：</text>\n      <input v-model=\"newTitle\" placeholder=\"请输入新标题\" />\n    </view>\n    <button :disabled=\"!dataId || !newTitle\" @click=\"updateData\">\n      更新数据\n    </button>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      dataId: \"\",\n      newTitle: \"\"\n    };\n  },\n  methods: {\n    // 更新数据\n    async updateData() {\n      try {\n        const { data, error } = await cloudbase\n          .database()\n          .from(\"{%TABLE_NAME%}\")\n          .update({ title: this.newTitle })\n          .eq(\"id\", this.dataId);\n\n        if (!error) {\n          uni.showToast({\n            title: \"更新成功\",\n            icon: \"success\"\n          });\n          this.dataId = \"\";\n          this.newTitle = \"\";\n        } else {\n          uni.showToast({\n            title: \"更新失败\",\n            icon: \"none\"\n          });\n        }\n      } catch (error) {\n        uni.showToast({\n          title: \"更新失败：\" + error.message,\n          icon: \"none\"\n        });\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 如果 {%TABLE_NAME%} 表中存在 id 为 1 的记录则更新 title 为\"示例标题\"，不存在则插入新记录\nconst { error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .upsert({ id: 1, title: \"示例标题\" });\nif (!error) {\n  console.log(\"操作成功\");\n}\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>ID：</text>\n      <input v-model=\"id\" type=\"number\" placeholder=\"请输入ID\" />\n    </view>\n    <view>\n      <text>标题：</text>\n      <input v-model=\"title\" placeholder=\"请输入标题\" />\n    </view>\n    <button :disabled=\"!id || !title\" @click=\"upsertData\">更新或创建</button>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      id: \"\",\n      title: \"\"\n    };\n  },\n  methods: {\n    // 更新或创建数据\n    async upsertData() {\n      try {\n        const { data, error } = await cloudbase\n          .database()\n          .from(\"{%TABLE_NAME%}\")\n          .upsert({ id: parseInt(this.id), title: this.title });\n\n        if (!error) {\n          uni.showToast({\n            title: \"操作成功\",\n            icon: \"success\"\n          });\n          this.id = \"\";\n          this.title = \"\";\n        } else {\n          uni.showToast({\n            title: \"操作失败\",\n            icon: \"none\"\n          });\n        }\n      } catch (error) {\n        uni.showToast({\n          title: \"操作失败：\" + error.message,\n          icon: \"none\"\n        });\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 4,
                "title": "更新或创建数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 删除 {%TABLE_NAME%} 表中 id 为指定值的数据\nconst { error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .delete()\n  .eq(\"id\", \"<数据id>\");\nif (!error) {\n  console.log(\"删除成功\");\n}\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>数据ID：</text>\n      <input v-model=\"dataId\" placeholder=\"请输入要删除的数据ID\" />\n    </view>\n    <button :disabled=\"!dataId\" @click=\"deleteData\">删除数据</button>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      dataId: \"\"\n    };\n  },\n  methods: {\n    // 删除数据\n    async deleteData() {\n      try {\n        const { data, error } = await cloudbase\n          .database()\n          .from(\"{%TABLE_NAME%}\")\n          .delete()\n          .eq(\"id\", this.dataId);\n\n        if (!error) {\n          uni.showToast({\n            title: \"删除成功\",\n            icon: \"success\"\n          });\n          this.dataId = \"\";\n        } else {\n          uni.showToast({\n            title: \"删除失败\",\n            icon: \"none\"\n          });\n        }\n      } catch (error) {\n        uni.showToast({\n          title: \"删除失败：\" + error.message,\n          icon: \"none\"\n        });\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 5,
                "title": "删除数据"
              }
            ]
          },
          {
            "index": 2,
            "id": "doc-db",
            "title": "文档型数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\n// 查询 {%TABLE_NAME%} 表前10条数据\nconst db = cloudbase.database();\nconst res = await db.collection(\"{%TABLE_NAME%}\").limit(10).get();\nconsole.log(res.data);\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <button @click=\"getData\">查询数据</button>\n    <view v-if=\"dataList.length > 0\">\n      <view v-for=\"(item, index) in dataList\" :key=\"index\" class=\"data-item\">\n        <text>{{ JSON.stringify(item) }}</text>\n      </view>\n    </view>\n    <text v-else>暂无数据</text>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      dataList: []\n    };\n  },\n  methods: {\n    // 查询数据\n    async getData() {\n      try {\n        const db = cloudbase.database();\n        const res = await db.collection(\"{%TABLE_NAME%}\").limit(10).get();\n\n        this.dataList = res.data;\n        uni.showToast({\n          title: \"查询成功\",\n          icon: \"success\"\n        });\n      } catch (error) {\n        uni.showToast({\n          title: \"查询失败：\" + error.message,\n          icon: \"none\"\n        });\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\n// 新增 {%TABLE_NAME%} 表数据\nconst db = cloudbase.database();\nconst res = await db.collection(\"{%TABLE_NAME%}\").add({ title: \"示例标题\" });\nconsole.log(`新增成功! id: ${res.id}`);\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>标题：</text>\n      <input v-model=\"title\" placeholder=\"请输入标题\" />\n    </view>\n    <button :disabled=\"!title\" @click=\"addData\">新增数据</button>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      title: \"\"\n    };\n  },\n  methods: {\n    // 新增数据\n    async addData() {\n      try {\n        const db = cloudbase.database();\n        const res = await db\n          .collection(\"{%TABLE_NAME%}\")\n          .add({ title: this.title });\n\n        uni.showToast({\n          title: `新增成功! id: ${res.id}`,\n          icon: \"success\"\n        });\n        this.title = \"\";\n      } catch (error) {\n        uni.showToast({\n          title: \"新增失败：\" + error.message,\n          icon: \"none\"\n        });\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\n// 更新 {%TABLE_NAME%} 表中 id 为指定值的数据\nconst db = cloudbase.database();\nawait db\n  .collection(\"{%TABLE_NAME%}\")\n  .doc(\"<数据id>\")\n  .update({ title: \"新标题\" });\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>数据ID：</text>\n      <input v-model=\"dataId\" placeholder=\"请输入数据ID\" />\n    </view>\n    <view>\n      <text>新标题：</text>\n      <input v-model=\"newTitle\" placeholder=\"请输入新标题\" />\n    </view>\n    <button :disabled=\"!dataId || !newTitle\" @click=\"updateData\">\n      更新数据\n    </button>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      dataId: \"\",\n      newTitle: \"\"\n    };\n  },\n  methods: {\n    // 更新数据\n    async updateData() {\n      try {\n        const db = cloudbase.database();\n        await db\n          .collection(\"{%TABLE_NAME%}\")\n          .doc(this.dataId)\n          .update({ title: this.newTitle });\n\n        uni.showToast({\n          title: \"更新成功\",\n          icon: \"success\"\n        });\n        this.dataId = \"\";\n        this.newTitle = \"\";\n      } catch (error) {\n        uni.showToast({\n          title: \"更新失败：\" + error.message,\n          icon: \"none\"\n        });\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\n// 删除 {%TABLE_NAME%} 表中 id 为指定值的数据\nconst db = cloudbase.database();\nawait db.collection(\"{%TABLE_NAME%}\").doc(\"<数据id>\").remove();\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>数据ID：</text>\n      <input v-model=\"dataId\" placeholder=\"请输入要删除的数据ID\" />\n    </view>\n    <button :disabled=\"!dataId\" @click=\"deleteData\">删除数据</button>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      dataId: \"\"\n    };\n  },\n  methods: {\n    // 删除数据\n    async deleteData() {\n      try {\n        const db = cloudbase.database();\n        await db.collection(\"{%TABLE_NAME%}\").doc(this.dataId).remove();\n\n        uni.showToast({\n          title: \"删除成功\",\n          icon: \"success\"\n        });\n        this.dataId = \"\";\n      } catch (error) {\n        uni.showToast({\n          title: \"删除失败：\" + error.message,\n          icon: \"none\"\n        });\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 4,
                "title": "删除数据"
              }
            ]
          },
          {
            "index": 3,
            "id": "data-model",
            "title": "数据模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 查询 {%TABLE_NAME%} 数据模型前10条数据\nconst res = await cloudbase.models[\"{%TABLE_NAME%}\"].list({\n  pageNumber: 1,\n  pagesize: 10\n});\nconsole.log(res.data?.records);\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <button @click=\"getData\">查询数据</button>\n    <view v-if=\"dataList.length > 0\">\n      <view v-for=\"(item, index) in dataList\" :key=\"index\" class=\"data-item\">\n        <text>{{ JSON.stringify(item) }}</text>\n      </view>\n    </view>\n    <text v-else>暂无数据</text>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      dataList: []\n    };\n  },\n  methods: {\n    // 查询数据\n    async getData() {\n      try {\n        const res = await cloudbase.models[\"{%TABLE_NAME%}\"].list({\n          pageNumber: 1,\n          pagesize: 10\n        });\n\n        this.dataList = res.data?.records || [];\n        uni.showToast({\n          title: \"查询成功\",\n          icon: \"success\"\n        });\n      } catch (error) {\n        uni.showToast({\n          title: \"查询失败：\" + error.message,\n          icon: \"none\"\n        });\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 新增 {%TABLE_NAME%} 数据模型数据\nconst res = await cloudbase.models[\"{%TABLE_NAME%}\"].create({\n  data: { title: \"示例标题\" }\n});\nconsole.log(`新增成功! id: ${res.data.id}`);\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>标题：</text>\n      <input v-model=\"title\" placeholder=\"请输入标题\" />\n    </view>\n    <button :disabled=\"!title\" @click=\"addData\">新增数据</button>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      title: \"\"\n    };\n  },\n  methods: {\n    // 新增数据\n    async addData() {\n      try {\n        const res = await cloudbase.models[\"{%TABLE_NAME%}\"].create({\n          data: { title: this.title }\n        });\n\n        uni.showToast({\n          title: `新增成功! id: ${res.data.id}`,\n          icon: \"success\"\n        });\n        this.title = \"\";\n      } catch (error) {\n        uni.showToast({\n          title: \"新增失败：\" + error.message,\n          icon: \"none\"\n        });\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 更新 {%TABLE_NAME%} 数据模型中 _id 为指定值的数据\nawait cloudbase.models[\"{%TABLE_NAME%}\"].update({\n  data: { title: \"新标题\" },\n  filter: { where: { _id: { $eq: \"<数据id>\" } } }\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>数据ID：</text>\n      <input v-model=\"dataId\" placeholder=\"请输入数据ID\" />\n    </view>\n    <view>\n      <text>新标题：</text>\n      <input v-model=\"newTitle\" placeholder=\"请输入新标题\" />\n    </view>\n    <button :disabled=\"!dataId || !newTitle\" @click=\"updateData\">\n      更新数据\n    </button>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      dataId: \"\",\n      newTitle: \"\"\n    };\n  },\n  methods: {\n    // 更新数据\n    async updateData() {\n      try {\n        await cloudbase.models[\"{%TABLE_NAME%}\"].update({\n          data: { title: this.newTitle },\n          filter: { where: { _id: { $eq: this.dataId } } }\n        });\n\n        uni.showToast({\n          title: \"更新成功\",\n          icon: \"success\"\n        });\n        this.dataId = \"\";\n        this.newTitle = \"\";\n      } catch (error) {\n        uni.showToast({\n          title: \"更新失败：\" + error.message,\n          icon: \"none\"\n        });\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 删除 {%TABLE_NAME%} 数据模型中 _id 为指定值的数据\nawait cloudbase.models[\"{%TABLE_NAME%}\"].delete({\n  filter: { where: { _id: { $eq: \"<数据id>\" } } }\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>数据ID：</text>\n      <input v-model=\"dataId\" placeholder=\"请输入要删除的数据ID\" />\n    </view>\n    <button :disabled=\"!dataId\" @click=\"deleteData\">删除数据</button>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      dataId: \"\"\n    };\n  },\n  methods: {\n    // 删除数据\n    async deleteData() {\n      try {\n        await cloudbase.models[\"{%TABLE_NAME%}\"].delete({\n          filter: { where: { _id: { $eq: this.dataId } } }\n        });\n\n        uni.showToast({\n          title: \"删除成功\",\n          icon: \"success\"\n        });\n        this.dataId = \"\";\n      } catch (error) {\n        uni.showToast({\n          title: \"删除失败：\" + error.message,\n          icon: \"none\"\n        });\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 4,
                "title": "删除数据"
              }
            ]
          },
          {
            "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\n// 调用 {%FUNCTION_NAME%} 云函数\nconst res = await cloudbase.callFunction({\n  name: \"{%FUNCTION_NAME%}\",\n  data: {}\n});\nconsole.log(res.result);\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <button @click=\"callFunction\">调用云函数</button>\n    <view v-if=\"result\">\n      <text>返回结果：</text>\n      <text>{{ JSON.stringify(result) }}</text>\n    </view>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      result: null\n    };\n  },\n  methods: {\n    // 调用云函数\n    async callFunction() {\n      try {\n        const res = await cloudbase.callFunction({\n          name: \"{%FUNCTION_NAME%}\",\n          data: {}\n        });\n\n        this.result = res.result;\n        uni.showToast({\n          title: \"调用成功\",\n          icon: \"success\"\n        });\n      } catch (error) {\n        uni.showToast({\n          title: \"调用失败：\" + error.message,\n          icon: \"none\"\n        });\n      }\n    }\n  }\n};\n</script>\n```",
            "index": 4,
            "id": "scf",
            "title": "云函数",
            "content": []
          },
          {
            "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 调用 {%SERVICE_NAME%} 云托管服务\nconst res = await cloudbase.callContainer({\n  name: \"{%SERVICE_NAME%}\"\n  method: 'POST',\n  path: '/',\n  header:{\n    'Content-Type': 'application/json; charset=utf-8'\n  },\n  data: {},\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <button @click=\"callRun\">调用云托管</button>\n    <view v-if=\"result\">\n      <text>返回结果：</text>\n      <text>{{ JSON.stringify(result) }}</text>\n    </view>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      result: null\n    };\n  },\n  methods: {\n    // 调用云托管\n    async callRun() {\n      try {\n        // 调用 {%SERVICE_NAME%} 云托管服务\n        const res = await cloudbase.callContainer({\n          name: \"{%SERVICE_NAME%}\"\n          method: 'POST',\n          path: '/',\n          header:{\n            'Content-Type': 'application/json; charset=utf-8'\n          },\n          data: {},\n        });\n\n        this.result = res;\n        uni.showToast({\n          title: \"调用成功\",\n          icon: \"success\"\n        });\n      } catch (error) {\n        uni.showToast({\n          title: \"调用失败：\" + error.message,\n          icon: \"none\"\n        });\n      }\n    }\n  }\n};\n</script>\n```",
            "index": 5,
            "id": "run",
            "title": "云托管",
            "content": []
          },
          {
            "index": 6,
            "id": "storage",
            "title": "云存储",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst res = await cloudbase.uploadFile({\n  cloudPath: `images/${Date.now()}-${file.name}`, // 上传至云端的路径\n  filePath: file\n});\nconsole.log(res.fileID);\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <button @click=\"uploadFile\">选择并上传图片</button>\n    <view v-if=\"fileId\">\n      <text>上传成功！</text>\n      <text>文件ID: {{ fileId }}</text>\n    </view>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      fileId: \"\"\n    };\n  },\n  methods: {\n    // 上传文件\n    async uploadFile() {\n      uni.chooseImage({\n        count: 1,\n        success: async chooseImageRes => {\n          try {\n            uni.showLoading({\n              title: \"上传中...\"\n            });\n\n            const tempFilePath = chooseImageRes.tempFilePaths[0];\n            const cloudPath = `images/${Date.now()}-${Math.random()}.png`;\n\n            const res = await cloudbase.uploadFile({\n              cloudPath: cloudPath,\n              filePath: tempFilePath\n            });\n\n            this.fileId = res.fileID;\n            uni.hideLoading();\n            uni.showToast({\n              title: \"上传成功\",\n              icon: \"success\"\n            });\n          } catch (error) {\n            uni.hideLoading();\n            uni.showToast({\n              title: \"上传失败：\" + error.message,\n              icon: \"none\"\n            });\n          }\n        }\n      });\n    }\n  }\n};\n</script>\n```",
                "index": 1,
                "title": "上传文件"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst res = await cloudbase.getTempFileURL({\n  fileList: [\"cloud://xxx.png\"] // 文件 fileID 列表\n});\nconsole.log(res.fileList[0].tempFileURL);\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>文件ID：</text>\n      <input v-model=\"fileId\" placeholder=\"请输入文件ID (cloud://xxx.png)\" />\n    </view>\n    <button :disabled=\"!fileId\" @click=\"getFileUrl\">获取文件链接</button>\n    <view v-if=\"fileUrl\">\n      <text>文件链接：</text>\n      <text>{{ fileUrl }}</text>\n      <image :src=\"fileUrl\" mode=\"aspectFit\"></image>\n    </view>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      fileId: \"\",\n      fileUrl: \"\"\n    };\n  },\n  methods: {\n    // 获取文件链接\n    async getFileUrl() {\n      try {\n        const res = await cloudbase.getTempFileURL({\n          fileList: [this.fileId]\n        });\n\n        this.fileUrl = res.fileList[0].tempFileURL;\n        uni.showToast({\n          title: \"获取成功\",\n          icon: \"success\"\n        });\n      } catch (error) {\n        uni.showToast({\n          title: \"获取失败：\" + error.message,\n          icon: \"none\"\n        });\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 2,
                "title": "获取文件链接"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nawait cloudbase.downloadFile({\n  fileID: \"cloud://xxx.png\" // 文件 fileID\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>文件ID：</text>\n      <input v-model=\"fileId\" placeholder=\"请输入文件ID (cloud://xxx.png)\" />\n    </view>\n    <button :disabled=\"!fileId\" @click=\"downloadFile\">下载文件</button>\n    <view v-if=\"localPath\">\n      <text>下载成功！</text>\n      <text>本地路径: {{ localPath }}</text>\n    </view>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      fileId: \"\",\n      localPath: \"\"\n    };\n  },\n  methods: {\n    // 下载文件\n    async downloadFile() {\n      try {\n        uni.showLoading({\n          title: \"下载中...\"\n        });\n\n        const res = await cloudbase.downloadFile({\n          fileID: this.fileId\n        });\n\n        this.localPath = res.tempFilePath;\n        uni.hideLoading();\n        uni.showToast({\n          title: \"下载成功\",\n          icon: \"success\"\n        });\n      } catch (error) {\n        uni.hideLoading();\n        uni.showToast({\n          title: \"下载失败：\" + error.message,\n          icon: \"none\"\n        });\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 3,
                "title": "下载文件"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst res = await cloudbase.deleteFile({\n  fileList: [\"cloud://xxx.png\"] // 文件 fileID 列表\n});\nif (res.fileList[0].code === \"SUCCESS\") {\n  console.log(\"删除成功\");\n}\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>文件ID：</text>\n      <input v-model=\"fileId\" placeholder=\"请输入文件ID (cloud://xxx.png)\" />\n    </view>\n    <button :disabled=\"!fileId\" @click=\"deleteFile\">删除文件</button>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      fileId: \"\"\n    };\n  },\n  methods: {\n    // 删除文件\n    async deleteFile() {\n      try {\n        const res = await cloudbase.deleteFile({\n          fileList: [this.fileId]\n        });\n\n        if (res.fileList[0].code === \"SUCCESS\") {\n          uni.showToast({\n            title: \"删除成功\",\n            icon: \"success\"\n          });\n          this.fileId = \"\";\n        } else {\n          uni.showToast({\n            title: \"删除失败\",\n            icon: \"none\"\n          });\n        }\n      } catch (error) {\n        uni.showToast({\n          title: \"删除失败：\" + error.message,\n          icon: \"none\"\n        });\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 4,
                "title": "删除文件"
              }
            ]
          },
          {
            "index": 7,
            "id": "ai-model",
            "title": "大模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst res = await cloudbase\n  .ai()\n  .createModel(\"{%AI_MODEL_NAME%}\")\n  .streamText({\n    model: \"{%AI_SUB_MODEL_NAME%}\",\n    messages: [{ role: \"user\", content: \"你好\" }]\n  });\n\nfor await (let data of res.dataStream) {\n  // 如果有则打印思维链内容\n  const think = data?.choices?.[0]?.delta?.reasoning_content;\n  if (think) console.log(think);\n\n  // 打印生成文本内容\n  const text = data?.choices?.[0]?.delta?.content;\n  if (text) console.log(text);\n}\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>输入主题：</text>\n      <input v-model=\"input\" placeholder=\"请输入主题，如：春天\" />\n    </view>\n    <button :disabled=\"!input || isGenerating\" @click=\"callAIModel\">\n      生成内容\n    </button>\n    <view v-if=\"response\">\n      <text>生成结果：</text>\n      <text>{{ response }}</text>\n    </view>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      input: \"\",\n      response: \"\",\n      isGenerating: false\n    };\n  },\n  methods: {\n    // 调用大模型\n    async callAIModel() {\n      this.isGenerating = true;\n      this.response = \"\";\n\n      try {\n        // 确保已登录\n        const loginState = await cloudbase.auth().getLoginState();\n        if (!loginState) {\n          await cloudbase.auth().signInAnonymously();\n        }\n\n        uni.showLoading({\n          title: \"生成中...\"\n        });\n\n        const res = await cloudbase\n          .ai()\n          .createModel(\"<YOUR_AI_MODEL_NAME>\")\n          .streamText({\n            model: \"<YOUR_AI_SUB_MODEL_NAME>\",\n            messages: [{ role: \"user\", content: this.input }]\n          });\n\n        for await (let str of res.textStream) {\n          this.response += str;\n        }\n\n        uni.hideLoading();\n        uni.showToast({\n          title: \"生成完成\",\n          icon: \"success\"\n        });\n      } catch (err) {\n        uni.hideLoading();\n        uni.showToast({\n          title: \"生成失败：\" + err.message,\n          icon: \"none\"\n        });\n      } finally {\n        this.isGenerating = false;\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 1,
                "id": "text-aiModel",
                "title": "生文模型"
              },
              {
                "markdown": "生图模型通过调用云函数来实现，在生图模型页面点击「一键创建云函数」，函数调用示例如下：\n\n**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 调用生图云函数\nconst res = await cloudbase.callFunction({\n  name: \"<YOUR_FUNCTION_NAME>\",\n  data: {\n    prompt: \"一只可爱的猫咪在阳光下玩耍\"\n  }\n});\n\nconst result = res.result;\n\nif (result.success) {\n  // 生成成功\n  console.log(\"生成成功!\");\n  console.log(\"图片URL:\", result.imageUrl);\n  console.log(\"优化后的提示词:\", result.revised_prompt);\n\n  // 使用图片\n  // 注意：图片URL有效期为24小时，请及时保存或转存\n} else {\n  // 生成失败\n  console.error(\"生成失败:\", result.code, result.message);\n}\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>图片描述：</text>\n      <input v-model=\"prompt\" placeholder=\"请输入图片描述\" />\n    </view>\n    <button :disabled=\"!prompt || loading\" @click=\"generateImage\">\n      {{ loading ? \"生成中...\" : \"生成图片\" }}\n    </button>\n    <view v-if=\"message\">\n      <text :style=\"{ color: message.includes('成功') ? 'green' : 'red' }\">\n        {{ message }}\n      </text>\n    </view>\n    <view v-if=\"imageUrl\">\n      <image :src=\"imageUrl\" mode=\"aspectFit\" style=\"width: 100%\"></image>\n      <text style=\"font-size: 12px; color: #666\">\n        注意：图片URL有效期为24小时，请及时保存\n      </text>\n    </view>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      prompt: \"\",\n      imageUrl: \"\",\n      message: \"\",\n      loading: false\n    };\n  },\n  methods: {\n    // 生成图片\n    async generateImage() {\n      this.loading = true;\n      this.message = \"\";\n      this.imageUrl = \"\";\n\n      try {\n        uni.showLoading({\n          title: \"生成中...\"\n        });\n\n        // 调用生图云函数\n        const res = await cloudbase.callFunction({\n          name: \"<YOUR_FUNCTION_NAME>\",\n          data: {\n            prompt: this.prompt\n          }\n        });\n\n        const result = res.result;\n\n        if (result.success) {\n          this.imageUrl = result.imageUrl;\n          this.message = \"生成成功！\";\n          uni.hideLoading();\n          uni.showToast({\n            title: \"生成成功\",\n            icon: \"success\"\n          });\n        } else {\n          this.message = `生成失败：${result.message}`;\n          uni.hideLoading();\n          uni.showToast({\n            title: \"生成失败\",\n            icon: \"none\"\n          });\n        }\n      } catch (error) {\n        this.message = \"调用失败：\" + error.message;\n        uni.hideLoading();\n        uni.showToast({\n          title: \"调用失败\",\n          icon: \"none\"\n        });\n      } finally {\n        this.loading = false;\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 2,
                "id": "image-aiModel",
                "title": "生图模型"
              }
            ]
          },
          {
            "markdown": "",
            "index": 8,
            "id": "agent",
            "title": "Agent",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from './utils/cloudbase';\n\nconst res = await cloudbase.ai().bot.sendMessage({\n  botId: '{%AGENT_ID%}',\n  // 入参结构参考前后端通信协议：\n  //  https://docs.cloudbase.net/ai/agent/http-agent-protocol\n  threadId: '550e8400-e29b-41d4-a716-446655440000',\n  runId: 'run_001',\n  messages: [\n    {\n      id: 'msg_001',\n      role: 'user',\n      content: '你好',\n    },\n  ],\n  tools: [],\n  context: [],\n  state: {},\n  forwardedProps: {},\n});\n\nfor await (const data of res.dataStream) {\n  // 如果有则打印思维链内容\n  const think = data.reasoning_content;\n  if (think) console.log(think);\n\n  // 打印输出正文\n  const content = data.content;\n  if (content) console.log(content);\n}\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>输入问题：</text>\n      <input v-model=\"input\" placeholder=\"请输入问题，如：你是谁\" />\n    </view>\n    <button :disabled=\"!input || isGenerating\" @click=\"callAgent\">\n      发送消息\n    </button>\n    <view v-if=\"response\">\n      <text>回答：</text>\n      <text>{{ response }}</text>\n    </view>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      input: \"\",\n      response: \"\",\n      isGenerating: false\n    };\n  },\n  methods: {\n    // 调用Agent\n    async callAgent() {\n      this.isGenerating = true;\n      this.response = \"\";\n\n      try {\n        // 确保已登录\n        const loginState = await cloudbase.auth().getLoginState();\n        if (!loginState) {\n          await cloudbase.auth().signInAnonymously();\n        }\n\n        uni.showLoading({\n          title: \"生成中...\"\n        });\n\n        const res = await cloudbase.ai().bot.sendMessage({\n          botId: \"{%AGENT_ID%}\",\n          // 入参结构参考前后端通信协议：\n          //  https://docs.cloudbase.net/ai/agent/http-agent-protocol\n          threadId: '550e8400-e29b-41d4-a716-446655440000',\n          runId: 'run_001',\n          messages: [\n            {\n              id: 'msg_001',\n              role: 'user',\n              content: '你好',\n            },\n          ],\n          tools: [],\n          context: [],\n          state: {},\n          forwardedProps: {},\n        });\n\n        for await (const data of res.dataStream) {\n          // 如果有则打印思维链内容\n          const think = data.reasoning_content;\n          if (think) this.response += think;\n\n          // 打印输出正文\n          const content = data.content;\n          if (content) this.response += content;\n        }\n\n        uni.hideLoading();\n        uni.showToast({\n          title: \"生成完成\",\n          icon: \"success\"\n        });\n      } catch (err) {\n        uni.hideLoading();\n        uni.showToast({\n          title: \"生成失败：\" + err.message,\n          icon: \"none\"\n        });\n      } finally {\n        this.isGenerating = false;\n      }\n    }\n  }\n};\n</script>\n\n```",
                "index": 0,
                "id": "scf",
                "title": "函数型"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst res = await cloudbase.ai().bot.sendMessage({\n  botId: \"{%AGENT_ID%}\",\n  msg: \"你好\"\n});\n\nfor await (const data of res.dataStream) {\n  // 如果有则打印思维链内容\n  const think = data.reasoning_content;\n  if (think) console.log(think);\n\n  // 打印输出正文\n  const content = data.content;\n  if (content) console.log(content);\n}\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>输入问题：</text>\n      <input v-model=\"input\" placeholder=\"请输入问题，如：你是谁\" />\n    </view>\n    <button :disabled=\"!input || isGenerating\" @click=\"callAgent\">\n      发送消息\n    </button>\n    <view v-if=\"response\">\n      <text>回答：</text>\n      <text>{{ response }}</text>\n    </view>\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      input: \"\",\n      response: \"\",\n      isGenerating: false\n    };\n  },\n  methods: {\n    // 调用Agent\n    async callAgent() {\n      this.isGenerating = true;\n      this.response = \"\";\n\n      try {\n        // 确保已登录\n        const loginState = await cloudbase.auth().getLoginState();\n        if (!loginState) {\n          await cloudbase.auth().signInAnonymously();\n        }\n\n        uni.showLoading({\n          title: \"生成中...\"\n        });\n\n        const res = await cloudbase.ai().bot.sendMessage({\n          botId: \"{%AGENT_ID%}\",\n          msg: \"你好\"\n        });\n\n        for await (const data of res.dataStream) {\n          // 如果有则打印思维链内容\n          const think = data.reasoning_content;\n          if (think) this.response += think;\n\n          // 打印输出正文\n          const content = data.content;\n          if (content) this.response += content;\n        }\n\n        uni.hideLoading();\n        uni.showToast({\n          title: \"生成完成\",\n          icon: \"success\"\n        });\n      } catch (err) {\n        uni.hideLoading();\n        uni.showToast({\n          title: \"生成失败：\" + err.message,\n          icon: \"none\"\n        });\n      } finally {\n        this.isGenerating = false;\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 1,
                "id": "baas",
                "title": "普通型"
              }
            ]
          },
          {
            "index": 9,
            "id": "identity",
            "title": "身份认证",
            "type": "sideTab",
            "content": [
              {
                "markdown": "使用 **短信验证码注册** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **短信验证码**\n\n**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ phone_number: phone });\n\n// 验证验证码\nconst verifyRes = await auth.verify({\n  verification_id: verificationId,\n  verification_code: code\n});\n\n// 注册（如用户已存在则自动登录）\nawait auth.signUp({\n  phone_number: `+86 ${phone}`,\n  verification_code: code,\n  verification_token: verifyRes.verification_token,\n  name: `user_${phone.slice(-4)}`,\n  password: \"admin@123\"\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>手机号：</text>\n      <input v-model=\"phone\" placeholder=\"13800000000\" />\n    </view>\n    <view>\n      <text>验证码：</text>\n      <input v-model=\"code\" placeholder=\"验证码\" />\n      <button :disabled=\"!phone\" @click=\"sendCode\">发送验证码</button>\n    </view>\n    <button :disabled=\"!verificationId || !code\" @click=\"register\">注册</button>\n    <text\n      v-if=\"message\"\n      :style=\"{ color: message.includes('成功') ? 'green' : 'red' }\"\n      >{{ message }}</text\n    >\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      phone: \"\",\n      code: \"\",\n      verificationId: \"\",\n      message: \"\"\n    };\n  },\n  methods: {\n    // 发送验证码\n    async sendCode() {\n      try {\n        const auth = cloudbase.auth();\n        const res = await auth.getVerification({ phone_number: this.phone });\n        this.verificationId = res.verification_id;\n        this.message = \"验证码已发送！\";\n      } catch (error) {\n        this.message = \"发送失败：\" + error.message;\n      }\n    },\n\n    // 注册\n    async register() {\n      try {\n        const auth = cloudbase.auth();\n        // 验证验证码\n        const verifyRes = await auth.verify({\n          verification_id: this.verificationId,\n          verification_code: this.code\n        });\n        // 注册（如用户已存在则自动登录）\n        await auth.signUp({\n          phone_number: `+86 ${this.phone}`,\n          verification_code: this.code,\n          verification_token: verifyRes.verification_token,\n          name: `user_${this.phone.slice(-4)}`,\n          password: \"admin@123\"\n        });\n        this.message = \"注册成功！\";\n      } catch (error) {\n        this.message = \"注册失败：\" + error.message;\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 1,
                "title": "短信验证码注册"
              },
              {
                "markdown": "使用 **邮箱验证码注册** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **邮箱验证码**\n\n**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ email });\n\n// 验证验证码\nconst verifyRes = await auth.verify({\n  verification_id: verificationId,\n  verification_code: code\n});\n\n// 注册（如用户已存在则自动登录）\nawait auth.signUp({\n  email,\n  verification_code: code,\n  verification_token: verifyRes.verification_token,\n  name: `user_${email.slice(-4)}`,\n  password: \"admin@123\"\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>邮箱：</text>\n      <input v-model=\"email\" placeholder=\"example@email.com\" />\n    </view>\n    <view>\n      <text>验证码：</text>\n      <input v-model=\"code\" placeholder=\"验证码\" />\n      <button :disabled=\"!email\" @click=\"sendCode\">发送验证码</button>\n    </view>\n    <button :disabled=\"!verificationId || !code\" @click=\"register\">注册</button>\n    <text\n      v-if=\"message\"\n      :style=\"{ color: message.includes('成功') ? 'green' : 'red' }\"\n      >{{ message }}</text\n    >\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      email: \"\",\n      code: \"\",\n      verificationId: \"\",\n      message: \"\"\n    };\n  },\n  methods: {\n    // 发送验证码\n    async sendCode() {\n      try {\n        const auth = cloudbase.auth();\n        const res = await auth.getVerification({ email: this.email });\n        this.verificationId = res.verification_id;\n        this.message = \"验证码已发送！\";\n      } catch (error) {\n        this.message = \"发送失败：\" + error.message;\n      }\n    },\n\n    // 注册\n    async register() {\n      try {\n        const auth = cloudbase.auth();\n        // 验证验证码\n        const verifyRes = await auth.verify({\n          verification_id: this.verificationId,\n          verification_code: this.code\n        });\n        // 注册（如用户已存在则自动登录）\n        await auth.signUp({\n          email: this.email,\n          verification_code: this.code,\n          verification_token: verifyRes.verification_token,\n          name: `user_${this.email.slice(-4)}`,\n          password: \"admin@123\"\n        });\n        this.message = \"注册成功！\";\n      } catch (error) {\n        this.message = \"注册失败：\" + error.message;\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 2,
                "title": "邮箱验证码注册"
              },
              {
                "markdown": "使用 **账号密码登录** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **用户名密码登录**\n\n**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\nawait auth.signIn({\n  username, // 可以是用户名、手机号或邮箱\n  password\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>账号：</text>\n      <input v-model=\"username\" placeholder=\"用户名/手机号/邮箱\" />\n      <text>注：手机号登录请添加区号 +86</text>\n    </view>\n    <view>\n      <text>密码：</text>\n      <input type=\"password\" v-model=\"password\" placeholder=\"请输入密码\" />\n    </view>\n    <button :disabled=\"!username || !password\" @click=\"login\">登录</button>\n    <text\n      v-if=\"message\"\n      :style=\"{ color: message.includes('成功') ? 'green' : 'red' }\"\n      >{{ message }}</text\n    >\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      username: \"\",\n      password: \"\",\n      message: \"\"\n    };\n  },\n  methods: {\n    // 登录\n    async login() {\n      try {\n        const auth = cloudbase.auth();\n        await auth.signIn({\n          username: this.username, // 可以是用户名、手机号或邮箱\n          password: this.password\n        });\n        this.message = \"登录成功！\";\n      } catch (error) {\n        this.message = \"登录失败：\" + error.message;\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 3,
                "id": "UserNameLogin",
                "title": "账号密码登录"
              },
              {
                "markdown": "使用 **短信验证码登录** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **短信验证码登录**\n\n**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ phone_number: `+86 ${phone}` });\n\n// 登录\nawait auth.signInWithSms({\n  verificationInfo: res,\n  verificationCode: code,\n  phoneNum: `+86 ${phone}`\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>手机号：</text>\n      <input v-model=\"phone\" placeholder=\"13800000000\" />\n    </view>\n    <view>\n      <text>验证码：</text>\n      <input v-model=\"code\" placeholder=\"验证码\" />\n      <button @click=\"sendCode\" :disabled=\"!phone\">发送验证码</button>\n    </view>\n    <button @click=\"login\" :disabled=\"!verificationInfo || !code\">登录</button>\n    <text\n      v-if=\"message\"\n      :style=\"{ color: message.includes('成功') ? 'green' : 'red' }\"\n      >{{ message }}</text\n    >\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      phone: \"\",\n      code: \"\",\n      verificationInfo: null,\n      message: \"\"\n    };\n  },\n  methods: {\n    // 发送验证码\n    async sendCode() {\n      try {\n        const auth = cloudbase.auth();\n        const res = await auth.getVerification({\n          phone_number: `+86 ${this.phone}`\n        });\n        this.verificationInfo = res;\n        this.message = \"验证码已发送！\";\n      } catch (error) {\n        this.message = \"发送失败：\" + error.message;\n      }\n    },\n\n    // 登录\n    async login() {\n      try {\n        const auth = cloudbase.auth();\n        await auth.signInWithSms({\n          verificationInfo: this.verificationInfo,\n          verificationCode: this.code,\n          phoneNum: `+86 ${this.phone}`\n        });\n        this.message = \"登录成功！\";\n      } catch (error) {\n        this.message = \"登录失败：\" + error.message;\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 4,
                "id": "PhoneNumberLogin",
                "title": "短信验证码登录"
              },
              {
                "markdown": "使用 **邮箱验证码登录** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **邮箱验证码**\n\n**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ email });\n\n// 登录\nawait auth.signInWithEmail({\n  verificationInfo: res,\n  verificationCode: code,\n  email\n});\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <view>\n      <text>邮箱：</text>\n      <input v-model=\"email\" placeholder=\"example@email.com\" />\n    </view>\n    <view>\n      <text>验证码：</text>\n      <input v-model=\"code\" placeholder=\"验证码\" />\n      <button @click=\"sendCode\" :disabled=\"!email\">发送验证码</button>\n    </view>\n    <button @click=\"login\" :disabled=\"!verificationInfo || !code\">登录</button>\n    <text\n      v-if=\"message\"\n      :style=\"{ color: message.includes('成功') ? 'green' : 'red' }\"\n      >{{ message }}</text\n    >\n  </view>\n</template>\n\n<script>\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default {\n  data() {\n    return {\n      email: \"\",\n      code: \"\",\n      verificationInfo: null,\n      message: \"\"\n    };\n  },\n  methods: {\n    // 发送验证码\n    async sendCode() {\n      try {\n        const auth = cloudbase.auth();\n        const res = await auth.getVerification({ email: this.email });\n        this.verificationInfo = res;\n        this.message = \"验证码已发送！\";\n      } catch (error) {\n        this.message = \"发送失败：\" + error.message;\n      }\n    },\n\n    // 登录\n    async login() {\n      try {\n        const auth = cloudbase.auth();\n        await auth.signInWithEmail({\n          verificationInfo: this.verificationInfo,\n          verificationCode: this.code,\n          email: this.email\n        });\n        this.message = \"登录成功！\";\n      } catch (error) {\n        this.message = \"登录失败：\" + error.message;\n      }\n    }\n  }\n};\n</script>\n```",
                "index": 5,
                "id": "email",
                "title": "邮箱验证码登录"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 手机号授权登录\nconst loginResult = await auth.signInWithPhoneAuth(code);\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <button open-type=\"getPhoneNumber\" @getphonenumber=\"handleGetPhoneNumber\">\n      微信小程序登录\n    </button>\n  </view>\n</template>\n\n<script>\nimport cloudbase from './utils/cloudbase';\n\nexport default {\n  data() {\n    return {}\n  },\n  methods: {\n    async handleGetPhoneNumber(event) {\n      if(!event.detail.code) {\n        console.error('获取手机号失败:', event.detail.errMsg);\n        uni.showToast({\n          title: '获取手机号失败',\n          icon: 'none'\n        });\n        return\n      }\n      console.log('获取到动态令牌(code):', event.detail.code);\n      uni.showLoading({\n        title: '登录中...'\n      });\n      try {\n        // 手机号授权登录\n        const auth = cloudbase.auth();\n        const loginResult = await auth.signInWithPhoneAuth( event.detail.code );\n        console.log('手机号授权登录结果:', loginResult);\n        uni.hideLoading();\n        uni.showToast({\n          title: '登录成功',\n          icon: 'success'\n        });\n      } catch (error: any) {\n        // 处理登录失败\n        console.error('手机号授权登录失败:', error);\n        uni.showToast({\n          title: error.message || '登录失败',\n          icon: 'none'\n        });\n      } finally {\n        uni.hideLoading();\n      }\n    }\n  }\n}\n</script>\n```",
                "index": 6,
                "title": "小程序手机号登录"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 微信 OpenID 登录\nconst loginResult = await auth.signInWithOpenId();\n```\n\n**完整示例：**\n\n```vue\n<template>\n  <view>\n    <button @click=\"openIdLogin\">微信小程序登录</button>\n  </view>\n</template>\n\n<script>\nimport cloudbase from './utils/cloudbase';\n\nexport default {\n  data() {\n    return {}\n  },\n  methods: {\n    async openIdLogin() {\n      uni.showLoading({\n        title: '正在登录...'\n      });\n\n      try {\n        const auth = cloudbase.auth();\n        const loginResult = await auth.signInWithOpenId();\n        console.log('微信 OpenID 登录成功:', loginResult);\n        uni.hideLoading();\n\n        uni.showToast({\n          title: '登录成功',\n          icon: 'success'\n        });\n      } catch (error: any) {\n        uni.hideLoading();\n        console.error('微信 OpenID 登录失败:', error);\n        uni.showToast({\n          title: error.message || '登录失败，请重试',\n          icon: 'none'\n        });\n      }\n    }\n  }\n}\n</script>\n```",
                "index": 7,
                "title": "微信 OpenID 登录"
              }
            ]
          }
        ]
      }
    ],
    "_id": "d595162669806293009868631c56e574",
    "_openid": "anon",
    "createdAt": 1770021523950,
    "updatedAt": 1770021523950
  },
  {
    "category": "框架集成,前端框架,React(Vite)",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": 10,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/api-reference/webv2/initialization",
    "content": [
      {
        "markdown": "`@cloudbase/js-sdk` 可以让您在 Web 端（如 PC Web 页面、微信公众平台 H5 等）使用 JavaScript 访问 CloudBase 服务和资源。",
        "index": 1,
        "title": "安装 SDK",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```bash\nnpm i @cloudbase/js-sdk\n```",
            "index": 1,
            "title": "npm",
            "content": []
          },
          {
            "markdown": "```bash\nyarn add @cloudbase/js-sdk\n```",
            "index": 2,
            "title": "yarn",
            "content": []
          },
          {
            "markdown": "```bash\npnpm add @cloudbase/js-sdk\n```",
            "index": 3,
            "title": "pnpm",
            "content": []
          }
        ]
      },
      {
        "markdown": "新增如下代码到您的 React 项目",
        "index": 2,
        "title": "初始化 SDK",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```js\nimport cloudbaseSDK from \"@cloudbase/js-sdk\";\n\nexport const cloudbase = cloudbaseSDK.init({\n  env: import.meta.env.VITE_CLOUDBASE_ENV_ID,\n  region: import.meta.env.VITE_CLOUDBASE_REGION,\n  accessKey: import.meta.env.VITE_CLOUDBASE_ACCESS_KEY\n});\n```",
            "index": 1,
            "title": "src/utils/cloudbase.js",
            "content": []
          },
          {
            "markdown": "```properties\n# 环境ID\nVITE_CLOUDBASE_ENV_ID={%ENV_ID%}\n\n# 环境所在地域\nVITE_CLOUDBASE_REGION={%REGION%}\n\n# 匿名访问令牌\nVITE_CLOUDBASE_ACCESS_KEY={%PUBLISHABLE_KEY%}\n```",
            "index": 2,
            "title": ".env",
            "content": []
          }
        ]
      },
      {
        "sideTabs": [
          {
            "id": "pg-db",
            "title": "PostgreSQL 数据库"
          }
        ],
        "index": 3,
        "title": "调用云开发能力",
        "type": "codeTab",
        "content": [
          {
            "index": 1,
            "id": "pg-db",
            "title": "PostgreSQL 数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 查询 {%TABLE_NAME%} 表前 10 条数据\nconst { data, error } = await cloudbase.rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .select(\"*\")\n  .limit(10);\n\nconsole.log(\"查询结果:\", data);\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 向 {%TABLE_NAME%} 表插入一条数据\n// 注意：anon 令牌（publishable key）仅有读权限，写操作需用户登录态或配置 RLS 写策略\nconst { data, error } = await cloudbase.rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .insert({ title: \"新文章\", status: \"draft\" })\n  .select();\n\nconsole.log(\"新增结果:\", data);\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 更新 {%TABLE_NAME%} 表中 id=1 的记录\n// 注意：anon 令牌（publishable key）仅有读权限，写操作需用户登录态或配置 RLS 写策略\nconst { data, error } = await cloudbase.rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .update({ status: \"published\" })\n  .eq(\"id\", 1)\n  .select();\n\nconsole.log(\"更新结果:\", data);\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 当 id 冲突时更新，否则插入\n// 注意：anon 令牌（publishable key）仅有读权限，写操作需用户登录态或配置 RLS 写策略\nconst { data, error } = await cloudbase.rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .upsert({ id: 1, title: \"标题\", status: \"published\" }, { onConflict: \"id\" })\n  .select();\n\nconsole.log(\"更新或创建结果:\", data);\n```",
                "index": 4,
                "title": "更新或创建数据"
              },
              {
                "markdown": "```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 删除 {%TABLE_NAME%} 表中 id=1 的记录\n// 注意：anon 令牌（publishable key）仅有读权限，写操作需用户登录态或配置 RLS 写策略\nconst { data, error } = await cloudbase.rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .delete()\n  .eq(\"id\", 1);\n\nconsole.log(\"删除完成:\", error);\n```",
                "index": 5,
                "title": "删除数据"
              }
            ]
          },
          {
            "index": 1,
            "id": "mysql-db",
            "title": "MySQL数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 查询 {%TABLE_NAME%} 表前10条数据\nconst { data, error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .select(\"*\")\n  .limit(10);\nif (!error) {\n  console.log(data);\n}\n```\n\n**完整示例：**\n\n```jsx\nimport { useState, useEffect } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [data, setData] = useState([]);\n\n  useEffect(() => {\n    getData();\n  }, []);\n\n  const getData = async () => {\n    // 查询 {%TABLE_NAME%} 表前10条数据\n    const { data, error } = await cloudbase\n      .rdb()\n      .from(\"{%TABLE_NAME%}\")\n      .select(\"*\")\n      .limit(10);\n    if (!error) setData(data || []);\n  };\n\n  return (\n    <ul>\n      {data.map(item => (\n        <li key={item.id}>{item.title}</li>\n      ))}\n    </ul>\n  );\n}\n\nexport default Page;\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 新增 {%TABLE_NAME%} 表数据\nconst { error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .insert({ title: \"示例标题\" });\nif (!error) {\n  console.log(\"新增成功\");\n}\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [title, setTitle] = useState(\"\");\n  const [message, setMessage] = useState(\"\");\n\n  const addData = async () => {\n    // 新增 {%TABLE_NAME%} 表数据\n    const { error } = await cloudbase\n      .rdb()\n      .from(\"{%TABLE_NAME%}\")\n      .insert({ title });\n    if (!error) {\n      setTitle(\"\");\n      setMessage(\"新增成功！\");\n    } else {\n      setMessage(\"新增失败：\" + error.message);\n    }\n  };\n\n  return (\n    <div>\n      <input value={title} onChange={e => setTitle(e.target.value)} />\n      <button onClick={addData}>新增</button>\n      {message && (\n        <p style={{ color: message.includes(\"成功\") ? \"green\" : \"red\" }}>\n          {message}\n        </p>\n      )}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 更新 {%TABLE_NAME%} 表中 id 为指定值的数据\nconst { error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .update({ title: \"新标题\" })\n  .eq(\"id\", \"<数据id>\");\nif (!error) {\n  console.log(\"更新成功\");\n}\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [message, setMessage] = useState(\"\");\n\n  const updateData = async () => {\n    // 更新 {%TABLE_NAME%} 表中 id 为指定值的数据\n    const { error } = await cloudbase\n      .rdb()\n      .from(\"{%TABLE_NAME%}\")\n      .update({ title: \"新标题\" })\n      .eq(\"id\", \"<数据id>\");\n    if (!error) {\n      setMessage(\"更新成功！\");\n    } else {\n      setMessage(\"更新失败：\" + error.message);\n    }\n  };\n\n  return (\n    <div>\n      <button onClick={updateData}>更新</button>\n      {message && (\n        <p style={{ color: message.includes(\"成功\") ? \"green\" : \"red\" }}>\n          {message}\n        </p>\n      )}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 如果 {%TABLE_NAME%} 表中存在 id 为 1 的记录则更新 title 为\"示例标题\"，不存在则插入新记录\nconst { error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .upsert({ id: 1, title: \"示例标题\" });\nif (!error) {\n  console.log(\"操作成功\");\n}\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [message, setMessage] = useState(\"\");\n\n  const upsertData = async () => {\n    // 如果 {%TABLE_NAME%} 表中存在 id 为 1 的记录则更新 title 为\"示例标题\"，不存在则插入新记录\n    const { error } = await cloudbase\n      .rdb()\n      .from(\"{%TABLE_NAME%}\")\n      .upsert({ id: 1, title: \"示例标题\" });\n    if (!error) {\n      setMessage(\"操作成功！\");\n    } else {\n      setMessage(\"操作失败：\" + error.message);\n    }\n  };\n\n  return (\n    <div>\n      <button onClick={upsertData}>更新或创建</button>\n      {message && (\n        <p style={{ color: message.includes(\"成功\") ? \"green\" : \"red\" }}>\n          {message}\n        </p>\n      )}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 4,
                "title": "更新或创建数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 删除 {%TABLE_NAME%} 表中 id 为指定值的数据\nconst { error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .delete()\n  .eq(\"id\", \"<数据id>\");\nif (!error) {\n  console.log(\"删除成功\");\n}\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [message, setMessage] = useState(\"\");\n\n  const deleteData = async () => {\n    // 删除 {%TABLE_NAME%} 表中 id 为指定值的数据\n    const { error } = await cloudbase\n      .rdb()\n      .from(\"{%TABLE_NAME%}\")\n      .delete()\n      .eq(\"id\", \"<数据id>\");\n    if (!error) {\n      setMessage(\"删除成功！\");\n    } else {\n      setMessage(\"删除失败：\" + error.message);\n    }\n  };\n\n  return (\n    <div>\n      <button onClick={deleteData}>删除</button>\n      {message && (\n        <p style={{ color: message.includes(\"成功\") ? \"green\" : \"red\" }}>\n          {message}\n        </p>\n      )}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 5,
                "title": "删除数据"
              }
            ]
          },
          {
            "index": 2,
            "id": "doc-db",
            "title": "文档型数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 查询 {%TABLE_NAME%} 表前10条数据\nconst db = cloudbase.database();\nconst res = await db.collection(\"{%TABLE_NAME%}\").limit(10).get();\nconsole.log(res.data);\n```\n\n**完整示例：**\n\n```jsx\nimport { useState, useEffect } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [data, setData] = useState([]);\n\n  useEffect(() => {\n    getData();\n  }, []);\n\n  const getData = async () => {\n    // 查询 {%TABLE_NAME%} 表前10条数据\n    const db = cloudbase.database();\n    const res = await db.collection(\"{%TABLE_NAME%}\").limit(10).get();\n    setData(res.data || []);\n  };\n\n  return (\n    <ul>\n      {data.map(item => (\n        <li key={item._id}>{item.title}</li>\n      ))}\n    </ul>\n  );\n}\n\nexport default Page;\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 新增 {%TABLE_NAME%} 表数据\nconst db = cloudbase.database();\nconst res = await db.collection(\"{%TABLE_NAME%}\").add({ title: \"示例标题\" });\nconsole.log(`新增成功! id: ${res.id}`);\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [message, setMessage] = useState(\"\");\n\n  const addData = async () => {\n    try {\n      // 新增 {%TABLE_NAME%} 表数据\n      const db = cloudbase.database();\n      const res = await db\n        .collection(\"{%TABLE_NAME%}\")\n        .add({ title: \"示例标题\" });\n      setMessage(`新增成功! id: ${res.id}`);\n    } catch (error) {\n      setMessage(\"新增失败：\" + error.message);\n    }\n  };\n\n  return (\n    <div>\n      <button onClick={addData}>新增</button>\n      {message && (\n        <p style={{ color: message.includes(\"成功\") ? \"green\" : \"red\" }}>\n          {message}\n        </p>\n      )}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 更新 {%TABLE_NAME%} 表中 id 为指定值的数据\nconst db = cloudbase.database();\nawait db\n  .collection(\"{%TABLE_NAME%}\")\n  .doc(\"<数据id>\")\n  .update({ title: \"新标题\" });\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [message, setMessage] = useState(\"\");\n\n  const updateData = async () => {\n    try {\n      // 更新 {%TABLE_NAME%} 表中 id 为指定值的数据\n      const db = cloudbase.database();\n      await db\n        .collection(\"{%TABLE_NAME%}\")\n        .doc(\"<数据id>\")\n        .update({ title: \"新标题\" });\n      setMessage(\"更新成功！\");\n    } catch (error) {\n      setMessage(\"更新失败：\" + error.message);\n    }\n  };\n\n  return (\n    <div>\n      <button onClick={updateData}>更新</button>\n      {message && (\n        <p style={{ color: message.includes(\"成功\") ? \"green\" : \"red\" }}>\n          {message}\n        </p>\n      )}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 删除 {%TABLE_NAME%} 表中 id 为指定值的数据\nconst db = cloudbase.database();\nawait db.collection(\"{%TABLE_NAME%}\").doc(\"<数据id>\").remove();\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [message, setMessage] = useState(\"\");\n\n  const deleteData = async () => {\n    try {\n      // 删除 {%TABLE_NAME%} 表中 id 为指定值的数据\n      const db = cloudbase.database();\n      await db.collection(\"{%TABLE_NAME%}\").doc(\"<数据id>\").remove();\n      setMessage(\"删除成功！\");\n    } catch (error) {\n      setMessage(\"删除失败：\" + error.message);\n    }\n  };\n\n  return (\n    <div>\n      <button onClick={deleteData}>删除</button>\n      {message && (\n        <p style={{ color: message.includes(\"成功\") ? \"green\" : \"red\" }}>\n          {message}\n        </p>\n      )}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 4,
                "title": "删除数据"
              }
            ]
          },
          {
            "index": 3,
            "id": "data-model",
            "title": "数据模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 查询 {%TABLE_NAME%} 数据模型前10条数据\nconst res = await cloudbase.models[\"{%TABLE_NAME%}\"].list({\n  pageNumber: 1,\n  pagesize: 10\n});\nconsole.log(res.data?.records);\n```\n\n**完整示例：**\n\n```jsx\nimport { useState, useEffect } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [data, setData] = useState([]);\n\n  useEffect(() => {\n    getData();\n  }, []);\n\n  const getData = async () => {\n    // 查询 {%TABLE_NAME%} 数据模型前10条数据\n    const res = await cloudbase.models[\"{%TABLE_NAME%}\"].list({\n      pageNumber: 1,\n      pagesize: 10\n    });\n    setData(res.data?.records || []);\n  };\n\n  return (\n    <ul>\n      {data.map(item => (\n        <li key={item._id}>{item.title}</li>\n      ))}\n    </ul>\n  );\n}\n\nexport default Page;\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 新增 {%TABLE_NAME%} 数据模型数据\nconst res = await cloudbase.models[\"{%TABLE_NAME%}\"].create({\n  data: { title: \"示例标题\" }\n});\nconsole.log(`新增成功! id: ${res.data.id}`);\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [message, setMessage] = useState(\"\");\n\n  const addData = async () => {\n    try {\n      // 新增 {%TABLE_NAME%} 数据模型数据\n      const res = await cloudbase.models[\"{%TABLE_NAME%}\"].create({\n        data: { title: \"示例标题\" }\n      });\n      setMessage(`新增成功! id: ${res.data.id}`);\n    } catch (error) {\n      setMessage(\"新增失败：\" + error.message);\n    }\n  };\n\n  return (\n    <div>\n      <button onClick={addData}>新增</button>\n      {message && (\n        <p style={{ color: message.includes(\"成功\") ? \"green\" : \"red\" }}>\n          {message}\n        </p>\n      )}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 更新 {%TABLE_NAME%} 数据模型中 _id 为指定值的数据\nawait cloudbase.models[\"{%TABLE_NAME%}\"].update({\n  data: { title: \"新标题\" },\n  filter: { where: { _id: { $eq: \"<数据id>\" } } }\n});\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [message, setMessage] = useState(\"\");\n\n  const updateData = async () => {\n    try {\n      // 更新 {%TABLE_NAME%} 数据模型中 _id 为指定值的数据\n      await cloudbase.models[\"{%TABLE_NAME%}\"].update({\n        data: { title: \"新标题\" },\n        filter: { where: { _id: { $eq: \"<数据id>\" } } }\n      });\n      setMessage(\"更新成功！\");\n    } catch (error) {\n      setMessage(\"更新失败：\" + error.message);\n    }\n  };\n\n  return (\n    <div>\n      <button onClick={updateData}>更新</button>\n      {message && (\n        <p style={{ color: message.includes(\"成功\") ? \"green\" : \"red\" }}>\n          {message}\n        </p>\n      )}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 删除 {%TABLE_NAME%} 数据模型中 _id 为指定值的数据\nawait cloudbase.models[\"{%TABLE_NAME%}\"].delete({\n  filter: { where: { _id: { $eq: \"<数据id>\" } } }\n});\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [message, setMessage] = useState(\"\");\n\n  const deleteData = async () => {\n    try {\n      // 删除 {%TABLE_NAME%} 数据模型中 _id 为指定值的数据\n      await cloudbase.models[\"{%TABLE_NAME%}\"].delete({\n        filter: { where: { _id: { $eq: \"<数据id>\" } } }\n      });\n      setMessage(\"删除成功！\");\n    } catch (error) {\n      setMessage(\"删除失败：\" + error.message);\n    }\n  };\n\n  return (\n    <div>\n      <button onClick={deleteData}>删除</button>\n      {message && (\n        <p style={{ color: message.includes(\"成功\") ? \"green\" : \"red\" }}>\n          {message}\n        </p>\n      )}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 4,
                "title": "删除数据"
              }
            ]
          },
          {
            "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 调用 {%FUNCTION_NAME%} 云函数\nconst res = await cloudbase.callFunction({\n  name: \"{%FUNCTION_NAME%}\",\n  data: {}\n});\nconsole.log(res.result);\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [data, setData] = useState(null);\n\n  const getData = async () => {\n    // 调用 {%FUNCTION_NAME%} 云函数\n    const res = await cloudbase.callFunction({\n      name: \"{%FUNCTION_NAME%}\",\n      data: {}\n    });\n    setData(res.result);\n  };\n\n  return (\n    <div>\n      <button onClick={getData}>调用云函数</button>\n      {data && <pre>{JSON.stringify(data, null, 2)}</pre>}\n    </div>\n  );\n}\n\nexport default Page;\n```",
            "index": 4,
            "id": "scf",
            "title": "云函数",
            "content": []
          },
          {
            "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 调用 {%SERVICE_NAME%} 云托管服务\nconst res = await cloudbase.callContainer({\n  name: \"{%SERVICE_NAME%}\"\n  method: 'POST',\n  path: '/',\n  header:{\n    'Content-Type': 'application/json; charset=utf-8'\n  },\n  data: {},\n});\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [data, setData] = useState(null);\n\n  const getData = async () => {\n    // 调用 {%SERVICE_NAME%} 云托管服务\n    const res = await cloudbase.callContainer({\n      name: \"{%SERVICE_NAME%}\"\n      method: 'POST',\n      path: '/',\n      header:{\n        'Content-Type': 'application/json; charset=utf-8'\n      },\n      data: {},\n    });\n    setData(res);\n  };\n\n  return (\n    <div>\n      <button onClick={getData}>调用云托管</button>\n      {data && <pre>{JSON.stringify(data, null, 2)}</pre>}\n    </div>\n  );\n}\n\nexport default Page;\n```",
            "index": 5,
            "id": "run",
            "title": "云托管",
            "content": []
          },
          {
            "index": 6,
            "id": "storage",
            "title": "云存储",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst res = await cloudbase.uploadFile({\n  cloudPath: `images/${Date.now()}-${file.name}`, // 上传至云端的路径\n  filePath: file\n});\nconsole.log(res.fileID);\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [fileID, setFileID] = useState(\"\");\n\n  const uploadFile = async e => {\n    const file = e.target.files[0];\n    const res = await cloudbase.uploadFile({\n      cloudPath: `images/${Date.now()}-${file.name}`, // 上传至云端的路径\n      filePath: file\n    });\n    setFileID(res.fileID);\n  };\n\n  return (\n    <div>\n      <input type=\"file\" onChange={uploadFile} />\n      {fileID && <p>上传成功: {fileID}</p>}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 1,
                "title": "上传文件"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst res = await cloudbase.getTempFileURL({\n  fileList: [\"cloud://xxx.png\"] // 文件 fileID 列表\n});\nconsole.log(res.fileList[0].tempFileURL);\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [fileUrl, setFileUrl] = useState(\"\");\n\n  const getData = async () => {\n    const res = await cloudbase.getTempFileURL({\n      fileList: [\"cloud://xxx.png\"] // 文件 fileID 列表\n    });\n    setFileUrl(res.fileList[0].tempFileURL);\n  };\n\n  return (\n    <div>\n      <button onClick={getData}>获取链接</button>\n      {fileUrl && <p>链接: {fileUrl}</p>}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 2,
                "title": "获取文件链接"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nawait cloudbase.downloadFile({\n  fileID: \"cloud://xxx.png\" // 文件 fileID\n});\n```\n\n**完整示例：**\n\n```jsx\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const downloadFile = async () => {\n    await cloudbase.downloadFile({\n      fileID: \"cloud://xxx.png\" // 文件 fileID\n    });\n  };\n\n  return <button onClick={downloadFile}>下载文件</button>;\n}\n\nexport default Page;\n```",
                "index": 3,
                "title": "下载文件"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst res = await cloudbase.deleteFile({\n  fileList: [\"cloud://xxx.png\"] // 文件 fileID 列表\n});\nif (res.fileList[0].code === \"SUCCESS\") {\n  console.log(\"删除成功\");\n}\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [message, setMessage] = useState(\"\");\n\n  const deleteFile = async () => {\n    const res = await cloudbase.deleteFile({\n      fileList: [\"cloud://xxx.png\"] // 文件 fileID 列表\n    });\n    if (res.fileList[0].code === \"SUCCESS\") {\n      setMessage(\"删除成功！\");\n    } else {\n      setMessage(\"删除失败！\", res.fileList);\n    }\n  };\n\n  return (\n    <div>\n      <button onClick={deleteFile}>删除文件</button>\n      {message && <p>{message}</p>}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 4,
                "title": "删除文件"
              }
            ]
          },
          {
            "index": 7,
            "id": "ai-model",
            "title": "大模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst res = await cloudbase\n  .ai()\n  .createModel(\"{%AI_MODEL_NAME%}\")\n  .streamText({\n    model: \"{%AI_SUB_MODEL_NAME%}\",\n    messages: [{ role: \"user\", content: \"你好\" }]\n  });\n\nfor await (let data of res.dataStream) {\n  // 如果有则打印思维链内容\n  const think = data?.choices?.[0]?.delta?.reasoning_content;\n  if (think) console.log(think);\n\n  // 打印生成文本内容\n  const text = data?.choices?.[0]?.delta?.content;\n  if (text) console.log(text);\n}\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [data, setData] = useState(\"\");\n  const [input, setInput] = useState(\"\");\n\n  const getData = async () => {\n    const res = await cloudbase\n      .ai()\n      .createModel(\"{%AI_MODEL_NAME%}\")\n      .streamText({\n        model: \"{%AI_SUB_MODEL_NAME%}\",\n        messages: [{ role: \"user\", content: input }]\n      });\n\n    let result = \"\";\n    for await (let data of res.dataStream) {\n      // 如果有则打印思维链内容\n      const think = data?.choices?.[0]?.delta?.reasoning_content;\n      if (think) {\n        result += think;\n      }\n\n      // 打印生成文本内容\n      const text = data?.choices?.[0]?.delta?.content;\n      if (text) result += text;\n\n      setData(result);\n    }\n  };\n\n  return (\n    <div>\n      <input\n        value={input}\n        placeholder=\"请输入大模型对话内容\"\n        onChange={e => setInput(e.target.value)}\n      />\n      <button onClick={getData}>发送</button>\n      <p>{data}</p>\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 1,
                "id": "text-aiModel",
                "title": "生文模型"
              },
              {
                "markdown": "生图模型通过调用云函数来实现，在生图模型页面点击「一键创建云函数」，函数调用示例如下：\n\n**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 调用生图云函数\nconst res = await cloudbase.callFunction({\n  name: \"<YOUR_FUNCTION_NAME>\",\n  data: {\n    prompt: \"一只可爱的猫咪在阳光下玩耍\"\n  }\n});\n\nconst result = res.result;\n\nif (result.success) {\n  // 生成成功\n  console.log(\"生成成功!\");\n  console.log(\"图片URL:\", result.imageUrl);\n  console.log(\"优化后的提示词:\", result.revised_prompt);\n\n  // 使用图片\n  // 注意：图片URL有效期为24小时，请及时保存或转存\n} else {\n  // 生成失败\n  console.error(\"生成失败:\", result.code, result.message);\n}\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [prompt, setPrompt] = useState(\"\");\n  const [imageUrl, setImageUrl] = useState(\"\");\n  const [message, setMessage] = useState(\"\");\n  const [loading, setLoading] = useState(false);\n\n  const generateImage = async () => {\n    setLoading(true);\n    setMessage(\"\");\n    setImageUrl(\"\");\n\n    try {\n      // 调用生图云函数\n      const res = await cloudbase.callFunction({\n        name: \"<YOUR_FUNCTION_NAME>\",\n        data: {\n          prompt: prompt\n        }\n      });\n\n      const result = res.result;\n\n      if (result.success) {\n        setImageUrl(result.imageUrl);\n        setMessage(\"生成成功！\");\n      } else {\n        setMessage(`生成失败：${result.message}`);\n      }\n    } catch (error) {\n      setMessage(\"调用失败：\" + error.message);\n    } finally {\n      setLoading(false);\n    }\n  };\n\n  return (\n    <div>\n      <input\n        value={prompt}\n        placeholder=\"请输入图片描述\"\n        onChange={e => setPrompt(e.target.value)}\n      />\n      <button onClick={generateImage} disabled={!prompt || loading}>\n        {loading ? \"生成中...\" : \"生成图片\"}\n      </button>\n      {message && (\n        <p style={{ color: message.includes(\"成功\") ? \"green\" : \"red\" }}>\n          {message}\n        </p>\n      )}\n      {imageUrl && (\n        <div>\n          <img src={imageUrl} alt=\"生成的图片\" style={{ maxWidth: \"100%\" }} />\n          <p style={{ fontSize: \"12px\", color: \"#666\" }}>\n            注意：图片URL有效期为24小时，请及时保存\n          </p>\n        </div>\n      )}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 2,
                "id": "image-aiModel",
                "title": "生图模型"
              }
            ]
          },
          {
            "markdown": "",
            "index": 8,
            "id": "agent",
            "title": "Agent",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from './utils/cloudbase';\n\nconst res = await cloudbase.ai().bot.sendMessage({\n  botId: '{%AGENT_ID%}',\n  // 入参结构参考前后端通信协议：\n  //  https://docs.cloudbase.net/ai/agent/http-agent-protocol\n  threadId: '550e8400-e29b-41d4-a716-446655440000',\n  runId: 'run_001',\n  messages: [\n    {\n      id: 'msg_001',\n      role: 'user',\n      content: '你好',\n    },\n  ],\n  tools: [],\n  context: [],\n  state: {},\n  forwardedProps: {},\n});\n\nfor await (const data of res.dataStream) {\n  // 如果有则打印思维链内容\n  const think = data.reasoning_content;\n  if (think) console.log(think);\n\n  // 打印输出正文\n  const content = data.content;\n  if (content) console.log(content);\n}\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from 'react';\nimport { cloudbase } from './utils/cloudbase';\n\nfunction Page() {\n  const [data, setData] = useState('');\n  const [input, setInput] = useState('');\n\n  const getData = async () => {\n    const res = await cloudbase.ai().bot.sendMessage({\n      botId: '{%AGENT_ID%}',\n      // 入参结构参考前后端通信协议：\n      //  https://docs.cloudbase.net/ai/agent/http-agent-protocol\n      threadId: '550e8400-e29b-41d4-a716-446655440000',\n      runId: 'run_001',\n      messages: [\n        {\n          id: 'msg_001',\n          role: 'user',\n          content: input,\n        },\n      ],\n      tools: [],\n      context: [],\n      state: {},\n      forwardedProps: {},\n    });\n\n    let result = '';\n    for await (const data of res.dataStream) {\n      // 如果有则打印思维链内容\n      const think = data.reasoning_content;\n      if (think) {\n        result += think;\n      }\n\n      // 打印输出正文\n      const content = data.content;\n      if (content) result += content;\n\n      setData(result);\n    }\n  };\n\n  return (\n    <div>\n      <input value={input} placeholder=\"请输入Agent对话内容\" onChange={(e) => setInput(e.target.value)} />\n      <button onClick={getData}>发送</button>\n      <p>{data}</p>\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 0,
                "id": "scf",
                "title": "函数型"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst res = await cloudbase.ai().bot.sendMessage({\n  botId: \"{%AGENT_ID%}\",\n  msg: \"你好\"\n});\n\nfor await (const data of res.dataStream) {\n  // 如果有则打印思维链内容\n  const think = data.reasoning_content;\n  if (think) console.log(think);\n\n  // 打印输出正文\n  const content = data.content;\n  if (content) console.log(content);\n}\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [data, setData] = useState(\"\");\n  const [input, setInput] = useState(\"\");\n\n  const getData = async () => {\n    const res = await cloudbase.ai().bot.sendMessage({\n      botId: \"{%AGENT_ID%}\",\n      msg: input\n    });\n\n    let result = \"\";\n    for await (const data of res.dataStream) {\n      // 如果有则打印思维链内容\n      const think = data.reasoning_content;\n      if (think) {\n        result += think;\n      }\n\n      // 打印输出正文\n      const content = data.content;\n      if (content) result += content;\n\n      setData(result);\n    }\n  };\n\n  return (\n    <div>\n      <input\n        value={input}\n        placeholder=\"请输入Agent对话内容\"\n        onChange={e => setInput(e.target.value)}\n      />\n      <button onClick={getData}>发送</button>\n      <p>{data}</p>\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 1,
                "id": "baas",
                "title": "普通型"
              }
            ]
          },
          {
            "index": 9,
            "id": "identity",
            "title": "身份认证",
            "type": "sideTab",
            "content": [
              {
                "markdown": "使用 **短信验证码注册** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **短信验证码**\n\n**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ phone_number: phone });\n\n// 验证验证码\nconst verifyRes = await auth.verify({\n  verification_id: verificationId,\n  verification_code: code\n});\n\n// 注册（如用户已存在则自动登录）\nawait auth.signUp({\n  phone_number: `+86 ${phone}`,\n  verification_code: code,\n  verification_token: verifyRes.verification_token,\n  name: `user_${phone.slice(-4)}`,\n  password: \"admin@123\"\n});\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [phone, setPhone] = useState(\"\");\n  const [code, setCode] = useState(\"\");\n  const [verificationId, setVerificationId] = useState(\"\");\n  const [message, setMessage] = useState(\"\");\n\n  // 发送验证码\n  const sendCode = async () => {\n    try {\n      const auth = cloudbase.auth();\n      const res = await auth.getVerification({ phone_number: phone });\n      setVerificationId(res.verification_id);\n      setMessage(\"验证码已发送！\");\n    } catch (error) {\n      setMessage(\"发送失败：\" + error.message);\n    }\n  };\n\n  // 注册\n  const register = async () => {\n    try {\n      const auth = cloudbase.auth();\n      // 验证验证码\n      const verifyRes = await auth.verify({\n        verification_id: verificationId,\n        verification_code: code\n      });\n      // 注册（如用户已存在则自动登录）\n      await auth.signUp({\n        phone_number: `+86 ${phone}`,\n        verification_code: code,\n        verification_token: verifyRes.verification_token,\n        name: `user_${phone.slice(-4)}`,\n        password: \"admin@123\"\n      });\n      setMessage(\"注册成功！\");\n    } catch (error) {\n      setMessage(\"注册失败：\" + error.message);\n    }\n  };\n\n  return (\n    <div>\n      <label>手机号：</label>\n      <input\n        value={phone}\n        onChange={e => setPhone(e.target.value)}\n        placeholder=\"13800000000\"\n      />\n      <div>\n        <label>验证码：</label>\n        <input\n          value={code}\n          onChange={e => setCode(e.target.value)}\n          placeholder=\"验证码\"\n        />\n        <button disabled={!phone} onClick={sendCode}>\n          发送验证码\n        </button>\n      </div>\n      <button disabled={!verificationId || !code} onClick={register}>\n        注册\n      </button>\n      {message && (\n        <p style={{ color: message.includes(\"成功\") ? \"green\" : \"red\" }}>\n          {message}\n        </p>\n      )}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 1,
                "title": "短信验证码注册"
              },
              {
                "markdown": "使用 **邮箱验证码注册** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **邮箱验证码**\n\n**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ email });\n\n// 验证验证码\nconst verifyRes = await auth.verify({\n  verification_id: verificationId,\n  verification_code: code\n});\n\n// 注册（如用户已存在则自动登录）\nawait auth.signUp({\n  email,\n  verification_code: code,\n  verification_token: verifyRes.verification_token,\n  name: `user_${email.slice(-4)}`,\n  password: \"admin@123\"\n});\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [email, setEmail] = useState(\"\");\n  const [code, setCode] = useState(\"\");\n  const [verificationId, setVerificationId] = useState(\"\");\n  const [message, setMessage] = useState(\"\");\n\n  // 发送验证码\n  const sendCode = async () => {\n    try {\n      const auth = cloudbase.auth();\n      const res = await auth.getVerification({ email });\n      setVerificationId(res.verification_id);\n      setMessage(\"验证码已发送！\");\n    } catch (error) {\n      setMessage(\"发送失败：\" + error.message);\n    }\n  };\n\n  // 注册\n  const register = async () => {\n    try {\n      const auth = cloudbase.auth();\n      // 验证验证码\n      const verifyRes = await auth.verify({\n        verification_id: verificationId,\n        verification_code: code\n      });\n      // 注册（如用户已存在则自动登录）\n      await auth.signUp({\n        email,\n        verification_code: code,\n        verification_token: verifyRes.verification_token,\n        name: `user_${email.slice(-4)}`,\n        password: \"admin@123\"\n      });\n      setMessage(\"注册成功！\");\n    } catch (error) {\n      setMessage(\"注册失败：\" + error.message);\n    }\n  };\n\n  return (\n    <div>\n      <label>邮箱：</label>\n      <input\n        value={email}\n        onChange={e => setEmail(e.target.value)}\n        placeholder=\"example@email.com\"\n      />\n      <div>\n        <label>验证码：</label>\n        <input\n          value={code}\n          onChange={e => setCode(e.target.value)}\n          placeholder=\"验证码\"\n        />\n        <button disabled={!email} onClick={sendCode}>\n          发送验证码\n        </button>\n      </div>\n      <button disabled={!verificationId || !code} onClick={register}>\n        注册\n      </button>\n      {message && (\n        <p style={{ color: message.includes(\"成功\") ? \"green\" : \"red\" }}>\n          {message}\n        </p>\n      )}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 2,
                "title": "邮箱验证码注册"
              },
              {
                "markdown": "使用 **账号密码登录** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **用户名密码登录**\n\n**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\nawait auth.signIn({\n  username, // 可以是用户名、手机号或邮箱\n  password\n});\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [username, setUsername] = useState(\"\");\n  const [password, setPassword] = useState(\"\");\n  const [message, setMessage] = useState(\"\");\n\n  // 登录\n  const login = async () => {\n    try {\n      const auth = cloudbase.auth();\n      await auth.signIn({\n        username: username, // 可以是用户名、手机号或邮箱\n        password: password\n      });\n      setMessage(\"登录成功！\");\n    } catch (error) {\n      setMessage(\"登录失败：\" + error.message);\n    }\n  };\n\n  return (\n    <div>\n      <label>账号：</label>\n      <input\n        value={username}\n        onChange={e => setUsername(e.target.value)}\n        placeholder=\"用户名/手机号/邮箱\"\n      />\n      注：手机号登录请添加区号 +86\n      <br />\n      <label>密码：</label>\n      <input\n        type=\"password\"\n        value={password}\n        onChange={e => setPassword(e.target.value)}\n        placeholder=\"请输入密码\"\n      />\n      <br />\n      <button disabled={!username || !password} onClick={login}>\n        登录\n      </button>\n      {message && (\n        <p style={{ color: message.includes(\"成功\") ? \"green\" : \"red\" }}>\n          {message}\n        </p>\n      )}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 3,
                "id": "UserNameLogin",
                "title": "账号密码登录"
              },
              {
                "markdown": "使用 **短信验证码登录** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **短信验证码登录**\n\n**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ phone_number: `+86 ${phone}` });\n\n// 登录\nawait auth.signInWithSms({\n  verificationInfo: res,\n  verificationCode: code,\n  phoneNum: `+86 ${phone}`\n});\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [phone, setPhone] = useState(\"\");\n  const [code, setCode] = useState(\"\");\n  const [verificationInfo, setVerificationInfo] = useState(null);\n  const [message, setMessage] = useState(\"\");\n\n  // 发送验证码\n  const sendCode = async () => {\n    try {\n      const auth = cloudbase.auth();\n      const res = await auth.getVerification({ phone_number: `+86 ${phone}` });\n      setVerificationInfo(res);\n      setMessage(\"验证码已发送！\");\n    } catch (error) {\n      setMessage(\"发送失败：\" + error.message);\n    }\n  };\n\n  // 登录\n  const login = async () => {\n    try {\n      const auth = cloudbase.auth();\n      await auth.signInWithSms({\n        verificationInfo,\n        verificationCode: code,\n        phoneNum: `+86 ${phone}`\n      });\n      setMessage(\"登录成功！\");\n    } catch (error) {\n      setMessage(\"登录失败：\" + error.message);\n    }\n  };\n\n  return (\n    <div>\n      <label>手机号：</label>\n      <input\n        value={phone}\n        onChange={e => setPhone(e.target.value)}\n        placeholder=\"13800000000\"\n      />\n      <div>\n        <label>验证码：</label>\n        <input\n          value={code}\n          onChange={e => setCode(e.target.value)}\n          placeholder=\"验证码\"\n        />\n        <button onClick={sendCode} disabled={!phone}>\n          发送验证码\n        </button>\n      </div>\n      <button onClick={login} disabled={!verificationInfo || !code}>\n        登录\n      </button>\n      {message && (\n        <p style={{ color: message.includes(\"成功\") ? \"green\" : \"red\" }}>\n          {message}\n        </p>\n      )}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 4,
                "id": "PhoneNumberLogin",
                "title": "短信验证码登录"
              },
              {
                "markdown": "使用 **邮箱验证码登录** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **邮箱验证码**\n\n**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ email });\n\n// 登录\nawait auth.signInWithEmail({\n  verificationInfo: res,\n  verificationCode: code,\n  email\n});\n```\n\n**完整示例：**\n\n```jsx\nimport { useState } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [email, setEmail] = useState(\"\");\n  const [code, setCode] = useState(\"\");\n  const [verificationInfo, setVerificationInfo] = useState(null);\n  const [message, setMessage] = useState(\"\");\n\n  // 发送验证码\n  const sendCode = async () => {\n    try {\n      const auth = cloudbase.auth();\n      const res = await auth.getVerification({ email });\n      setVerificationInfo(res);\n      setMessage(\"验证码已发送！\");\n    } catch (error) {\n      setMessage(\"发送失败：\" + error.message);\n    }\n  };\n\n  // 登录\n  const login = async () => {\n    try {\n      const auth = cloudbase.auth();\n      await auth.signInWithEmail({\n        verificationInfo,\n        verificationCode: code,\n        email\n      });\n      setMessage(\"登录成功！\");\n    } catch (error) {\n      setMessage(\"登录失败：\" + error.message);\n    }\n  };\n\n  return (\n    <div>\n      <label>邮箱：</label>\n      <input\n        value={email}\n        onChange={e => setEmail(e.target.value)}\n        placeholder=\"example@email.com\"\n      />\n      <div>\n        <label>验证码：</label>\n        <input\n          value={code}\n          onChange={e => setCode(e.target.value)}\n          placeholder=\"验证码\"\n        />\n        <button onClick={sendCode} disabled={!email}>\n          发送验证码\n        </button>\n      </div>\n      <button onClick={login} disabled={!verificationInfo || !code}>\n        登录\n      </button>\n      {message && (\n        <p style={{ color: message.includes(\"成功\") ? \"green\" : \"red\" }}>\n          {message}\n        </p>\n      )}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 5,
                "id": "email",
                "title": "邮箱验证码登录"
              },
              {
                "markdown": "使用 **Google 授权登录** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **Google 授权登录**\n\n**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 步骤1：生成Google授权URL并跳转\nconst state = Date.now().toString();\nlocalStorage.setItem(\"google_login_state\", state);\nconst { uri } = await auth.genProviderRedirectUri({\n  provider_id: \"google\",\n  provider_redirect_uri: window.location.href,\n  state: state\n});\nwindow.location.href = uri;\n\n// 步骤2：使用code换取provider_token\nconst { provider_token } = await auth.grantProviderToken({\n  provider_id: \"google\",\n  provider_redirect_uri: window.location.origin + window.location.pathname,\n  provider_code: code\n});\n\n// 步骤3：使用provider_token登录\nawait auth.signInWithProvider({\n  provider_token: provider_token\n});\n```\n\n**完整示例：**\n\n```jsx\nimport { useState, useEffect } from \"react\";\nimport { cloudbase } from \"./utils/cloudbase\";\n\nfunction Page() {\n  const [message, setMessage] = useState(\"\");\n  const [isCallback, setIsCallback] = useState(false);\n\n  useEffect(() => {\n    // 检查是否是Google回调页面\n    const urlParams = new URLSearchParams(window.location.search);\n    const code = urlParams.get(\"code\");\n    const state = urlParams.get(\"state\");\n\n    if (code && state) {\n      setIsCallback(true);\n      handleGoogleCallback(code, state);\n    }\n  }, []);\n\n  // 步骤1：跳转到Google授权页\n  const startGoogleLogin = async () => {\n    try {\n      const auth = cloudbase.auth();\n      const state = Date.now().toString(); // 生成唯一标识，防止CSRF攻击\n\n      // 保存state到本地，用于回调时验证\n      localStorage.setItem(\"google_login_state\", state);\n\n      // 生成Google授权URL\n      const { uri } = await auth.genProviderRedirectUri({\n        provider_id: \"google\", // 固定值，代表Google开放平台\n        provider_redirect_uri: window.location.href, // 授权后回调当前页面\n        state: state\n      });\n\n      // 跳转到Google授权页\n      window.location.href = uri;\n    } catch (error) {\n      setMessage(\"跳转失败：\" + error.message);\n    }\n  };\n\n  // 步骤2和3：处理Google回调并完成登录\n  const handleGoogleCallback = async (code, state) => {\n    try {\n      // 验证state是否匹配，防止CSRF攻击\n      const savedState = localStorage.getItem(\"google_login_state\");\n      if (savedState !== state) {\n        setMessage(\"登录失败：状态验证失败\");\n        return;\n      }\n\n      const auth = cloudbase.auth();\n\n      // 使用code换取provider_token\n      const { provider_token } = await auth.grantProviderToken({\n        provider_id: \"google\",\n        provider_redirect_uri:\n          window.location.origin + window.location.pathname,\n        provider_code: code\n      });\n\n      try {\n        // 尝试直接登录\n        await auth.signInWithProvider({\n          provider_token: provider_token\n        });\n\n        setMessage(\"登录成功！\");\n\n        // 清除URL参数并清除本地存储\n        localStorage.removeItem(\"google_login_state\");\n        window.history.replaceState(\n          {},\n          document.title,\n          window.location.pathname\n        );\n      } catch (loginError) {\n        // 如果是首次Google登录，需要先注册并绑定\n        if (loginError.error === \"not_found\") {\n          setMessage(\"检测到首次Google登录，需要绑定账号...\");\n\n          // 这里需要引导用户完成注册流程\n          // 例如：收集手机号验证码进行注册\n          // 注册成功后调用 bindWithProvider 绑定Google身份\n\n          // 示例：假设已有其他方式注册的账号，直接绑定\n          await auth.bindWithProvider({\n            provider_token: provider_token\n          });\n\n          // 绑定成功后重新登录\n          await auth.signInWithProvider({\n            provider_token: provider_token\n          });\n\n          setMessage(\"绑定并登录成功！\");\n\n          // 清除URL参数和本地存储\n          localStorage.removeItem(\"google_login_state\");\n          window.history.replaceState(\n            {},\n            document.title,\n            window.location.pathname\n          );\n        } else {\n          throw loginError;\n        }\n      }\n    } catch (error) {\n      setMessage(\"登录失败：\" + error.message);\n      localStorage.removeItem(\"google_login_state\");\n    }\n  };\n\n  return (\n    <div>\n      {!isCallback && <button onClick={startGoogleLogin}>Google登录</button>}\n      {isCallback && <p>正在处理Google登录...</p>}\n      {message && (\n        <p style={{ color: message.includes(\"成功\") ? \"green\" : \"red\" }}>\n          {message}\n        </p>\n      )}\n    </div>\n  );\n}\n\nexport default Page;\n```",
                "index": 6,
                "id": "google",
                "title": "Google 授权登录"
              }
            ]
          }
        ]
      }
    ],
    "_id": "d84694f26960d98b0b5496155d821c0b",
    "_openid": "anon",
    "createdAt": 1767954827894,
    "updatedAt": 1770372666591
  },
  {
    "category": "框架集成,后端框架,Go",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": 22,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/http-api/basic/overview",
    "content": [
      {
        "markdown": "通过 **HTTP 请求** 在 **Go** 中调用各种云开发能力\n\n```bash\ngo get github.com/joho/godotenv\n```",
        "index": 1,
        "title": "安装依赖",
        "content": []
      },
      {
        "markdown": "新增如下代码到您的 **Go** 项目",
        "index": 2,
        "title": "初始化配置",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```go\npackage main\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\n\t\"github.com/joho/godotenv\"\n)\n\ntype CloudBaseClient struct {\n\tEnvID       string\n\tAccessToken string\n\tBaseURL     string\n\tHTTPClient  *http.Client\n}\n\nfunc NewCloudBaseClient() *CloudBaseClient {\n\tgodotenv.Load()\n\n\tenvID := os.Getenv(\"CLOUDBASE_ENV_ID\")\n\taccessToken := os.Getenv(\"CLOUDBASE_ACCESS_TOKEN\")\n\n\treturn &CloudBaseClient{\n\t\tEnvID:       envID,\n\t\tAccessToken: accessToken,\n\t\tBaseURL:     fmt.Sprintf(\"https://%s.api.tcloudbasegateway.com\", envID),\n\t\tHTTPClient:  &http.Client{},\n\t}\n}\n\nfunc (c *CloudBaseClient) Request(method, path string, body interface{}, customHeaders map[string]string) (interface{}, error) {\n\turl := c.BaseURL + path\n\n\tvar reqBody io.Reader\n\tif body != nil {\n\t\tjsonData, err := json.Marshal(body)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"JSON序列化失败: %w\", err)\n\t\t}\n\t\treqBody = bytes.NewBuffer(jsonData)\n\t}\n\n\treq, err := http.NewRequest(method, url, reqBody)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"创建请求失败: %w\", err)\n\t}\n\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\treq.Header.Set(\"Accept\", \"application/json\")\n\treq.Header.Set(\"Authorization\", \"Bearer \"+c.AccessToken)\n\n\tfor key, value := range customHeaders {\n\t\treq.Header.Set(key, value)\n\t}\n\n\tresp, err := c.HTTPClient.Do(req)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"请求失败: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode < 200 || resp.StatusCode >= 300 {\n\t\tbodyBytes, _ := io.ReadAll(resp.Body)\n\t\treturn nil, fmt.Errorf(\"请求失败，状态码: %d, 响应: %s\", resp.StatusCode, string(bodyBytes))\n\t}\n\n\tbodyBytes, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"读取响应失败: %w\", err)\n\t}\n\n\tif len(bodyBytes) == 0 {\n\t\treturn true, nil\n\t}\n\n\tvar result interface{}\n\tif err := json.Unmarshal(bodyBytes, &result); err != nil {\n\t\treturn nil, fmt.Errorf(\"JSON解析失败: %w\", err)\n\t}\n\n\treturn result, nil\n}\n\nvar Cloudbase = NewCloudBaseClient()\n```",
            "index": 1,
            "title": "cloudbase_client.go"
          },
          {
            "markdown": "> 💡提示：如需管理员权限，请通过 [云开发平台/ApiKey管理页](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}&#/env/apikey) 获取 APIKey 替换 CLOUDBASE_ACCESS_TOKEN\n\n```properties\n# 环境ID\nCLOUDBASE_ENV_ID={%ENV_ID%}\n\n# 匿名访问令牌\nCLOUDBASE_ACCESS_TOKEN={%PUBLISHABLE_KEY%}\n```",
            "index": 2,
            "title": ".env"
          }
        ]
      },
      {
        "sideTabs": [
          {
            "id": "pg-db",
            "title": "PostgreSQL 数据库"
          }
        ],
        "index": 3,
        "title": "调用云开发能力",
        "type": "codeTab",
        "content": [
          {
            "index": 1,
            "id": "pg-db",
            "title": "PostgreSQL 数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```go\npackage main\n\nimport (\n    \"fmt\"\n    \"net/http\"\n)\n\nfunc getPgData(cloudbase *CloudBaseClient, tableName string) {\n    // 查询 {%TABLE_NAME%}\n    path := fmt.Sprintf(\"/v1/rdb/rest/%s?select=*&limit=10\", tableName)\n    headers := map[string]string{\"Accept\": \"application/json\"}\n    data, err := cloudbase.Request(\"GET\", path, nil, headers)\n\n    if err != nil {\n        fmt.Println(\"错误:\", err)\n        return\n    }\n\n    fmt.Println(\"查询结果:\", data)\n}\n\n// 使用示例\n// func main() {\n//     cloudbase := &CloudBaseClient{ ... }\n//     getPgData(cloudbase, \"{%TABLE_NAME%}\")\n// }\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "```go\npackage main\n\nimport (\n    \"fmt\"\n    \"net/http\"\n)\n\nfunc addPgData(cloudbase *CloudBaseClient, tableName string) {\n    // 新增 {%TABLE_NAME%}\n    path := fmt.Sprintf(\"/v1/rdb/rest/%s\", tableName)\n    body := []byte(`{\"title\":\"新文章\",\"status\":\"draft\"}`)\n    headers := map[string]string{\"Content-Type\": \"application/json\", \"Prefer\": \"return=representation\"}\n    data, err := cloudbase.Request(\"POST\", path, body, headers)\n\n    if err != nil {\n        fmt.Println(\"错误:\", err)\n        return\n    }\n\n    fmt.Println(\"新增结果:\", data)\n}\n\n// 使用示例\n// func main() {\n//     cloudbase := &CloudBaseClient{ ... }\n//     addPgData(cloudbase, \"{%TABLE_NAME%}\")\n// }\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "```go\npackage main\n\nimport (\n    \"fmt\"\n    \"net/http\"\n)\n\nfunc updatePgData(cloudbase *CloudBaseClient, tableName string) {\n    // 更新 {%TABLE_NAME%}\n    path := fmt.Sprintf(\"/v1/rdb/rest/%s?id=eq.1\", tableName)\n    body := []byte(`{\"status\":\"published\"}`)\n    headers := map[string]string{\"Content-Type\": \"application/json\", \"Prefer\": \"return=representation\"}\n    data, err := cloudbase.Request(\"PATCH\", path, body, headers)\n\n    if err != nil {\n        fmt.Println(\"错误:\", err)\n        return\n    }\n\n    fmt.Println(\"更新结果:\", data)\n}\n\n// 使用示例\n// func main() {\n//     cloudbase := &CloudBaseClient{ ... }\n//     updatePgData(cloudbase, \"{%TABLE_NAME%}\")\n// }\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "```go\npackage main\n\nimport (\n    \"fmt\"\n    \"net/http\"\n)\n\nfunc upsertPgData(cloudbase *CloudBaseClient, tableName string) {\n    // 更新或创建 {%TABLE_NAME%}\n    path := fmt.Sprintf(\"/v1/rdb/rest/%s\", tableName)\n    body := []byte(`{\"id\":1,\"title\":\"标题\",\"status\":\"published\"}`)\n    headers := map[string]string{\"Content-Type\": \"application/json\", \"Prefer\": \"resolution=merge-duplicates,return=representation\"}\n    data, err := cloudbase.Request(\"POST\", path, body, headers)\n\n    if err != nil {\n        fmt.Println(\"错误:\", err)\n        return\n    }\n\n    fmt.Println(\"更新或创建结果:\", data)\n}\n\n// 使用示例\n// func main() {\n//     cloudbase := &CloudBaseClient{ ... }\n//     upsertPgData(cloudbase, \"{%TABLE_NAME%}\")\n// }\n```",
                "index": 4,
                "title": "更新或创建数据"
              },
              {
                "markdown": "```go\npackage main\n\nimport (\n    \"fmt\"\n    \"net/http\"\n)\n\nfunc deletePgData(cloudbase *CloudBaseClient, tableName string) {\n    // 删除 {%TABLE_NAME%}\n    path := fmt.Sprintf(\"/v1/rdb/rest/%s?id=eq.1\", tableName)\n    headers := map[string]string{\"Accept\": \"application/json\"}\n    data, err := cloudbase.Request(\"DELETE\", path, nil, headers)\n\n    if err != nil {\n        fmt.Println(\"错误:\", err)\n        return\n    }\n\n    fmt.Println(\"删除完成:\", data)\n}\n\n// 使用示例\n// func main() {\n//     cloudbase := &CloudBaseClient{ ... }\n//     deletePgData(cloudbase, \"{%TABLE_NAME%}\")\n// }\n```",
                "index": 5,
                "title": "删除数据"
              }
            ]
          },
          {
            "index": 1,
            "id": "mysql-db",
            "title": "MySQL数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```go\npackage main\n\nimport \"fmt\"\n\nfunc GetMySQLData(tableName string) (interface{}, error) {\n\tpath := fmt.Sprintf(\"/v1/rdb/rest/%s?limit=10\", tableName)\n\tdata, err := Cloudbase.Request(\"GET\", path, nil, nil)\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfmt.Println(\"查询成功:\", data)\n\treturn data, nil\n}\n\n// 使用示例\nfunc main() {\n\tresult, err := GetMySQLData(\"{%TABLE_NAME%}\")\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t}\n}\n```",
                "index": 1,
                "title": "查询数据",
                "content": []
              },
              {
                "markdown": "```go\npackage main\n\nimport \"fmt\"\n\nfunc AddMySQLData(tableName string, data map[string]interface{}) (interface{}, error) {\n\tpath := fmt.Sprintf(\"/v1/rdb/rest/%s\", tableName)\n\tresult, err := Cloudbase.Request(\"POST\", path, data, nil)\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfmt.Println(\"新增成功:\", result)\n\treturn result, nil\n}\n\n// 使用示例\nfunc main() {\n\tresult, err := AddMySQLData(\"{%TABLE_NAME%}\", map[string]interface{}{\n\t\t\"title\": \"示例标题\",\n\t})\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t}\n}\n```",
                "index": 2,
                "title": "新增数据",
                "content": []
              },
              {
                "markdown": "```go\npackage main\n\nimport \"fmt\"\n\nfunc UpdateMySQLData(tableName, dataID string, data map[string]interface{}) (interface{}, error) {\n\tpath := fmt.Sprintf(\"/v1/rdb/rest/%s?id=eq.%s\", tableName, dataID)\n\tresult, err := Cloudbase.Request(\"PATCH\", path, data, nil)\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfmt.Println(\"更新成功:\", result)\n\treturn result, nil\n}\n\n// 使用示例\nfunc main() {\n\tresult, err := UpdateMySQLData(\"{%TABLE_NAME%}\", \"<数据id>\", map[string]interface{}{\n\t\t\"title\": \"新标题\",\n\t})\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t}\n}\n```",
                "index": 3,
                "title": "更新数据",
                "content": []
              },
              {
                "markdown": "```go\npackage main\n\nimport \"fmt\"\n\nfunc DeleteMySQLData(tableName, dataID string) (bool, error) {\n\tpath := fmt.Sprintf(\"/v1/rdb/rest/%s?id=eq.%s\", tableName, dataID)\n\t_, err := Cloudbase.Request(\"DELETE\", path, nil, nil)\n\n\tif err != nil {\n\t\treturn false, err\n\t}\n\n\tfmt.Println(\"删除成功\")\n\treturn true, nil\n}\n\n// 使用示例\nfunc main() {\n\tsuccess, err := DeleteMySQLData(\"{%TABLE_NAME%}\", \"<数据id>\")\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t}\n\tfmt.Println(\"删除结果:\", success)\n}\n```",
                "index": 4,
                "title": "删除数据",
                "content": []
              }
            ]
          },
          {
            "index": 2,
            "id": "data-model",
            "title": "数据模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```go\npackage main\n\nimport \"fmt\"\n\nfunc GetModelData(modelName, envType string) ([]interface{}, error) {\n\tif envType == \"\" {\n\t\tenvType = \"prod\"\n\t}\n\n\tpath := fmt.Sprintf(\"/v1/model/%s/%s/list\", envType, modelName)\n\tpayload := map[string]interface{}{\n\t\t\"pageSize\":   10,\n\t\t\"pageNumber\": 1,\n\t\t\"getCount\":   true,\n\t}\n\n\tresult, err := Cloudbase.Request(\"POST\", path, payload, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif resultMap, ok := result.(map[string]interface{}); ok {\n\t\tif data, ok := resultMap[\"data\"].(map[string]interface{}); ok {\n\t\t\tif records, ok := data[\"records\"].([]interface{}); ok {\n\t\t\t\tfmt.Println(\"查询成功:\", records)\n\t\t\t\treturn records, nil\n\t\t\t}\n\t\t}\n\t}\n\n\treturn []interface{}{}, nil\n}\n\n// 使用示例\nfunc main() {\n\trecords, err := GetModelData(\"{%TABLE_NAME%}\", \"prod\")\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t}\n}\n```",
                "index": 1,
                "title": "查询数据",
                "content": []
              },
              {
                "markdown": "```go\npackage main\n\nimport \"fmt\"\n\nfunc AddModelData(modelName string, data map[string]interface{}, envType string) (interface{}, error) {\n\tif envType == \"\" {\n\t\tenvType = \"prod\"\n\t}\n\n\tpath := fmt.Sprintf(\"/v1/model/%s/%s/create\", envType, modelName)\n\tpayload := map[string]interface{}{\n\t\t\"data\": data,\n\t}\n\n\tresult, err := Cloudbase.Request(\"POST\", path, payload, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif resultMap, ok := result.(map[string]interface{}); ok {\n\t\tif dataMap, ok := resultMap[\"data\"].(map[string]interface{}); ok {\n\t\t\tif docID, ok := dataMap[\"id\"].(string); ok {\n\t\t\t\tfmt.Printf(\"新增成功! id: %s\\n\", docID)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result, nil\n}\n\n// 使用示例\nfunc main() {\n\tresult, err := AddModelData(\"{%TABLE_NAME%}\", map[string]interface{}{\n\t\t\"title\": \"示例标题\",\n\t}, \"prod\")\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t}\n}\n```",
                "index": 2,
                "title": "新增数据",
                "content": []
              },
              {
                "markdown": "```go\npackage main\n\nimport \"fmt\"\n\nfunc UpdateModelData(modelName, dataID string, data map[string]interface{}, envType string) (bool, error) {\n\tif envType == \"\" {\n\t\tenvType = \"prod\"\n\t}\n\n\tpath := fmt.Sprintf(\"/v1/model/%s/%s/update\", envType, modelName)\n\tpayload := map[string]interface{}{\n\t\t\"data\": data,\n\t\t\"filter\": map[string]interface{}{\n\t\t\t\"where\": map[string]interface{}{\n\t\t\t\t\"_id\": map[string]interface{}{\n\t\t\t\t\t\"$eq\": dataID,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\t_, err := Cloudbase.Request(\"PUT\", path, payload, nil)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\n\tfmt.Println(\"更新成功!\")\n\treturn true, nil\n}\n\n// 使用示例\nfunc main() {\n\tsuccess, err := UpdateModelData(\"{%TABLE_NAME%}\", \"<数据id>\", map[string]interface{}{\n\t\t\"title\": \"新标题\",\n\t}, \"prod\")\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t}\n}\n```",
                "index": 3,
                "title": "更新数据",
                "content": []
              },
              {
                "markdown": "```go\npackage main\n\nimport \"fmt\"\n\nfunc DeleteModelData(modelName, dataID, envType string) (bool, error) {\n\tif envType == \"\" {\n\t\tenvType = \"prod\"\n\t}\n\n\tpath := fmt.Sprintf(\"/v1/model/%s/%s/delete\", envType, modelName)\n\tpayload := map[string]interface{}{\n\t\t\"filter\": map[string]interface{}{\n\t\t\t\"where\": map[string]interface{}{\n\t\t\t\t\"_id\": map[string]interface{}{\n\t\t\t\t\t\"$eq\": dataID,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\t_, err := Cloudbase.Request(\"POST\", path, payload, nil)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\n\tfmt.Println(\"删除成功!\")\n\treturn true, nil\n}\n\n// 使用示例\nfunc main() {\n\tsuccess, err := DeleteModelData(\"{%TABLE_NAME%}\", \"<数据id>\", \"prod\")\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t}\n}\n```",
                "index": 4,
                "title": "删除数据",
                "content": []
              }
            ]
          },
          {
            "markdown": "```go\npackage main\n\nimport \"fmt\"\n\nfunc CallFunction(functionName string, data map[string]interface{}) (interface{}, error) {\n\tif data == nil {\n\t\tdata = map[string]interface{}{}\n\t}\n\n\tpath := fmt.Sprintf(\"/v1/functions/%s\", functionName)\n\tresult, err := Cloudbase.Request(\"POST\", path, data, nil)\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfmt.Println(\"云函数调用结果:\", result)\n\treturn result, nil\n}\n\n// 使用示例\nfunc main() {\n\tresult, err := CallFunction(\"{%FUNCTION_NAME%}\", nil)\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t}\n}\n```",
            "index": 3,
            "id": "scf",
            "title": "云函数"
          },
          {
            "markdown": "```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\nfunc CallContainer(serviceName, path, method string, data map[string]interface{}) (interface{}, error) {\n\tif method == \"\" {\n\t\tmethod = \"GET\"\n\t}\n\n\tfullPath := fmt.Sprintf(\"/v1/cloudrun/%s/%s\", serviceName, path)\n\tfullPath = strings.TrimSuffix(fullPath, \"/\")\n\n\tresult, err := Cloudbase.Request(strings.ToUpper(method), fullPath, data, nil)\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfmt.Println(\"云托管调用结果:\", result)\n\treturn result, nil\n}\n\n// 使用示例\nfunc main() {\n\tresult, err := CallContainer(\"{%SERVICE_NAME%}\", \"\", \"GET\", nil)\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t}\n}\n```",
            "index": 4,
            "id": "run",
            "title": "云托管"
          },
          {
            "index": 5,
            "id": "storage",
            "title": "云存储",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"time\"\n)\n\nfunc UploadFile(filePath, objectID string) (map[string]interface{}, error) {\n\tif objectID == \"\" {\n\t\tfilename := filepath.Base(filePath)\n\t\ttimestamp := time.Now().UnixMilli()\n\t\tobjectID = fmt.Sprintf(\"uploads/%d-%s\", timestamp, filename)\n\t}\n\n\tuploadInfo, err := Cloudbase.Request(\"POST\", \"/v1/storages/get-objects-upload-info\",\n\t\t[]map[string]interface{}{{\"objectId\": objectID}}, nil)\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tinfoList, ok := uploadInfo.([]interface{})\n\tif !ok || len(infoList) == 0 {\n\t\treturn nil, fmt.Errorf(\"获取上传信息失败\")\n\t}\n\n\tinfo := infoList[0].(map[string]interface{})\n\tuploadURL := info[\"uploadUrl\"].(string)\n\n\tfile, err := os.Open(filePath)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"文件不存在: %s\", filePath)\n\t}\n\tdefer file.Close()\n\n\tfileData, err := io.ReadAll(file)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"读取文件失败: %w\", err)\n\t}\n\n\treq, err := http.NewRequest(\"PUT\", uploadURL, bytes.NewReader(fileData))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treq.Header.Set(\"Authorization\", info[\"authorization\"].(string))\n\treq.Header.Set(\"X-Cos-Security-Token\", info[\"token\"].(string))\n\treq.Header.Set(\"X-Cos-Meta-Fileid\", info[\"cloudObjectMeta\"].(string))\n\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"文件上传失败: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode < 200 || resp.StatusCode >= 300 {\n\t\treturn nil, fmt.Errorf(\"上传失败，状态码: %d\", resp.StatusCode)\n\t}\n\n\tresult := map[string]interface{}{\n\t\t\"cloudObjectId\": info[\"cloudObjectId\"],\n\t\t\"downloadUrl\":   info[\"downloadUrl\"],\n\t\t\"objectId\":      objectID,\n\t}\n\n\tfmt.Println(\"文件上传成功:\")\n\tfmt.Printf(\"- 对象ID: %s\\n\", result[\"objectId\"])\n\tfmt.Printf(\"- 下载URL: %s\\n\", result[\"downloadUrl\"])\n\n\treturn result, nil\n}\n\n// 使用示例\nfunc main() {\n\tresult, err := UploadFile(\"./example.jpg\", \"\")\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t}\n}\n```",
                "index": 1,
                "title": "上传文件",
                "content": []
              },
              {
                "markdown": "```go\npackage main\n\nimport \"fmt\"\n\nfunc GetFileURL(cloudObjectID string) (string, error) {\n\tresult, err := Cloudbase.Request(\"POST\", \"/v1/storages/get-objects-download-info\",\n\t\t[]map[string]interface{}{{\"cloudObjectId\": cloudObjectID}}, nil)\n\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tif resultList, ok := result.([]interface{}); ok && len(resultList) > 0 {\n\t\tif info, ok := resultList[0].(map[string]interface{}); ok {\n\t\t\tif downloadURL, ok := info[\"downloadUrl\"].(string); ok {\n\t\t\t\tfmt.Println(\"文件链接:\", downloadURL)\n\t\t\t\treturn downloadURL, nil\n\t\t\t}\n\t\t}\n\t}\n\n\treturn \"\", fmt.Errorf(\"获取文件链接失败\")\n}\n\n// 使用示例\nfunc main() {\n\tfileURL, err := GetFileURL(\"cloud://xxx.png\")\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t}\n}\n```",
                "index": 2,
                "title": "获取文件链接",
                "content": []
              },
              {
                "markdown": "```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n)\n\nfunc DownloadFile(cloudObjectID, savePath string) (bool, error) {\n\tif savePath == \"\" {\n\t\tsavePath = \"./\"\n\t}\n\n\tresult, err := Cloudbase.Request(\"POST\", \"/v1/storages/get-objects-download-info\",\n\t\t[]map[string]interface{}{{\"cloudObjectId\": cloudObjectID}}, nil)\n\n\tif err != nil {\n\t\treturn false, err\n\t}\n\n\tif resultList, ok := result.([]interface{}); ok && len(resultList) > 0 {\n\t\tif info, ok := resultList[0].(map[string]interface{}); ok {\n\t\t\tdownloadURL := info[\"downloadUrl\"].(string)\n\n\t\t\tparts := strings.Split(downloadURL, \"/\")\n\t\t\tfilename := strings.Split(parts[len(parts)-1], \"?\")[0]\n\n\t\t\tfileInfo, err := os.Stat(savePath)\n\t\t\tvar fullPath string\n\t\t\tif err == nil && fileInfo.IsDir() || strings.HasSuffix(savePath, \"/\") {\n\t\t\t\tfullPath = filepath.Join(savePath, filename)\n\t\t\t} else {\n\t\t\t\tfullPath = savePath\n\t\t\t}\n\n\t\t\tresp, err := http.Get(downloadURL)\n\t\t\tif err != nil {\n\t\t\t\treturn false, fmt.Errorf(\"下载失败: %w\", err)\n\t\t\t}\n\t\t\tdefer resp.Body.Close()\n\n\t\t\tif resp.StatusCode < 200 || resp.StatusCode >= 300 {\n\t\t\t\treturn false, fmt.Errorf(\"下载失败，状态码: %d\", resp.StatusCode)\n\t\t\t}\n\n\t\t\toutFile, err := os.Create(fullPath)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tdefer outFile.Close()\n\n\t\t\t_, err = io.Copy(outFile, resp.Body)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\n\t\t\tfmt.Printf(\"下载成功! 文件已保存到: %s\\n\", fullPath)\n\t\t\treturn true, nil\n\t\t}\n\t}\n\n\treturn false, fmt.Errorf(\"下载失败\")\n}\n\n// 使用示例\nfunc main() {\n\t// 下载到当前目录，使用原文件名\n\tsuccess, err := DownloadFile(\"cloud://xxx.png\", \"\")\n\n\t// 下载到指定目录\n\t// success, err := DownloadFile(\"cloud://xxx.png\", \"./downloads/\")\n\n\t// 下载并重命名\n\t// success, err := DownloadFile(\"cloud://xxx.png\", \"./my-image.png\")\n\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t}\n}\n```",
                "index": 3,
                "title": "下载文件",
                "content": []
              },
              {
                "markdown": "```go\npackage main\n\nimport \"fmt\"\n\nfunc DeleteFile(cloudObjectIDs interface{}) (bool, error) {\n\tvar data []map[string]interface{}\n\n\tswitch v := cloudObjectIDs.(type) {\n\tcase string:\n\t\tdata = []map[string]interface{}{{\"cloudObjectId\": v}}\n\tcase []string:\n\t\tfor _, id := range v {\n\t\t\tdata = append(data, map[string]interface{}{\"cloudObjectId\": id})\n\t\t}\n\tdefault:\n\t\treturn false, fmt.Errorf(\"不支持的参数类型\")\n\t}\n\n\t_, err := Cloudbase.Request(\"POST\", \"/v1/storages/delete-objects\", data, nil)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\n\tfmt.Println(\"删除成功!\")\n\treturn true, nil\n}\n\n// 使用示例\nfunc main() {\n\tsuccess, err := DeleteFile(\"cloud://xxx.png\")\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t}\n}\n```",
                "index": 4,
                "title": "删除文件",
                "content": []
              }
            ]
          },
          {
            "index": 6,
            "id": "ai-model",
            "title": "大模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```go\npackage main\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"strings\"\n)\n\nfunc StreamText(model, subModel string, messages []map[string]string) (string, error) {\n\tpayload := map[string]interface{}{\n\t\t\"model\":    subModel,\n\t\t\"messages\": messages,\n\t\t\"stream\":   true,\n\t}\n\n\tjsonData, err := json.Marshal(payload)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\turl := fmt.Sprintf(\"%s/v1/ai/%s/chat/completions\", Cloudbase.BaseURL, model)\n\treq, err := http.NewRequest(\"POST\", url, bytes.NewBuffer(jsonData))\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\treq.Header.Set(\"Accept\", \"text/event-stream\")\n\treq.Header.Set(\"Authorization\", \"Bearer \"+Cloudbase.AccessToken)\n\n\tresp, err := Cloudbase.HTTPClient.Do(req)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"AI 调用失败: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\tfmt.Println(\"AI 流式响应:\")\n\tfullContent := \"\"\n\tscanner := bufio.NewScanner(resp.Body)\n\n\tfor scanner.Scan() {\n\t\tline := scanner.Text()\n\t\tif strings.HasPrefix(line, \"data: \") {\n\t\t\tdataStr := strings.TrimPrefix(line, \"data: \")\n\t\t\tif strings.TrimSpace(dataStr) != \"[DONE]\" {\n\t\t\t\tvar chunkData map[string]interface{}\n\t\t\t\tif err := json.Unmarshal([]byte(dataStr), &chunkData); err == nil {\n\t\t\t\t\tif choices, ok := chunkData[\"choices\"].([]interface{}); ok && len(choices) > 0 {\n\t\t\t\t\t\tif choice, ok := choices[0].(map[string]interface{}); ok {\n\t\t\t\t\t\t\tif delta, ok := choice[\"delta\"].(map[string]interface{}); ok {\n\t\t\t\t\t\t\t\tif content, ok := delta[\"content\"].(string); ok {\n\t\t\t\t\t\t\t\t\tfmt.Print(content)\n\t\t\t\t\t\t\t\t\tfullContent += content\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tfmt.Println()\n\treturn fullContent, nil\n}\n\n// 使用示例\nfunc main() {\n\tresponse, err := StreamText(\n\t\t\"{%AI_MODEL_NAME%}\",\n\t\t\"{%AI_SUB_MODEL_NAME%}\",\n\t\t[]map[string]string{\n\t\t\t{\"role\": \"system\", \"content\": \"请严格按照七言绝句或七言律诗的格律要求创作，平仄需符合规则，押韵要和谐自然，韵脚字需在同一韵部。\"},\n\t\t\t{\"role\": \"user\", \"content\": \"春天\"},\n\t\t},\n\t)\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t}\n}\n```",
                "index": 1,
                "id": "text-aiModel",
                "title": "生文模型",
                "content": []
              },
              {
                "markdown": "生图模型通过调用云函数来实现，在生图模型页面点击「一键创建云函数」，函数调用示例如下：\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc GenerateImage(prompt string) (map[string]interface{}, error) {\n\t// 准备调用参数\n\tdata := map[string]interface{}{\n\t\t\"prompt\": prompt,\n\t}\n\n\t// 调用云函数生成图片\n\tresult, err := Cloudbase.Request(\"POST\", \"/v1/functions/<YOUR_FUNCTION_NAME>\", data, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif resultMap, ok := result.(map[string]interface{}); ok {\n\t\tif success, ok := resultMap[\"success\"].(bool); ok && success {\n\t\t\timageUrl := resultMap[\"imageUrl\"].(string)\n\t\t\trevisedPrompt := \"\"\n\t\t\tif rp, ok := resultMap[\"revised_prompt\"].(string); ok {\n\t\t\t\trevisedPrompt = rp\n\t\t\t}\n\n\t\t\tfmt.Println(\"生成成功!\")\n\t\t\tfmt.Printf(\"图片URL: %s\\n\", imageUrl)\n\t\t\tfmt.Printf(\"优化后的提示词: %s\\n\", revisedPrompt)\n\t\t\tfmt.Println(\"注意: 图片URL有效期为24小时\")\n\n\t\t\treturn resultMap, nil\n\t\t} else {\n\t\t\tcode := \"\"\n\t\t\tmessage := \"\"\n\t\t\tif c, ok := resultMap[\"code\"].(string); ok {\n\t\t\t\tcode = c\n\t\t\t}\n\t\t\tif m, ok := resultMap[\"message\"].(string); ok {\n\t\t\t\tmessage = m\n\t\t\t}\n\t\t\treturn nil, fmt.Errorf(\"生成失败: %s - %s\", code, message)\n\t\t}\n\t}\n\n\treturn nil, fmt.Errorf(\"请求失败\")\n}\n\n// 使用示例\nfunc main() {\n\tresult, err := GenerateImage(\"一只可爱的猫咪在阳光下玩耍\")\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t} else {\n\t\tfmt.Println(\"图片生成完成:\", result)\n\t}\n}\n```",
                "index": 2,
                "id": "image-aiModel",
                "title": "生图模型",
                "content": []
              }
            ]
          },
          {
            "markdown": "",
            "index": 7,
            "id": "agent",
            "title": "Agent",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```go\n/*\nGo 调用 Agent 示例（AG-UI 协议）\n协议文档：https://docs.cloudbase.net/ai/agent-development/protocol\n*/\npackage main\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n)\n\n// Message AG-UI 协议消息结构\ntype Message struct {\n\tID      string `json:\"id\"`\n\tRole    string `json:\"role\"`\n\tContent string `json:\"content\"`\n}\n\n// AGUIRequest AG-UI 协议请求体\ntype AGUIRequest struct {\n\tMessages       []Message              `json:\"messages\"`                 // 必填：消息列表\n\tThreadID       string                 `json:\"threadId,omitempty\"`       // 可选：会话ID，用于多轮对话\n\tRunID          string                 `json:\"runId,omitempty\"`          // 可选：运行ID，用于追踪执行\n\tTools          []interface{}          `json:\"tools,omitempty\"`          // 可选：前端工具定义\n\tContext        []interface{}          `json:\"context,omitempty\"`        // 可选：上下文信息\n\tForwardedProps map[string]interface{} `json:\"forwardedProps,omitempty\"` // 可选：透传参数\n}\n\nfunc ChatWithAgentStream(botID, msg string, history []Message) (string, error) {\n\tif history == nil {\n\t\thistory = []Message{}\n\t}\n\n\turl := fmt.Sprintf(\"%s/v1/aibot/bots/%s/send-message\", Cloudbase.BaseURL, botID)\n\n\t// 构建消息列表（AG-UI 协议格式）\n\tmessages := make([]Message, 0, len(history)+1)\n\n\t// 添加历史消息\n\tmessages = append(messages, history...)\n\n\t// 添加当前用户消息\n\tmessages = append(messages, Message{\n\t\tID:      fmt.Sprintf(\"msg-%s\", uuid.New().String()),\n\t\tRole:    \"user\",\n\t\tContent: msg,\n\t})\n\n\t// AG-UI 协议请求体\n\tpayload := AGUIRequest{\n\t\tMessages:       messages,\n\t\tThreadID:       fmt.Sprintf(\"thread-%s\", uuid.New().String()),\n\t\tRunID:          fmt.Sprintf(\"run-%s\", uuid.New().String()),\n\t\tTools:          []interface{}{},\n\t\tContext:        []interface{}{},\n\t\tForwardedProps: map[string]interface{}{},\n\t}\n\n\tjsonData, err := json.Marshal(payload)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treq, err := http.NewRequest(\"POST\", url, bytes.NewBuffer(jsonData))\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\treq.Header.Set(\"Accept\", \"text/event-stream\")\n\treq.Header.Set(\"Authorization\", \"Bearer \"+Cloudbase.AccessToken)\n\n\tclient := &http.Client{Timeout: 30 * time.Second}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"AI 调用失败: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\tfmt.Println(\"AI 流式响应:\")\n\tfullContent := \"\"\n\tscanner := bufio.NewScanner(resp.Body)\n\n\tfor scanner.Scan() {\n\t\tline := strings.TrimSpace(scanner.Text())\n\t\tif strings.HasPrefix(line, \"data: \") {\n\t\t\tdataStr := strings.TrimSpace(strings.TrimPrefix(line, \"data: \"))\n\t\t\tif dataStr != \"\" && dataStr != \"[DONE]\" {\n\t\t\t\tvar chunkData map[string]interface{}\n\t\t\t\tif err := json.Unmarshal([]byte(dataStr), &chunkData); err == nil {\n\t\t\t\t\tvar content string\n\t\t\t\t\tif c, ok := chunkData[\"content\"].(string); ok {\n\t\t\t\t\t\tcontent = c\n\t\t\t\t\t} else if choices, ok := chunkData[\"choices\"].([]interface{}); ok && len(choices) > 0 {\n\t\t\t\t\t\tif choice, ok := choices[0].(map[string]interface{}); ok {\n\t\t\t\t\t\t\tif delta, ok := choice[\"delta\"].(map[string]interface{}); ok {\n\t\t\t\t\t\t\t\tif c, ok := delta[\"content\"].(string); ok {\n\t\t\t\t\t\t\t\t\tcontent = c\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if message, ok := choice[\"message\"].(map[string]interface{}); ok {\n\t\t\t\t\t\t\t\tif c, ok := message[\"content\"].(string); ok {\n\t\t\t\t\t\t\t\t\tcontent = c\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif content != \"\" {\n\t\t\t\t\t\tfmt.Print(content)\n\t\t\t\t\t\tfullContent += content\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tfmt.Println()\n\treturn fullContent, nil\n}\n\n// 使用示例\nfunc main() {\n\tresponse, err := ChatWithAgentStream(\"{%AGENT_ID%}\", \"你是谁\", nil)\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t}\n\t_ = response\n}\n\n```",
                "index": 0,
                "id": "scf",
                "title": "函数型"
              },
              {
                "markdown": "```go\npackage main\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"strings\"\n\t\"time\"\n)\n\nfunc ChatWithAgentStream(botID, msg string, history []map[string]string) (string, error) {\n\tif history == nil {\n\t\thistory = []map[string]string{}\n\t}\n\n\turl := fmt.Sprintf(\"%s/v1/aibot/bots/%s/send-message\", Cloudbase.BaseURL, botID)\n\tpayload := map[string]interface{}{\n\t\t\"history\": history,\n\t\t\"msg\":     msg,\n\t}\n\n\tjsonData, err := json.Marshal(payload)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treq, err := http.NewRequest(\"POST\", url, bytes.NewBuffer(jsonData))\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\treq.Header.Set(\"Accept\", \"text/event-stream\")\n\treq.Header.Set(\"Authorization\", \"Bearer \"+Cloudbase.AccessToken)\n\n\tclient := &http.Client{Timeout: 30 * time.Second}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"AI 调用失败: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\tfmt.Println(\"AI 流式响应:\")\n\tfullContent := \"\"\n\tscanner := bufio.NewScanner(resp.Body)\n\n\tfor scanner.Scan() {\n\t\tline := strings.TrimSpace(scanner.Text())\n\t\tif strings.HasPrefix(line, \"data: \") {\n\t\t\tdataStr := strings.TrimSpace(strings.TrimPrefix(line, \"data: \"))\n\t\t\tif dataStr != \"\" && dataStr != \"[DONE]\" {\n\t\t\t\tvar chunkData map[string]interface{}\n\t\t\t\tif err := json.Unmarshal([]byte(dataStr), &chunkData); err == nil {\n\t\t\t\t\tvar content string\n\t\t\t\t\tif c, ok := chunkData[\"content\"].(string); ok {\n\t\t\t\t\t\tcontent = c\n\t\t\t\t\t} else if choices, ok := chunkData[\"choices\"].([]interface{}); ok && len(choices) > 0 {\n\t\t\t\t\t\tif choice, ok := choices[0].(map[string]interface{}); ok {\n\t\t\t\t\t\t\tif delta, ok := choice[\"delta\"].(map[string]interface{}); ok {\n\t\t\t\t\t\t\t\tif c, ok := delta[\"content\"].(string); ok {\n\t\t\t\t\t\t\t\t\tcontent = c\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if message, ok := choice[\"message\"].(map[string]interface{}); ok {\n\t\t\t\t\t\t\t\tif c, ok := message[\"content\"].(string); ok {\n\t\t\t\t\t\t\t\t\tcontent = c\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif content != \"\" {\n\t\t\t\t\t\tfmt.Print(content)\n\t\t\t\t\t\tfullContent += content\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tfmt.Println()\n\treturn fullContent, nil\n}\n\n// 使用示例\nfunc main() {\n\tresponse, err := ChatWithAgentStream(\"{%AGENT_ID%}\", \"你是谁\", nil)\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t}\n}\n```",
                "index": 1,
                "id": "baas",
                "title": "普通型"
              }
            ]
          },
          {
            "markdown": "```go\npackage main\n\nimport \"fmt\"\n\nfunc SignIn(username, password string) (map[string]interface{}, error) {\n\tresult, err := Cloudbase.Request(\"POST\", \"/auth/v1/signin\",\n\t\tmap[string]interface{}{\n\t\t\t\"username\": username,\n\t\t\t\"password\": password,\n\t\t}, nil)\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif resultMap, ok := result.(map[string]interface{}); ok {\n\t\taccessToken := resultMap[\"access_token\"].(string)\n\t\tuserID := resultMap[\"sub\"].(string)\n\n\t\tfmt.Printf(\"登录成功! 用户ID: %s\\n\", userID)\n\t\tfmt.Printf(\"访问令牌: %s...\\n\", accessToken[:20])\n\t\treturn resultMap, nil\n\t}\n\n\treturn nil, fmt.Errorf(\"登录失败\")\n}\n\n// 使用示例\nfunc main() {\n\tresult, err := SignIn(\"your_username\", \"your_password\")\n\tif err != nil {\n\t\tfmt.Println(\"错误:\", err)\n\t}\n}\n```",
            "index": 8,
            "id": "identity",
            "title": "身份认证"
          }
        ]
      }
    ],
    "_id": "dab5292a6964c1d80bc39f9c47676652",
    "_openid": "anon",
    "createdAt": 1768210904876,
    "updatedAt": 1770370661156
  },
  {
    "category": "框架集成,小程序 / 小游戏,微信小程序",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": -1,
    "hasTemplate": false,
    "docsUrl": "https://developers.weixin.qq.com/miniprogram/dev/wxcloudservice/wxcloud/guide/init.html",
    "content": [
      {
        "markdown": "在 `app.js` 中初始化云开发：",
        "index": 1,
        "title": "初始化 SDK",
        "type": "codeTab",
        "content": [
          {
            "markdown": "大部分云开发能力可通过 `小程序原生 API` 直接调用，无需安装 SDK，若 `原生API` 不支持请使用 `Client SDK` 进行调用\n\n```js\nApp({\n  onLaunch() {\n    wx.cloud.init({\n      env: \"{%ENV_ID%}\"\n    });\n  }\n});\n```",
            "index": 1,
            "title": "原生API 初始化",
            "content": []
          },
          {
            "markdown": "**安装**\n\n使用 Client SDK 前请先安装 SDK\n\n在小程序 `package.json` 所在目录（通常为 `miniprogram` 目录）执行：\n\n```bash\nnpm i @cloudbase/wx-cloud-client-sdk --save\n```\n\n安装完成后，在微信开发者工具点击 **工具 → 构建 npm**。\n\n**初始化**\n\n```js\nconst { init } = require(\"@cloudbase/wx-cloud-client-sdk\");\n\nApp({\n  onLaunch() {\n    wx.cloud.init({\n      env: \"{%ENV_ID%}\"\n    });\n    this.globalData.cloudbase = init(wx.cloud);\n  },\n  globalData: {}\n});\n```",
            "index": 2,
            "title": "Client SDK 初始化",
            "content": []
          }
        ]
      },
      {
        "sideTabs": [
          {
            "id": "pg-db",
            "title": "PostgreSQL 数据库"
          }
        ],
        "index": 2,
        "title": "调用云开发能力",
        "type": "codeTab",
        "content": [
          {
            "index": 1,
            "id": "pg-db",
            "title": "PostgreSQL 数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\nconst cloudbase = getApp().globalData.cloudbase;\n\n// 查询 {%TABLE_NAME%} 表前 10 条数据\nconst { data, error } = await cloudbase.rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .select(\"*\")\n  .limit(10);\n\nconsole.log(\"查询结果:\", data);\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "```js\nconst cloudbase = getApp().globalData.cloudbase;\n\n// 向 {%TABLE_NAME%} 表插入一条数据\n// 注意：anon 令牌（publishable key）仅有读权限，写操作需用户登录态或配置 RLS 写策略\nconst { data, error } = await cloudbase.rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .insert({ title: \"新文章\", status: \"draft\" })\n  .select();\n\nconsole.log(\"新增结果:\", data);\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "```js\nconst cloudbase = getApp().globalData.cloudbase;\n\n// 更新 {%TABLE_NAME%} 表中 id=1 的记录\n// 注意：anon 令牌（publishable key）仅有读权限，写操作需用户登录态或配置 RLS 写策略\nconst { data, error } = await cloudbase.rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .update({ status: \"published\" })\n  .eq(\"id\", 1)\n  .select();\n\nconsole.log(\"更新结果:\", data);\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "```js\nconst cloudbase = getApp().globalData.cloudbase;\n\n// 当 id 冲突时更新，否则插入\n// 注意：anon 令牌（publishable key）仅有读权限，写操作需用户登录态或配置 RLS 写策略\nconst { data, error } = await cloudbase.rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .upsert({ id: 1, title: \"标题\", status: \"published\" }, { onConflict: \"id\" })\n  .select();\n\nconsole.log(\"更新或创建结果:\", data);\n```",
                "index": 4,
                "title": "更新或创建数据"
              },
              {
                "markdown": "```js\nconst cloudbase = getApp().globalData.cloudbase;\n\n// 删除 {%TABLE_NAME%} 表中 id=1 的记录\n// 注意：anon 令牌（publishable key）仅有读权限，写操作需用户登录态或配置 RLS 写策略\nconst { data, error } = await cloudbase.rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .delete()\n  .eq(\"id\", 1);\n\nconsole.log(\"删除完成:\", error);\n```",
                "index": 5,
                "title": "删除数据"
              }
            ]
          },
          {
            "markdown": "请使用 `Client SDK` 进行调用",
            "index": 1,
            "id": "mysql-db",
            "title": "MySQL数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\nconst cloudbase = getApp().globalData.cloudbase;\n\n// 查询 {%TABLE_NAME%} 表前10条数据\nconst { data, error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .select(\"*\")\n  .limit(10);\n\nconsole.log(\"查询结果:\", data);\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "```js\nconst cloudbase = getApp().globalData.cloudbase;\n\n// 新增 {%TABLE_NAME%} 表数据\nconst { data, error } = await cloudbase.rdb().from(\"{%TABLE_NAME%}\").insert({\n  title: \"示例标题\"\n});\n\nconsole.log(\"新增结果:\", error ? \"失败\" : \"成功\");\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "```js\nconst cloudbase = getApp().globalData.cloudbase;\n\n// 更新 {%TABLE_NAME%} 表中 id 为 <数据ID> 的数据\nconst { data, error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .update({\n    title: \"更新后的标题\"\n  })\n  .eq(\"id\", \"<数据ID>\");\n\nconsole.log(\"更新结果:\", error ? \"失败\" : \"成功\");\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "```js\nconst cloudbase = getApp().globalData.cloudbase;\n\n// 如果 {%TABLE_NAME%} 表中存在 id 为 1 的记录则更新 title 为\"示例标题\"，不存在则插入新记录\nconst { data, error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .upsert({ id: 1, title: \"示例标题\" });\n\nconsole.log(\"新增更新结果:\", error ? \"失败\" : \"成功\");\n```",
                "index": 4,
                "title": "更新或创建数据"
              },
              {
                "markdown": "```js\nconst cloudbase = getApp().globalData.cloudbase;\n\n// 删除 {%TABLE_NAME%} 表中 id 为 <数据ID> 的数据\nconst { data, error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .delete()\n  .eq(\"id\", \"<数据ID>\");\n\nconsole.log(\"删除结果:\", error ? \"失败\" : \"成功\");\n```",
                "index": 5,
                "title": "删除数据"
              }
            ]
          },
          {
            "index": 2,
            "id": "doc-db",
            "title": "文档型数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\nconst db = wx.cloud.database();\n\n// 查询 {%TABLE_NAME%} 表前10条数据\nconst res = await db.collection(\"{%TABLE_NAME%}\").limit(10).get();\n\nconsole.log(res.data);\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "```js\nconst db = wx.cloud.database();\n\n// 新增 {%TABLE_NAME%} 表数据\nconst res = await db.collection(\"{%TABLE_NAME%}\").add({\n  data: {\n    title: \"示例标题\",\n    content: \"示例内容\"\n  }\n});\n\nconsole.log(res);\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "```js\nconst db = wx.cloud.database();\n\n// 更新 {%TABLE_NAME%} 表中 id 为 <数据ID> 的数据\nconst res = await db\n  .collection(\"{%TABLE_NAME%}\")\n  .doc(\"<数据ID>\")\n  .update({\n    data: {\n      title: \"更新后的标题\"\n    }\n  });\n\nconsole.log(res.stats.updated);\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "```js\nconst db = wx.cloud.database();\n\n// 删除 {%TABLE_NAME%} 表中 id 为 <数据ID> 的数据\nconst res = await db.collection(\"{%TABLE_NAME%}\").doc(\"<数据ID>\").remove();\n\nconsole.log(res.stats.removed);\n```",
                "index": 4,
                "title": "删除数据"
              }
            ]
          },
          {
            "markdown": "请使用 `Client SDK` 进行调用",
            "index": 3,
            "id": "data-model",
            "title": "数据模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\nconst cloudbase = getApp().globalData.cloudbase;\n\n// 查询 {%TABLE_NAME%} 数据模型前10条数据\nconst res = await cloudbase.models[\"{%TABLE_NAME%}\"].list({\n  pageNumber: 1,\n  pagesize: 10\n});\n\nconsole.log(res.data.records);\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "```js\nconst cloudbase = getApp().globalData.cloudbase;\n\n// 新增 {%TABLE_NAME%} 数据模型数据\nconst res = await cloudbase.models[\"{%TABLE_NAME%}\"].create({\n  data: {\n    title: \"示例标题\",\n    content: \"示例内容\"\n  }\n});\n\nconsole.log(res.data);\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "```js\nconst cloudbase = getApp().globalData.cloudbase;\n\n// 更新 {%TABLE_NAME%} 数据模型中 _id 为 <数据ID> 的数据\nconst res = await cloudbase.models[\"{%TABLE_NAME%}\"].update({\n  data: {\n    title: \"更新后的标题\"\n  },\n  filter: {\n    where: {\n      _id: {\n        $eq: \"<数据ID>\"\n      }\n    }\n  }\n});\n\nconsole.log(res.data);\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "```js\nconst cloudbase = getApp().globalData.cloudbase;\n\n// 删除 {%TABLE_NAME%} 数据模型中 _id 为 <数据ID> 的数据\nconst res = await cloudbase.models[\"{%TABLE_NAME%}\"].delete({\n  filter: {\n    where: {\n      _id: {\n        $eq: \"<数据ID>\"\n      }\n    }\n  }\n});\n\nconsole.log(res.data);\n```",
                "index": 4,
                "title": "删除数据"
              }
            ]
          },
          {
            "markdown": "```js\n// 调用 {%FUNCTION_NAME%} 云函数\nconst res = await wx.cloud.callFunction({\n  name: \"{%FUNCTION_NAME%}\",\n  data: {} // 云函数入参\n});\n\nconsole.log(res.result);\n```",
            "index": 4,
            "id": "scf",
            "title": "云函数",
            "content": []
          },
          {
            "markdown": "```js\n// 调用 {%SERVICE_NAME%} 云托管服务\nconst res = await wx.cloud.callContainer({\n  config: {\n    env: \"{%ENV_ID%}\" // 与小程序已关联的云开发环境 ID\n  },\n  path: \"/\", // 业务自定义路径，根目录为 /\n  method: \"GET\", // 依业务选择\n  header: {\n    \"X-WX-SERVICE\": \"{%SERVICE_NAME%}\" // 云托管服务名称\n    // 其他 header\n  }\n  // dataType: 'text' // 默认为 JSON；如需自行解析可设为 'text'\n});\n\nconsole.log(res);\n```",
            "index": 5,
            "id": "run",
            "title": "云托管",
            "content": []
          },
          {
            "index": 1,
            "id": "storage",
            "title": "云存储",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\nwx.chooseMedia({\n  count: 1,\n  mediaType: [\"image\", \"video\"],\n  sourceType: [\"album\", \"camera\"],\n  success: async res => {\n    const res = await wx.cloud.uploadFile({\n      cloudPath: \"images/\" + Date.now() + \".png\", // 上传至云端的路径\n      filePath: res.tempFiles[0].tempFilePath // 小程序临时文件路径\n    });\n\n    console.log(res.fileID);\n  }\n});\n```",
                "index": 1,
                "title": "上传文件"
              },
              {
                "markdown": "```js\nconst res = await wx.cloud.getTempFileURL({\n  fileList: [\"cloud://xxx.png\"] // 文件 fileID 列表\n});\n\nconsole.log(res.fileList);\n// fileList示例\n// [{\n//    fileID: \"cloud://xxx.png\", // 文件 ID\n//    tempFileURL: \"https://xxx.png\", // 临时文件网络链接\n//    maxAge: 120 * 60 * 1000, // 有效期\n// }]\n```",
                "index": 2,
                "title": "获取文件链接"
              },
              {
                "markdown": "```js\nconst res = await wx.cloud.downloadFile({\n  fileID: \"cloud://xxx.png\" // 文件 fileID\n});\n\nconsole.log(res.tempFilePath); // 返回临时文件路径\n```",
                "index": 3,
                "title": "下载文件"
              },
              {
                "markdown": "```js\nconst res = await wx.cloud.deleteFile({\n  fileList: [\"cloud://xxx.png\"] // 文件 fileID 列表\n});\n\nconsole.log(res.fileList);\n```",
                "index": 4,
                "title": "删除文件"
              }
            ]
          },
          {
            "index": 7,
            "id": "ai-model",
            "title": "大模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\nconst res = await wx.cloud.extend.AI.createModel(\n  \"{%AI_MODEL_NAME%}\"\n).streamText({\n  data: {\n    model: \"{%AI_SUB_MODEL_NAME%}\",\n    messages: [\n      {\n        role: \"user\",\n        content: \"你好\"\n      }\n    ]\n  }\n});\n\nfor await (let event of res.eventStream) {\n  if (event.data === \"[DONE]\") {\n    break;\n  }\n  const data = JSON.parse(event.data);\n\n  // 当使用 deepseek-r1 时，模型会生成思维链内容\n  const think = data?.choices?.[0]?.delta?.reasoning_content;\n  if (think) {\n    console.log(think);\n  }\n\n  // 打印生成文本内容\n  const text = data?.choices?.[0]?.delta?.content;\n  if (text) {\n    console.log(text);\n  }\n}\n```",
                "index": 1,
                "id": "text-aiModel",
                "title": "生文模型"
              },
              {
                "markdown": "生图模型通过调用云函数来实现，在生图模型页面点击「一键创建云函数」，函数调用示例如下：\n\n```js\n// 调用生图云函数\nwx.cloud.callFunction({\n  name: \"<YOUR_FUNCTION_NAME>\",\n  data: {\n    prompt: \"一只可爱的猫咪在阳光下玩耍\"\n  },\n  success: res => {\n    const result = res.result;\n\n    if (result.success) {\n      // 生成成功\n      console.log(\"生成成功!\");\n      console.log(\"图片URL:\", result.imageUrl);\n      console.log(\"优化后的提示词:\", result.revised_prompt);\n\n      // 使用图片\n      // 注意：图片URL有效期为24小时，请及时保存或转存\n    } else {\n      // 生成失败\n      console.error(\"生成失败:\", result.code, result.message);\n    }\n  },\n  fail: err => {\n    console.error(\"调用失败:\", err);\n  }\n});\n```",
                "index": 2,
                "id": "image-aiModel",
                "title": "生图模型"
              }
            ]
          },
          {
            "markdown": "",
            "index": 8,
            "id": "agent",
            "title": "Agent",
            "type": "sideTab",
            "content": [
              {
                "markdown": "\n```js\nfunction generateId() {\n  const timestamp = Date.now().toString().slice(-4);\n  const random = Math.floor(Math.random() * 10000).toString().padStart(4, '0');\n  return timestamp + random;\n}\n\nasync function sendMessage(message) {\n  const res = await wx.cloud.extend.AI.bot.sendMessage({\n    data: {\n      // botId 必填，标识调用的 Agent\n      botId: '{%AGENT_ID%}',\n      // 入参结构参考前后端通信协议：\n      // https://docs.cloudbase.net/ai/agent/http-agent-protocol\n      threadId: 'thread_id_' + generateId(),\n      runId: 'run_id_' + generateId(),\n      messages: [\n        { id: String(Date.now()), role: 'user', content: message }\n      ],\n      tools: [],\n      context: [],\n      state: {},\n      forwardedProps: {},\n    }\n  });\n\n  // 流式接收响应\n  let response = '';\n  for await (const event of res.eventStream) {\n    // 需要手动解析 event.data\n    const data = JSON.parse(event.data);\n    // 根据事件类型输出，响应事件参考文档：\n    // https://docs.cloudbase.net/ai/agent/http-agent-protocol#%E5%93%8D%E5%BA%94%E4%BA%8B%E4%BB%B6\n    switch (data.type) {\n      case 'TEXT_MESSAGE_CONTENT':\n        response += data.delta;\n        console.log(data.delta);  // 实时输出\n        break;\n\n      case 'RUN_ERROR':\n        console.error('运行出错:', data.message);\n        break;\n\n      case 'RUN_FINISHED':\n        // 运行结束\n        break;\n    }\n  }\n\n  return response;\n}\n\nsendMessage('你好');\n```\n",
                "index": 0,
                "id": "scf",
                "title": "函数型"
              },
              {
                "markdown": "```js\nconst res = await wx.cloud.extend.AI.bot.sendMessage({\n  data: {\n    botId: \"{%AGENT_ID%}\",\n    msg: \"你好\"\n  }\n});\n\nfor await (const event of res.eventStream) {\n  if (event.data === \"[DONE]\") {\n    break;\n  }\n  const data = JSON.parse(event.data);\n\n  // 当使用 deepseek-r1 时，模型会生成思维链内容\n  const think = data.reasoning_content;\n  if (think) {\n    console.log(think);\n  }\n\n  // 打印输出正文\n  const content = data.content;\n  if (content) {\n    console.log(content);\n  }\n}\n```",
                "index": 1,
                "id": "baas",
                "title": "普通型"
              }
            ]
          },
          {
            "markdown": "```js\n// 调用 <YOUR_INSTANCE_ID> 云主机实例\nconst result = await wx.cloud.callContainer({\n    config: {\n        env: \"{%ENV_ID%}\"  // 与小程序已关联的云开发环境 ID\n    },\n    header: {\n        \"X-WX-SERVICE\": \"tcbanyservice\",        // 【必填】固定值，指定为云开发服务\n        \"X-Vm-Service\": \"{%INSTANCE_ID%}\",      // 【必填】替换为你的实例 ID\n        // 可以添加其他自定义 Header\n    },\n    path: \"/\",                  //业务自定义路径，根目录为 /\n    method: \"GET\",      // 业务自定义HTTP方法\n    //data: \"hello\"         // 业务自定义请求参数\n})\n\nconsole.log(result.data)\n```",
            "index": 5,
            "id": "vm",
            "title": "云主机",
            "content": []
          }
        ]
      }
    ],
    "_id": "dc08b5d96969f04d0005bcc62fe84821",
    "_openid": "anon",
    "createdAt": 1768550477235,
    "updatedAt": 1775129825658
  },
  {
    "category": "框架集成,移动端框架,React Native",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": 33,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/api-reference/webv2/adapter",
    "content": [
      {
        "markdown": "`@cloudbase/js-sdk` 配合 `@cloudbase/adapter-rn` 可以让您在 React Native 项目中使用 JavaScript 访问 CloudBase 服务和资源。",
        "index": 1,
        "title": "安装 SDK",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```bash\nnpm i @cloudbase/js-sdk @cloudbase/adapter-rn\n```",
            "index": 1,
            "title": "npm"
          },
          {
            "markdown": "```bash\nyarn add @cloudbase/js-sdk @cloudbase/adapter-rn\n```",
            "index": 2,
            "title": "yarn"
          },
          {
            "markdown": "```bash\npnpm add @cloudbase/js-sdk @cloudbase/adapter-rn\n```\n\niOS 需要安装原生依赖：\n\n```bash\ncd ios && pod install && cd ..\n```",
            "index": 3,
            "title": "pnpm"
          }
        ]
      },
      {
        "markdown": "新增如下代码到您的 React Native 项目",
        "index": 2,
        "title": "初始化 SDK",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```js\nimport cloudbaseSDK from \"@cloudbase/js-sdk\";\nimport adapter from \"@cloudbase/adapter-rn\";\n\ncloudbaseSDK.useAdapters(adapter);\n\nconst cloudbase = cloudbaseSDK.init({\n  // 环境 ID\n  env: \"{%ENV_ID%}\",\n  // 地域\n  region: \"{%REGION%}\",\n  // 匿名访问令牌\n  accessKey: \"{%PUBLISHABLE_KEY%}\"\n});\n\nexport default cloudbase;\n```",
            "index": 1,
            "title": "src/utils/cloudbase.js"
          }
        ]
      },
      {
        "sideTabs": [
          {
            "id": "pg-db",
            "title": "PostgreSQL 数据库"
          }
        ],
        "index": 3,
        "title": "调用云开发能力",
        "type": "codeTab",
        "content": [
          {
            "index": 1,
            "id": "pg-db",
            "title": "PostgreSQL 数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\nimport cloudbase from \"./utils/cloudbase\";\n\n// 查询 {%TABLE_NAME%} 表前 10 条数据\nconst { data, error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .select(\"*\")\n  .limit(10);\n\nconsole.log(\"查询结果:\", data);\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "```js\nimport cloudbase from \"./utils/cloudbase\";\n\n// 向 {%TABLE_NAME%} 表插入一条数据\nconst { data, error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .insert({ title: \"新文章\", status: \"draft\" })\n  .select();\n\nconsole.log(\"新增结果:\", data);\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "```js\nimport cloudbase from \"./utils/cloudbase\";\n\n// 更新 {%TABLE_NAME%} 表中 id=1 的记录\nconst { data, error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .update({ status: \"published\" })\n  .eq(\"id\", 1)\n  .select();\n\nconsole.log(\"更新结果:\", data);\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "```js\nimport cloudbase from \"./utils/cloudbase\";\n\n// 当 id 冲突时更新，否则插入\nconst { data, error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .upsert({ id: 1, title: \"标题\", status: \"published\" }, { onConflict: \"id\" })\n  .select();\n\nconsole.log(\"更新或创建结果:\", data);\n```",
                "index": 4,
                "title": "更新或创建数据"
              },
              {
                "markdown": "```js\nimport cloudbase from \"./utils/cloudbase\";\n\n// 删除 {%TABLE_NAME%} 表中 id=1 的记录\nconst { data, error } = await cloudbase\n  .rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .delete()\n  .eq(\"id\", 1);\n\nconsole.log(\"删除完成:\", error);\n```",
                "index": 5,
                "title": "删除数据"
              }
            ]
          },
          {
            "index": 1,
            "id": "mysql-db",
            "title": "MySQL数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst { data, error } = await cloudbase\n  .database()\n  .from(\"{%TABLE_NAME%}\")\n  .select(\"*\")\n  .limit(10);\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, Button, FlatList, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function QueryData() {\n  const [dataList, setDataList] = useState([]);\n\n  // 查询数据\n  const getData = async () => {\n    try {\n      const { data, error } = await cloudbase\n        .database()\n        .from(\"{%TABLE_NAME%}\")\n        .select(\"*\")\n        .limit(10);\n\n      if (!error) {\n        setDataList(data);\n        Alert.alert(\"成功\", \"查询成功\");\n      } else {\n        Alert.alert(\"失败\", \"查询失败\");\n      }\n    } catch (error) {\n      Alert.alert(\"错误\", `查询失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Button title=\"查询数据\" onPress={getData} />\n      {dataList.length > 0 ? (\n        <FlatList\n          data={dataList}\n          keyExtractor={(item, index) => index.toString()}\n          renderItem={({ item }) => (\n            <View style={styles.item}>\n              <Text>{JSON.stringify(item)}</Text>\n            </View>\n          )}\n        />\n      ) : (\n        <Text>暂无数据</Text>\n      )}\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  item: {\n    padding: 10,\n    marginVertical: 5,\n    backgroundColor: \"#f9f9f9\",\n    borderRadius: 5\n  }\n});\n```",
                "index": 1,
                "title": "查询数据",
                "content": []
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst { data, error } = await cloudbase\n  .database()\n  .from(\"{%TABLE_NAME%}\")\n  .insert({ title });\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, TextInput, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function AddData() {\n  const [title, setTitle] = useState(\"\");\n\n  // 新增数据\n  const addData = async () => {\n    try {\n      const { data, error } = await cloudbase\n        .database()\n        .from(\"{%TABLE_NAME%}\")\n        .insert({ title });\n\n      if (!error) {\n        Alert.alert(\"成功\", \"新增成功\");\n        setTitle(\"\");\n      } else {\n        Alert.alert(\"失败\", \"新增失败\");\n      }\n    } catch (error) {\n      Alert.alert(\"错误\", `新增失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>标题：</Text>\n      <TextInput\n        style={styles.input}\n        value={title}\n        onChangeText={setTitle}\n        placeholder=\"请输入标题\"\n      />\n      <Button title=\"新增数据\" onPress={addData} disabled={!title} />\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  }\n});\n```",
                "index": 2,
                "title": "新增数据",
                "content": []
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst { data, error } = await cloudbase\n  .database()\n  .from(\"{%TABLE_NAME%}\")\n  .update({ title: newTitle })\n  .eq(\"id\", dataId);\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, TextInput, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function UpdateData() {\n  const [dataId, setDataId] = useState(\"\");\n  const [newTitle, setNewTitle] = useState(\"\");\n\n  // 更新数据\n  const updateData = async () => {\n    try {\n      const { data, error } = await cloudbase\n        .database()\n        .from(\"{%TABLE_NAME%}\")\n        .update({ title: newTitle })\n        .eq(\"id\", dataId);\n\n      if (!error) {\n        Alert.alert(\"成功\", \"更新成功\");\n        setDataId(\"\");\n        setNewTitle(\"\");\n      } else {\n        Alert.alert(\"失败\", \"更新失败\");\n      }\n    } catch (error) {\n      Alert.alert(\"错误\", `更新失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>数据ID：</Text>\n      <TextInput\n        style={styles.input}\n        value={dataId}\n        onChangeText={setDataId}\n        placeholder=\"请输入数据ID\"\n      />\n      <Text>新标题：</Text>\n      <TextInput\n        style={styles.input}\n        value={newTitle}\n        onChangeText={setNewTitle}\n        placeholder=\"请输入新标题\"\n      />\n      <Button\n        title=\"更新数据\"\n        onPress={updateData}\n        disabled={!dataId || !newTitle}\n      />\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  }\n});\n```",
                "index": 3,
                "title": "更新数据",
                "content": []
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst { data, error } = await cloudbase\n  .database()\n  .from(\"{%TABLE_NAME%}\")\n  .upsert({ id: parseInt(id), title });\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, TextInput, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function UpsertData() {\n  const [id, setId] = useState(\"\");\n  const [title, setTitle] = useState(\"\");\n\n  // 更新或创建数据\n  const upsertData = async () => {\n    try {\n      const { data, error } = await cloudbase\n        .database()\n        .from(\"{%TABLE_NAME%}\")\n        .upsert({ id: parseInt(id), title });\n\n      if (!error) {\n        Alert.alert(\"成功\", \"操作成功\");\n        setId(\"\");\n        setTitle(\"\");\n      } else {\n        Alert.alert(\"失败\", \"操作失败\");\n      }\n    } catch (error) {\n      Alert.alert(\"错误\", `操作失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>ID：</Text>\n      <TextInput\n        style={styles.input}\n        value={id}\n        onChangeText={setId}\n        placeholder=\"请输入ID\"\n        keyboardType=\"numeric\"\n      />\n      <Text>标题：</Text>\n      <TextInput\n        style={styles.input}\n        value={title}\n        onChangeText={setTitle}\n        placeholder=\"请输入标题\"\n      />\n      <Button\n        title=\"更新或创建\"\n        onPress={upsertData}\n        disabled={!id || !title}\n      />\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  }\n});\n```",
                "index": 4,
                "title": "更新或创建数据",
                "content": []
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst { data, error } = await cloudbase\n  .database()\n  .from(\"{%TABLE_NAME%}\")\n  .delete()\n  .eq(\"id\", dataId);\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, TextInput, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function DeleteData() {\n  const [dataId, setDataId] = useState(\"\");\n\n  // 删除数据\n  const deleteData = async () => {\n    try {\n      const { data, error } = await cloudbase\n        .database()\n        .from(\"{%TABLE_NAME%}\")\n        .delete()\n        .eq(\"id\", dataId);\n\n      if (!error) {\n        Alert.alert(\"成功\", \"删除成功\");\n        setDataId(\"\");\n      } else {\n        Alert.alert(\"失败\", \"删除失败\");\n      }\n    } catch (error) {\n      Alert.alert(\"错误\", `删除失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>数据ID：</Text>\n      <TextInput\n        style={styles.input}\n        value={dataId}\n        onChangeText={setDataId}\n        placeholder=\"请输入要删除的数据ID\"\n      />\n      <Button title=\"删除数据\" onPress={deleteData} disabled={!dataId} />\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  }\n});\n```",
                "index": 5,
                "title": "删除数据",
                "content": []
              }
            ]
          },
          {
            "index": 2,
            "id": "doc-db",
            "title": "文档型数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst db = cloudbase.database();\nconst res = await db.collection(\"{%TABLE_NAME%}\").limit(10).get();\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, Button, FlatList, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function QueryDocData() {\n  const [dataList, setDataList] = useState([]);\n\n  // 查询数据\n  const getData = async () => {\n    try {\n      const db = cloudbase.database();\n      const res = await db.collection(\"{%TABLE_NAME%}\").limit(10).get();\n\n      setDataList(res.data);\n      Alert.alert(\"成功\", \"查询成功\");\n    } catch (error) {\n      Alert.alert(\"错误\", `查询失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Button title=\"查询数据\" onPress={getData} />\n      {dataList.length > 0 ? (\n        <FlatList\n          data={dataList}\n          keyExtractor={(item, index) => index.toString()}\n          renderItem={({ item }) => (\n            <View style={styles.item}>\n              <Text>{JSON.stringify(item)}</Text>\n            </View>\n          )}\n        />\n      ) : (\n        <Text>暂无数据</Text>\n      )}\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  item: {\n    padding: 10,\n    marginVertical: 5,\n    backgroundColor: \"#f9f9f9\",\n    borderRadius: 5\n  }\n});\n```",
                "index": 1,
                "title": "查询数据",
                "content": []
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst db = cloudbase.database();\nconst res = await db.collection(\"{%TABLE_NAME%}\").add({ title });\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, TextInput, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function AddDocData() {\n  const [title, setTitle] = useState(\"\");\n\n  // 新增数据\n  const addData = async () => {\n    try {\n      const db = cloudbase.database();\n      const res = await db.collection(\"{%TABLE_NAME%}\").add({ title });\n\n      Alert.alert(\"成功\", `新增成功! id: ${res.id}`);\n      setTitle(\"\");\n    } catch (error) {\n      Alert.alert(\"错误\", `新增失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>标题：</Text>\n      <TextInput\n        style={styles.input}\n        value={title}\n        onChangeText={setTitle}\n        placeholder=\"请输入标题\"\n      />\n      <Button title=\"新增数据\" onPress={addData} disabled={!title} />\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  }\n});\n```",
                "index": 2,
                "title": "新增数据",
                "content": []
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst db = cloudbase.database();\nawait db.collection(\"{%TABLE_NAME%}\").doc(dataId).update({ title: newTitle });\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, TextInput, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function UpdateDocData() {\n  const [dataId, setDataId] = useState(\"\");\n  const [newTitle, setNewTitle] = useState(\"\");\n\n  // 更新数据\n  const updateData = async () => {\n    try {\n      const db = cloudbase.database();\n      await db\n        .collection(\"{%TABLE_NAME%}\")\n        .doc(dataId)\n        .update({ title: newTitle });\n\n      Alert.alert(\"成功\", \"更新成功\");\n      setDataId(\"\");\n      setNewTitle(\"\");\n    } catch (error) {\n      Alert.alert(\"错误\", `更新失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>数据ID：</Text>\n      <TextInput\n        style={styles.input}\n        value={dataId}\n        onChangeText={setDataId}\n        placeholder=\"请输入数据ID\"\n      />\n      <Text>新标题：</Text>\n      <TextInput\n        style={styles.input}\n        value={newTitle}\n        onChangeText={setNewTitle}\n        placeholder=\"请输入新标题\"\n      />\n      <Button\n        title=\"更新数据\"\n        onPress={updateData}\n        disabled={!dataId || !newTitle}\n      />\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  }\n});\n```",
                "index": 3,
                "title": "更新数据",
                "content": []
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst db = cloudbase.database();\nawait db.collection(\"{%TABLE_NAME%}\").doc(dataId).remove();\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, TextInput, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function DeleteDocData() {\n  const [dataId, setDataId] = useState(\"\");\n\n  // 删除数据\n  const deleteData = async () => {\n    try {\n      const db = cloudbase.database();\n      await db.collection(\"{%TABLE_NAME%}\").doc(dataId).remove();\n\n      Alert.alert(\"成功\", \"删除成功\");\n      setDataId(\"\");\n    } catch (error) {\n      Alert.alert(\"错误\", `删除失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>数据ID：</Text>\n      <TextInput\n        style={styles.input}\n        value={dataId}\n        onChangeText={setDataId}\n        placeholder=\"请输入要删除的数据ID\"\n      />\n      <Button title=\"删除数据\" onPress={deleteData} disabled={!dataId} />\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  }\n});\n```",
                "index": 4,
                "title": "删除数据",
                "content": []
              }
            ]
          },
          {
            "index": 3,
            "id": "data-model",
            "title": "数据模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst res = await cloudbase.models[\"{%TABLE_NAME%}\"].list({\n  pageNumber: 1,\n  pagesize: 10\n});\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, Button, FlatList, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function QueryModelData() {\n  const [dataList, setDataList] = useState([]);\n\n  // 查询数据\n  const getData = async () => {\n    try {\n      const res = await cloudbase.models[\"{%TABLE_NAME%}\"].list({\n        pageNumber: 1,\n        pagesize: 10\n      });\n\n      setDataList(res.data?.records || []);\n      Alert.alert(\"成功\", \"查询成功\");\n    } catch (error) {\n      Alert.alert(\"错误\", `查询失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Button title=\"查询数据\" onPress={getData} />\n      {dataList.length > 0 ? (\n        <FlatList\n          data={dataList}\n          keyExtractor={(item, index) => index.toString()}\n          renderItem={({ item }) => (\n            <View style={styles.item}>\n              <Text>{JSON.stringify(item)}</Text>\n            </View>\n          )}\n        />\n      ) : (\n        <Text>暂无数据</Text>\n      )}\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  item: {\n    padding: 10,\n    marginVertical: 5,\n    backgroundColor: \"#f9f9f9\",\n    borderRadius: 5\n  }\n});\n```",
                "index": 1,
                "title": "查询数据",
                "content": []
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst res = await cloudbase.models[\"{%TABLE_NAME%}\"].create({\n  data: { title }\n});\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, TextInput, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function AddModelData() {\n  const [title, setTitle] = useState(\"\");\n\n  // 新增数据\n  const addData = async () => {\n    try {\n      const res = await cloudbase.models[\"{%TABLE_NAME%}\"].create({\n        data: { title }\n      });\n\n      Alert.alert(\"成功\", `新增成功! id: ${res.data.id}`);\n      setTitle(\"\");\n    } catch (error) {\n      Alert.alert(\"错误\", `新增失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>标题：</Text>\n      <TextInput\n        style={styles.input}\n        value={title}\n        onChangeText={setTitle}\n        placeholder=\"请输入标题\"\n      />\n      <Button title=\"新增数据\" onPress={addData} disabled={!title} />\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  }\n});\n```",
                "index": 2,
                "title": "新增数据",
                "content": []
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nawait cloudbase.models[\"{%TABLE_NAME%}\"].update({\n  data: { title: newTitle },\n  filter: { where: { _id: { $eq: dataId } } }\n});\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, TextInput, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function UpdateModelData() {\n  const [dataId, setDataId] = useState(\"\");\n  const [newTitle, setNewTitle] = useState(\"\");\n\n  // 更新数据\n  const updateData = async () => {\n    try {\n      await cloudbase.models[\"{%TABLE_NAME%}\"].update({\n        data: { title: newTitle },\n        filter: { where: { _id: { $eq: dataId } } }\n      });\n\n      Alert.alert(\"成功\", \"更新成功\");\n      setDataId(\"\");\n      setNewTitle(\"\");\n    } catch (error) {\n      Alert.alert(\"错误\", `更新失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>数据ID：</Text>\n      <TextInput\n        style={styles.input}\n        value={dataId}\n        onChangeText={setDataId}\n        placeholder=\"请输入数据ID\"\n      />\n      <Text>新标题：</Text>\n      <TextInput\n        style={styles.input}\n        value={newTitle}\n        onChangeText={setNewTitle}\n        placeholder=\"请输入新标题\"\n      />\n      <Button\n        title=\"更新数据\"\n        onPress={updateData}\n        disabled={!dataId || !newTitle}\n      />\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  }\n});\n```",
                "index": 3,
                "title": "更新数据",
                "content": []
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nawait cloudbase.models[\"{%TABLE_NAME%}\"].delete({\n  filter: { where: { _id: { $eq: dataId } } }\n});\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, TextInput, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function DeleteModelData() {\n  const [dataId, setDataId] = useState(\"\");\n\n  // 删除数据\n  const deleteData = async () => {\n    try {\n      await cloudbase.models[\"{%TABLE_NAME%}\"].delete({\n        filter: { where: { _id: { $eq: dataId } } }\n      });\n\n      Alert.alert(\"成功\", \"删除成功\");\n      setDataId(\"\");\n    } catch (error) {\n      Alert.alert(\"错误\", `删除失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>数据ID：</Text>\n      <TextInput\n        style={styles.input}\n        value={dataId}\n        onChangeText={setDataId}\n        placeholder=\"请输入要删除的数据ID\"\n      />\n      <Button title=\"删除数据\" onPress={deleteData} disabled={!dataId} />\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  }\n});\n```",
                "index": 4,
                "title": "删除数据",
                "content": []
              }
            ]
          },
          {
            "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst res = await cloudbase.callFunction({\n  name: \"{%FUNCTION_NAME%}\",\n  data: {}\n});\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function CallFunction() {\n  const [result, setResult] = useState(null);\n\n  // 调用云函数\n  const callFunction = async () => {\n    try {\n      const res = await cloudbase.callFunction({\n        name: \"{%FUNCTION_NAME%}\",\n        data: {}\n      });\n\n      setResult(res.result);\n      Alert.alert(\"成功\", \"调用成功\");\n    } catch (error) {\n      Alert.alert(\"错误\", `调用失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Button title=\"调用云函数\" onPress={callFunction} />\n      {result && (\n        <View style={styles.resultContainer}>\n          <Text>返回结果：</Text>\n          <Text>{JSON.stringify(result)}</Text>\n        </View>\n      )}\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  resultContainer: {\n    marginTop: 20,\n    padding: 10,\n    backgroundColor: \"#f9f9f9\",\n    borderRadius: 5\n  }\n});\n```",
            "index": 4,
            "id": "scf",
            "title": "云函数"
          },
          {
            "markdown": "**调用方式：**\n\n```js\nimport { cloudbase } from \"./utils/cloudbase\";\n\n// 调用 {%SERVICE_NAME%} 云托管服务\nconst res = await cloudbase.callContainer({\n  name: \"{%SERVICE_NAME%}\"\n  method: 'POST',\n  path: '/',\n  header:{\n    'Content-Type': 'application/json; charset=utf-8'\n  },\n  data: {},\n});\n```\n\n**完整示例：**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function CallRun() {\n  const [result, setResult] = useState(null);\n\n  // 调用云托管\n  const callRun = async () => {\n    try {\n      // 调用 {%SERVICE_NAME%} 云托管服务\n      const res = await cloudbase.callContainer({\n        name: \"{%SERVICE_NAME%}\"\n        method: 'POST',\n        path: '/',\n        header:{\n          'Content-Type': 'application/json; charset=utf-8'\n        },\n        data: {},\n      });\n\n      setResult(res);\n      Alert.alert(\"成功\", \"调用成功\");\n    } catch (error) {\n      Alert.alert(\"错误\", `调用失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Button title=\"调用云托管\" onPress={callRun} />\n      {result && (\n        <View style={styles.resultContainer}>\n          <Text>返回结果：</Text>\n          <Text>{JSON.stringify(result)}</Text>\n        </View>\n      )}\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  resultContainer: {\n    marginTop: 20,\n    padding: 10,\n    backgroundColor: \"#f9f9f9\",\n    borderRadius: 5\n  }\n});\n```",
            "index": 5,
            "id": "run",
            "title": "云托管"
          },
          {
            "index": 6,
            "id": "storage",
            "title": "云存储",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst res = await cloudbase.uploadFile({\n  cloudPath: cloudPath,\n  filePath: asset.uri\n});\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, Button, StyleSheet, Alert } from \"react-native\";\nimport { launchImageLibrary } from \"react-native-image-picker\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function UploadFile() {\n  const [fileId, setFileId] = useState(\"\");\n\n  // 上传文件\n  const uploadFile = async () => {\n    try {\n      const result = await launchImageLibrary({\n        mediaType: \"photo\",\n        quality: 0.8\n      });\n\n      if (result.didCancel) {\n        return;\n      }\n\n      if (result.errorCode) {\n        Alert.alert(\"错误\", \"选择图片失败\");\n        return;\n      }\n\n      const asset = result.assets[0];\n      const fileExtension = asset.fileName?.split(\".\").pop() || \"jpg\";\n      const cloudPath = `images/${Date.now()}-${Math.random()}.${fileExtension}`;\n\n      const res = await cloudbase.uploadFile({\n        cloudPath: cloudPath,\n        filePath: asset.uri\n      });\n\n      setFileId(res.fileID);\n      Alert.alert(\"成功\", \"上传成功\");\n    } catch (error) {\n      Alert.alert(\"错误\", `上传失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Button title=\"选择并上传图片\" onPress={uploadFile} />\n      {fileId && (\n        <View style={styles.resultContainer}>\n          <Text>上传成功！</Text>\n          <Text>文件ID: {fileId}</Text>\n        </View>\n      )}\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  resultContainer: {\n    marginTop: 20,\n    padding: 10,\n    backgroundColor: \"#f9f9f9\",\n    borderRadius: 5\n  }\n});\n```",
                "index": 1,
                "title": "上传文件",
                "content": []
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst res = await cloudbase.getTempFileURL({\n  fileList: [fileId]\n});\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport {\n  View,\n  Text,\n  TextInput,\n  Button,\n  Image,\n  StyleSheet,\n  Alert\n} from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function GetFileUrl() {\n  const [fileId, setFileId] = useState(\"\");\n  const [fileUrl, setFileUrl] = useState(\"\");\n\n  // 获取文件链接\n  const getFileUrl = async () => {\n    try {\n      const res = await cloudbase.getTempFileURL({\n        fileList: [fileId]\n      });\n\n      setFileUrl(res.fileList[0].tempFileURL);\n      Alert.alert(\"成功\", \"获取成功\");\n    } catch (error) {\n      Alert.alert(\"错误\", `获取失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>文件ID：</Text>\n      <TextInput\n        style={styles.input}\n        value={fileId}\n        onChangeText={setFileId}\n        placeholder=\"请输入文件ID (cloud://xxx.png)\"\n      />\n      <Button title=\"获取文件链接\" onPress={getFileUrl} disabled={!fileId} />\n      {fileUrl && (\n        <View style={styles.resultContainer}>\n          <Text>文件链接：</Text>\n          <Text>{fileUrl}</Text>\n          <Image\n            source={{ uri: fileUrl }}\n            style={styles.image}\n            resizeMode=\"contain\"\n          />\n        </View>\n      )}\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  },\n  resultContainer: {\n    marginTop: 20,\n    padding: 10,\n    backgroundColor: \"#f9f9f9\",\n    borderRadius: 5\n  },\n  image: {\n    width: \"100%\",\n    height: 200,\n    marginTop: 10\n  }\n});\n```",
                "index": 2,
                "title": "获取文件链接",
                "content": []
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst res = await cloudbase.downloadFile({\n  fileID: fileId\n});\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, TextInput, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function DownloadFile() {\n  const [fileId, setFileId] = useState(\"\");\n  const [localPath, setLocalPath] = useState(\"\");\n\n  // 下载文件\n  const downloadFile = async () => {\n    try {\n      const res = await cloudbase.downloadFile({\n        fileID: fileId\n      });\n\n      setLocalPath(res.tempFilePath);\n      Alert.alert(\"成功\", \"下载成功\");\n    } catch (error) {\n      Alert.alert(\"错误\", `下载失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>文件ID：</Text>\n      <TextInput\n        style={styles.input}\n        value={fileId}\n        onChangeText={setFileId}\n        placeholder=\"请输入文件ID (cloud://xxx.png)\"\n      />\n      <Button title=\"下载文件\" onPress={downloadFile} disabled={!fileId} />\n      {localPath && (\n        <View style={styles.resultContainer}>\n          <Text>下载成功！</Text>\n          <Text>本地路径: {localPath}</Text>\n        </View>\n      )}\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  },\n  resultContainer: {\n    marginTop: 20,\n    padding: 10,\n    backgroundColor: \"#f9f9f9\",\n    borderRadius: 5\n  }\n});\n```",
                "index": 3,
                "title": "下载文件",
                "content": []
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst res = await cloudbase.deleteFile({\n  fileList: [fileId]\n});\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, TextInput, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function DeleteFile() {\n  const [fileId, setFileId] = useState(\"\");\n\n  // 删除文件\n  const deleteFile = async () => {\n    try {\n      const res = await cloudbase.deleteFile({\n        fileList: [fileId]\n      });\n\n      if (res.fileList[0].code === \"SUCCESS\") {\n        Alert.alert(\"成功\", \"删除成功\");\n        setFileId(\"\");\n      } else {\n        Alert.alert(\"失败\", \"删除失败\");\n      }\n    } catch (error) {\n      Alert.alert(\"错误\", `删除失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>文件ID：</Text>\n      <TextInput\n        style={styles.input}\n        value={fileId}\n        onChangeText={setFileId}\n        placeholder=\"请输入文件ID (cloud://xxx.png)\"\n      />\n      <Button title=\"删除文件\" onPress={deleteFile} disabled={!fileId} />\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  }\n});\n```",
                "index": 4,
                "title": "删除文件",
                "content": []
              }
            ]
          },
          {
            "index": 7,
            "id": "ai-model",
            "title": "大模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst ai = cloudbase.ai();\nconst model = ai.createModel(\"{%AI_MODEL_NAME%}\");\n\n// 确保已登录\nconst loginState = await cloudbase.auth().getLoginState();\nif (!loginState) {\n  await cloudbase.auth().signInAnonymously();\n}\n\nconst res = await model.streamText({\n  model: \"{%AI_SUB_MODEL_NAME%}\",\n  messages: [\n    {\n      role: \"system\",\n      content:\n        \"请严格按照七言绝句或七言律诗的格律要求创作，平仄需符合规则，押韵要和谐自然，韵脚字需在同一韵部。\"\n    },\n    { role: \"user\", content: input }\n  ]\n});\n\nfor await (let str of res.textStream) {\n  // 处理流式响应\n}\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport {\n  View,\n  Text,\n  TextInput,\n  Button,\n  StyleSheet,\n  Alert,\n  ActivityIndicator\n} from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function CallAIModel() {\n  const [input, setInput] = useState(\"\");\n  const [response, setResponse] = useState(\"\");\n  const [isGenerating, setIsGenerating] = useState(false);\n\n  // 调用大模型\n  const callAIModel = async () => {\n    setIsGenerating(true);\n    setResponse(\"\");\n\n    try {\n      const ai = cloudbase.ai();\n      const model = ai.createModel(\"{%AI_MODEL_NAME%}\");\n\n      // 确保已登录\n      const loginState = await cloudbase.auth().getLoginState();\n      if (!loginState) {\n        await cloudbase.auth().signInAnonymously();\n      }\n\n      const res = await model.streamText({\n        model: \"{%AI_SUB_MODEL_NAME%}\",\n        messages: [\n          {\n            role: \"system\",\n            content:\n              \"请严格按照七言绝句或七言律诗的格律要求创作，平仄需符合规则，押韵要和谐自然，韵脚字需在同一韵部。\"\n          },\n          { role: \"user\", content: input }\n        ]\n      });\n\n      for await (let str of res.textStream) {\n        setResponse(prev => prev + str);\n      }\n\n      Alert.alert(\"成功\", \"生成完成\");\n    } catch (err) {\n      Alert.alert(\"错误\", `生成失败: ${err.message}`);\n    } finally {\n      setIsGenerating(false);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>输入主题：</Text>\n      <TextInput\n        style={styles.input}\n        value={input}\n        onChangeText={setInput}\n        placeholder=\"请输入主题，如：春天\"\n      />\n      <Button\n        title=\"生成内容\"\n        onPress={callAIModel}\n        disabled={!input || isGenerating}\n      />\n      {isGenerating && <ActivityIndicator size=\"large\" style={styles.loader} />}\n      {response && (\n        <View style={styles.resultContainer}>\n          <Text>生成结果：</Text>\n          <Text>{response}</Text>\n        </View>\n      )}\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  },\n  loader: {\n    marginVertical: 20\n  },\n  resultContainer: {\n    marginTop: 20,\n    padding: 10,\n    backgroundColor: \"#f9f9f9\",\n    borderRadius: 5\n  }\n});\n```",
                "index": 1,
                "id": "text-aiModel",
                "title": "生文模型",
                "content": []
              },
              {
                "markdown": "生图模型通过调用云函数来实现，在生图模型页面点击「一键创建云函数」，函数调用示例如下：\n\n**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst res = await cloudbase.callFunction({\n  name: \"<YOUR_FUNCTION_NAME>\",\n  data: { prompt: \"一只可爱的猫咪在阳光下玩耍\" }\n});\n\nif (res.result.success) {\n  console.log(\"图片URL:\", res.result.imageUrl);\n  console.log(\"优化后的提示词:\", res.result.revised_prompt);\n} else {\n  console.error(\"生成失败:\", res.result.code, res.result.message);\n}\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport {\n  View,\n  Text,\n  TextInput,\n  Button,\n  Image,\n  StyleSheet,\n  Alert,\n  ActivityIndicator\n} from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function GenerateImage() {\n  const [prompt, setPrompt] = useState(\"\");\n  const [imageUrl, setImageUrl] = useState(\"\");\n  const [revisedPrompt, setRevisedPrompt] = useState(\"\");\n  const [isGenerating, setIsGenerating] = useState(false);\n\n  // 生成图片\n  const generateImage = async () => {\n    setIsGenerating(true);\n    setImageUrl(\"\");\n    setRevisedPrompt(\"\");\n\n    try {\n      const res = await cloudbase.callFunction({\n        name: \"<YOUR_FUNCTION_NAME>\",\n        data: { prompt }\n      });\n\n      if (res.result.success) {\n        setImageUrl(res.result.imageUrl);\n        setRevisedPrompt(res.result.revised_prompt || \"\");\n        Alert.alert(\"成功\", \"图片生成成功\");\n      } else {\n        Alert.alert(\n          \"失败\",\n          `生成失败: ${res.result.code} - ${res.result.message}`\n        );\n      }\n    } catch (err) {\n      Alert.alert(\"错误\", `生成失败: ${err.message}`);\n    } finally {\n      setIsGenerating(false);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>输入描述：</Text>\n      <TextInput\n        style={styles.input}\n        value={prompt}\n        onChangeText={setPrompt}\n        placeholder=\"例如：一只可爱的猫咪在阳光下玩耍\"\n        multiline\n      />\n      <Button\n        title=\"生成图片\"\n        onPress={generateImage}\n        disabled={!prompt || isGenerating}\n      />\n      {isGenerating && <ActivityIndicator size=\"large\" style={styles.loader} />}\n      {imageUrl && (\n        <View style={styles.resultContainer}>\n          <Text style={styles.label}>生成结果：</Text>\n          <Image\n            source={{ uri: imageUrl }}\n            style={styles.image}\n            resizeMode=\"contain\"\n          />\n          {revisedPrompt && (\n            <View style={styles.promptContainer}>\n              <Text style={styles.label}>优化后的提示词：</Text>\n              <Text>{revisedPrompt}</Text>\n            </View>\n          )}\n          <Text style={styles.note}>注意：图片URL有效期为24小时</Text>\n        </View>\n      )}\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    minHeight: 80,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    paddingVertical: 10,\n    borderRadius: 5,\n    textAlignVertical: \"top\"\n  },\n  loader: {\n    marginVertical: 20\n  },\n  resultContainer: {\n    marginTop: 20,\n    padding: 10,\n    backgroundColor: \"#f9f9f9\",\n    borderRadius: 5\n  },\n  label: {\n    fontWeight: \"bold\",\n    marginBottom: 5\n  },\n  image: {\n    width: \"100%\",\n    height: 300,\n    marginVertical: 10\n  },\n  promptContainer: {\n    marginTop: 10\n  },\n  note: {\n    marginTop: 10,\n    fontSize: 12,\n    color: \"#666\",\n    fontStyle: \"italic\"\n  }\n});\n```",
                "index": 2,
                "id": "image-aiModel",
                "title": "生图模型",
                "content": []
              }
            ]
          },
          {
            "markdown": "",
            "index": 8,
            "id": "agent",
            "title": "Agent",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\n/**\n * React Native 调用 Agent 示例（AG-UI 协议）\n * 协议文档：https://docs.cloudbase.net/ai/agent-development/protocol\n */\nimport cloudbase from './utils/cloudbase';\n\n// 确保已登录\nconst loginState = await cloudbase.auth().getLoginState();\nif (!loginState) {\n  await cloudbase.auth().signInAnonymously();\n}\n\nconst ai = cloudbase.ai();\n\n// 构建消息列表（AG-UI 协议格式）\nconst messages = [\n  {\n    id: 'msg_001',\n    role: 'user',\n    content: input,\n  },\n];\n\n// AG-UI 协议请求参数\nconst res = await ai.bot.sendMessage({\n  botId: '{%AGENT_ID%}',\n  data: {\n    messages,                                            // 必填：消息列表\n    threadId: '550e8400-e29b-41d4-a716-446655440000',   // 可选：会话ID，用于多轮对话\n    runId: 'run_001',                                    // 可选：运行ID，用于追踪执行\n    tools: [],                                           // 可选：前端工具定义\n    context: [],                                         // 可选：上下文信息\n    forwardedProps: {},                                  // 可选：透传参数\n  },\n});\n\n// 处理流式响应\nfor await (const str of res.textStream) {\n  console.log(str);\n}\n\n```\n\n**完整示例:**\n\n```jsx\n/**\n * React Native 调用 Agent 完整示例（AG-UI 协议）\n * 协议文档：https://docs.cloudbase.net/ai/agent-development/protocol\n */\nimport React, { useState } from 'react';\nimport { View, Text, TextInput, Button, StyleSheet, Alert, ActivityIndicator } from 'react-native';\nimport cloudbase from './utils/cloudbase';\n\nexport default function CallAgent() {\n  const [input, setInput] = useState('');\n  const [response, setResponse] = useState('');\n  const [isGenerating, setIsGenerating] = useState(false);\n\n  // 调用Agent（AG-UI 协议）\n  const callAgent = async () => {\n    setIsGenerating(true);\n    setResponse('');\n\n    try {\n      const ai = cloudbase.ai();\n\n      // 确保已登录\n      const loginState = await cloudbase.auth().getLoginState();\n      if (!loginState) {\n        await cloudbase.auth().signInAnonymously();\n      }\n\n      // 构建消息列表（AG-UI 协议格式）\n      const messages = [\n        {\n          id: 'msg_001',\n          role: 'user',\n          content: input,\n        },\n      ];\n\n      // AG-UI 协议请求参数\n      const res = await ai.bot.sendMessage({\n        botId: '{%AGENT_ID%}',\n        data: {\n          messages,                                            // 必填：消息列表\n          threadId: '550e8400-e29b-41d4-a716-446655440000',   // 可选：会话ID，用于多轮对话\n          runId: 'run_001',                                    // 可选：运行ID，用于追踪执行\n          tools: [],                                           // 可选：前端工具定义\n          context: [],                                         // 可选：上下文信息\n          forwardedProps: {},                                  // 可选：透传参数\n        },\n      });\n\n      // 处理流式响应\n      for await (const str of res.textStream) {\n        setResponse((prev) => prev + str);\n      }\n\n      Alert.alert('成功', '生成完成');\n    } catch (err) {\n      Alert.alert('错误', `生成失败: ${err.message}`);\n    } finally {\n      setIsGenerating(false);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>输入问题：</Text>\n      <TextInput style={styles.input} value={input} onChangeText={setInput} placeholder=\"请输入问题，如：你是谁\" />\n      <Button title=\"发送消息\" onPress={callAgent} disabled={!input || isGenerating} />\n      {isGenerating && <ActivityIndicator size=\"large\" style={styles.loader} />}\n      {response && (\n        <View style={styles.resultContainer}>\n          <Text>回答：</Text>\n          <Text>{response}</Text>\n        </View>\n      )}\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20,\n  },\n  input: {\n    height: 40,\n    borderColor: '#ccc',\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5,\n  },\n  loader: {\n    marginVertical: 20,\n  },\n  resultContainer: {\n    marginTop: 20,\n    padding: 10,\n    backgroundColor: '#f9f9f9',\n    borderRadius: 5,\n  },\n});\n\n```",
                "index": 0,
                "id": "scf",
                "title": "函数型"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst ai = cloudbase.ai();\n\n// 确保已登录\nconst loginState = await cloudbase.auth().getLoginState();\nif (!loginState) {\n  await cloudbase.auth().signInAnonymously();\n}\n\nconst res = await ai.bot.sendMessage({\n  botId: \"{%AGENT_ID%}\",\n  msg: input\n});\n\nfor await (let str of res.textStream) {\n  // 处理流式响应\n}\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport {\n  View,\n  Text,\n  TextInput,\n  Button,\n  StyleSheet,\n  Alert,\n  ActivityIndicator\n} from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function CallAgent() {\n  const [input, setInput] = useState(\"\");\n  const [response, setResponse] = useState(\"\");\n  const [isGenerating, setIsGenerating] = useState(false);\n\n  // 调用Agent\n  const callAgent = async () => {\n    setIsGenerating(true);\n    setResponse(\"\");\n\n    try {\n      const ai = cloudbase.ai();\n\n      // 确保已登录\n      const loginState = await cloudbase.auth().getLoginState();\n      if (!loginState) {\n        await cloudbase.auth().signInAnonymously();\n      }\n\n      const res = await ai.bot.sendMessage({\n        botId: \"{%AGENT_ID%}\",\n        msg: input\n      });\n\n      for await (let str of res.textStream) {\n        setResponse(prev => prev + str);\n      }\n\n      Alert.alert(\"成功\", \"生成完成\");\n    } catch (err) {\n      Alert.alert(\"错误\", `生成失败: ${err.message}`);\n    } finally {\n      setIsGenerating(false);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>输入问题：</Text>\n      <TextInput\n        style={styles.input}\n        value={input}\n        onChangeText={setInput}\n        placeholder=\"请输入问题，如：你是谁\"\n      />\n      <Button\n        title=\"发送消息\"\n        onPress={callAgent}\n        disabled={!input || isGenerating}\n      />\n      {isGenerating && <ActivityIndicator size=\"large\" style={styles.loader} />}\n      {response && (\n        <View style={styles.resultContainer}>\n          <Text>回答：</Text>\n          <Text>{response}</Text>\n        </View>\n      )}\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  },\n  loader: {\n    marginVertical: 20\n  },\n  resultContainer: {\n    marginTop: 20,\n    padding: 10,\n    backgroundColor: \"#f9f9f9\",\n    borderRadius: 5\n  }\n});\n```",
                "index": 1,
                "id": "baas",
                "title": "普通型"
              }
            ]
          },
          {
            "index": 9,
            "id": "identity",
            "title": "身份认证",
            "type": "sideTab",
            "content": [
              {
                "markdown": "使用 **短信验证码注册** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **短信验证码**\n\n**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ phone_number: phone });\n\n// 验证验证码\nconst verifyRes = await auth.verify({\n  verification_id: verificationId,\n  verification_code: code\n});\n\n// 注册（如用户已存在则自动登录）\nawait auth.signUp({\n  phone_number: `+86 ${phone}`,\n  verification_code: code,\n  verification_token: verifyRes.verification_token,\n  name: `user_${phone.slice(-4)}`,\n  password: \"admin@123\"\n});\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, TextInput, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function SmsRegister() {\n  const [phone, setPhone] = useState(\"\");\n  const [code, setCode] = useState(\"\");\n  const [verificationId, setVerificationId] = useState(\"\");\n  const [message, setMessage] = useState(\"\");\n\n  // 发送验证码\n  const sendCode = async () => {\n    try {\n      const auth = cloudbase.auth();\n      const res = await auth.getVerification({ phone_number: phone });\n      setVerificationId(res.verification_id);\n      setMessage(\"验证码已发送！\");\n    } catch (error) {\n      setMessage(`发送失败: ${error.message}`);\n    }\n  };\n\n  // 注册\n  const register = async () => {\n    try {\n      const auth = cloudbase.auth();\n      // 验证验证码\n      const verifyRes = await auth.verify({\n        verification_id: verificationId,\n        verification_code: code\n      });\n      // 注册（如用户已存在则自动登录）\n      await auth.signUp({\n        phone_number: `+86 ${phone}`,\n        verification_code: code,\n        verification_token: verifyRes.verification_token,\n        name: `user_${phone.slice(-4)}`,\n        password: \"admin@123\"\n      });\n      setMessage(\"注册成功！\");\n      Alert.alert(\"成功\", \"注册成功\");\n    } catch (error) {\n      setMessage(`注册失败: ${error.message}`);\n      Alert.alert(\"失败\", `注册失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>手机号：</Text>\n      <TextInput\n        style={styles.input}\n        value={phone}\n        onChangeText={setPhone}\n        placeholder=\"13800000000\"\n        keyboardType=\"phone-pad\"\n      />\n      <Text>验证码：</Text>\n      <View style={styles.row}>\n        <TextInput\n          style={[styles.input, styles.codeInput]}\n          value={code}\n          onChangeText={setCode}\n          placeholder=\"验证码\"\n          keyboardType=\"numeric\"\n        />\n        <Button title=\"发送验证码\" onPress={sendCode} disabled={!phone} />\n      </View>\n      <Button\n        title=\"注册\"\n        onPress={register}\n        disabled={!verificationId || !code}\n      />\n      {message && (\n        <Text\n          style={[\n            styles.message,\n            { color: message.includes(\"成功\") ? \"green\" : \"red\" }\n          ]}\n        >\n          {message}\n        </Text>\n      )}\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  },\n  row: {\n    flexDirection: \"row\",\n    alignItems: \"center\"\n  },\n  codeInput: {\n    flex: 1,\n    marginRight: 10\n  },\n  message: {\n    marginTop: 20,\n    textAlign: \"center\"\n  }\n});\n```",
                "index": 1,
                "title": "短信验证码注册",
                "content": []
              },
              {
                "markdown": "使用 **邮箱验证码注册** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **邮箱验证码**\n\n**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ email });\n\n// 验证验证码\nconst verifyRes = await auth.verify({\n  verification_id: verificationId,\n  verification_code: code\n});\n\n// 注册（如用户已存在则自动登录）\nawait auth.signUp({\n  email,\n  verification_code: code,\n  verification_token: verifyRes.verification_token,\n  name: `user_${email.slice(-4)}`,\n  password: \"admin@123\"\n});\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, TextInput, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function EmailRegister() {\n  const [email, setEmail] = useState(\"\");\n  const [code, setCode] = useState(\"\");\n  const [verificationId, setVerificationId] = useState(\"\");\n  const [message, setMessage] = useState(\"\");\n\n  // 发送验证码\n  const sendCode = async () => {\n    try {\n      const auth = cloudbase.auth();\n      const res = await auth.getVerification({ email });\n      setVerificationId(res.verification_id);\n      setMessage(\"验证码已发送！\");\n    } catch (error) {\n      setMessage(`发送失败: ${error.message}`);\n    }\n  };\n\n  // 注册\n  const register = async () => {\n    try {\n      const auth = cloudbase.auth();\n      // 验证验证码\n      const verifyRes = await auth.verify({\n        verification_id: verificationId,\n        verification_code: code\n      });\n      // 注册（如用户已存在则自动登录）\n      await auth.signUp({\n        email,\n        verification_code: code,\n        verification_token: verifyRes.verification_token,\n        name: `user_${email.slice(-4)}`,\n        password: \"admin@123\"\n      });\n      setMessage(\"注册成功！\");\n      Alert.alert(\"成功\", \"注册成功\");\n    } catch (error) {\n      setMessage(`注册失败: ${error.message}`);\n      Alert.alert(\"失败\", `注册失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>邮箱：</Text>\n      <TextInput\n        style={styles.input}\n        value={email}\n        onChangeText={setEmail}\n        placeholder=\"example@email.com\"\n        keyboardType=\"email-address\"\n      />\n      <Text>验证码：</Text>\n      <View style={styles.row}>\n        <TextInput\n          style={[styles.input, styles.codeInput]}\n          value={code}\n          onChangeText={setCode}\n          placeholder=\"验证码\"\n          keyboardType=\"numeric\"\n        />\n        <Button title=\"发送验证码\" onPress={sendCode} disabled={!email} />\n      </View>\n      <Button\n        title=\"注册\"\n        onPress={register}\n        disabled={!verificationId || !code}\n      />\n      {message && (\n        <Text\n          style={[\n            styles.message,\n            { color: message.includes(\"成功\") ? \"green\" : \"red\" }\n          ]}\n        >\n          {message}\n        </Text>\n      )}\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  },\n  row: {\n    flexDirection: \"row\",\n    alignItems: \"center\"\n  },\n  codeInput: {\n    flex: 1,\n    marginRight: 10\n  },\n  message: {\n    marginTop: 20,\n    textAlign: \"center\"\n  }\n});\n```",
                "index": 2,
                "title": "邮箱验证码注册",
                "content": []
              },
              {
                "markdown": "使用 **账号密码登录** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **用户名密码登录**\n\n**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\nawait auth.signIn({\n  username, // 可以是用户名、手机号或邮箱\n  password\n});\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, TextInput, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function PasswordLogin() {\n  const [username, setUsername] = useState(\"\");\n  const [password, setPassword] = useState(\"\");\n  const [message, setMessage] = useState(\"\");\n\n  // 登录\n  const login = async () => {\n    try {\n      const auth = cloudbase.auth();\n      await auth.signIn({\n        username, // 可以是用户名、手机号或邮箱\n        password\n      });\n      setMessage(\"登录成功！\");\n      Alert.alert(\"成功\", \"登录成功\");\n    } catch (error) {\n      setMessage(`登录失败: ${error.message}`);\n      Alert.alert(\"失败\", `登录失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>账号：</Text>\n      <TextInput\n        style={styles.input}\n        value={username}\n        onChangeText={setUsername}\n        placeholder=\"用户名/手机号/邮箱\"\n      />\n      <Text style={styles.note}>注：手机号登录请添加区号 +86</Text>\n      <Text>密码：</Text>\n      <TextInput\n        style={styles.input}\n        value={password}\n        onChangeText={setPassword}\n        placeholder=\"请输入密码\"\n        secureTextEntry\n      />\n      <Button title=\"登录\" onPress={login} disabled={!username || !password} />\n      {message && (\n        <Text\n          style={[\n            styles.message,\n            { color: message.includes(\"成功\") ? \"green\" : \"red\" }\n          ]}\n        >\n          {message}\n        </Text>\n      )}\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  },\n  note: {\n    fontSize: 12,\n    color: \"#666\",\n    marginBottom: 10\n  },\n  message: {\n    marginTop: 20,\n    textAlign: \"center\"\n  }\n});\n```",
                "index": 3,
                "id": "UserNameLogin",
                "title": "账号密码登录",
                "content": []
              },
              {
                "markdown": "使用 **短信验证码登录** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **短信验证码登录**\n\n**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ phone_number: `+86 ${phone}` });\n\n// 登录\nawait auth.signInWithSms({\n  verificationInfo: res,\n  verificationCode: code,\n  phoneNum: `+86 ${phone}`\n});\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, TextInput, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function SmsLogin() {\n  const [phone, setPhone] = useState(\"\");\n  const [code, setCode] = useState(\"\");\n  const [verificationInfo, setVerificationInfo] = useState(null);\n  const [message, setMessage] = useState(\"\");\n\n  // 发送验证码\n  const sendCode = async () => {\n    try {\n      const auth = cloudbase.auth();\n      const res = await auth.getVerification({ phone_number: `+86 ${phone}` });\n      setVerificationInfo(res);\n      setMessage(\"验证码已发送！\");\n    } catch (error) {\n      setMessage(`发送失败: ${error.message}`);\n    }\n  };\n\n  // 登录\n  const login = async () => {\n    try {\n      const auth = cloudbase.auth();\n      await auth.signInWithSms({\n        verificationInfo,\n        verificationCode: code,\n        phoneNum: `+86 ${phone}`\n      });\n      setMessage(\"登录成功！\");\n      Alert.alert(\"成功\", \"登录成功\");\n    } catch (error) {\n      setMessage(`登录失败: ${error.message}`);\n      Alert.alert(\"失败\", `登录失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>手机号：</Text>\n      <TextInput\n        style={styles.input}\n        value={phone}\n        onChangeText={setPhone}\n        placeholder=\"13800000000\"\n        keyboardType=\"phone-pad\"\n      />\n      <Text>验证码：</Text>\n      <View style={styles.row}>\n        <TextInput\n          style={[styles.input, styles.codeInput]}\n          value={code}\n          onChangeText={setCode}\n          placeholder=\"验证码\"\n          keyboardType=\"numeric\"\n        />\n        <Button title=\"发送验证码\" onPress={sendCode} disabled={!phone} />\n      </View>\n      <Button\n        title=\"登录\"\n        onPress={login}\n        disabled={!verificationInfo || !code}\n      />\n      {message && (\n        <Text\n          style={[\n            styles.message,\n            { color: message.includes(\"成功\") ? \"green\" : \"red\" }\n          ]}\n        >\n          {message}\n        </Text>\n      )}\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  },\n  row: {\n    flexDirection: \"row\",\n    alignItems: \"center\"\n  },\n  codeInput: {\n    flex: 1,\n    marginRight: 10\n  },\n  message: {\n    marginTop: 20,\n    textAlign: \"center\"\n  }\n});\n```",
                "index": 4,
                "id": "PhoneNumberLogin",
                "title": "短信验证码登录",
                "content": []
              },
              {
                "markdown": "使用 **邮箱验证码登录** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **邮箱验证码**\n\n**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ email });\n\n// 登录\nawait auth.signInWithEmail({\n  verificationInfo: res,\n  verificationCode: code,\n  email\n});\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Text, TextInput, Button, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function EmailLogin() {\n  const [email, setEmail] = useState(\"\");\n  const [code, setCode] = useState(\"\");\n  const [verificationInfo, setVerificationInfo] = useState(null);\n  const [message, setMessage] = useState(\"\");\n\n  // 发送验证码\n  const sendCode = async () => {\n    try {\n      const auth = cloudbase.auth();\n      const res = await auth.getVerification({ email });\n      setVerificationInfo(res);\n      setMessage(\"验证码已发送！\");\n    } catch (error) {\n      setMessage(`发送失败: ${error.message}`);\n    }\n  };\n\n  // 登录\n  const login = async () => {\n    try {\n      const auth = cloudbase.auth();\n      await auth.signInWithEmail({\n        verificationInfo,\n        verificationCode: code,\n        email\n      });\n      setMessage(\"登录成功！\");\n      Alert.alert(\"成功\", \"登录成功\");\n    } catch (error) {\n      setMessage(`登录失败: ${error.message}`);\n      Alert.alert(\"失败\", `登录失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Text>邮箱：</Text>\n      <TextInput\n        style={styles.input}\n        value={email}\n        onChangeText={setEmail}\n        placeholder=\"example@email.com\"\n        keyboardType=\"email-address\"\n      />\n      <Text>验证码：</Text>\n      <View style={styles.row}>\n        <TextInput\n          style={[styles.input, styles.codeInput]}\n          value={code}\n          onChangeText={setCode}\n          placeholder=\"验证码\"\n          keyboardType=\"numeric\"\n        />\n        <Button title=\"发送验证码\" onPress={sendCode} disabled={!email} />\n      </View>\n      <Button\n        title=\"登录\"\n        onPress={login}\n        disabled={!verificationInfo || !code}\n      />\n      {message && (\n        <Text\n          style={[\n            styles.message,\n            { color: message.includes(\"成功\") ? \"green\" : \"red\" }\n          ]}\n        >\n          {message}\n        </Text>\n      )}\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20\n  },\n  input: {\n    height: 40,\n    borderColor: \"#ccc\",\n    borderWidth: 1,\n    marginVertical: 10,\n    paddingHorizontal: 10,\n    borderRadius: 5\n  },\n  row: {\n    flexDirection: \"row\",\n    alignItems: \"center\"\n  },\n  codeInput: {\n    flex: 1,\n    marginRight: 10\n  },\n  message: {\n    marginTop: 20,\n    textAlign: \"center\"\n  }\n});\n```",
                "index": 5,
                "id": "email",
                "title": "邮箱验证码登录",
                "content": []
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./utils/cloudbase\";\n\nconst auth = cloudbase.auth();\n\nawait auth.signInAnonymously();\n```\n\n**完整示例:**\n\n```jsx\nimport React, { useState } from \"react\";\nimport { View, Button, Text, StyleSheet, Alert } from \"react-native\";\nimport cloudbase from \"./utils/cloudbase\";\n\nexport default function AnonymousLogin() {\n  const [message, setMessage] = useState(\"\");\n\n  // 匿名登录\n  const anonymousLogin = async () => {\n    try {\n      const auth = cloudbase.auth();\n      await auth.signInAnonymously();\n      setMessage(\"匿名登录成功！\");\n      Alert.alert(\"成功\", \"匿名登录成功\");\n    } catch (error) {\n      setMessage(`登录失败: ${error.message}`);\n      Alert.alert(\"失败\", `登录失败: ${error.message}`);\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <Button title=\"匿名登录\" onPress={anonymousLogin} />\n      {message && (\n        <Text\n          style={[\n            styles.message,\n            { color: message.includes(\"成功\") ? \"green\" : \"red\" }\n          ]}\n        >\n          {message}\n        </Text>\n      )}\n    </View>\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    padding: 20,\n    justifyContent: \"center\"\n  },\n  message: {\n    marginTop: 20,\n    textAlign: \"center\"\n  }\n});\n```",
                "index": 6,
                "title": "匿名登录",
                "content": []
              }
            ]
          }
        ]
      }
    ],
    "_id": "de58e949696a010300087fd77a113734",
    "_openid": "anon",
    "createdAt": 1768554755123,
    "updatedAt": 1770371605903
  },
  {
    "category": "框架集成,ORMs,Prisma",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": 41,
    "hasTemplate": false,
    "docsUrl": "https://prisma.org.cn/docs/getting-started/prisma-orm/quickstart/mysql",
    "content": [
      {
        "docsUrl": "",
        "markdown": "使用 `Prisma` 操作 **MySQL数据库**\n\n新增如下代码到您的 **Prisma** 项目",
        "title": "修改环境变量",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```\nDATABASE_URL=mysql://{%DATABASE_URL%}\n```",
            "index": 2,
            "id": "mysqlString",
            "title": ".env"
          },
          {
            "markdown": "```prisma\ngenerator client {\n  provider = \"prisma-client-js\"\n}\n\ndatasource db {\n  provider = \"mysql\"\n  url      = env(\"DATABASE_URL\")\n}\n```",
            "index": 1,
            "id": "",
            "title": "prisma/schema.prisma"
          }
        ]
      }
    ],
    "_id": "e18d057969649dca0bcc9062570f0c39",
    "_openid": "anon",
    "createdAt": 1768201674449,
    "updatedAt": 1770105728114
  },
  {
    "category": "框架集成,小程序 / 小游戏,微信小游戏,Cocos",
    "targetPlatform": [
      "default"
    ],
    "lang": "zh",
    "index": 3,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/api-reference/webv2/adapter",
    "content": [
      {
        "markdown": "`@cloudbase/js-sdk` 配合 `@cloudbase/adapter-cocos_native` 可以让您在 Cocos 项目中访问 CloudBase 服务和资源。",
        "index": 1,
        "title": "安装 SDK",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```bash\nnpm i @cloudbase/js-sdk @cloudbase/adapter-cocos_native\n```",
            "index": 1,
            "title": "npm",
            "content": []
          },
          {
            "markdown": "```bash\nyarn add @cloudbase/js-sdk @cloudbase/adapter-cocos_native\n```",
            "index": 2,
            "title": "yarn",
            "content": []
          },
          {
            "markdown": "```bash\npnpm add @cloudbase/js-sdk @cloudbase/adapter-cocos_native\n```",
            "index": 3,
            "title": "pnpm",
            "content": []
          }
        ]
      },
      {
        "markdown": "新增如下代码到您的 Cocos 项目",
        "index": 2,
        "title": "初始化 SDK",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```js\nimport cloudbaseSDK from \"@cloudbase/js-sdk\";\nimport adapter from \"@cloudbase/adapter-cocos_native\";\n\n// 注册适配器\ncloudbaseSDK.useAdapters(adapter);\n\nconst cloudbase = cloudbaseSDK.init({\n  // 环境 ID\n  env: \"{%ENV_ID%}\",\n  // 地域\n  region: \"{%REGION%}\",\n  // 匿名访问令牌\n  accessKey: \"{%PUBLISHABLE_KEY%}\"\n});\n\nexport default cloudbase;\n```",
            "index": 1,
            "title": "scripts/services/CloudbaseService.js",
            "content": []
          }
        ]
      },
      {
        "sideTabs": [
          {
            "id": "pg-db",
            "title": "PostgreSQL 数据库"
          }
        ],
        "index": 3,
        "title": "调用云开发能力",
        "type": "codeTab",
        "content": [
          {
            "index": 1,
            "id": "pg-db",
            "title": "PostgreSQL 数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\nconst cloudbase = getApp().globalData.cloudbase;\n\n// 查询 {%TABLE_NAME%} 表前 10 条数据\nconst { data, error } = await cloudbase.rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .select(\"*\")\n  .limit(10);\n\nconsole.log(\"查询结果:\", data);\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "```js\nconst cloudbase = getApp().globalData.cloudbase;\n\n// 向 {%TABLE_NAME%} 表插入一条数据\n// 注意：anon 令牌（publishable key）仅有读权限，写操作需用户登录态或配置 RLS 写策略\nconst { data, error } = await cloudbase.rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .insert({ title: \"新文章\", status: \"draft\" })\n  .select();\n\nconsole.log(\"新增结果:\", data);\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "```js\nconst cloudbase = getApp().globalData.cloudbase;\n\n// 更新 {%TABLE_NAME%} 表中 id=1 的记录\n// 注意：anon 令牌（publishable key）仅有读权限，写操作需用户登录态或配置 RLS 写策略\nconst { data, error } = await cloudbase.rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .update({ status: \"published\" })\n  .eq(\"id\", 1)\n  .select();\n\nconsole.log(\"更新结果:\", data);\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "```js\nconst cloudbase = getApp().globalData.cloudbase;\n\n// 当 id 冲突时更新，否则插入\n// 注意：anon 令牌（publishable key）仅有读权限，写操作需用户登录态或配置 RLS 写策略\nconst { data, error } = await cloudbase.rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .upsert({ id: 1, title: \"标题\", status: \"published\" }, { onConflict: \"id\" })\n  .select();\n\nconsole.log(\"更新或创建结果:\", data);\n```",
                "index": 4,
                "title": "更新或创建数据"
              },
              {
                "markdown": "```js\nconst cloudbase = getApp().globalData.cloudbase;\n\n// 删除 {%TABLE_NAME%} 表中 id=1 的记录\n// 注意：anon 令牌（publishable key）仅有读权限，写操作需用户登录态或配置 RLS 写策略\nconst { data, error } = await cloudbase.rdb()\n  .from(\"{%TABLE_NAME%}\")\n  .delete()\n  .eq(\"id\", 1);\n\nconsole.log(\"删除完成:\", error);\n```",
                "index": 5,
                "title": "删除数据"
              }
            ]
          },
          {
            "index": 1,
            "id": "mysql-db",
            "title": "MySQL数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst { data, error } = await cloudbase\n  .database()\n  .from(\"{%TABLE_NAME%}\")\n  .select(\"*\")\n  .limit(10);\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('QueryData')\nexport class QueryData extends Component {\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onLoad() {\n    try {\n      const { data, error } = await cloudbase.database().from(\"{%TABLE_NAME%}\").select(\"*\").limit(10);\n\n      if (!error) {\n        this.resultLabel.string = `查询成功：${JSON.stringify(data)}`;\n        console.log('查询结果：', data);\n      } else {\n        this.resultLabel.string = '查询失败';\n        console.error('查询失败：', error);\n      }\n    } catch (error) {\n      this.resultLabel.string = `查询失败: ${error.message}`;\n      console.error('查询失败：', error);\n    }\n  }\n}\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst { data, error } = await cloudbase\n  .database()\n  .from(\"{%TABLE_NAME%}\")\n  .insert({ title: \"示例标题\" });\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('AddData')\nexport class AddData extends Component {\n  @property(EditBox)\n  titleInput: EditBox = null;\n\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onAddButtonClick() {\n    const title = this.titleInput.string;\n    if (!title) {\n      this.resultLabel.string = '请输入标题';\n      return;\n    }\n\n    try {\n      const { data, error } = await cloudbase.database().from(\"{%TABLE_NAME%}\").insert({ title });\n\n      if (!error) {\n        this.resultLabel.string = '新增成功';\n        this.titleInput.string = '';\n        console.log('新增成功：', data);\n      } else {\n        this.resultLabel.string = '新增失败';\n        console.error('新增失败：', error);\n      }\n    } catch (error) {\n      this.resultLabel.string = `新增失败: ${error.message}`;\n      console.error('新增失败：', error);\n    }\n  }\n}\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst { data, error } = await cloudbase\n  .database()\n  .from(\"{%TABLE_NAME%}\")\n  .update({ title: \"新标题\" })\n  .eq(\"id\", dataId);\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('UpdateData')\nexport class UpdateData extends Component {\n  @property(EditBox)\n  idInput: EditBox = null;\n\n  @property(EditBox)\n  titleInput: EditBox = null;\n\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onUpdateButtonClick() {\n    const dataId = this.idInput.string;\n    const newTitle = this.titleInput.string;\n\n    if (!dataId || !newTitle) {\n      this.resultLabel.string = '请输入数据ID和新标题';\n      return;\n    }\n\n    try {\n      const { data, error } = await cloudbase.database().from(\"{%TABLE_NAME%}\").update({ title: newTitle }).eq(\"id\", dataId);\n\n      if (!error) {\n        this.resultLabel.string = '更新成功';\n        this.idInput.string = '';\n        this.titleInput.string = '';\n        console.log('更新成功：', data);\n      } else {\n        this.resultLabel.string = '更新失败';\n        console.error('更新失败：', error);\n      }\n    } catch (error) {\n      this.resultLabel.string = `更新失败: ${error.message}`;\n      console.error('更新失败：', error);\n    }\n  }\n}\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst { data, error } = await cloudbase\n  .database()\n  .from(\"{%TABLE_NAME%}\")\n  .upsert({ id: 1, title: \"标题\" });\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('UpsertData')\nexport class UpsertData extends Component {\n  @property(EditBox)\n  idInput: EditBox = null;\n\n  @property(EditBox)\n  titleInput: EditBox = null;\n\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onUpsertButtonClick() {\n    const id = parseInt(this.idInput.string);\n    const title = this.titleInput.string;\n\n    if (!id || !title) {\n      this.resultLabel.string = '请输入ID和标题';\n      return;\n    }\n\n    try {\n      const { data, error } = await cloudbase.database().from(\"{%TABLE_NAME%}\").upsert({ id, title });\n\n      if (!error) {\n        this.resultLabel.string = '操作成功';\n        this.idInput.string = '';\n        this.titleInput.string = '';\n        console.log('操作成功：', data);\n      } else {\n        this.resultLabel.string = '操作失败';\n        console.error('操作失败：', error);\n      }\n    } catch (error) {\n      this.resultLabel.string = `操作失败: ${error.message}`;\n      console.error('操作失败：', error);\n    }\n  }\n}\n```",
                "index": 4,
                "title": "更新或创建数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst { data, error } = await cloudbase\n  .database()\n  .from(\"{%TABLE_NAME%}\")\n  .delete()\n  .eq(\"id\", dataId);\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('DeleteData')\nexport class DeleteData extends Component {\n  @property(EditBox)\n  idInput: EditBox = null;\n\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onDeleteButtonClick() {\n    const dataId = this.idInput.string;\n\n    if (!dataId) {\n      this.resultLabel.string = '请输入要删除的数据ID';\n      return;\n    }\n\n    try {\n      const { data, error } = await cloudbase.database().from(\"{%TABLE_NAME%}\").delete().eq(\"id\", dataId);\n\n      if (!error) {\n        this.resultLabel.string = '删除成功';\n        this.idInput.string = '';\n        console.log('删除成功：', data);\n      } else {\n        this.resultLabel.string = '删除失败';\n        console.error('删除失败：', error);\n      }\n    } catch (error) {\n      this.resultLabel.string = `删除失败: ${error.message}`;\n      console.error('删除失败：', error);\n    }\n  }\n}\n```",
                "index": 5,
                "title": "删除数据"
              }
            ]
          },
          {
            "index": 2,
            "id": "doc-db",
            "title": "文档型数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst db = cloudbase.database();\nconst res = await db.collection(\"{%TABLE_NAME%}\").limit(10).get();\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('QueryDocData')\nexport class QueryDocData extends Component {\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onLoad() {\n    try {\n      const db = cloudbase.database();\n      const res = await db.collection(\"{%TABLE_NAME%}\").limit(10).get();\n\n      this.resultLabel.string = `查询成功：${JSON.stringify(res.data)}`;\n      console.log('查询结果：', res.data);\n    } catch (error) {\n      this.resultLabel.string = `查询失败: ${error.message}`;\n      console.error('查询失败：', error);\n    }\n  }\n}\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst db = cloudbase.database();\nconst res = await db.collection(\"{%TABLE_NAME%}\").add({ title: \"示例标题\" });\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('AddDocData')\nexport class AddDocData extends Component {\n  @property(EditBox)\n  titleInput: EditBox = null;\n\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onAddButtonClick() {\n    const title = this.titleInput.string;\n    if (!title) {\n      this.resultLabel.string = '请输入标题';\n      return;\n    }\n\n    try {\n      const db = cloudbase.database();\n      const res = await db.collection(\"{%TABLE_NAME%}\").add({ title });\n\n      this.resultLabel.string = `新增成功! id: ${res.id}`;\n      this.titleInput.string = '';\n      console.log('新增成功：', res);\n    } catch (error) {\n      this.resultLabel.string = `新增失败: ${error.message}`;\n      console.error('新增失败：', error);\n    }\n  }\n}\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst db = cloudbase.database();\nawait db.collection(\"{%TABLE_NAME%}\").doc(dataId).update({ title: \"新标题\" });\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('UpdateDocData')\nexport class UpdateDocData extends Component {\n  @property(EditBox)\n  idInput: EditBox = null;\n\n  @property(EditBox)\n  titleInput: EditBox = null;\n\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onUpdateButtonClick() {\n    const dataId = this.idInput.string;\n    const newTitle = this.titleInput.string;\n\n    if (!dataId || !newTitle) {\n      this.resultLabel.string = '请输入数据ID和新标题';\n      return;\n    }\n\n    try {\n      const db = cloudbase.database();\n      await db.collection(\"{%TABLE_NAME%}\").doc(dataId).update({ title: newTitle });\n\n      this.resultLabel.string = '更新成功';\n      this.idInput.string = '';\n      this.titleInput.string = '';\n      console.log('更新成功');\n    } catch (error) {\n      this.resultLabel.string = `更新失败: ${error.message}`;\n      console.error('更新失败：', error);\n    }\n  }\n}\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst db = cloudbase.database();\nawait db.collection(\"{%TABLE_NAME%}\").doc(dataId).remove();\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('DeleteDocData')\nexport class DeleteDocData extends Component {\n  @property(EditBox)\n  idInput: EditBox = null;\n\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onDeleteButtonClick() {\n    const dataId = this.idInput.string;\n\n    if (!dataId) {\n      this.resultLabel.string = '请输入要删除的数据ID';\n      return;\n    }\n\n    try {\n      const db = cloudbase.database();\n      await db.collection(\"{%TABLE_NAME%}\").doc(dataId).remove();\n\n      this.resultLabel.string = '删除成功';\n      this.idInput.string = '';\n      console.log('删除成功');\n    } catch (error) {\n      this.resultLabel.string = `删除失败: ${error.message}`;\n      console.error('删除失败：', error);\n    }\n  }\n}\n```",
                "index": 4,
                "title": "删除数据"
              }
            ]
          },
          {
            "index": 3,
            "id": "data-model",
            "title": "数据模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst res = await cloudbase.models[\"{%TABLE_NAME%}\"].list({\n  pageNumber: 1,\n  pagesize: 10\n});\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('QueryModelData')\nexport class QueryModelData extends Component {\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onLoad() {\n    try {\n      const res = await cloudbase.models[\"{%TABLE_NAME%}\"].list({ pageNumber: 1, pagesize: 10 });\n\n      const records = res.data?.records || [];\n      this.resultLabel.string = `查询成功：${JSON.stringify(records)}`;\n      console.log('查询结果：', records);\n    } catch (error) {\n      this.resultLabel.string = `查询失败: ${error.message}`;\n      console.error('查询失败：', error);\n    }\n  }\n}\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst res = await cloudbase.models[\"{%TABLE_NAME%}\"].create({\n  data: { title: \"示例标题\" }\n});\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('AddModelData')\nexport class AddModelData extends Component {\n  @property(EditBox)\n  titleInput: EditBox = null;\n\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onAddButtonClick() {\n    const title = this.titleInput.string;\n    if (!title) {\n      this.resultLabel.string = '请输入标题';\n      return;\n    }\n\n    try {\n      const res = await cloudbase.models[\"{%TABLE_NAME%}\"].create({ data: { title } });\n\n      this.resultLabel.string = `新增成功! id: ${res.data.id}`;\n      this.titleInput.string = '';\n      console.log('新增成功：', res);\n    } catch (error) {\n      this.resultLabel.string = `新增失败: ${error.message}`;\n      console.error('新增失败：', error);\n    }\n  }\n}\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nawait cloudbase.models[\"{%TABLE_NAME%}\"].update({\n  data: { title: \"新标题\" },\n  filter: { where: { _id: { $eq: dataId } } }\n});\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('UpdateModelData')\nexport class UpdateModelData extends Component {\n  @property(EditBox)\n  idInput: EditBox = null;\n\n  @property(EditBox)\n  titleInput: EditBox = null;\n\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onUpdateButtonClick() {\n    const dataId = this.idInput.string;\n    const newTitle = this.titleInput.string;\n\n    if (!dataId || !newTitle) {\n      this.resultLabel.string = '请输入数据ID和新标题';\n      return;\n    }\n\n    try {\n      await cloudbase.models[\"{%TABLE_NAME%}\"].update({\n        data: { title: newTitle },\n        filter: { where: { _id: { $eq: dataId } } }\n      });\n\n      this.resultLabel.string = '更新成功';\n      this.idInput.string = '';\n      this.titleInput.string = '';\n      console.log('更新成功');\n    } catch (error) {\n      this.resultLabel.string = `更新失败: ${error.message}`;\n      console.error('更新失败：', error);\n    }\n  }\n}\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nawait cloudbase.models[\"{%TABLE_NAME%}\"].delete({\n  filter: { where: { _id: { $eq: dataId } } }\n});\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('DeleteModelData')\nexport class DeleteModelData extends Component {\n  @property(EditBox)\n  idInput: EditBox = null;\n\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onDeleteButtonClick() {\n    const dataId = this.idInput.string;\n\n    if (!dataId) {\n      this.resultLabel.string = '请输入要删除的数据ID';\n      return;\n    }\n\n    try {\n      await cloudbase.models[\"{%TABLE_NAME%}\"].delete({\n        filter: { where: { _id: { $eq: dataId } } }\n      });\n\n      this.resultLabel.string = '删除成功';\n      this.idInput.string = '';\n      console.log('删除成功');\n    } catch (error) {\n      this.resultLabel.string = `删除失败: ${error.message}`;\n      console.error('删除失败：', error);\n    }\n  }\n}\n```",
                "index": 4,
                "title": "删除数据"
              }
            ]
          },
          {
            "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst res = await cloudbase.callFunction({\n  name: \"{%FUNCTION_NAME%}\",\n  data: {}\n});\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('CallFunction')\nexport class CallFunction extends Component {\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onCallButtonClick() {\n    try {\n      const res = await cloudbase.callFunction({\n        name: \"{%FUNCTION_NAME%}\",\n        data: {}\n      });\n\n      this.resultLabel.string = `调用成功：${JSON.stringify(res.result)}`;\n      console.log('调用结果：', res.result);\n    } catch (error) {\n      this.resultLabel.string = `调用失败: ${error.message}`;\n      console.error('调用失败：', error);\n    }\n  }\n}\n```",
            "index": 4,
            "id": "scf",
            "title": "云函数",
            "content": []
          },
          {
            "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\n// 调用 {%SERVICE_NAME%} 云托管服务\nconst res = await cloudbase.callContainer({\n  name: \"{%SERVICE_NAME%}\"\n  method: 'POST',\n  path: '/',\n  header:{\n    'Content-Type': 'application/json; charset=utf-8'\n  },\n  data: {},\n});\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('CallRun')\nexport class CallRun extends Component {\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onCallButtonClick() {\n    try {\n      // 调用 {%SERVICE_NAME%} 云托管服务\n      const res = await cloudbase.callContainer({\n        name: \"{%SERVICE_NAME%}\"\n        method: 'POST',\n        path: '/',\n        header:{\n          'Content-Type': 'application/json; charset=utf-8'\n        },\n        data: {},\n      });\n\n      this.resultLabel.string = `调用成功：${JSON.stringify(res)}`;\n      console.log('调用结果：', res);\n    } catch (error) {\n      this.resultLabel.string = `调用失败: ${error.message}`;\n      console.error('调用失败：', error);\n    }\n  }\n}\n```",
            "index": 5,
            "id": "run",
            "title": "云托管",
            "content": []
          },
          {
            "index": 6,
            "id": "storage",
            "title": "云存储",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst res = await cloudbase.uploadFile({\n  cloudPath: `images/${Date.now()}.png`,\n  filePath: filePath\n});\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('UploadFile')\nexport class UploadFile extends Component {\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onUploadButtonClick() {\n    try {\n      // 注意：实际使用中需要从用户选择或游戏资源中获取文件路径\n      const filePath = 'path/to/your/file.png';\n      const cloudPath = `images/${Date.now()}-${Math.random()}.png`;\n\n      const res = await cloudbase.uploadFile({\n        cloudPath: cloudPath,\n        filePath: filePath\n      });\n\n      this.resultLabel.string = `上传成功！文件ID: ${res.fileID}`;\n      console.log('上传成功：', res);\n    } catch (error) {\n      this.resultLabel.string = `上传失败: ${error.message}`;\n      console.error('上传失败：', error);\n    }\n  }\n}\n```",
                "index": 1,
                "title": "上传文件"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst res = await cloudbase.getTempFileURL({\n  fileList: [fileId]\n});\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('GetFileUrl')\nexport class GetFileUrl extends Component {\n  @property(EditBox)\n  fileIdInput: EditBox = null;\n\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onGetUrlButtonClick() {\n    const fileId = this.fileIdInput.string;\n\n    if (!fileId) {\n      this.resultLabel.string = '请输入文件ID';\n      return;\n    }\n\n    try {\n      const res = await cloudbase.getTempFileURL({\n        fileList: [fileId]\n      });\n\n      const fileUrl = res.fileList[0].tempFileURL;\n      this.resultLabel.string = `文件链接：${fileUrl}`;\n      console.log('文件链接：', fileUrl);\n    } catch (error) {\n      this.resultLabel.string = `获取失败: ${error.message}`;\n      console.error('获取失败：', error);\n    }\n  }\n}\n```",
                "index": 2,
                "title": "获取文件链接"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst res = await cloudbase.downloadFile({\n  fileID: fileId\n});\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('DownloadFile')\nexport class DownloadFile extends Component {\n  @property(EditBox)\n  fileIdInput: EditBox = null;\n\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onDownloadButtonClick() {\n    const fileId = this.fileIdInput.string;\n\n    if (!fileId) {\n      this.resultLabel.string = '请输入文件ID';\n      return;\n    }\n\n    try {\n      const res = await cloudbase.downloadFile({\n        fileID: fileId\n      });\n\n      this.resultLabel.string = `下载成功！本地路径: ${res.tempFilePath}`;\n      console.log('下载成功：', res);\n    } catch (error) {\n      this.resultLabel.string = `下载失败: ${error.message}`;\n      console.error('下载失败：', error);\n    }\n  }\n}\n```",
                "index": 3,
                "title": "下载文件"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst res = await cloudbase.deleteFile({\n  fileList: [fileId]\n});\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('DeleteFile')\nexport class DeleteFile extends Component {\n  @property(EditBox)\n  fileIdInput: EditBox = null;\n\n  @property(Label)\n  resultLabel: Label = null;\n\n  async onDeleteButtonClick() {\n    const fileId = this.fileIdInput.string;\n\n    if (!fileId) {\n      this.resultLabel.string = '请输入文件ID';\n      return;\n    }\n\n    try {\n      const res = await cloudbase.deleteFile({\n        fileList: [fileId]\n      });\n\n      if (res.fileList[0].code === \"SUCCESS\") {\n        this.resultLabel.string = '删除成功';\n        this.fileIdInput.string = '';\n        console.log('删除成功');\n      } else {\n        this.resultLabel.string = '删除失败';\n        console.error('删除失败');\n      }\n    } catch (error) {\n      this.resultLabel.string = `删除失败: ${error.message}`;\n      console.error('删除失败：', error);\n    }\n  }\n}\n```",
                "index": 4,
                "title": "删除文件"
              }
            ]
          },
          {
            "index": 7,
            "id": "ai-model",
            "title": "大模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst ai = cloudbase.ai();\nconst model = ai.createModel(\"{%AI_MODEL_NAME%}\");\n\n// 确保已登录\nconst loginState = await cloudbase.auth().getLoginState();\nif (!loginState) {\n  await cloudbase.auth().signInAnonymously();\n}\n\nconst res = await model.streamText({\n  model: \"{%AI_SUB_MODEL_NAME%}\",\n  messages: [\n    { role: \"system\", content: \"系统提示词\" },\n    { role: \"user\", content: \"用户输入\" }\n  ]\n});\n\nfor await (let str of res.textStream) {\n  // 处理流式响应\n}\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('CallAIModel')\nexport class CallAIModel extends Component {\n  @property(EditBox)\n  inputBox: EditBox = null;\n\n  @property(Label)\n  resultLabel: Label = null;\n\n  @property(Label)\n  statusLabel: Label = null;\n\n  async onGenerateButtonClick() {\n    const input = this.inputBox.string;\n    if (!input) {\n      this.statusLabel.string = '请输入主题';\n      return;\n    }\n\n    this.statusLabel.string = '生成中...';\n    this.resultLabel.string = '';\n\n    try {\n      const ai = cloudbase.ai();\n      const model = ai.createModel(\"{%AI_MODEL_NAME%}\");\n\n      // 确保已登录\n      const loginState = await cloudbase.auth().getLoginState();\n      if (!loginState) {\n        await cloudbase.auth().signInAnonymously();\n      }\n\n      const res = await model.streamText({\n        model: \"{%AI_SUB_MODEL_NAME%}\",\n        messages: [\n          { role: \"system\", content: \"请严格按照七言绝句或七言律诗的格律要求创作，平仄需符合规则，押韵要和谐自然，韵脚字需在同一韵部。\" },\n          { role: \"user\", content: input }\n        ]\n      });\n\n      let fullText = '';\n      for await (let str of res.textStream) {\n        fullText += str;\n        this.resultLabel.string = fullText;\n      }\n\n      this.statusLabel.string = '生成完成';\n      console.log('生成完成：', fullText);\n    } catch (err) {\n      this.statusLabel.string = '生成失败';\n      this.resultLabel.string = `错误: ${err.message}`;\n      console.error('生成失败：', err);\n    }\n  }\n}\n```",
                "index": 1,
                "id": "text-aiModel",
                "title": "生文模型"
              },
              {
                "markdown": "生图模型通过调用云函数来实现，在生图模型页面点击「一键创建云函数」，函数调用示例如下：\n\n**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\n// 调用生图云函数\nconst res = await cloudbase.callFunction({\n  name: \"<YOUR_FUNCTION_NAME>\",\n  data: {\n    prompt: \"一只可爱的猫咪在阳光下玩耍\"\n  }\n});\n\nconst result = res.result;\n\nif (result.success) {\n  // 生成成功\n  console.log(\"生成成功!\");\n  console.log(\"图片URL:\", result.imageUrl);\n  console.log(\"优化后的提示词:\", result.revised_prompt);\n\n  // 使用图片\n  // 注意：图片URL有效期为24小时，请及时保存或转存\n} else {\n  // 生成失败\n  console.error(\"生成失败:\", result.code, result.message);\n}\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label, Sprite } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('GenerateImage')\nexport class GenerateImage extends Component {\n  @property(EditBox)\n  promptInput: EditBox = null;\n\n  @property(Label)\n  statusLabel: Label = null;\n\n  @property(Sprite)\n  imageSprite: Sprite = null;\n\n  async onGenerateButtonClick() {\n    const prompt = this.promptInput.string;\n    if (!prompt) {\n      this.statusLabel.string = '请输入图片描述';\n      return;\n    }\n\n    this.statusLabel.string = '生成中...';\n\n    try {\n      // 调用生图云函数\n      const res = await cloudbase.callFunction({\n        name: \"<YOUR_FUNCTION_NAME>\",\n        data: {\n          prompt: prompt\n        }\n      });\n\n      const result = res.result;\n\n      if (result.success) {\n        this.statusLabel.string = '生成成功！';\n        console.log('图片URL:', result.imageUrl);\n        console.log('优化后的提示词:', result.revised_prompt);\n\n        // 加载图片到 Sprite\n        // 注意：需要使用网络加载图片的方式\n        // 具体实现可根据 Cocos Creator 版本调整\n      } else {\n        this.statusLabel.string = `生成失败：${result.message}`;\n        console.error('生成失败:', result.code, result.message);\n      }\n    } catch (err) {\n      this.statusLabel.string = '调用失败';\n      console.error('调用失败:', err);\n    }\n  }\n}\n```",
                "index": 2,
                "id": "image-aiModel",
                "title": "生图模型"
              }
            ]
          },
          {
            "markdown": "",
            "index": 8,
            "id": "agent",
            "title": "Agent",
            "type": "sideTab",
            "content": [
              {
                "markdown": "**调用方式：**\n\n```javascript\nimport cloudbase from './services/CloudbaseService';\n\nconst ai = cloudbase.ai();\n\n// 确保已登录\nconst loginState = await cloudbase.auth().getLoginState();\nif (!loginState) {\n  await cloudbase.auth().signInAnonymously();\n}\n\nconst res = await ai.bot.sendMessage({\n  botId: '{%AGENT_ID%}',\n  // 入参结构参考前后端通信协议：\n  // https://docs.cloudbase.net/ai/agent/http-agent-protocol\n  threadId: '550e8400-e29b-41d4-a716-446655440000',\n  runId: 'run_001',\n  messages: [\n    {\n      id: 'msg-1',\n      role: 'user',\n      content: '你好',\n    },\n  ],\n  tools: [],\n  context: [],\n  state: {},\n  forwardedProps: {},\n});\n\nfor await (let str of res.textStream) {\n  // 处理流式响应\n}\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('CallAgent')\nexport class CallAgent extends Component {\n  @property(EditBox)\n  inputBox: EditBox = null;\n\n  @property(Label)\n  resultLabel: Label = null;\n\n  @property(Label)\n  statusLabel: Label = null;\n\n  async onSendButtonClick() {\n    const input = this.inputBox.string;\n    if (!input) {\n      this.statusLabel.string = '请输入问题';\n      return;\n    }\n\n    this.statusLabel.string = '发送中...';\n    this.resultLabel.string = '';\n\n    try {\n      const ai = cloudbase.ai();\n\n      // 确保已登录\n      const loginState = await cloudbase.auth().getLoginState();\n      if (!loginState) {\n        await cloudbase.auth().signInAnonymously();\n      }\n\n      const res = await ai.bot.sendMessage({\n        botId: '{%AGENT_ID%}',\n        // 入参结构参考前后端通信协议：\n        // https://docs.cloudbase.net/ai/agent/http-agent-protocol\n        threadId: '550e8400-e29b-41d4-a716-446655440000',\n        runId: 'run_001',\n        messages: [\n          {\n            id: 'msg-1',\n            role: 'user',\n            content: input,\n          },\n        ],\n        tools: [],\n        context: [],\n        state: {},\n        forwardedProps: {},\n      });\n\n      let fullText = '';\n      for await (let str of res.textStream) {\n        fullText += str;\n        this.resultLabel.string = fullText;\n      }\n\n      this.statusLabel.string = '回答完成';\n      console.log('回答完成：', fullText);\n    } catch (err) {\n      this.statusLabel.string = '发送失败';\n      this.resultLabel.string = `错误: ${err.message}`;\n      console.error('发送失败：', err);\n    }\n  }\n}\n\n```",
                "index": 0,
                "id": "scf",
                "title": "函数型"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst ai = cloudbase.ai();\n\n// 确保已登录\nconst loginState = await cloudbase.auth().getLoginState();\nif (!loginState) {\n  await cloudbase.auth().signInAnonymously();\n}\n\nconst res = await ai.bot.sendMessage({\n  botId: \"{%AGENT_ID%}\",\n  msg: \"用户消息\"\n});\n\nfor await (let str of res.textStream) {\n  // 处理流式响应\n}\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('CallAgent')\nexport class CallAgent extends Component {\n  @property(EditBox)\n  inputBox: EditBox = null;\n\n  @property(Label)\n  resultLabel: Label = null;\n\n  @property(Label)\n  statusLabel: Label = null;\n\n  async onSendButtonClick() {\n    const input = this.inputBox.string;\n    if (!input) {\n      this.statusLabel.string = '请输入问题';\n      return;\n    }\n\n    this.statusLabel.string = '发送中...';\n    this.resultLabel.string = '';\n\n    try {\n      const ai = cloudbase.ai();\n\n      // 确保已登录\n      const loginState = await cloudbase.auth().getLoginState();\n      if (!loginState) {\n        await cloudbase.auth().signInAnonymously();\n      }\n\n      const res = await ai.bot.sendMessage({\n        botId: '{%AGENT_ID%}',\n        msg: input,\n      });\n\n      let fullText = '';\n      for await (let str of res.textStream) {\n        fullText += str;\n        this.resultLabel.string = fullText;\n      }\n\n      this.statusLabel.string = '回答完成';\n      console.log('回答完成：', fullText);\n    } catch (err) {\n      this.statusLabel.string = '发送失败';\n      this.resultLabel.string = `错误: ${err.message}`;\n      console.error('发送失败：', err);\n    }\n  }\n}\n```",
                "index": 1,
                "id": "baas",
                "title": "普通型"
              }
            ]
          },
          {
            "index": 9,
            "id": "identity",
            "title": "身份认证",
            "type": "sideTab",
            "content": [
              {
                "markdown": "使用 **短信验证码注册** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **短信验证码**\n\n**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ phone_number: phone });\nconst verificationId = res.verification_id;\n\n// 验证验证码\nconst verifyRes = await auth.verify({\n  verification_id: verificationId,\n  verification_code: code\n});\n\n// 注册\nawait auth.signUp({\n  phone_number: `+86 ${phone}`,\n  verification_code: code,\n  verification_token: verifyRes.verification_token,\n  name: `user_${phone.slice(-4)}`,\n  password: \"admin@123\"\n});\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('SmsRegister')\nexport class SmsRegister extends Component {\n  @property(EditBox)\n  phoneInput: EditBox = null;\n\n  @property(EditBox)\n  codeInput: EditBox = null;\n\n  @property(Label)\n  messageLabel: Label = null;\n\n  private verificationId: string = '';\n\n  // 发送验证码\n  async onSendCodeButtonClick() {\n    const phone = this.phoneInput.string;\n    if (!phone) {\n      this.messageLabel.string = '请输入手机号';\n      return;\n    }\n\n    try {\n      const auth = cloudbase.auth();\n      const res = await auth.getVerification({ phone_number: phone });\n      this.verificationId = res.verification_id;\n      this.messageLabel.string = '验证码已发送！';\n    } catch (error) {\n      this.messageLabel.string = `发送失败: ${error.message}`;\n    }\n  }\n\n  // 注册\n  async onRegisterButtonClick() {\n    const phone = this.phoneInput.string;\n    const code = this.codeInput.string;\n\n    if (!this.verificationId || !code) {\n      this.messageLabel.string = '请先发送验证码';\n      return;\n    }\n\n    try {\n      const auth = cloudbase.auth();\n      // 验证验证码\n      const verifyRes = await auth.verify({\n        verification_id: this.verificationId,\n        verification_code: code,\n      });\n      // 注册（如用户已存在则自动登录）\n      await auth.signUp({\n        phone_number: `+86 ${phone}`,\n        verification_code: code,\n        verification_token: verifyRes.verification_token,\n        name: `user_${phone.slice(-4)}`,\n        password: \"admin@123\"\n      });\n      this.messageLabel.string = '注册成功！';\n      console.log('注册成功');\n    } catch (error) {\n      this.messageLabel.string = `注册失败: ${error.message}`;\n      console.error('注册失败：', error);\n    }\n  }\n}\n```",
                "index": 1,
                "title": "短信验证码注册"
              },
              {
                "markdown": "使用 **邮箱验证码注册** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **邮箱验证码**\n\n**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ email });\nconst verificationId = res.verification_id;\n\n// 验证验证码\nconst verifyRes = await auth.verify({\n  verification_id: verificationId,\n  verification_code: code\n});\n\n// 注册\nawait auth.signUp({\n  email,\n  verification_code: code,\n  verification_token: verifyRes.verification_token,\n  name: `user_${email.slice(-4)}`,\n  password: \"admin@123\"\n});\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('EmailRegister')\nexport class EmailRegister extends Component {\n  @property(EditBox)\n  emailInput: EditBox = null;\n\n  @property(EditBox)\n  codeInput: EditBox = null;\n\n  @property(Label)\n  messageLabel: Label = null;\n\n  private verificationId: string = '';\n\n  // 发送验证码\n  async onSendCodeButtonClick() {\n    const email = this.emailInput.string;\n    if (!email) {\n      this.messageLabel.string = '请输入邮箱';\n      return;\n    }\n\n    try {\n      const auth = cloudbase.auth();\n      const res = await auth.getVerification({ email });\n      this.verificationId = res.verification_id;\n      this.messageLabel.string = '验证码已发送！';\n    } catch (error) {\n      this.messageLabel.string = `发送失败: ${error.message}`;\n    }\n  }\n\n  // 注册\n  async onRegisterButtonClick() {\n    const email = this.emailInput.string;\n    const code = this.codeInput.string;\n\n    if (!this.verificationId || !code) {\n      this.messageLabel.string = '请先发送验证码';\n      return;\n    }\n\n    try {\n      const auth = cloudbase.auth();\n      // 验证验证码\n      const verifyRes = await auth.verify({\n        verification_id: this.verificationId,\n        verification_code: code,\n      });\n      // 注册（如用户已存在则自动登录）\n      await auth.signUp({\n        email,\n        verification_code: code,\n        verification_token: verifyRes.verification_token,\n        name: `user_${email.slice(-4)}`,\n        password: \"admin@123\"\n      });\n      this.messageLabel.string = '注册成功！';\n      console.log('注册成功');\n    } catch (error) {\n      this.messageLabel.string = `注册失败: ${error.message}`;\n      console.error('注册失败：', error);\n    }\n  }\n}\n```",
                "index": 2,
                "title": "邮箱验证码注册"
              },
              {
                "markdown": "使用 **账号密码登录** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **用户名密码登录**\n\n**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst auth = cloudbase.auth();\nawait auth.signIn({\n  username, // 可以是用户名、手机号或邮箱\n  password\n});\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('PasswordLogin')\nexport class PasswordLogin extends Component {\n  @property(EditBox)\n  usernameInput: EditBox = null;\n\n  @property(EditBox)\n  passwordInput: EditBox = null;\n\n  @property(Label)\n  messageLabel: Label = null;\n\n  async onLoginButtonClick() {\n    const username = this.usernameInput.string;\n    const password = this.passwordInput.string;\n\n    if (!username || !password) {\n      this.messageLabel.string = '请输入账号和密码';\n      return;\n    }\n\n    try {\n      const auth = cloudbase.auth();\n      await auth.signIn({\n        username, // 可以是用户名、手机号或邮箱\n        password,\n      });\n      this.messageLabel.string = '登录成功！';\n      console.log('登录成功');\n    } catch (error) {\n      this.messageLabel.string = `登录失败: ${error.message}`;\n      console.error('登录失败：', error);\n    }\n  }\n}\n```",
                "index": 3,
                "id": "UserNameLogin",
                "title": "账号密码登录"
              },
              {
                "markdown": "使用 **短信验证码登录** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **短信验证码登录**\n\n**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ phone_number: `+86 ${phone}` });\nconst verificationInfo = res;\n\n// 登录\nawait auth.signInWithSms({\n  verificationInfo: verificationInfo,\n  verificationCode: code,\n  phoneNum: `+86 ${phone}`\n});\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('SmsLogin')\nexport class SmsLogin extends Component {\n  @property(EditBox)\n  phoneInput: EditBox = null;\n\n  @property(EditBox)\n  codeInput: EditBox = null;\n\n  @property(Label)\n  messageLabel: Label = null;\n\n  private verificationInfo: any = null;\n\n  // 发送验证码\n  async onSendCodeButtonClick() {\n    const phone = this.phoneInput.string;\n    if (!phone) {\n      this.messageLabel.string = '请输入手机号';\n      return;\n    }\n\n    try {\n      const auth = cloudbase.auth();\n      const res = await auth.getVerification({ phone_number: `+86 ${phone}` });\n      this.verificationInfo = res;\n      this.messageLabel.string = '验证码已发送！';\n    } catch (error) {\n      this.messageLabel.string = `发送失败: ${error.message}`;\n    }\n  }\n\n  // 登录\n  async onLoginButtonClick() {\n    const phone = this.phoneInput.string;\n    const code = this.codeInput.string;\n\n    if (!this.verificationInfo || !code) {\n      this.messageLabel.string = '请先发送验证码';\n      return;\n    }\n\n    try {\n      const auth = cloudbase.auth();\n      await auth.signInWithSms({\n        verificationInfo: this.verificationInfo,\n        verificationCode: code,\n        phoneNum: `+86 ${phone}`\n      });\n      this.messageLabel.string = '登录成功！';\n      console.log('登录成功');\n    } catch (error) {\n      this.messageLabel.string = `登录失败: ${error.message}`;\n      console.error('登录失败：', error);\n    }\n  }\n}\n```",
                "index": 4,
                "id": "PhoneNumberLogin",
                "title": "短信验证码登录"
              },
              {
                "markdown": "使用 **邮箱验证码登录** 请先前往 [身份认证/登录方式](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}#/identity/login-manage) 开启 **邮箱验证码**\n\n**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst auth = cloudbase.auth();\n\n// 发送验证码\nconst res = await auth.getVerification({ email });\nconst verificationInfo = res;\n\n// 登录\nawait auth.signInWithEmail({\n  verificationInfo: verificationInfo,\n  verificationCode: code,\n  email\n});\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, EditBox, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('EmailLogin')\nexport class EmailLogin extends Component {\n  @property(EditBox)\n  emailInput: EditBox = null;\n\n  @property(EditBox)\n  codeInput: EditBox = null;\n\n  @property(Label)\n  messageLabel: Label = null;\n\n  private verificationInfo: any = null;\n\n  // 发送验证码\n  async onSendCodeButtonClick() {\n    const email = this.emailInput.string;\n    if (!email) {\n      this.messageLabel.string = '请输入邮箱';\n      return;\n    }\n\n    try {\n      const auth = cloudbase.auth();\n      const res = await auth.getVerification({ email });\n      this.verificationInfo = res;\n      this.messageLabel.string = '验证码已发送！';\n    } catch (error) {\n      this.messageLabel.string = `发送失败: ${error.message}`;\n    }\n  }\n\n  // 登录\n  async onLoginButtonClick() {\n    const email = this.emailInput.string;\n    const code = this.codeInput.string;\n\n    if (!this.verificationInfo || !code) {\n      this.messageLabel.string = '请先发送验证码';\n      return;\n    }\n\n    try {\n      const auth = cloudbase.auth();\n      await auth.signInWithEmail({\n        verificationInfo: this.verificationInfo,\n        verificationCode: code,\n        email\n      });\n      this.messageLabel.string = '登录成功！';\n      console.log('登录成功');\n    } catch (error) {\n      this.messageLabel.string = `登录失败: ${error.message}`;\n      console.error('登录失败：', error);\n    }\n  }\n}\n```",
                "index": 5,
                "id": "email",
                "title": "邮箱验证码登录"
              },
              {
                "markdown": "**调用方式：**\n\n```js\nimport cloudbase from \"./services/CloudbaseService\";\n\nconst auth = cloudbase.auth();\nawait auth.signInAnonymously();\n```\n\n**完整示例：**\n\n```js\nimport { _decorator, Component, Node, Label } from 'cc';\nimport cloudbase from './services/CloudbaseService';\n\nconst { ccclass, property } = _decorator;\n\n@ccclass('AnonymousLogin')\nexport class AnonymousLogin extends Component {\n  @property(Label)\n  messageLabel: Label = null;\n\n  async onLoginButtonClick() {\n    try {\n      const auth = cloudbase.auth();\n      await auth.signInAnonymously();\n      this.messageLabel.string = '匿名登录成功！';\n      console.log('匿名登录成功');\n    } catch (error) {\n      this.messageLabel.string = `登录失败: ${error.message}`;\n      console.error('登录失败：', error);\n    }\n  }\n}\n```",
                "index": 6,
                "title": "匿名登录"
              }
            ]
          }
        ]
      }
    ],
    "_id": "e4a8c1446972e0e90054dac130678986",
    "_openid": "anon",
    "createdAt": 1769136361496,
    "updatedAt": 1770372929675
  },
  {
    "category": "框架集成,后端框架,Java",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": 23,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/http-api/basic/overview",
    "content": [
      {
        "markdown": "通过 **HTTP 请求** 在 **Java** 中调用各种云开发能力",
        "index": 1,
        "title": "安装依赖",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```xml\n<dependencies>\n    <!-- HTTP 客户端 -->\n    <dependency>\n        <groupId>com.squareup.okhttp3</groupId>\n        <artifactId>okhttp</artifactId>\n        <version>4.12.0</version>\n    </dependency>\n\n    <!-- JSON 处理 -->\n    <dependency>\n        <groupId>com.google.code.gson</groupId>\n        <artifactId>gson</artifactId>\n        <version>2.10.1</version>\n    </dependency>\n\n    <!-- 环境变量加载 -->\n    <dependency>\n        <groupId>io.github.cdimascio</groupId>\n        <artifactId>dotenv-java</artifactId>\n        <version>3.0.0</version>\n    </dependency>\n</dependencies>\n```",
            "index": 1,
            "title": "Maven"
          },
          {
            "markdown": "```groovy\ndependencies {\n    implementation 'com.squareup.okhttp3:okhttp:4.12.0'\n    implementation 'com.google.code.gson:gson:2.10.1'\n    implementation 'io.github.cdimascio:dotenv-java:3.0.0'\n}\n```",
            "index": 2,
            "title": "Gradle"
          }
        ]
      },
      {
        "markdown": "新增如下代码到您的 **Java** 项目",
        "index": 2,
        "title": "初始化配置",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```java\npackage com.cloudbase;\n\nimport com.google.gson.Gson;\nimport com.google.gson.JsonObject;\nimport io.github.cdimascio.dotenv.Dotenv;\nimport okhttp3.*;\n\nimport java.io.IOException;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class CloudBaseClient {\n    private final String envId;\n    private final String accessToken;\n    private final String baseUrl;\n    private final OkHttpClient client;\n    private final Gson gson;\n    private final Map<String, String> defaultHeaders;\n\n    public CloudBaseClient() {\n        // 加载环境变量\n        Dotenv dotenv = Dotenv.configure().ignoreIfMissing().load();\n        this.envId = dotenv.get(\"CLOUDBASE_ENV_ID\");\n        this.accessToken = dotenv.get(\"CLOUDBASE_ACCESS_TOKEN\");\n        this.baseUrl = \"https://\" + envId + \".api.tcloudbasegateway.com\";\n\n        this.client = new OkHttpClient();\n        this.gson = new Gson();\n\n        // 设置默认请求头\n        this.defaultHeaders = new HashMap<>();\n        this.defaultHeaders.put(\"Content-Type\", \"application/json\");\n        this.defaultHeaders.put(\"Accept\", \"application/json\");\n        this.defaultHeaders.put(\"Authorization\", \"Bearer \" + accessToken);\n    }\n\n    public String getEnvId() {\n        return envId;\n    }\n\n    public String getAccessToken() {\n        return accessToken;\n    }\n\n    public OkHttpClient getClient() {\n        return client;\n    }\n\n    public Gson getGson() {\n        return gson;\n    }\n\n    /**\n     * 统一的HTTP请求方法\n     *\n     * @param method 请求方法 (GET, POST, PUT, PATCH, DELETE)\n     * @param path API路径 (如 /v1/rdb/rest/table_name)\n     * @param body 请求体 (可选)\n     * @param customHeaders 自定义请求头 (可选)\n     * @return 响应数据或null\n     */\n    public JsonObject request(String method, String path, Object body, Map<String, String> customHeaders) {\n        try {\n            String url = baseUrl + path;\n\n            // 构建请求头\n            Headers.Builder headersBuilder = new Headers.Builder();\n            defaultHeaders.forEach(headersBuilder::add);\n            if (customHeaders != null) {\n                customHeaders.forEach(headersBuilder::add);\n            }\n\n            // 构建请求体\n            RequestBody requestBody = null;\n            if (body != null) {\n                String jsonBody = gson.toJson(body);\n                requestBody = RequestBody.create(jsonBody, MediaType.parse(\"application/json\"));\n            } else if (method.equals(\"POST\") || method.equals(\"PUT\") || method.equals(\"PATCH\")) {\n                requestBody = RequestBody.create(\"\", MediaType.parse(\"application/json\"));\n            }\n\n            // 构建请求\n            Request.Builder requestBuilder = new Request.Builder()\n                    .url(url)\n                    .headers(headersBuilder.build())\n                    .method(method, requestBody);\n\n            // 发送请求\n            try (Response response = client.newCall(requestBuilder.build()).execute()) {\n                if (!response.isSuccessful()) {\n                    System.err.println(\"请求失败: \" + response.code() + \" \" + response.message());\n                    return null;\n                }\n\n                // 如果响应为空，返回成功标识\n                String responseBody = response.body().string();\n                if (responseBody == null || responseBody.isEmpty()) {\n                    JsonObject result = new JsonObject();\n                    result.addProperty(\"success\", true);\n                    return result;\n                }\n\n                return gson.fromJson(responseBody, JsonObject.class);\n            }\n        } catch (IOException e) {\n            System.err.println(\"请求失败: \" + e.getMessage());\n            return null;\n        }\n    }\n\n    public JsonObject request(String method, String path, Object body) {\n        return request(method, path, body, null);\n    }\n\n    public JsonObject request(String method, String path) {\n        return request(method, path, null, null);\n    }\n}\n```",
            "index": 1,
            "title": "CloudBaseClient.java"
          },
          {
            "markdown": "> 💡提示：如需管理员权限，请通过 [云开发平台/ApiKey管理页](https://tcb.cloud.tencent.com/dev?envId={%ENV_ID%}&#/env/apikey) 获取 APIKey 替换 CLOUDBASE_ACCESS_TOKEN\n\n```properties\n# 环境ID\nCLOUDBASE_ENV_ID={%ENV_ID%}\n\n# 匿名访问令牌\nCLOUDBASE_ACCESS_TOKEN={%PUBLISHABLE_KEY%}\n```",
            "index": 2,
            "title": ".env"
          }
        ]
      },
      {
        "index": 3,
        "title": "调用云开发能力",
        "type": "codeTab",
        "content": [
          {
            "index": 1,
            "id": "mysql-db",
            "title": "MySQL数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonObject;\n\npublic class Example {\n    public static void main(String[] args) {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 查询 MySQL 数据库数据\n        JsonObject data = cloudbase.request(\"GET\", \"/v1/rdb/rest/{%TABLE_NAME%}?limit=10\");\n\n        if (data != null) {\n            System.out.println(\"查询成功: \" + data);\n        }\n    }\n}\n```",
                "index": 1,
                "title": "查询数据",
                "content": []
              },
              {
                "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonObject;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class Example {\n    public static void main(String[] args) {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 准备数据\n        Map<String, Object> data = new HashMap<>();\n        data.put(\"title\", \"示例标题\");\n\n        // 新增 MySQL 数据库数据\n        JsonObject result = cloudbase.request(\"POST\", \"/v1/rdb/rest/{%TABLE_NAME%}\", data);\n\n        if (result != null) {\n            System.out.println(\"新增成功: \" + result);\n        }\n    }\n}\n```",
                "index": 2,
                "title": "新增数据",
                "content": []
              },
              {
                "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonObject;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class Example {\n    public static void main(String[] args) {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 准备更新数据\n        Map<String, Object> data = new HashMap<>();\n        data.put(\"title\", \"新标题\");\n\n        // 更新 MySQL 数据库数据\n        String dataId = \"<数据id>\";\n        JsonObject result = cloudbase.request(\"PATCH\", \"/v1/rdb/rest/{%TABLE_NAME%}?id=eq.\" + dataId, data);\n\n        if (result != null) {\n            System.out.println(\"更新成功: \" + result);\n        }\n    }\n}\n```",
                "index": 3,
                "title": "更新数据",
                "content": []
              },
              {
                "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonObject;\n\npublic class Example {\n    public static void main(String[] args) {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 删除 MySQL 数据库数据\n        String dataId = \"<数据id>\";\n        JsonObject result = cloudbase.request(\"DELETE\", \"/v1/rdb/rest/{%TABLE_NAME%}?id=eq.\" + dataId);\n\n        if (result != null) {\n            System.out.println(\"删除成功\");\n        }\n    }\n}\n```",
                "index": 4,
                "title": "删除数据",
                "content": []
              }
            ]
          },
          {
            "index": 2,
            "id": "data-model",
            "title": "数据模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonArray;\nimport com.google.gson.JsonObject;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class Example {\n    public static void main(String[] args) {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 准备查询参数\n        Map<String, Object> payload = new HashMap<>();\n        payload.put(\"pageSize\", 10);\n        payload.put(\"pageNumber\", 1);\n        payload.put(\"getCount\", true);\n\n        // 查询数据模型数据\n        JsonObject result = cloudbase.request(\"POST\", \"/v1/model/prod/{%TABLE_NAME%}/list\", payload);\n\n        if (result != null) {\n            JsonArray records = result.getAsJsonObject(\"data\").getAsJsonArray(\"records\");\n            System.out.println(\"查询成功: \" + records);\n        }\n    }\n}\n```",
                "index": 1,
                "title": "查询数据",
                "content": []
              },
              {
                "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonObject;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class Example {\n    public static void main(String[] args) {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 准备数据\n        Map<String, Object> data = new HashMap<>();\n        data.put(\"title\", \"示例标题\");\n\n        Map<String, Object> payload = new HashMap<>();\n        payload.put(\"data\", data);\n\n        // 新增数据模型数据\n        JsonObject result = cloudbase.request(\"POST\", \"/v1/model/prod/{%TABLE_NAME%}/create\", payload);\n\n        if (result != null) {\n            String docId = result.getAsJsonObject(\"data\").get(\"id\").getAsString();\n            System.out.println(\"新增成功! id: \" + docId);\n        }\n    }\n}\n```",
                "index": 2,
                "title": "新增数据",
                "content": []
              },
              {
                "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonObject;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class Example {\n    public static void main(String[] args) {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 准备更新数据\n        Map<String, Object> data = new HashMap<>();\n        data.put(\"title\", \"新标题\");\n\n        // 准备过滤条件\n        Map<String, Object> eqCondition = new HashMap<>();\n        eqCondition.put(\"$eq\", \"<数据id>\");\n\n        Map<String, Object> whereCondition = new HashMap<>();\n        whereCondition.put(\"_id\", eqCondition);\n\n        Map<String, Object> filter = new HashMap<>();\n        filter.put(\"where\", whereCondition);\n\n        Map<String, Object> payload = new HashMap<>();\n        payload.put(\"data\", data);\n        payload.put(\"filter\", filter);\n\n        // 更新数据模型数据\n        JsonObject result = cloudbase.request(\"PUT\", \"/v1/model/prod/{%TABLE_NAME%}/update\", payload);\n\n        if (result != null) {\n            System.out.println(\"更新成功!\");\n        }\n    }\n}\n```",
                "index": 3,
                "title": "更新数据",
                "content": []
              },
              {
                "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonObject;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class Example {\n    public static void main(String[] args) {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 准备过滤条件\n        Map<String, Object> eqCondition = new HashMap<>();\n        eqCondition.put(\"$eq\", \"<数据id>\");\n\n        Map<String, Object> whereCondition = new HashMap<>();\n        whereCondition.put(\"_id\", eqCondition);\n\n        Map<String, Object> filter = new HashMap<>();\n        filter.put(\"where\", whereCondition);\n\n        Map<String, Object> payload = new HashMap<>();\n        payload.put(\"filter\", filter);\n\n        // 删除数据模型数据\n        JsonObject result = cloudbase.request(\"POST\", \"/v1/model/prod/{%TABLE_NAME%}/delete\", payload);\n\n        if (result != null) {\n            System.out.println(\"删除成功!\");\n        }\n    }\n}\n```",
                "index": 4,
                "title": "删除数据",
                "content": []
              }
            ]
          },
          {
            "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonObject;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class Example {\n    public static void main(String[] args) {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 调用云函数\n        Map<String, Object> data = new HashMap<>();\n        // data.put(\"key\", \"value\"); // 可选参数\n\n        JsonObject result = cloudbase.request(\"POST\", \"/v1/functions/{%FUNCTION_NAME%}\", data);\n\n        if (result != null) {\n            System.out.println(\"云函数调用结果: \" + result);\n        }\n    }\n}\n```",
            "index": 3,
            "id": "scf",
            "title": "云函数"
          },
          {
            "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonObject;\n\npublic class Example {\n    public static void main(String[] args) {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 调用云托管服务\n        String serviceName = \"{%SERVICE_NAME%}\";\n        String path = \"\"; // 可选路径\n        String fullPath = \"/v1/cloudrun/\" + serviceName + (path.isEmpty() ? \"\" : \"/\" + path);\n\n        JsonObject result = cloudbase.request(\"GET\", fullPath);\n\n        if (result != null) {\n            System.out.println(\"云托管调用结果: \" + result);\n        }\n    }\n}\n```",
            "index": 4,
            "id": "run",
            "title": "云托管"
          },
          {
            "index": 5,
            "id": "storage",
            "title": "云存储",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonArray;\nimport com.google.gson.JsonObject;\nimport okhttp3.*;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.file.Files;\nimport java.util.*;\n\npublic class Example {\n    public static void main(String[] args) throws IOException {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 上传文件到云存储\n        String filePath = \"./example.jpg\";\n        String objectId = \"uploads/\" + System.currentTimeMillis() + \"-\" + new File(filePath).getName();\n\n        // 1. 获取上传信息\n        List<Map<String, String>> uploadInfoRequest = new ArrayList<>();\n        Map<String, String> objectInfo = new HashMap<>();\n        objectInfo.put(\"objectId\", objectId);\n        uploadInfoRequest.add(objectInfo);\n\n        JsonObject uploadInfoResponse = cloudbase.request(\"POST\", \"/v1/storages/get-objects-upload-info\", uploadInfoRequest);\n\n        if (uploadInfoResponse == null) {\n            System.err.println(\"获取上传信息失败\");\n            return;\n        }\n\n        JsonObject uploadInfo = uploadInfoResponse.getAsJsonArray().get(0).getAsJsonObject();\n        String uploadUrl = uploadInfo.get(\"uploadUrl\").getAsString();\n        String authorization = uploadInfo.get(\"authorization\").getAsString();\n        String token = uploadInfo.get(\"token\").getAsString();\n        String cloudObjectMeta = uploadInfo.get(\"cloudObjectMeta\").getAsString();\n\n        // 2. 上传文件\n        File file = new File(filePath);\n        byte[] fileData = Files.readAllBytes(file.toPath());\n\n        OkHttpClient client = new OkHttpClient();\n        RequestBody requestBody = RequestBody.create(fileData, MediaType.parse(\"application/octet-stream\"));\n\n        Request uploadRequest = new Request.Builder()\n                .url(uploadUrl)\n                .put(requestBody)\n                .addHeader(\"Authorization\", authorization)\n                .addHeader(\"X-Cos-Security-Token\", token)\n                .addHeader(\"X-Cos-Meta-Fileid\", cloudObjectMeta)\n                .build();\n\n        try (Response response = client.newCall(uploadRequest).execute()) {\n            if (response.isSuccessful()) {\n                String cloudObjectId = uploadInfo.get(\"cloudObjectId\").getAsString();\n                String downloadUrl = uploadInfo.get(\"downloadUrl\").getAsString();\n\n                System.out.println(\"文件上传成功:\");\n                System.out.println(\"- 对象ID: \" + objectId);\n                System.out.println(\"- 云对象ID: \" + cloudObjectId);\n                System.out.println(\"- 下载URL: \" + downloadUrl);\n            } else {\n                System.err.println(\"文件上传失败: \" + response.code());\n            }\n        }\n    }\n}\n```",
                "index": 1,
                "title": "上传文件",
                "content": []
              },
              {
                "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonArray;\nimport com.google.gson.JsonObject;\nimport java.util.*;\n\npublic class Example {\n    public static void main(String[] args) {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 获取云存储文件的临时访问链接\n        String cloudObjectId = \"cloud://xxx.png\";\n\n        List<Map<String, String>> request = new ArrayList<>();\n        Map<String, String> objectInfo = new HashMap<>();\n        objectInfo.put(\"cloudObjectId\", cloudObjectId);\n        request.add(objectInfo);\n\n        JsonObject result = cloudbase.request(\"POST\", \"/v1/storages/get-objects-download-info\", request);\n\n        if (result != null) {\n            String downloadUrl = result.getAsJsonArray().get(0).getAsJsonObject().get(\"downloadUrl\").getAsString();\n            System.out.println(\"文件链接: \" + downloadUrl);\n        }\n    }\n}\n```",
                "index": 2,
                "title": "获取文件链接",
                "content": []
              },
              {
                "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonObject;\nimport okhttp3.OkHttpClient;\nimport okhttp3.Request;\nimport okhttp3.Response;\n\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.util.*;\n\npublic class Example {\n    public static void main(String[] args) throws IOException {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 下载云存储文件到本地\n        String cloudObjectId = \"cloud://xxx.png\";\n        String savePath = \"./downloaded.png\";\n\n        // 1. 获取下载链接\n        List<Map<String, String>> request = new ArrayList<>();\n        Map<String, String> objectInfo = new HashMap<>();\n        objectInfo.put(\"cloudObjectId\", cloudObjectId);\n        request.add(objectInfo);\n\n        JsonObject result = cloudbase.request(\"POST\", \"/v1/storages/get-objects-download-info\", request);\n\n        if (result == null) {\n            System.err.println(\"获取下载链接失败\");\n            return;\n        }\n\n        String downloadUrl = result.getAsJsonArray().get(0).getAsJsonObject().get(\"downloadUrl\").getAsString();\n\n        // 2. 下载文件\n        OkHttpClient client = new OkHttpClient();\n        Request downloadRequest = new Request.Builder().url(downloadUrl).build();\n\n        try (Response response = client.newCall(downloadRequest).execute()) {\n            if (response.isSuccessful() && response.body() != null) {\n                try (FileOutputStream fos = new FileOutputStream(savePath)) {\n                    fos.write(response.body().bytes());\n                }\n                System.out.println(\"下载成功! 文件已保存到: \" + savePath);\n            } else {\n                System.err.println(\"下载失败: \" + response.code());\n            }\n        }\n    }\n}\n```",
                "index": 3,
                "title": "下载文件",
                "content": []
              },
              {
                "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonObject;\nimport java.util.*;\n\npublic class Example {\n    public static void main(String[] args) {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 删除云存储文件\n        String cloudObjectId = \"cloud://xxx.png\";\n\n        List<Map<String, String>> request = new ArrayList<>();\n        Map<String, String> objectInfo = new HashMap<>();\n        objectInfo.put(\"cloudObjectId\", cloudObjectId);\n        request.add(objectInfo);\n\n        JsonObject result = cloudbase.request(\"POST\", \"/v1/storages/delete-objects\", request);\n\n        if (result != null) {\n            System.out.println(\"删除成功!\");\n        }\n    }\n}\n```",
                "index": 4,
                "title": "删除文件",
                "content": []
              }
            ]
          },
          {
            "index": 6,
            "id": "ai-model",
            "title": "大模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonObject;\nimport okhttp3.*;\n\nimport java.io.BufferedReader;\nimport java.io.IOException;\nimport java.io.InputStreamReader;\nimport java.nio.charset.StandardCharsets;\nimport java.util.*;\n\npublic class Example {\n    public static void main(String[] args) throws IOException {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 流式文本生成\n        String model = \"{%AI_MODEL_NAME%}\";\n        String subModel = \"{%AI_SUB_MODEL_NAME%}\";\n\n        // 准备消息\n        List<Map<String, String>> messages = new ArrayList<>();\n        Map<String, String> systemMsg = new HashMap<>();\n        systemMsg.put(\"role\", \"system\");\n        systemMsg.put(\"content\", \"请严格按照七言绝句或七言律诗的格律要求创作，平仄需符合规则，押韵要和谐自然，韵脚字需在同一韵部。\");\n        messages.add(systemMsg);\n\n        Map<String, String> userMsg = new HashMap<>();\n        userMsg.put(\"role\", \"user\");\n        userMsg.put(\"content\", \"春天\");\n        messages.add(userMsg);\n\n        // 准备请求体\n        Map<String, Object> payload = new HashMap<>();\n        payload.put(\"model\", subModel);\n        payload.put(\"messages\", messages);\n        payload.put(\"stream\", true);\n\n        // 使用 CloudBaseClient 的配置构建流式请求\n        String url = \"https://\" + cloudbase.getEnvId() + \".api.tcloudbasegateway.com/v1/ai/\" + model + \"/chat/completions\";\n        String jsonPayload = cloudbase.getGson().toJson(payload);\n\n        RequestBody requestBody = RequestBody.create(jsonPayload, MediaType.parse(\"application/json\"));\n\n        Request request = new Request.Builder()\n                .url(url)\n                .post(requestBody)\n                .addHeader(\"Content-Type\", \"application/json\")\n                .addHeader(\"Accept\", \"text/event-stream\")\n                .addHeader(\"Authorization\", \"Bearer \" + cloudbase.getAccessToken())\n                .build();\n\n        System.out.println(\"AI 流式响应:\");\n        StringBuilder fullContent = new StringBuilder();\n\n        try (Response response = cloudbase.getClient().newCall(request).execute()) {\n            if (response.isSuccessful() && response.body() != null) {\n                BufferedReader reader = new BufferedReader(\n                    new InputStreamReader(response.body().byteStream(), StandardCharsets.UTF_8)\n                );\n                String line;\n\n                while ((line = reader.readLine()) != null) {\n                    if (line.startsWith(\"data: \")) {\n                        String dataStr = line.substring(6);\n                        if (!dataStr.trim().equals(\"[DONE]\")) {\n                            try {\n                                JsonObject chunkData = cloudbase.getGson().fromJson(dataStr, JsonObject.class);\n                                if (chunkData.has(\"choices\") && chunkData.getAsJsonArray(\"choices\").size() > 0) {\n                                    JsonObject choice = chunkData.getAsJsonArray(\"choices\").get(0).getAsJsonObject();\n                                    if (choice.has(\"delta\") && choice.getAsJsonObject(\"delta\").has(\"content\")) {\n                                        String content = choice.getAsJsonObject(\"delta\").get(\"content\").getAsString();\n                                        System.out.print(content);\n                                        fullContent.append(content);\n                                    }\n                                }\n                            } catch (Exception e) {\n                                // 忽略JSON解析错误\n                            }\n                        }\n                    }\n                }\n                System.out.println(); // 换行\n            }\n        }\n    }\n}\n```",
                "index": 1,
                "id": "text-aiModel",
                "title": "生文模型",
                "content": []
              },
              {
                "markdown": "生图模型通过调用云函数来实现，在生图模型页面点击「一键创建云函数」，函数调用示例如下：\n\n```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonObject;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class Example {\n    public static void main(String[] args) {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        try {\n            // 准备调用参数\n            Map<String, Object> data = new HashMap<>();\n            data.put(\"prompt\", \"一只可爱的猫咪在阳光下玩耍\");\n\n            // 调用云函数生成图片\n            JsonObject result = cloudbase.request(\"POST\", \"/v1/functions/<YOUR_FUNCTION_NAME>\", data);\n\n            if (result != null) {\n                boolean success = result.has(\"success\") && result.get(\"success\").getAsBoolean();\n                \n                if (success) {\n                    String imageUrl = result.get(\"imageUrl\").getAsString();\n                    String revisedPrompt = result.has(\"revised_prompt\") \n                        ? result.get(\"revised_prompt\").getAsString() \n                        : \"\";\n                    \n                    System.out.println(\"生成成功!\");\n                    System.out.println(\"图片URL: \" + imageUrl);\n                    System.out.println(\"优化后的提示词: \" + revisedPrompt);\n                    System.out.println(\"注意: 图片URL有效期为24小时\");\n                } else {\n                    String code = result.has(\"code\") ? result.get(\"code\").getAsString() : \"\";\n                    String message = result.has(\"message\") ? result.get(\"message\").getAsString() : \"\";\n                    System.err.println(\"生成失败: \" + code + \" - \" + message);\n                }\n            } else {\n                System.err.println(\"请求失败\");\n            }\n        } catch (Exception e) {\n            System.err.println(\"生成图片时出错: \" + e.getMessage());\n        }\n    }\n}\n```",
                "index": 2,
                "id": "image-aiModel",
                "title": "生图模型",
                "content": []
              }
            ]
          },
          {
            "markdown": "",
            "index": 7,
            "id": "agent",
            "title": "Agent",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```java\n/**\n * Java 调用 Agent 示例（AG-UI 协议）\n * 协议文档：https://docs.cloudbase.net/ai/agent-development/protocol\n */\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonObject;\nimport okhttp3.*;\n\nimport java.io.BufferedReader;\nimport java.io.IOException;\nimport java.io.InputStreamReader;\nimport java.nio.charset.StandardCharsets;\nimport java.util.*;\n\npublic class Example {\n    public static void main(String[] args) throws IOException {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 流式调用Agent（AG-UI 协议）\n        String botId = \"{%AGENT_ID%}\";\n\n        // 准备消息列表（AG-UI 协议格式）\n        List<Map<String, Object>> messages = new ArrayList<>();\n        Map<String, Object> userMessage = new HashMap<>();\n        userMessage.put(\"id\", \"msg-\" + UUID.randomUUID().toString());\n        userMessage.put(\"role\", \"user\");\n        userMessage.put(\"content\", \"你是谁\");\n        messages.add(userMessage);\n\n        // 准备请求体（AG-UI 协议）\n        Map<String, Object> payload = new HashMap<>();\n        payload.put(\"messages\", messages);                    // 必填：消息列表\n        payload.put(\"threadId\", \"thread-\" + UUID.randomUUID().toString()); // 可选：会话ID，用于多轮对话\n        payload.put(\"runId\", \"run-\" + UUID.randomUUID().toString());       // 可选：本次运行ID\n        payload.put(\"tools\", new ArrayList<>());              // 可选：前端工具定义\n        payload.put(\"context\", new ArrayList<>());            // 可选：上下文信息\n        payload.put(\"forwardedProps\", new HashMap<>());       // 可选：透传参数\n\n        // 使用 CloudBaseClient 的配置构建流式请求\n        String url = \"https://\" + cloudbase.getEnvId() + \".api.tcloudbasegateway.com/v1/aibot/bots/\" + botId + \"/send-message\";\n        String jsonPayload = cloudbase.getGson().toJson(payload);\n\n        RequestBody requestBody = RequestBody.create(jsonPayload, MediaType.parse(\"application/json\"));\n\n        Request request = new Request.Builder()\n                .url(url)\n                .post(requestBody)\n                .addHeader(\"Content-Type\", \"application/json\")\n                .addHeader(\"Accept\", \"text/event-stream\")\n                .addHeader(\"Authorization\", \"Bearer \" + cloudbase.getAccessToken())\n                .build();\n\n        System.out.println(\"AI 流式响应:\");\n        StringBuilder fullContent = new StringBuilder();\n\n        try (Response response = cloudbase.getClient().newCall(request).execute()) {\n            if (response.isSuccessful() && response.body() != null) {\n                BufferedReader reader = new BufferedReader(\n                    new InputStreamReader(response.body().byteStream(), StandardCharsets.UTF_8)\n                );\n                String line;\n\n                while ((line = reader.readLine()) != null) {\n                    if (line.startsWith(\"data: \")) {\n                        String dataStr = line.substring(6).trim();\n                        if (!dataStr.isEmpty() && !dataStr.equals(\"[DONE]\")) {\n                            try {\n                                JsonObject chunkData = cloudbase.getGson().fromJson(dataStr, JsonObject.class);\n\n                                // 支持多种响应格式\n                                String content = null;\n                                if (chunkData.has(\"content\")) {\n                                    content = chunkData.get(\"content\").getAsString();\n                                } else if (chunkData.has(\"choices\") && chunkData.getAsJsonArray(\"choices\").size() > 0) {\n                                    JsonObject choice = chunkData.getAsJsonArray(\"choices\").get(0).getAsJsonObject();\n                                    if (choice.has(\"delta\") && choice.getAsJsonObject(\"delta\").has(\"content\")) {\n                                        content = choice.getAsJsonObject(\"delta\").get(\"content\").getAsString();\n                                    } else if (choice.has(\"message\") && choice.getAsJsonObject(\"message\").has(\"content\")) {\n                                        content = choice.getAsJsonObject(\"message\").get(\"content\").getAsString();\n                                    }\n                                }\n\n                                if (content != null && !content.isEmpty()) {\n                                    System.out.print(content);\n                                    fullContent.append(content);\n                                }\n                            } catch (Exception e) {\n                                // 忽略JSON解析错误\n                            }\n                        }\n                    }\n                }\n                System.out.println(); // 换行\n            }\n        }\n    }\n}\n\n```",
                "index": 0,
                "id": "scf",
                "title": "函数型"
              },
              {
                "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonObject;\nimport okhttp3.*;\n\nimport java.io.BufferedReader;\nimport java.io.IOException;\nimport java.io.InputStreamReader;\nimport java.nio.charset.StandardCharsets;\nimport java.util.*;\n\npublic class Example {\n    public static void main(String[] args) throws IOException {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 流式调用Agent\n        String botId = \"{%AGENT_ID%}\";\n        String msg = \"你是谁\";\n        List<Map<String, String>> history = new ArrayList<>();\n\n        // 准备请求体\n        Map<String, Object> payload = new HashMap<>();\n        payload.put(\"history\", history);\n        payload.put(\"msg\", msg);\n\n        // 使用 CloudBaseClient 的配置构建流式请求\n        String url = \"https://\" + cloudbase.getEnvId() + \".api.tcloudbasegateway.com/v1/aibot/bots/\" + botId + \"/send-message\";\n        String jsonPayload = cloudbase.getGson().toJson(payload);\n\n        RequestBody requestBody = RequestBody.create(jsonPayload, MediaType.parse(\"application/json\"));\n\n        Request request = new Request.Builder()\n                .url(url)\n                .post(requestBody)\n                .addHeader(\"Content-Type\", \"application/json\")\n                .addHeader(\"Accept\", \"text/event-stream\")\n                .addHeader(\"Authorization\", \"Bearer \" + cloudbase.getAccessToken())\n                .build();\n\n        System.out.println(\"AI 流式响应:\");\n        StringBuilder fullContent = new StringBuilder();\n\n        try (Response response = cloudbase.getClient().newCall(request).execute()) {\n            if (response.isSuccessful() && response.body() != null) {\n                BufferedReader reader = new BufferedReader(\n                    new InputStreamReader(response.body().byteStream(), StandardCharsets.UTF_8)\n                );\n                String line;\n\n                while ((line = reader.readLine()) != null) {\n                    if (line.startsWith(\"data: \")) {\n                        String dataStr = line.substring(6).trim();\n                        if (!dataStr.isEmpty() && !dataStr.equals(\"[DONE]\")) {\n                            try {\n                                JsonObject chunkData = cloudbase.getGson().fromJson(dataStr, JsonObject.class);\n\n                                // 支持多种响应格式\n                                String content = null;\n                                if (chunkData.has(\"content\")) {\n                                    content = chunkData.get(\"content\").getAsString();\n                                } else if (chunkData.has(\"choices\") && chunkData.getAsJsonArray(\"choices\").size() > 0) {\n                                    JsonObject choice = chunkData.getAsJsonArray(\"choices\").get(0).getAsJsonObject();\n                                    if (choice.has(\"delta\") && choice.getAsJsonObject(\"delta\").has(\"content\")) {\n                                        content = choice.getAsJsonObject(\"delta\").get(\"content\").getAsString();\n                                    } else if (choice.has(\"message\") && choice.getAsJsonObject(\"message\").has(\"content\")) {\n                                        content = choice.getAsJsonObject(\"message\").get(\"content\").getAsString();\n                                    }\n                                }\n\n                                if (content != null && !content.isEmpty()) {\n                                    System.out.print(content);\n                                    fullContent.append(content);\n                                }\n                            } catch (Exception e) {\n                                // 忽略JSON解析错误\n                            }\n                        }\n                    }\n                }\n                System.out.println(); // 换行\n            }\n        }\n    }\n}\n```",
                "index": 1,
                "id": "baas",
                "title": "普通型"
              }
            ]
          },
          {
            "markdown": "```java\nimport com.cloudbase.CloudBaseClient;\nimport com.google.gson.JsonObject;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class Example {\n    public static void main(String[] args) {\n        CloudBaseClient cloudbase = new CloudBaseClient();\n\n        // 账号密码登录\n        Map<String, String> credentials = new HashMap<>();\n        credentials.put(\"username\", \"your_username\");\n        credentials.put(\"password\", \"your_password\");\n\n        JsonObject result = cloudbase.request(\"POST\", \"/auth/v1/signin\", credentials);\n\n        if (result != null) {\n            String accessToken = result.get(\"access_token\").getAsString();\n            String refreshToken = result.get(\"refresh_token\").getAsString();\n            String userId = result.get(\"sub\").getAsString();\n\n            System.out.println(\"登录成功! 用户ID: \" + userId);\n            System.out.println(\"访问令牌: \" + accessToken.substring(0, 20) + \"...\");\n        }\n    }\n}\n```",
            "index": 8,
            "id": "identity",
            "title": "身份认证"
          }
        ]
      }
    ],
    "_id": "ee4af104697c22ec0037be6b53c8561f",
    "_openid": "anon",
    "createdAt": 1769743084576,
    "updatedAt": 1770021221334
  },
  {
    "category": "框架集成,后端框架,Node.js",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": 20,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/api-reference/server/node-sdk/initialization",
    "content": [
      {
        "markdown": "`@cloudbase/node-sdk` 可以让您在 Node.js 服务端使用 JavaScript/TypeScript 访问 CloudBase 服务和资源。",
        "index": 1,
        "title": "安装 SDK",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```bash\nnpm i @cloudbase/node-sdk dotenv\n```",
            "index": 1,
            "title": "npm",
            "content": []
          },
          {
            "markdown": "```bash\nyarn add @cloudbase/node-sdk dotenv\n```",
            "index": 2,
            "title": "yarn",
            "content": []
          },
          {
            "markdown": "```bash\npnpm add @cloudbase/node-sdk dotenv\n```",
            "index": 3,
            "title": "pnpm",
            "content": []
          }
        ]
      },
      {
        "markdown": "新增如下代码到您的 Node.js 项目",
        "index": 2,
        "title": "初始化 SDK",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```js\nconst cloudbaseSDK = require(\"@cloudbase/node-sdk\");\nrequire(\"dotenv\").config();\n\nconst cloudbase = cloudbaseSDK.init({\n  env: process.env.CLOUDBASE_ENV_ID,\n  secretId: process.env.CLOUDBASE_SECRETID,\n  secretKey: process.env.CLOUDBASE_SECRETKEY\n});\n\nmodule.exports = { cloudbase };\n```",
            "index": 1,
            "title": "./utils/cloudbase.js",
            "content": []
          },
          {
            "markdown": "<div class=\"tea-alert tea-alert--brand\" style=\"padding:9px calc(var(--tea-space-100)*4)\">\n<div class=\"tea-alert__info\">\n请前往 <a target=\"_blank\"  class=\"tea-link-external\"  style =\"text-decoration:underline\" href=\"https://console.cloud.tencent.com/cam/capi\">腾讯云控制台/API密钥管理</a> 生成API密钥\n</div>\n</div>\n\n```properties\n# 环境ID\nCLOUDBASE_ENV_ID={%ENV_ID%}\n\n# 腾讯云API密钥ID\nCLOUDBASE_SECRET_ID={%SECRET_ID%}\n\n# 腾讯云API密钥Key\nCLOUDBASE_SECRET_KEY={%SECRET_KEY%}\n```",
            "index": 2,
            "title": ".env",
            "content": []
          }
        ]
      },
      {
        "index": 3,
        "title": "调用云开发能力",
        "type": "codeTab",
        "content": [
          {
            "index": 1,
            "id": "mysql-db",
            "title": "MySQL数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function getData() {\n  // 查询 {%TABLE_NAME%} 表前10条数据\n  const { data, error } = await cloudbase\n    .rdb()\n    .from(\"{%TABLE_NAME%}\")\n    .select(\"*\")\n    .limit(10);\n\n  if (!error) {\n    console.log(\"查询成功:\", data);\n    return data;\n  } else {\n    console.error(\"查询失败:\", error);\n  }\n}\n\ngetData();\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function addData() {\n  // 新增 {%TABLE_NAME%} 表数据\n  const { data, error } = await cloudbase\n    .rdb()\n    .from(\"{%TABLE_NAME%}\")\n    .insert({ title: \"示例标题\" });\n\n  if (!error) {\n    console.log(\"新增成功:\", data);\n  } else {\n    console.error(\"新增失败:\", error);\n  }\n}\n\naddData();\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function updateData() {\n  // 更新 {%TABLE_NAME%} 表中 id 为指定值的数据\n  const { data, error } = await cloudbase\n    .rdb()\n    .from(\"{%TABLE_NAME%}\")\n    .update({ title: \"新标题\" })\n    .eq(\"id\", \"<数据id>\");\n\n  if (!error) {\n    console.log(\"更新成功:\", data);\n  } else {\n    console.error(\"更新失败:\", error);\n  }\n}\n\nupdateData();\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function upsertData() {\n  // 如果 {%TABLE_NAME%} 表中存在 id 为 1 的记录则更新 title 为\"示例标题\"，不存在则插入新记录\n  const { data, error } = await cloudbase\n    .rdb()\n    .from(\"{%TABLE_NAME%}\")\n    .upsert({ id: 1, title: \"示例标题\" });\n\n  if (!error) {\n    console.log(\"操作成功:\", data);\n  } else {\n    console.error(\"操作失败:\", error);\n  }\n}\n\nupsertData();\n```",
                "index": 4,
                "title": "更新或创建数据"
              },
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function deleteData() {\n  // 删除 {%TABLE_NAME%} 表中 id 为指定值的数据\n  const { data, error } = await cloudbase\n    .rdb()\n    .from(\"{%TABLE_NAME%}\")\n    .delete()\n    .eq(\"id\", \"<数据id>\");\n\n  if (!error) {\n    console.log(\"删除成功:\", data);\n  } else {\n    console.error(\"删除失败:\", error);\n  }\n}\n\ndeleteData();\n```",
                "index": 5,
                "title": "删除数据"
              }
            ]
          },
          {
            "index": 2,
            "id": "doc-db",
            "title": "文档型数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function getData() {\n  // 查询 {%TABLE_NAME%} 表前10条数据\n  const db = cloudbase.database();\n  const res = await db.collection(\"{%TABLE_NAME%}\").limit(10).get();\n\n  console.log(\"查询成功:\", res.data);\n  return res.data;\n}\n\ngetData();\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function addData() {\n  try {\n    // 新增 {%TABLE_NAME%} 表数据\n    const db = cloudbase.database();\n    const res = await db\n      .collection(\"{%TABLE_NAME%}\")\n      .add({ title: \"示例标题\" });\n\n    console.log(`新增成功! id: ${res.id}`);\n  } catch (error) {\n    console.error(\"新增失败:\", error);\n  }\n}\n\naddData();\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function updateData() {\n  try {\n    // 更新 {%TABLE_NAME%} 表中 id 为指定值的数据\n    const db = cloudbase.database();\n    await db\n      .collection(\"{%TABLE_NAME%}\")\n      .doc(\"<数据id>\")\n      .update({ title: \"新标题\" });\n\n    console.log(\"更新成功!\");\n  } catch (error) {\n    console.error(\"更新失败:\", error);\n  }\n}\n\nupdateData();\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function deleteData() {\n  try {\n    // 删除 {%TABLE_NAME%} 表中 id 为指定值的数据\n    const db = cloudbase.database();\n    await db.collection(\"{%TABLE_NAME%}\").doc(\"<数据id>\").remove();\n\n    console.log(\"删除成功!\");\n  } catch (error) {\n    console.error(\"删除失败:\", error);\n  }\n}\n\ndeleteData();\n```",
                "index": 4,
                "title": "删除数据"
              }
            ]
          },
          {
            "index": 3,
            "id": "data-model",
            "title": "数据模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function getData() {\n  // 查询 {%TABLE_NAME%} 数据模型前10条数据\n  const res = await cloudbase.models[\"{%TABLE_NAME%}\"].list({\n    pageNumber: 1,\n    pagesize: 10\n  });\n\n  console.log(\"查询成功:\", res.data?.records);\n  return res.data?.records;\n}\n\ngetData();\n```",
                "index": 1,
                "title": "查询数据"
              },
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function addData() {\n  try {\n    // 新增 {%TABLE_NAME%} 数据模型数据\n    const res = await cloudbase.models[\"{%TABLE_NAME%}\"].create({\n      data: { title: \"示例标题\" }\n    });\n\n    console.log(`新增成功! id: ${res.data.id}`);\n  } catch (error) {\n    console.error(\"新增失败:\", error);\n  }\n}\n\naddData();\n```",
                "index": 2,
                "title": "新增数据"
              },
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function updateData() {\n  try {\n    // 更新 {%TABLE_NAME%} 数据模型中 _id 为指定值的数据\n    await cloudbase.models[\"{%TABLE_NAME%}\"].update({\n      data: { title: \"新标题\" },\n      filter: { where: { _id: { $eq: \"<数据id>\" } } }\n    });\n\n    console.log(\"更新成功!\");\n  } catch (error) {\n    console.error(\"更新失败:\", error);\n  }\n}\n\nupdateData();\n```",
                "index": 3,
                "title": "更新数据"
              },
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function deleteData() {\n  try {\n    // 删除 {%TABLE_NAME%} 数据模型中 _id 为指定值的数据\n    await cloudbase.models[\"{%TABLE_NAME%}\"].delete({\n      filter: { where: { _id: { $eq: \"<数据id>\" } } }\n    });\n\n    console.log(\"删除成功!\");\n  } catch (error) {\n    console.error(\"删除失败:\", error);\n  }\n}\n\ndeleteData();\n```",
                "index": 4,
                "title": "删除数据"
              }
            ]
          },
          {
            "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function callFunction() {\n  // 调用 {%FUNCTION_NAME%} 云函数\n  const res = await cloudbase.callFunction({\n    name: \"{%FUNCTION_NAME%}\",\n    data: {}\n  });\n\n  console.log(\"云函数返回:\", res.result);\n  return res.result;\n}\n\ncallFunction();\n```",
            "index": 4,
            "id": "scf",
            "title": "云函数",
            "content": []
          },
          {
            "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function callRun() {\n  // 调用 {%SERVICE_NAME%} 云托管服务\n  const res = await cloudbase.callContainer({\n    name: \"{%SERVICE_NAME%}\"\n    method: 'POST',\n    path: '/',\n    header:{\n      'Content-Type': 'application/json; charset=utf-8'\n    },\n    data: {},\n  });\n}\n\ncallRun();\n```",
            "index": 5,
            "id": "run",
            "title": "云托管",
            "content": []
          },
          {
            "index": 6,
            "id": "storage",
            "title": "云存储",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\nconst fs = require(\"fs\");\n\nasync function uploadFile() {\n  const filePath = \"./example.png\"; // 本地文件路径\n  const cloudPath = `images/${Date.now()}-example.png`; // 上传至云端的路径\n\n  const res = await cloudbase.uploadFile({\n    cloudPath: cloudPath,\n    fileContent: fs.createReadStream(filePath)\n  });\n\n  console.log(\"上传成功:\", res.fileID);\n  return res.fileID;\n}\n\nuploadFile();\n```",
                "index": 1,
                "title": "上传文件"
              },
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function getFileUrl() {\n  const res = await cloudbase.getTempFileURL({\n    fileList: [\"cloud://xxx.png\"] // 文件 fileID 列表\n  });\n\n  console.log(\"文件链接:\", res.fileList[0].tempFileURL);\n  return res.fileList[0].tempFileURL;\n}\n\ngetFileUrl();\n```",
                "index": 2,
                "title": "获取文件链接"
              },
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\nconst fs = require(\"fs\");\n\nasync function downloadFile() {\n  const res = await cloudbase.downloadFile({\n    fileID: \"cloud://xxx.png\" // 文件 fileID\n  });\n\n  // 将文件保存到本地\n  fs.writeFileSync(\"./downloaded-file.png\", res.fileContent);\n  console.log(\"下载成功!\");\n}\n\ndownloadFile();\n```",
                "index": 3,
                "title": "下载文件"
              },
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function deleteFile() {\n  const res = await cloudbase.deleteFile({\n    fileList: [\"cloud://xxx.png\"] // 文件 fileID 列表\n  });\n\n  if (res.fileList[0].code === \"SUCCESS\") {\n    console.log(\"删除成功!\");\n  } else {\n    console.error(\"删除失败:\", res.fileList);\n  }\n}\n\ndeleteFile();\n```",
                "index": 4,
                "title": "删除文件"
              }
            ]
          },
          {
            "index": 7,
            "id": "ai-model",
            "title": "大模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function callAIModel(input) {\n  const ai = cloudbase.ai();\n  // <YOUR_AI_MODEL_NAME> 请填写模型提供商标识，计费模型使用 cloudbase\n  const model = ai.createModel(\"{%AI_MODEL_NAME%}\");\n\n  try {\n    const res = await model.streamText({\n      model: \"{%AI_SUB_MODEL_NAME%}\",\n      messages: [\n        {\n          role: \"system\",\n          content:\n            \"请严格按照七言绝句或七言律诗的格律要求创作，平仄需符合规则，押韵要和谐自然，韵脚字需在同一韵部。\"\n        },\n        { role: \"user\", content: input }\n      ]\n    });\n\n    let response = \"\";\n    for await (let str of res.textStream) {\n      process.stdout.write(str);\n      response += str;\n    }\n    return response;\n  } catch (err) {\n    console.error(\"error:\", err);\n    return null;\n  }\n}\n\n// 调用示例\ncallAIModel(\"春天\");\n```",
                "index": 1,
                "title": "SDK调用"
              },
              {
                "markdown": "<div class=\"tea-alert tea-alert--brand\" style=\"padding:9px calc(var(--tea-space-100)*4)\">\n<div class=\"tea-alert__info\">\n前往 <a target=\"_blank\" class=\"tea-link-external\" style=\"text-decoration:underline\" href=\"https://tcb.cloud.tencent.com/dev#/env/apikey\">环境配置</a> 获取服务端 API Key。\n</div>\n</div>\n\n**安装依赖**\n\n```bash\nnpm i @langchain/openai\n```\n\n**使用示例：**\n\n```js\nconst { ChatOpenAI } = require(\"@langchain/openai\");\n\nconst model = new ChatOpenAI({\n  modelName: \"{%AI_SUB_MODEL_NAME%}\",\n  apiKey: \"<CLOUDBASE_API_KEY>\",\n  configuration: {\n    baseURL: \"https://{%ENV_ID%}.api.tcloudbasegateway.com/v1/ai/{%AI_MODEL_NAME%}\"\n  }\n});\n\nasync function main() {\n  const response = await model.invoke(\"你好\");\n  console.log(\"AI回答:\", response.content);\n}\n\nmain();\n```",
                "index": 2,
                "title": "LangChain"
              },
              {
                "markdown": "<div class=\"tea-alert tea-alert--brand\" style=\"padding:9px calc(var(--tea-space-100)*4)\">\n<div class=\"tea-alert__info\">\n前往 <a target=\"_blank\" class=\"tea-link-external\" style=\"text-decoration:underline\" href=\"https://tcb.cloud.tencent.com/dev#/env/apikey\">环境配置</a> 获取服务端 API Key。\n</div>\n</div>\n\n**安装依赖**\n\n```bash\nnpm i openai\n```\n\n**使用示例：**\n\n```js\nconst OpenAI = require(\"openai\");\n\nconst client = new OpenAI({\n  apiKey: \"<CLOUDBASE_API_KEY>\",\n  baseURL: \"https://{%ENV_ID%}.api.tcloudbasegateway.com/v1/ai/{%AI_MODEL_NAME%}\"\n});\n\nasync function main() {\n  const completion = await client.chat.completions.create({\n    model: \"{%AI_SUB_MODEL_NAME%}\",\n    messages: [\n      { role: \"user\", content: \"hi\" }\n    ],\n    temperature: 0.3,\n    stream: true\n  });\n\n  for await (const chunk of completion) {\n    console.log(chunk);\n  }\n}\n\nmain();\n```",
                "index": 3,
                "title": "OpenAI SDK"
              },
              {
                "markdown": "生图模型通过调用云函数来实现，在生图模型页面点击「一键创建云函数」，函数调用示例如下：\n\n```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function generateImage() {\n  // 调用生图云函数\n  const res = await cloudbase.callFunction({\n    name: \"<YOUR_FUNCTION_NAME>\",\n    data: {\n      prompt: \"一只可爱的猫咪在阳光下玩耍\"\n    }\n  });\n\n  const result = res.result;\n\n  if (result.success) {\n    // 生成成功\n    console.log(\"生成成功!\");\n    console.log(\"图片URL:\", result.imageUrl);\n    console.log(\"优化后的提示词:\", result.revised_prompt);\n\n    // 使用图片\n    // 注意：图片URL有效期为24小时，请及时保存或转存\n  } else {\n    // 生成失败\n    console.error(\"生成失败:\", result.code, result.message);\n  }\n}\n\ngenerateImage();\n```",
                "index": 4,
                "id": "image-aiModel",
                "title": "生图模型"
              }
            ]
          },
          {
            "markdown": "",
            "index": 8,
            "id": "agent",
            "title": "Agent",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```js\nconst { cloudbase } = require('./utils/cloudbase');\n\nasync function callAgent(input) {\n  const ai = cloudbase.ai();\n  await auth.signInAnonymously();\n\n  try {\n    console.log('正在生成答案...');\n    const res = await ai.bot.sendMessage({\n      botId: '{%AGENT_ID%}', // 替换为你的AgentId\n      // 入参结构参考前后端通信协议：\n      //  https://docs.cloudbase.net/ai/agent/http-agent-protocol\n      threadId: '550e8400-e29b-41d4-a716-446655440000',\n      runId: 'run_001',\n      messages: [\n        {\n          id: 'msg_001',\n          role: 'user',\n          content: '你好',\n        },\n      ],\n      tools: [],\n      context: [],\n      state: {},\n      forwardedProps: {},\n    });\n\n    let response = '';\n    for await (let str of res.textStream) {\n      process.stdout.write(str);\n      response += str;\n    }\n    console.log('\\n生成完成！');\n    return response;\n  } catch (err) {\n    console.error('生成失败:', err);\n    return null;\n  }\n}\n\n// 调用示例\ncallAgent('你是谁');\n\n```",
                "index": 0,
                "id": "scf",
                "title": "函数型"
              },
              {
                "markdown": "```js\nconst { cloudbase } = require(\"./utils/cloudbase\");\n\nasync function callAgent(input) {\n  const ai = cloudbase.ai();\n  await auth.signInAnonymously();\n\n  try {\n    console.log(\"正在生成答案...\");\n    const res = await ai.bot.sendMessage({\n      botId: \"{%AGENT_ID%}\", // 替换为你的AgentId\n      msg: input\n    });\n\n    let response = \"\";\n    for await (let str of res.textStream) {\n      process.stdout.write(str);\n      response += str;\n    }\n    console.log(\"\\n生成完成！\");\n    return response;\n  } catch (err) {\n    console.error(\"生成失败:\", err);\n    return null;\n  }\n}\n\n// 调用示例\ncallAgent(\"你是谁\");\n```",
                "index": 1,
                "id": "baas",
                "title": "普通型"
              }
            ]
          }
        ]
      }
    ],
    "_id": "ee4af104697c22ef0037be9243511aa4",
    "_openid": "anon",
    "createdAt": 1769743087288,
    "updatedAt": 1777689755017
  },
  {
    "category": "框架集成,移动端框架,iOS Swift",
    "targetPlatform": [
      "intl"
    ],
    "lang": "zh",
    "index": 32,
    "hasTemplate": false,
    "docsUrl": "https://docs.cloudbase.net/http-api/basic/overview",
    "content": [
      {
        "markdown": "通过 **HTTP 请求** 在 **iOS Swift** 中调用各种云开发能力\n\n本项目使用 Swift 原生 URLSession，无需额外依赖。\n\n如需使用第三方库，可通过 CocoaPods 或 Swift Package Manager 安装：\n\n```ruby\n# Podfile\npod 'Alamofire', '~> 5.8'\n```",
        "index": 1,
        "title": "安装依赖",
        "content": []
      },
      {
        "markdown": "新增如下代码到您的 **iOS Swift** 项目",
        "index": 2,
        "title": "初始化配置",
        "type": "codeTab",
        "content": [
          {
            "markdown": "```swift\nimport Foundation\n\nclass CloudBaseClient {\n    let envId: String\n    private(set) var accessToken: String\n    let baseUrl: String\n\n    init(envId: String, accessToken: String) {\n        self.envId = envId\n        self.accessToken = accessToken\n        self.baseUrl = \"https://\\(envId).api.tcloudbasegateway.com\"\n    }\n\n    /// 更新访问令牌\n    ///\n    /// - Parameter newToken: 新的访问令牌\n    func updateAccessToken(_ newToken: String) {\n        self.accessToken = newToken\n        print(\"访问令牌已更新\")\n    }\n\n    /// 统一的HTTP请求方法\n    ///\n    /// - Parameters:\n    ///   - method: 请求方法 (GET, POST, PUT, PATCH, DELETE)\n    ///   - path: API路径 (如 /v1/rdb/rest/table_name)\n    ///   - body: 请求体数据\n    ///   - customHeaders: 自定义headers\n    /// - Returns: 响应数据或nil\n    func request<T: Decodable>(\n        method: String,\n        path: String,\n        body: [String: Any]? = nil,\n        customHeaders: [String: String] = [:],\n        completion: @escaping (T?) -> Void\n    ) {\n        guard let url = URL(string: \"\\(baseUrl)\\(path)\") else {\n            print(\"无效的URL\")\n            completion(nil)\n            return\n        }\n\n        var request = URLRequest(url: url)\n        request.httpMethod = method.uppercased()\n        request.setValue(\"application/json\", forHTTPHeaderField: \"Content-Type\")\n        request.setValue(\"application/json\", forHTTPHeaderField: \"Accept\")\n        request.setValue(\"Bearer \\(accessToken)\", forHTTPHeaderField: \"Authorization\")\n\n        // 添加自定义headers\n        customHeaders.forEach { key, value in\n            request.setValue(value, forHTTPHeaderField: key)\n        }\n\n        // 设置请求体\n        if let body = body {\n            do {\n                request.httpBody = try JSONSerialization.data(withJSONObject: body)\n            } catch {\n                print(\"JSON序列化失败: \\(error)\")\n                completion(nil)\n                return\n            }\n        }\n\n        let task = URLSession.shared.dataTask(with: request) { data, response, error in\n            if let error = error {\n                print(\"请求失败: \\(error.localizedDescription)\")\n                completion(nil)\n                return\n            }\n\n            guard let httpResponse = response as? HTTPURLResponse,\n                  (200...299).contains(httpResponse.statusCode) else {\n                print(\"请求失败: \\((response as? HTTPURLResponse)?.statusCode ?? -1)\")\n                completion(nil)\n                return\n            }\n\n            guard let data = data else {\n                // 如果响应为空，返回true表示成功\n                if T.self == Bool.self {\n                    completion(true as? T)\n                } else {\n                    completion(nil)\n                }\n                return\n            }\n\n            do {\n                let decoder = JSONDecoder()\n                let result = try decoder.decode(T.self, from: data)\n                completion(result)\n            } catch {\n                // 尝试作为Any解码\n                if let json = try? JSONSerialization.jsonObject(with: data) as? T {\n                    completion(json)\n                } else {\n                    print(\"JSON解析失败: \\(error)\")\n                    completion(nil)\n                }\n            }\n        }\n\n        task.resume()\n    }\n\n    /// 同步版本（使用 async/await）\n    @available(iOS 13.0, *)\n    func request<T: Decodable>(\n        method: String,\n        path: String,\n        body: [String: Any]? = nil,\n        customHeaders: [String: String] = [:]\n    ) async -> T? {\n        await withCheckedContinuation { continuation in\n            request(method: method, path: path, body: body, customHeaders: customHeaders) { (result: T?) in\n                continuation.resume(returning: result)\n            }\n        }\n    }\n}\n\n// 配置文件或初始化时创建实例\n// let cloudbase = CloudBaseClient(\n//     envId: \"your-env-id\",\n//     accessToken: \"your-access-token\"\n// )\n```",
            "index": 1,
            "title": "CloudBaseClient.swift"
          },
          {
            "markdown": "创建 `Config.plist` 文件存储配置：\n\n> 💡 提示：用户权限请参考「身份认证」模块获取 access_token\n\n```xml\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n    <!-- 环境ID -->\n    <key>CLOUDBASE_ENV_ID</key>\n    <string>{%ENV_ID%}</string>\n    <!-- 匿名访问令牌 -->\n    <key>CLOUDBASE_ACCESS_TOKEN</key>\n    <string>{%PUBLISHABLE_KEY%}</string>\n</dict>\n</plist>\n```\n\n读取配置并初始化客户端：\n\n```swift\nfunc loadConfig() -> (envId: String, accessToken: String)? {\n    guard let path = Bundle.main.path(forResource: \"Config\", ofType: \"plist\"),\n          let config = NSDictionary(contentsOfFile: path),\n          let envId = config[\"CLOUDBASE_ENV_ID\"] as? String,\n          let accessToken = config[\"CLOUDBASE_ACCESS_TOKEN\"] as? String else {\n        return nil\n    }\n    return (envId, accessToken)\n}\n\n// 在 AppDelegate 或 SceneDelegate 中初始化\nclass AppDelegate: UIResponder, UIApplicationDelegate {\n    var cloudbase: CloudBaseClient?\n\n    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {\n        // 从配置文件加载环境信息\n        if let config = loadConfig() {\n            cloudbase = CloudBaseClient(envId: config.envId, accessToken: config.accessToken)\n            print(\"云开发客户端初始化成功\")\n        } else {\n            print(\"配置文件加载失败\")\n        }\n        return true\n    }\n}\n\n// 或者在需要的地方直接初始化\n// if let config = loadConfig() {\n//     let cloudbase = CloudBaseClient(envId: config.envId, accessToken: config.accessToken)\n//     // 使用 cloudbase 进行后续操作\n// }\n```",
            "index": 2,
            "title": "Config.plist"
          }
        ]
      },
      {
        "index": 3,
        "title": "调用云开发能力",
        "type": "codeTab",
        "content": [
          {
            "index": 1,
            "id": "mysql-db",
            "title": "MySQL数据库",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```swift\nfunc getMysqlData(cloudbase: CloudBaseClient, tableName: String, completion: @escaping ([[String: Any]]?) -> Void) {\n    // 查询 MySQL 数据库数据\n    cloudbase.request(\n        method: \"GET\",\n        path: \"/v1/rdb/rest/\\(tableName)?limit=10\"\n    ) { (data: [[String: Any]]?) in\n        if let data = data {\n            print(\"查询成功: \\(data)\")\n        }\n        completion(data ?? [])\n    }\n}\n\n// 使用示例（async/await）\n// Task {\n//     let result: [[String: Any]]? = await cloudbase.request(\n//         method: \"GET\",\n//         path: \"/v1/rdb/rest/{%TABLE_NAME%}?limit=10\"\n//     )\n//     print(result)\n// }\n```",
                "index": 1,
                "title": "查询数据",
                "content": []
              },
              {
                "markdown": "```swift\nfunc addMysqlData(cloudbase: CloudBaseClient, tableName: String, data: [String: Any], completion: @escaping ([String: Any]?) -> Void) {\n    // 新增 MySQL 数据库数据\n    cloudbase.request(\n        method: \"POST\",\n        path: \"/v1/rdb/rest/\\(tableName)\",\n        body: data\n    ) { (result: [String: Any]?) in\n        if let result = result {\n            print(\"新增成功: \\(result)\")\n        }\n        completion(result)\n    }\n}\n\n// 使用示例（async/await）\n// Task {\n//     let result: [String: Any]? = await cloudbase.request(\n//         method: \"POST\",\n//         path: \"/v1/rdb/rest/{%TABLE_NAME%}\",\n//         body: [\"title\": \"示例标题\"]\n//     )\n//     print(result)\n// }\n```",
                "index": 2,
                "title": "新增数据",
                "content": []
              },
              {
                "markdown": "```swift\nfunc updateMysqlData(cloudbase: CloudBaseClient, tableName: String, dataId: String, data: [String: Any], completion: @escaping (Any?) -> Void) {\n    // 更新 MySQL 数据库数据\n    cloudbase.request(\n        method: \"PATCH\",\n        path: \"/v1/rdb/rest/\\(tableName)?id=eq.\\(dataId)\",\n        body: data\n    ) { (result: Any?) in\n        if result != nil {\n            print(\"更新成功: \\(result ?? \"\")\")\n        }\n        completion(result)\n    }\n}\n\n// 使用示例（async/await）\n// Task {\n//     let result: Any? = await cloudbase.request(\n//         method: \"PATCH\",\n//         path: \"/v1/rdb/rest/{%TABLE_NAME%}?id=eq.<数据id>\",\n//         body: [\"title\": \"新标题\"]\n//     )\n//     print(result)\n// }\n```",
                "index": 3,
                "title": "更新数据",
                "content": []
              },
              {
                "markdown": "```swift\nfunc deleteMysqlData(cloudbase: CloudBaseClient, tableName: String, dataId: String, completion: @escaping (Bool) -> Void) {\n    // 删除 MySQL 数据库数据\n    cloudbase.request(\n        method: \"DELETE\",\n        path: \"/v1/rdb/rest/\\(tableName)?id=eq.\\(dataId)\"\n    ) { (result: Bool?) in\n        if result == true {\n            print(\"删除成功\")\n            completion(true)\n        } else {\n            completion(false)\n        }\n    }\n}\n\n// 使用示例（async/await）\n// Task {\n//     let result: Bool? = await cloudbase.request(\n//         method: \"DELETE\",\n//         path: \"/v1/rdb/rest/{%TABLE_NAME%}?id=eq.<数据id>\"\n//     )\n//     print(result ?? false)\n// }\n```",
                "index": 4,
                "title": "删除数据",
                "content": []
              }
            ]
          },
          {
            "index": 2,
            "id": "data-model",
            "title": "数据模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```swift\nfunc getModelData(cloudbase: CloudBaseClient, modelName: String, envType: String = \"prod\", completion: @escaping ([[String: Any]]) -> Void) {\n    // 查询数据模型数据\n    let payload: [String: Any] = [\n        \"pageSize\": 10,\n        \"pageNumber\": 1,\n        \"getCount\": true\n    ]\n\n    cloudbase.request(\n        method: \"POST\",\n        path: \"/v1/model/\\(envType)/\\(modelName)/list\",\n        body: payload\n    ) { (result: [String: Any]?) in\n        if let result = result,\n           let data = result[\"data\"] as? [String: Any],\n           let records = data[\"records\"] as? [[String: Any]] {\n            print(\"查询成功: \\(records)\")\n            completion(records)\n        } else {\n            completion([])\n        }\n    }\n}\n\n// 使用示例（async/await）\n// Task {\n//     let result: [String: Any]? = await cloudbase.request(\n//         method: \"POST\",\n//         path: \"/v1/model/prod/{%TABLE_NAME%}/list\",\n//         body: [\"pageSize\": 10, \"pageNumber\": 1, \"getCount\": true]\n//     )\n//     print(result)\n// }\n```",
                "index": 1,
                "title": "查询数据",
                "content": []
              },
              {
                "markdown": "```swift\nfunc addModelData(cloudbase: CloudBaseClient, modelName: String, data: [String: Any], envType: String = \"prod\", completion: @escaping ([String: Any]?) -> Void) {\n    // 新增数据模型数据\n    let payload: [String: Any] = [\"data\": data]\n\n    cloudbase.request(\n        method: \"POST\",\n        path: \"/v1/model/\\(envType)/\\(modelName)/create\",\n        body: payload\n    ) { (result: [String: Any]?) in\n        if let result = result,\n           let data = result[\"data\"] as? [String: Any],\n           let docId = data[\"id\"] {\n            print(\"新增成功! id: \\(docId)\")\n        }\n        completion(result)\n    }\n}\n\n// 使用示例（async/await）\n// Task {\n//     let result: [String: Any]? = await cloudbase.request(\n//         method: \"POST\",\n//         path: \"/v1/model/prod/{%TABLE_NAME%}/create\",\n//         body: [\"data\": [\"title\": \"示例标题\"]]\n//     )\n//     print(result)\n// }\n```",
                "index": 2,
                "title": "新增数据",
                "content": []
              },
              {
                "markdown": "```swift\nfunc updateModelData(cloudbase: CloudBaseClient, modelName: String, dataId: String, data: [String: Any], envType: String = \"prod\", completion: @escaping (Bool) -> Void) {\n    // 更新数据模型数据\n    let payload: [String: Any] = [\n        \"data\": data,\n        \"filter\": [\n            \"where\": [\n                \"_id\": [\"$eq\": dataId]\n            ]\n        ]\n    ]\n\n    cloudbase.request(\n        method: \"PUT\",\n        path: \"/v1/model/\\(envType)/\\(modelName)/update\",\n        body: payload\n    ) { (result: Any?) in\n        if result != nil {\n            print(\"更新成功!\")\n            completion(true)\n        } else {\n            completion(false)\n        }\n    }\n}\n\n// 使用示例（async/await）\n// Task {\n//     let payload: [String: Any] = [\n//         \"data\": [\"title\": \"新标题\"],\n//         \"filter\": [\"where\": [\"_id\": [\"$eq\": \"<数据id>\"]]]\n//     ]\n//     let result: Any? = await cloudbase.request(\n//         method: \"PUT\",\n//         path: \"/v1/model/prod/{%TABLE_NAME%}/update\",\n//         body: payload\n//     )\n//     print(result != nil)\n// }\n```",
                "index": 3,
                "title": "更新数据",
                "content": []
              },
              {
                "markdown": "```swift\nfunc deleteModelData(cloudbase: CloudBaseClient, modelName: String, dataId: String, envType: String = \"prod\", completion: @escaping (Bool) -> Void) {\n    // 删除数据模型数据\n    let payload: [String: Any] = [\n        \"filter\": [\n            \"where\": [\n                \"_id\": [\"$eq\": dataId]\n            ]\n        ]\n    ]\n\n    cloudbase.request(\n        method: \"POST\",\n        path: \"/v1/model/\\(envType)/\\(modelName)/delete\",\n        body: payload\n    ) { (result: Any?) in\n        if result != nil {\n            print(\"删除成功!\")\n            completion(true)\n        } else {\n            completion(false)\n        }\n    }\n}\n\n// 使用示例（async/await）\n// Task {\n//     let payload: [String: Any] = [\n//         \"filter\": [\"where\": [\"_id\": [\"$eq\": \"<数据id>\"]]]\n//     ]\n//     let result: Any? = await cloudbase.request(\n//         method: \"POST\",\n//         path: \"/v1/model/prod/{%TABLE_NAME%}/delete\",\n//         body: payload\n//     )\n//     print(result != nil)\n// }\n```",
                "index": 4,
                "title": "删除数据",
                "content": []
              }
            ]
          },
          {
            "markdown": "```swift\nfunc callFunction(cloudbase: CloudBaseClient, functionName: String, data: [String: Any]? = nil, completion: @escaping ([String: Any]?) -> Void) {\n    // 调用云函数\n    cloudbase.request(\n        method: \"POST\",\n        path: \"/v1/functions/\\(functionName)\",\n        body: data ?? [:]\n    ) { (result: [String: Any]?) in\n        if let result = result {\n            print(\"云函数调用结果: \\(result)\")\n        }\n        completion(result)\n    }\n}\n\n// 使用示例（async/await）\n// Task {\n//     let result: [String: Any]? = await cloudbase.request(\n//         method: \"POST\",\n//         path: \"/v1/functions/{%FUNCTION_NAME%}\",\n//         body: [:]\n//     )\n//     print(result)\n// }\n```",
            "index": 3,
            "id": "scf",
            "title": "云函数"
          },
          {
            "markdown": "```swift\nfunc callContainer(cloudbase: CloudBaseClient, serviceName: String, path: String = \"\", method: String = \"GET\", data: [String: Any]? = nil, completion: @escaping (Any?) -> Void) {\n    // 调用云托管服务\n    var fullPath = \"/v1/cloudrun/\\(serviceName)/\\(path)\"\n    if fullPath.hasSuffix(\"/\") {\n        fullPath = String(fullPath.dropLast())\n    }\n\n    cloudbase.request(\n        method: method.uppercased(),\n        path: fullPath,\n        body: data\n    ) { (result: Any?) in\n        if let result = result {\n            print(\"云托管调用结果: \\(result)\")\n        }\n        completion(result)\n    }\n}\n\n// 使用示例（async/await）\n// Task {\n//     let result: Any? = await cloudbase.request(\n//         method: \"GET\",\n//         path: \"/v1/cloudrun/{%SERVICE_NAME%}\"\n//     )\n//     print(result)\n// }\n```",
            "index": 4,
            "id": "run",
            "title": "云托管"
          },
          {
            "index": 5,
            "id": "storage",
            "title": "云存储",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```swift\nfunc uploadFile(cloudbase: CloudBaseClient, filePath: String, objectId: String? = nil, completion: @escaping ([String: String]?) -> Void) {\n    // 上传文件到云存储\n    guard let fileUrl = URL(string: filePath),\n          let fileData = try? Data(contentsOf: fileUrl) else {\n        print(\"文件不存在: \\(filePath)\")\n        completion(nil)\n        return\n    }\n\n    let filename = fileUrl.lastPathComponent\n    let timestamp = Int(Date().timeIntervalSince1970 * 1000)\n    let finalObjectId = objectId ?? \"uploads/\\(timestamp)-\\(filename)\"\n\n    // 1. 获取上传信息\n    cloudbase.request(\n        method: \"POST\",\n        path: \"/v1/storages/get-objects-upload-info\",\n        body: [[\"objectId\": finalObjectId]]\n    ) { (uploadInfo: [[String: Any]]?) in\n        guard let uploadInfo = uploadInfo, !uploadInfo.isEmpty else {\n            completion(nil)\n            return\n        }\n\n        let info = uploadInfo[0]\n        guard let uploadUrl = info[\"uploadUrl\"] as? String,\n              let authorization = info[\"authorization\"] as? String,\n              let token = info[\"token\"] as? String,\n              let cloudObjectMeta = info[\"cloudObjectMeta\"] as? String else {\n            completion(nil)\n            return\n        }\n\n        // 2. 上传文件\n        guard let url = URL(string: uploadUrl) else {\n            completion(nil)\n            return\n        }\n\n        var request = URLRequest(url: url)\n        request.httpMethod = \"PUT\"\n        request.setValue(authorization, forHTTPHeaderField: \"Authorization\")\n        request.setValue(token, forHTTPHeaderField: \"X-Cos-Security-Token\")\n        request.setValue(cloudObjectMeta, forHTTPHeaderField: \"X-Cos-Meta-Fileid\")\n        request.httpBody = fileData\n\n        let task = URLSession.shared.dataTask(with: request) { _, response, error in\n            if let error = error {\n                print(\"文件上传失败: \\(error.localizedDescription)\")\n                completion(nil)\n                return\n            }\n\n            guard let httpResponse = response as? HTTPURLResponse,\n                  (200...299).contains(httpResponse.statusCode) else {\n                print(\"文件上传失败\")\n                completion(nil)\n                return\n            }\n\n            let result = [\n                \"cloudObjectId\": info[\"cloudObjectId\"] as? String ?? \"\",\n                \"downloadUrl\": info[\"downloadUrl\"] as? String ?? \"\",\n                \"objectId\": finalObjectId\n            ]\n\n            print(\"文件上传成功:\")\n            print(\"- 对象ID: \\(result[\"objectId\"] ?? \"\")\")\n            print(\"- 下载URL: \\(result[\"downloadUrl\"] ?? \"\")\")\n\n            completion(result)\n        }\n\n        task.resume()\n    }\n}\n\n// 使用示例\n// uploadFile(cloudbase: cloudbase, filePath: \"./example.jpg\") { result in\n//     print(result)\n// }\n```",
                "index": 1,
                "title": "上传文件",
                "content": []
              },
              {
                "markdown": "```swift\nfunc getFileUrl(cloudbase: CloudBaseClient, cloudObjectId: String, completion: @escaping (String?) -> Void) {\n    // 获取云存储文件的临时访问链接\n    cloudbase.request(\n        method: \"POST\",\n        path: \"/v1/storages/get-objects-download-info\",\n        body: [[\"cloudObjectId\": cloudObjectId]]\n    ) { (result: [[String: Any]]?) in\n        if let result = result, !result.isEmpty,\n           let downloadUrl = result[0][\"downloadUrl\"] as? String {\n            print(\"文件链接: \\(downloadUrl)\")\n            completion(downloadUrl)\n        } else {\n            completion(nil)\n        }\n    }\n}\n\n// 使用示例（async/await）\n// Task {\n//     let result: [[String: Any]]? = await cloudbase.request(\n//         method: \"POST\",\n//         path: \"/v1/storages/get-objects-download-info\",\n//         body: [[\"cloudObjectId\": \"cloud://xxx.png\"]]\n//     )\n//     if let downloadUrl = result?.first?[\"downloadUrl\"] as? String {\n//         print(downloadUrl)\n//     }\n// }\n```",
                "index": 2,
                "title": "获取文件链接",
                "content": []
              },
              {
                "markdown": "```swift\nfunc downloadFile(cloudbase: CloudBaseClient, cloudObjectId: String, savePath: String = \"./\", completion: @escaping (Bool) -> Void) {\n    // 下载云存储文件到本地\n    // 1. 获取下载链接\n    cloudbase.request(\n        method: \"POST\",\n        path: \"/v1/storages/get-objects-download-info\",\n        body: [[\"cloudObjectId\": cloudObjectId]]\n    ) { (result: [[String: Any]]?) in\n        guard let result = result, !result.isEmpty,\n              let downloadUrl = result[0][\"downloadUrl\"] as? String else {\n            completion(false)\n            return\n        }\n\n        guard let url = URL(string: downloadUrl) else {\n            completion(false)\n            return\n        }\n\n        // 2. 下载文件\n        let task = URLSession.shared.downloadTask(with: url) { tempUrl, _, error in\n            if let error = error {\n                print(\"下载失败: \\(error.localizedDescription)\")\n                completion(false)\n                return\n            }\n\n            guard let tempUrl = tempUrl else {\n                completion(false)\n                return\n            }\n\n            // 3. 确定保存路径\n            let filename = url.lastPathComponent.components(separatedBy: \"?\").first ?? \"file\"\n            let fileManager = FileManager.default\n            var fullPath: URL\n\n            if savePath.hasSuffix(\"/\") {\n                fullPath = URL(fileURLWithPath: savePath).appendingPathComponent(filename)\n            } else {\n                fullPath = URL(fileURLWithPath: savePath)\n            }\n\n            // 4. 保存文件\n            do {\n                if fileManager.fileExists(atPath: fullPath.path) {\n                    try fileManager.removeItem(at: fullPath)\n                }\n                try fileManager.moveItem(at: tempUrl, to: fullPath)\n                print(\"下载成功! 文件已保存到: \\(fullPath.path)\")\n                completion(true)\n            } catch {\n                print(\"下载失败: \\(error.localizedDescription)\")\n                completion(false)\n            }\n        }\n\n        task.resume()\n    }\n}\n\n// 使用示例\n// downloadFile(cloudbase: cloudbase, cloudObjectId: \"cloud://xxx.png\", savePath: \"./downloads/\") { success in\n//     print(success)\n// }\n```",
                "index": 3,
                "title": "下载文件",
                "content": []
              },
              {
                "markdown": "```swift\nfunc deleteFile(cloudbase: CloudBaseClient, cloudObjectIds: Any, completion: @escaping (Bool) -> Void) {\n    // 删除云存储文件\n    var ids: [String] = []\n\n    if let idString = cloudObjectIds as? String {\n        ids = [idString]\n    } else if let idArray = cloudObjectIds as? [String] {\n        ids = idArray\n    } else {\n        print(\"参数类型错误\")\n        completion(false)\n        return\n    }\n\n    let data = ids.map { [\"cloudObjectId\": $0] }\n\n    cloudbase.request(\n        method: \"POST\",\n        path: \"/v1/storages/delete-objects\",\n        body: data\n    ) { (result: Any?) in\n        if result != nil {\n            print(\"删除成功!\")\n            completion(true)\n        } else {\n            completion(false)\n        }\n    }\n}\n\n// 使用示例（async/await）\n// Task {\n//     let data = [[\"cloudObjectId\": \"cloud://xxx.png\"]]\n//     let result: Any? = await cloudbase.request(\n//         method: \"POST\",\n//         path: \"/v1/storages/delete-objects\",\n//         body: data\n//     )\n//     print(result != nil)\n// }\n```",
                "index": 4,
                "title": "删除文件",
                "content": []
              }
            ]
          },
          {
            "index": 6,
            "id": "ai-model",
            "title": "大模型",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```swift\nfunc streamText(cloudbase: CloudBaseClient, model: String, subModel: String, messages: [[String: String]], completion: @escaping (String?) -> Void) {\n    // 流式文本生成\n    let payload: [String: Any] = [\n        \"model\": subModel,\n        \"messages\": messages,\n        \"stream\": true\n    ]\n\n    guard let url = URL(string: \"\\(cloudbase.baseUrl)/v1/ai/\\(model)/chat/completions\") else {\n        completion(nil)\n        return\n    }\n\n    var request = URLRequest(url: url)\n    request.httpMethod = \"POST\"\n    request.setValue(\"application/json\", forHTTPHeaderField: \"Content-Type\")\n    request.setValue(\"text/event-stream\", forHTTPHeaderField: \"Accept\")\n    request.setValue(\"Bearer \\(cloudbase.accessToken)\", forHTTPHeaderField: \"Authorization\")\n\n    do {\n        request.httpBody = try JSONSerialization.data(withJSONObject: payload)\n    } catch {\n        print(\"JSON序列化失败: \\(error)\")\n        completion(nil)\n        return\n    }\n\n    let task = URLSession.shared.dataTask(with: request) { data, response, error in\n        if let error = error {\n            print(\"AI 调用失败: \\(error.localizedDescription)\")\n            completion(nil)\n            return\n        }\n\n        guard let data = data,\n              let responseString = String(data: data, encoding: .utf8) else {\n            completion(nil)\n            return\n        }\n\n        print(\"AI 流式响应:\")\n        var fullContent = \"\"\n\n        let lines = responseString.components(separatedBy: \"\\n\")\n        for line in lines {\n            if line.hasPrefix(\"data: \") {\n                let dataStr = String(line.dropFirst(6))\n                if dataStr.trimmingCharacters(in: .whitespaces) != \"[DONE]\" {\n                    if let data = dataStr.data(using: .utf8),\n                       let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any],\n                       let choices = json[\"choices\"] as? [[String: Any]],\n                       let delta = choices.first?[\"delta\"] as? [String: Any],\n                       let content = delta[\"content\"] as? String {\n                        print(content, terminator: \"\")\n                        fullContent += content\n                    }\n                }\n            }\n        }\n\n        print()\n        completion(fullContent)\n    }\n\n    task.resume()\n}\n\n// 使用示例\n// streamText(\n//     cloudbase: cloudbase,\n//     model: \"{%AI_MODEL_NAME%}\",\n//     subModel: \"{%AI_SUB_MODEL_NAME%}\",\n//     messages: [\n//         [\"role\": \"system\", \"content\": \"请严格按照七言绝句或七言律诗的格律要求创作\"],\n//         [\"role\": \"user\", \"content\": \"春天\"]\n//     ]\n// ) { response in\n//     print(\"\\n完整回复: \\(response ?? \"\")\")\n// }\n```",
                "index": 1,
                "id": "text-aiModel",
                "title": "生文模型",
                "content": []
              },
              {
                "markdown": "生图模型通过调用云函数来实现，在生图模型页面点击「一键创建云函数」，函数调用示例如下：\n\n```swift\nfunc generateImage(cloudbase: CloudBaseClient, prompt: String, completion: @escaping ([String: Any]?) -> Void) {\n    // 准备调用参数\n    let data: [String: Any] = [\"prompt\": prompt]\n    \n    // 调用云函数生成图片\n    cloudbase.request(\n        method: \"POST\",\n        path: \"/v1/functions/<YOUR_FUNCTION_NAME>\",\n        body: data\n    ) { (result: [String: Any]?) in\n        if let result = result {\n            if let success = result[\"success\"] as? Bool, success {\n                let imageUrl = result[\"imageUrl\"] as? String ?? \"\"\n                let revisedPrompt = result[\"revised_prompt\"] as? String ?? \"\"\n                \n                print(\"生成成功!\")\n                print(\"图片URL: \\(imageUrl)\")\n                print(\"优化后的提示词: \\(revisedPrompt)\")\n                print(\"注意: 图片URL有效期为24小时\")\n                \n                completion(result)\n            } else {\n                let code = result[\"code\"] as? String ?? \"\"\n                let message = result[\"message\"] as? String ?? \"\"\n                print(\"生成失败: \\(code) - \\(message)\")\n                completion(nil)\n            }\n        } else {\n            print(\"请求失败\")\n            completion(nil)\n        }\n    }\n}\n\n// 使用示例\n// generateImage(cloudbase: cloudbase, prompt: \"一只可爱的猫咪在阳光下玩耍\") { result in\n//     if let result = result {\n//         print(\"图片生成完成: \\(result)\")\n//     }\n// }\n```",
                "index": 2,
                "id": "image-aiModel",
                "title": "生图模型",
                "content": []
              }
            ]
          },
          {
            "markdown": "",
            "index": 7,
            "id": "agent",
            "title": "Agent",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```swift\n/**\n * iOS Swift 调用 Agent 示例（AG-UI 协议）\n * 协议文档：https://docs.cloudbase.net/ai/agent-development/protocol\n */\nfunc chatWithAgentStream(cloudbase: CloudBaseClient, botId: String, userMessage: String, completion: @escaping (String?) -> Void) {\n    // 构建消息列表（AG-UI 协议格式）\n    let messages: [[String: Any]] = [\n        [\n            \"id\": \"msg_001\",\n            \"role\": \"user\",\n            \"content\": userMessage\n        ]\n    ]\n\n    // AG-UI 协议请求参数\n    let payload: [String: Any] = [\n        \"messages\": messages,                                    // 必填：消息列表\n        \"threadId\": \"550e8400-e29b-41d4-a716-446655440000\",     // 可选：会话ID，用于多轮对话\n        \"runId\": \"run_001\",                                      // 可选：运行ID，用于追踪执行\n        \"tools\": [],                                             // 可选：前端工具定义\n        \"context\": [],                                           // 可选：上下文信息\n        \"forwardedProps\": [:]                                    // 可选：透传参数\n    ]\n\n    guard let url = URL(string: \"\\(cloudbase.baseUrl)/v1/aibot/bots/\\(botId)/send-message\") else {\n        completion(nil)\n        return\n    }\n\n    var request = URLRequest(url: url)\n    request.httpMethod = \"POST\"\n    request.setValue(\"application/json\", forHTTPHeaderField: \"Content-Type\")\n    request.setValue(\"text/event-stream\", forHTTPHeaderField: \"Accept\")\n    request.setValue(\"Bearer \\(cloudbase.accessToken)\", forHTTPHeaderField: \"Authorization\")\n\n    do {\n        request.httpBody = try JSONSerialization.data(withJSONObject: payload)\n    } catch {\n        print(\"JSON序列化失败: \\(error)\")\n        completion(nil)\n        return\n    }\n\n    let task = URLSession.shared.dataTask(with: request) { data, response, error in\n        if let error = error {\n            print(\"AI 调用失败: \\(error.localizedDescription)\")\n            completion(nil)\n            return\n        }\n\n        guard let data = data,\n              let responseString = String(data: data, encoding: .utf8) else {\n            completion(nil)\n            return\n        }\n\n        print(\"AI 流式响应:\")\n        var fullContent = \"\"\n\n        let lines = responseString.components(separatedBy: \"\\n\")\n        for line in lines {\n            if line.hasPrefix(\"data: \") {\n                let dataStr = String(line.dropFirst(6)).trimmingCharacters(in: .whitespaces)\n                if !dataStr.isEmpty && dataStr != \"[DONE]\" {\n                    if let data = dataStr.data(using: .utf8),\n                       let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any] {\n                        var content = \"\"\n\n                        if let directContent = json[\"content\"] as? String {\n                            content = directContent\n                        } else if let choices = json[\"choices\"] as? [[String: Any]] {\n                            if let delta = choices.first?[\"delta\"] as? [String: Any],\n                               let deltaContent = delta[\"content\"] as? String {\n                                content = deltaContent\n                            } else if let message = choices.first?[\"message\"] as? [String: Any],\n                                      let messageContent = message[\"content\"] as? String {\n                                content = messageContent\n                            }\n                        }\n\n                        if !content.isEmpty {\n                            print(content, terminator: \"\")\n                            fullContent += content\n                        }\n                    }\n                }\n            }\n        }\n\n        print()\n        completion(fullContent)\n    }\n\n    task.resume()\n}\n\n// 使用示例\n// chatWithAgentStream(cloudbase: cloudbase, botId: \"{%AGENT_ID%}\", userMessage: \"你是谁\") { response in\n//     print(\"\\n完整回复: \\(response ?? \"\")\")\n// }\n\n```",
                "index": 0,
                "id": "scf",
                "title": "函数型"
              },
              {
                "markdown": "```swift\nfunc chatWithAgentStream(cloudbase: CloudBaseClient, botId: String, msg: String, history: [[String: String]]? = nil, completion: @escaping (String?) -> Void) {\n    // 流式调用Agent\n    let payload: [String: Any] = [\n        \"history\": history ?? [],\n        \"msg\": msg\n    ]\n\n    guard let url = URL(string: \"\\(cloudbase.baseUrl)/v1/aibot/bots/\\(botId)/send-message\") else {\n        completion(nil)\n        return\n    }\n\n    var request = URLRequest(url: url)\n    request.httpMethod = \"POST\"\n    request.setValue(\"application/json\", forHTTPHeaderField: \"Content-Type\")\n    request.setValue(\"text/event-stream\", forHTTPHeaderField: \"Accept\")\n    request.setValue(\"Bearer \\(cloudbase.accessToken)\", forHTTPHeaderField: \"Authorization\")\n\n    do {\n        request.httpBody = try JSONSerialization.data(withJSONObject: payload)\n    } catch {\n        print(\"JSON序列化失败: \\(error)\")\n        completion(nil)\n        return\n    }\n\n    let task = URLSession.shared.dataTask(with: request) { data, response, error in\n        if let error = error {\n            print(\"AI 调用失败: \\(error.localizedDescription)\")\n            completion(nil)\n            return\n        }\n\n        guard let data = data,\n              let responseString = String(data: data, encoding: .utf8) else {\n            completion(nil)\n            return\n        }\n\n        print(\"AI 流式响应:\")\n        var fullContent = \"\"\n\n        let lines = responseString.components(separatedBy: \"\\n\")\n        for line in lines {\n            if line.hasPrefix(\"data: \") {\n                let dataStr = String(line.dropFirst(6)).trimmingCharacters(in: .whitespaces)\n                if !dataStr.isEmpty && dataStr != \"[DONE]\" {\n                    if let data = dataStr.data(using: .utf8),\n                       let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any] {\n                        var content = \"\"\n\n                        if let directContent = json[\"content\"] as? String {\n                            content = directContent\n                        } else if let choices = json[\"choices\"] as? [[String: Any]] {\n                            if let delta = choices.first?[\"delta\"] as? [String: Any],\n                               let deltaContent = delta[\"content\"] as? String {\n                                content = deltaContent\n                            } else if let message = choices.first?[\"message\"] as? [String: Any],\n                                      let messageContent = message[\"content\"] as? String {\n                                content = messageContent\n                            }\n                        }\n\n                        if !content.isEmpty {\n                            print(content, terminator: \"\")\n                            fullContent += content\n                        }\n                    }\n                }\n            }\n        }\n\n        print()\n        completion(fullContent)\n    }\n\n    task.resume()\n}\n\n// 使用示例\n// chatWithAgentStream(cloudbase: cloudbase, botId: \"{%AGENT_ID%}\", msg: \"你是谁\") { response in\n//     print(\"\\n完整回复: \\(response ?? \"\")\")\n// }\n```",
                "index": 1,
                "id": "baas",
                "title": "普通型"
              }
            ]
          },
          {
            "index": 8,
            "id": "identity",
            "title": "身份认证",
            "type": "sideTab",
            "content": [
              {
                "markdown": "```swift\nfunc signUpWithPhoneCode(cloudbase: CloudBaseClient, phoneNumber: String, verificationCode: String, username: String? = nil, password: String? = nil, captchaToken: String? = nil, completion: @escaping ([String: Any]?) -> Void) {\n    // 步骤1: 发送短信验证码\n    var body: [String: Any] = [\n        \"phone_number\": phoneNumber.hasPrefix(\"+86\") ? phoneNumber : \"+86\\(phoneNumber)\",\n        \"target\": \"NON_USER\"  // \"NON_USER\" - 账号不存在才发送; \"ANY\" - 不限制\n    ]\n\n    var headers: [String: String] = [:]\n    if let token = captchaToken {\n        headers[\"x-captcha-token\"] = token\n    }\n\n    cloudbase.request(\n        method: \"POST\",\n        path: \"/auth/v1/verification\",\n        body: body,\n        customHeaders: headers\n    ) { (sendResult: [String: Any]?) in\n        guard let sendResult = sendResult,\n              let verificationId = sendResult[\"verification_id\"] as? String else {\n            print(\"发送验证码失败\")\n            completion(nil)\n            return\n        }\n\n        print(\"验证码发送成功! ID: \\(verificationId)\")\n\n        // 步骤2: 验证验证码\n        cloudbase.request(\n            method: \"POST\",\n            path: \"/auth/v1/verification/verify\",\n            body: [\n                \"verification_id\": verificationId,\n                \"verification_code\": verificationCode\n            ]\n        ) { (verifyResult: [String: Any]?) in\n            guard let verifyResult = verifyResult,\n                  let verificationToken = verifyResult[\"verification_token\"] as? String else {\n                print(\"验证码错误\")\n                completion(nil)\n                return\n            }\n\n            print(\"验证成功!\")\n\n            // 步骤3: 使用验证令牌注册\n            var signUpBody: [String: Any] = [\n                \"phone_number\": phoneNumber.hasPrefix(\"+86\") ? phoneNumber : \"+86\\(phoneNumber)\",\n                \"verification_token\": verificationToken\n            ]\n\n            // 可选：添加用户名和密码\n            if let username = username {\n                signUpBody[\"username\"] = username\n            }\n            if let password = password {\n                signUpBody[\"password\"] = password\n            }\n\n            cloudbase.request(\n                method: \"POST\",\n                path: \"/auth/v1/signup\",\n                body: signUpBody\n            ) { (signUpResult: [String: Any]?) in\n                if let signUpResult = signUpResult,\n                   let accessToken = signUpResult[\"access_token\"] as? String,\n                   let userId = signUpResult[\"sub\"] as? String {\n                    print(\"注册成功! 用户ID: \\(userId)\")\n                    print(\"访问令牌: \\(String(accessToken.prefix(20)))...\")\n\n                    // 更新访问令牌\n                    cloudbase.updateAccessToken(accessToken)\n                    completion(signUpResult)\n                } else {\n                    print(\"注册失败\")\n                    completion(nil)\n                }\n            }\n        }\n    }\n}\n\n// 使用示例\n// signUpWithPhoneCode(\n//     cloudbase: cloudbase,\n//     phoneNumber: \"13800138000\",\n//     verificationCode: \"123456\",\n//     username: \"myusername\",\n//     password: \"mypassword\"\n// ) { result in\n//     if result != nil {\n//         print(\"手机号注册成功\")\n//     }\n// }\n```",
                "index": 1,
                "title": "短信验证码注册",
                "content": []
              },
              {
                "markdown": "```swift\nfunc signUpWithEmailCode(cloudbase: CloudBaseClient, email: String, verificationCode: String, username: String? = nil, password: String? = nil, captchaToken: String? = nil, completion: @escaping ([String: Any]?) -> Void) {\n    // 步骤1: 发送邮箱验证码\n    var body: [String: Any] = [\n        \"email\": email,\n        \"target\": \"NON_USER\"  // \"NON_USER\" - 账号不存在才发送; \"ANY\" - 不限制\n    ]\n\n    var headers: [String: String] = [:]\n    if let token = captchaToken {\n        headers[\"x-captcha-token\"] = token\n    }\n\n    cloudbase.request(\n        method: \"POST\",\n        path: \"/auth/v1/verification\",\n        body: body,\n        customHeaders: headers\n    ) { (sendResult: [String: Any]?) in\n        guard let sendResult = sendResult,\n              let verificationId = sendResult[\"verification_id\"] as? String else {\n            print(\"发送验证码失败\")\n            completion(nil)\n            return\n        }\n\n        print(\"验证码发送成功! ID: \\(verificationId)\")\n\n        // 步骤2: 验证验证码\n        cloudbase.request(\n            method: \"POST\",\n            path: \"/auth/v1/verification/verify\",\n            body: [\n                \"verification_id\": verificationId,\n                \"verification_code\": verificationCode\n            ]\n        ) { (verifyResult: [String: Any]?) in\n            guard let verifyResult = verifyResult,\n                  let verificationToken = verifyResult[\"verification_token\"] as? String else {\n                print(\"验证码错误\")\n                completion(nil)\n                return\n            }\n\n            print(\"验证成功!\")\n\n            // 步骤3: 使用验证令牌注册\n            var signUpBody: [String: Any] = [\n                \"email\": email,\n                \"verification_token\": verificationToken\n            ]\n\n            // 可选：添加用户名和密码\n            if let username = username {\n                signUpBody[\"username\"] = username\n            }\n            if let password = password {\n                signUpBody[\"password\"] = password\n            }\n\n            cloudbase.request(\n                method: \"POST\",\n                path: \"/auth/v1/signup\",\n                body: signUpBody\n            ) { (signUpResult: [String: Any]?) in\n                if let signUpResult = signUpResult,\n                   let accessToken = signUpResult[\"access_token\"] as? String,\n                   let userId = signUpResult[\"sub\"] as? String {\n                    print(\"注册成功! 用户ID: \\(userId)\")\n                    print(\"访问令牌: \\(String(accessToken.prefix(20)))...\")\n\n                    // 更新访问令牌\n                    cloudbase.updateAccessToken(accessToken)\n                    completion(signUpResult)\n                } else {\n                    print(\"注册失败\")\n                    completion(nil)\n                }\n            }\n        }\n    }\n}\n\n// 使用示例\n// signUpWithEmailCode(\n//     cloudbase: cloudbase,\n//     email: \"user@example.com\",\n//     verificationCode: \"123456\",\n//     username: \"myusername\",\n//     password: \"mypassword\"\n// ) { result in\n//     if result != nil {\n//         print(\"邮箱注册成功\")\n//     }\n// }\n```",
                "index": 2,
                "title": "邮箱验证码注册",
                "content": []
              },
              {
                "markdown": "```swift\nfunc signIn(cloudbase: CloudBaseClient, username: String, password: String, completion: @escaping ([String: Any]?) -> Void) {\n    // 账号密码登录\n    cloudbase.request(\n        method: \"POST\",\n        path: \"/auth/v1/signin\",\n        body: [\"username\": username, \"password\": password]\n    ) { (result: [String: Any]?) in\n        if let result = result,\n           let accessToken = result[\"access_token\"] as? String,\n           let userId = result[\"sub\"] as? String {\n            print(\"登录成功! 用户ID: \\(userId)\")\n            print(\"访问令牌: \\(String(accessToken.prefix(20)))...\")\n\n            // 更新访问令牌\n            cloudbase.updateAccessToken(accessToken)\n        }\n        completion(result)\n    }\n}\n\n// 使用示例（async/await）\n// Task {\n//     let result: [String: Any]? = await cloudbase.request(\n//         method: \"POST\",\n//         path: \"/auth/v1/signin\",\n//         body: [\"username\": \"your_username\", \"password\": \"your_password\"]\n//     )\n//     if let result = result,\n//        let accessToken = result[\"access_token\"] as? String {\n//         // 更新访问令牌\n//         cloudbase.updateAccessToken(accessToken)\n//     }\n//     print(result)\n// }\n```",
                "index": 3,
                "id": "UserNameLogin",
                "title": "账号密码登录",
                "content": []
              },
              {
                "markdown": "```swift\nfunc loginWithPhoneCode(cloudbase: CloudBaseClient, phoneNumber: String, verificationCode: String, captchaToken: String? = nil, completion: @escaping (Bool) -> Void) {\n    // 步骤1: 发送短信验证码\n    var body: [String: Any] = [\n        \"phone_number\": phoneNumber.hasPrefix(\"+86\") ? phoneNumber : \"+86\\(phoneNumber)\",\n        \"target\": \"ANY\"  // \"ANY\" - 不限制，无论用户是否存在都发送; \"USER\" - 账号必须存在才发送\n    ]\n\n    var headers: [String: String] = [:]\n    if let token = captchaToken {\n        headers[\"x-captcha-token\"] = token\n    }\n\n    cloudbase.request(\n        method: \"POST\",\n        path: \"/auth/v1/verification\",\n        body: body,\n        customHeaders: headers\n    ) { (sendResult: [String: Any]?) in\n        guard let sendResult = sendResult,\n              let verificationId = sendResult[\"verification_id\"] as? String else {\n            print(\"发送验证码失败\")\n            completion(false)\n            return\n        }\n\n        print(\"验证码发送成功! ID: \\(verificationId)\")\n\n        // 步骤2: 验证验证码\n        cloudbase.request(\n            method: \"POST\",\n            path: \"/auth/v1/verification/verify\",\n            body: [\n                \"verification_id\": verificationId,\n                \"verification_code\": verificationCode\n            ]\n        ) { (verifyResult: [String: Any]?) in\n            guard let verifyResult = verifyResult,\n                  let verificationToken = verifyResult[\"verification_token\"] as? String else {\n                print(\"验证码错误\")\n                completion(false)\n                return\n            }\n\n            print(\"验证成功!\")\n\n            // 步骤3: 使用验证令牌登录\n            cloudbase.request(\n                method: \"POST\",\n                path: \"/auth/v1/signin\",\n                body: [\n                    \"phone_number\": phoneNumber.hasPrefix(\"+86\") ? phoneNumber : \"+86\\(phoneNumber)\",\n                    \"verification_token\": verificationToken\n                ]\n            ) { (loginResult: [String: Any]?) in\n                if let loginResult = loginResult,\n                   let accessToken = loginResult[\"access_token\"] as? String {\n                    print(\"登录成功!\")\n                    cloudbase.updateAccessToken(accessToken)\n                    completion(true)\n                } else {\n                    print(\"登录失败\")\n                    completion(false)\n                }\n            }\n        }\n    }\n}\n\n// 使用示例\n// loginWithPhoneCode(\n//     cloudbase: cloudbase,\n//     phoneNumber: \"13800138000\",\n//     verificationCode: \"123456\"\n// ) { success in\n//     if success {\n//         print(\"手机号登录成功\")\n//     }\n// }\n```",
                "index": 4,
                "id": "PhoneNumberLogin",
                "title": "短信验证码登录",
                "content": []
              },
              {
                "markdown": "```swift\nfunc loginWithEmailCode(cloudbase: CloudBaseClient, email: String, verificationCode: String, captchaToken: String? = nil, completion: @escaping (Bool) -> Void) {\n    // 步骤1: 发送邮箱验证码\n    var body: [String: Any] = [\n        \"email\": email,\n        \"target\": \"ANY\"  // \"ANY\" - 不限制，无论用户是否存在都发送; \"USER\" - 账号必须存在才发送\n    ]\n\n    var headers: [String: String] = [:]\n    if let token = captchaToken {\n        headers[\"x-captcha-token\"] = token\n    }\n\n    cloudbase.request(\n        method: \"POST\",\n        path: \"/auth/v1/verification\",\n        body: body,\n        customHeaders: headers\n    ) { (sendResult: [String: Any]?) in\n        guard let sendResult = sendResult,\n              let verificationId = sendResult[\"verification_id\"] as? String else {\n            print(\"发送验证码失败\")\n            completion(false)\n            return\n        }\n\n        print(\"验证码发送成功! ID: \\(verificationId)\")\n\n        // 步骤2: 验证验证码\n        cloudbase.request(\n            method: \"POST\",\n            path: \"/auth/v1/verification/verify\",\n            body: [\n                \"verification_id\": verificationId,\n                \"verification_code\": verificationCode\n            ]\n        ) { (verifyResult: [String: Any]?) in\n            guard let verifyResult = verifyResult,\n                  let verificationToken = verifyResult[\"verification_token\"] as? String else {\n                print(\"验证码错误\")\n                completion(false)\n                return\n            }\n\n            print(\"验证成功!\")\n\n            // 步骤3: 使用验证令牌登录\n            cloudbase.request(\n                method: \"POST\",\n                path: \"/auth/v1/signin\",\n                body: [\n                    \"email\": email,\n                    \"verification_token\": verificationToken\n                ]\n            ) { (loginResult: [String: Any]?) in\n                if let loginResult = loginResult,\n                   let accessToken = loginResult[\"access_token\"] as? String {\n                    print(\"登录成功!\")\n                    cloudbase.updateAccessToken(accessToken)\n                    completion(true)\n                } else {\n                    print(\"登录失败\")\n                    completion(false)\n                }\n            }\n        }\n    }\n}\n\n// 使用示例\n// loginWithEmailCode(\n//     cloudbase: cloudbase,\n//     email: \"user@example.com\",\n//     verificationCode: \"123456\"\n// ) { success in\n//     if success {\n//         print(\"邮箱登录成功\")\n//     }\n// }\n```",
                "index": 5,
                "id": "email",
                "title": "邮箱验证码登录",
                "content": []
              }
            ]
          }
        ]
      }
    ],
    "_id": "fa1010a2697c22f2003704550a330c5a",
    "_openid": "anon",
    "createdAt": 1769743090190,
    "updatedAt": 1770021227356
  }
]
