跳到主要内容

Flutter 快速开始

准备工作

在开始之前,请确保您已完成以下准备:

  1. 开通云开发环境开通云开发环境
  2. 获取 API 访问凭证:在 CloudBase 控制台 获取环境 ID 和 API 密钥

更多详情请参考:Flutter 完整文档

添加 CloudBase AI 开发插件

可选:如果你使用 AI 编程助手(如 Cursor、Claude Code、CodeBuddy 等)进行开发,建议先完成本步骤,让 AI 具备 CloudBase 开发能力。

复制 AI Prompt 粘贴到 AI IDE

在 AI 对话中输入:

帮我把 CloudBase 接好,按下面做:
1. 打开 https://docs.cloudbase.net/skill.md,按说明完成接入。
2. 接入完成后告诉我,并建议最相关的下一步。

查看 skill.md →

使用 Skills 开发

对 AI 说:

使用 CloudBase Skills:在 Flutter 应用中集成 CloudBase HTTP API

Skills 使用文档 →

也可以手动安装 CloudBase Skills:

npx skills add tencentcloudbase/cloudbase-skills -y

身份认证

import 'cloudbase_client.dart';

Future<Map<String, dynamic>?> signUpWithPhoneCode(String phoneNumber, String verificationCode, {String? username, String? password, String? captchaToken}) async {
try {
// 步骤1: 发送短信验证码
final sendBody = {
'phone_number': phoneNumber.startsWith('+86') ? phoneNumber : '+86$phoneNumber',
'target': 'NON_USER', // "NON_USER" - 账号不存在才发送; "ANY" - 不限制
};

final sendHeaders = captchaToken != null ? {'x-captcha-token': captchaToken} : null;

final sendResult = await cloudbase.request(
'POST',
'/auth/v1/verification',
body: sendBody,
customHeaders: sendHeaders,
);

if (sendResult == null) {
print('发送验证码失败');
return null;
}

final verificationId = sendResult['verification_id'];
print('验证码发送成功! ID: $verificationId');

// 步骤2: 验证验证码
final verifyResult = await cloudbase.request(
'POST',
'/auth/v1/verification/verify',
body: {
'verification_id': verificationId,
'verification_code': verificationCode,
},
);

if (verifyResult == null) {
print('验证码错误');
return null;
}

final verificationToken = verifyResult['verification_token'];
print('验证成功!');

// 步骤3: 使用验证令牌注册
final signUpBody = {
'phone_number': phoneNumber.startsWith('+86') ? phoneNumber : '+86$phoneNumber',
'verification_token': verificationToken,
};

// 可选:添加用户名和密码
if (username != null) signUpBody['username'] = username;
if (password != null) signUpBody['password'] = password;

final signUpResult = await cloudbase.request(
'POST',
'/auth/v1/signup',
body: signUpBody,
);

if (signUpResult != null) {
final accessToken = signUpResult['access_token'];
final userId = signUpResult['sub'];

print('注册成功! 用户ID: $userId');
print('访问令牌: ${accessToken.substring(0, 20)}...');

// 更新访问令牌
cloudbase.updateAccessToken(accessToken);
return signUpResult;
}

print('注册失败');
return null;
} catch (e) {
print('注册失败: $e');
return null;
}
}

// 使用示例
void main() async {
final result = await signUpWithPhoneCode('13800138000', '123456', username: 'myusername', password: 'mypassword');
if (result != null) {
print('手机号注册成功');
}
}

云存储

import 'dart:io';
import 'package:http/http.dart' as http;
import 'cloudbase_client.dart';

Future<Map<String, dynamic>?> uploadFile(String filePath, {String? objectId}) async {
/// 上传文件到云存储
final file = File(filePath);

if (!await file.exists()) {
print('文件不存在: $filePath');
return null;
}

if (objectId == null) {
final filename = filePath.split('/').last;
final timestamp = DateTime.now().millisecondsSinceEpoch;
objectId = 'uploads/$timestamp-$filename';
}

// 1. 获取上传信息
final uploadInfo = await cloudbase.request(
'POST',
'/v1/storages/get-objects-upload-info',
body: [{'objectId': objectId}],
);

if (uploadInfo == null || uploadInfo.isEmpty) {
return null;
}

final info = uploadInfo[0];
final uploadUrl = info['uploadUrl'];

try {
// 2. 上传文件
final fileData = await file.readAsBytes();
final uploadHeaders = {
'Authorization': info['authorization'],
'X-Cos-Security-Token': info['token'],
'X-Cos-Meta-Fileid': info['cloudObjectMeta'],
};

final uploadResponse = await http.put(
Uri.parse(uploadUrl),
headers: uploadHeaders,
body: fileData,
);

if (uploadResponse.statusCode >= 200 && uploadResponse.statusCode < 300) {
final result = {
'cloudObjectId': info['cloudObjectId'],
'downloadUrl': info['downloadUrl'],
'objectId': objectId,
};

print('文件上传成功:');
print('- 对象ID: ${result['objectId']}');
print('- 下载URL: ${result['downloadUrl']}');

return result;
}

print('文件上传失败: ${uploadResponse.statusCode}');
return null;
} catch (e) {
print('文件上传失败: $e');
return null;
}
}

// 使用示例
void main() async {
final result = await uploadFile('./example.jpg');
print(result);
}

云函数

import 'cloudbase_client.dart';

Future<dynamic> callFunction(String functionName, {Map<String, dynamic>? data}) async {
/// 调用云函数
final result = await cloudbase.request('POST', '/v1/functions/$functionName', body: data ?? {});

if (result != null) {
print('云函数调用结果: $result');
}
return result;
}

// 使用示例
void main() async {
final result = await callFunction('{%FUNCTION_NAME%}');
print(result);
}

大模型

import 'dart:convert';
import 'package:http/http.dart' as http;
import 'cloudbase_client.dart';

Future<String?> streamText(String model, String subModel, List<Map<String, String>> messages) async {
/// 流式文本生成
final payload = {
'model': subModel,
'messages': messages,
'stream': true,
};

final url = '${cloudbase.baseUrl}/v1/ai/$model/chat/completions';
final headers = Map<String, String>.from(cloudbase.headers);
headers['Accept'] = 'text/event-stream';

try {
final request = http.Request('POST', Uri.parse(url));
request.headers.addAll(headers);
request.body = jsonEncode(payload);

final streamedResponse = await request.send();

if (streamedResponse.statusCode >= 200 && streamedResponse.statusCode < 300) {
print('AI 流式响应:');
String fullContent = '';

await for (var chunk in streamedResponse.stream.transform(utf8.decoder)) {
final lines = chunk.split('\n');
for (var line in lines) {
if (line.startsWith('data: ')) {
final dataStr = line.substring(6);
if (dataStr.trim() != '[DONE]') {
try {
final chunkData = jsonDecode(dataStr);
final content = chunkData['choices']?[0]?['delta']?['content'] ?? '';
if (content.isNotEmpty) {
print(content);
fullContent += content;
}
} catch (e) {
// 忽略JSON解析错误
}
}
}
}
}

return fullContent;
} else {
print('AI 调用失败: ${streamedResponse.statusCode}');
return null;
}
} catch (e) {
print('AI 调用失败: $e');
return null;
}
}

// 使用示例
void main() async {
final response = await streamText(
'{%AI_MODEL_NAME%}',
'{%AI_SUB_MODEL_NAME%}',
[
{'role': 'system', 'content': '请严格按照七言绝句或七言律诗的格律要求创作'},
{'role': 'user', 'content': '春天'}
],
);
print('\n完整回复: $response');
}