Flutter 快速开始
- AI 快速开始
- 完整开发指引
准备工作
在开始之前,请确保您已完成以下准备:
- 开通云开发环境:开通云开发环境
- 获取 API 访问凭证:在 CloudBase 控制台 获取环境 ID 和 API 密钥
Client
配置你的 AI 工具以连接 CloudBase 能力 支持本地与托管两种连接方式,详见 连接方式。
步骤 1:安装 / 配置 CloudBase
步骤 2:和 AI 对话
在 AI 对话中依次输入以下内容:
prompt
安装 CloudBase Skills:命令 npx skills add tencentcloudbase/cloudbase-skills -y使用 CloudBase Skills: 使用 CloudBase Skills:在 Flutter 应用中集成 CloudBase HTTP API准备工作
在开始之前,请确保您已完成以下准备:
- 开通云开发环境:开通云开发环境
- 获取 API 访问凭证:在 CloudBase 控制台 获取环境 ID 和 API 密钥
更多详情请参考:Flutter 完整文档
身份认证
- 短信验证码注册
- 邮箱验证码注册
- 账号密码登录
- 短信验证码登录
- 邮箱验证码登录
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 'cloudbase_client.dart';
Future<Map<String, dynamic>?> signUpWithEmailCode(String email, String verificationCode, {String? username, String? password, String? captchaToken}) async {
try {
// 步骤1: 发送邮箱验证码
final sendBody = {
'email': email,
'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 = {
'email': email,
'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 signUpWithEmailCode('user@example.com', '123456', username: 'myusername', password: 'mypassword');
if (result != null) {
print('邮箱注册成功');
}
}
import 'cloudbase_client.dart';
Future<Map<String, dynamic>?> signIn(String username, String password) async {
/// 账号密码登录
final result = await cloudbase.request(
'POST',
'/auth/v1/signin',
body: {'username': username, 'password': password},
);
if (result != null) {
final accessToken = result['access_token'];
final refreshToken = result['refresh_token'];
final userId = result['sub'];
print('登录成功! 用户ID: $userId');
print('访问令牌: ${accessToken.substring(0, 20)}...');
// 更新访问令牌
cloudbase.updateAccessToken(accessToken);
return result;
}
return null;
}
// 使用示例
void main() async {
final result = await signIn('your_username', 'your_password');
print(result);
}
import 'cloudbase_client.dart';
Future<bool> loginWithPhoneCode(String phoneNumber, String verificationCode, {String? captchaToken}) async {
try {
// 步骤1: 发送短信验证码
final sendBody = {
'phone_number': phoneNumber.startsWith('+86') ? phoneNumber : '+86$phoneNumber',
'target': 'ANY', // "ANY" - 不限制,无论用户是否存在都发送; "USER" - 账号必须存在才发送
};
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 false;
}
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 false;
}
final verificationToken = verifyResult['verification_token'];
print('验证成功!');
// 步骤3: 使用验证令牌登录
final loginResult = await cloudbase.request(
'POST',
'/auth/v1/signin',
body: {
'phone_number': phoneNumber.startsWith('+86') ? phoneNumber : '+86$phoneNumber',
'verification_token': verificationToken,
},
);
if (loginResult != null) {
final accessToken = loginResult['access_token'];
print('登录成功!');
cloudbase.updateAccessToken(accessToken);
return true;
}
print('登录失败');
return false;
} catch (e) {
print('登录失败: $e');
return false;
}
}
// 使用示例
void main() async {
final success = await loginWithPhoneCode('13800138000', '123456');
if (success) {
print('手机号登录成功');
}
}
import 'cloudbase_client.dart';
Future<bool> loginWithEmailCode(String email, String verificationCode, {String? captchaToken}) async {
try {
// 步骤1: 发送邮箱验证码
final sendBody = {
'email': email,
'target': 'ANY', // "ANY" - 不限制,无论用户是否存在都发送; "USER" - 账号必须存在才发送
};
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 false;
}
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 false;
}
final verificationToken = verifyResult['verification_token'];
print('验证成功!');
// 步骤3: 使用验证令牌登录
final loginResult = await cloudbase.request(
'POST',
'/auth/v1/signin',
body: {
'email': email,
'verification_token': verificationToken,
},
);
if (loginResult != null) {
final accessToken = loginResult['access_token'];
print('登录成功!');
cloudbase.updateAccessToken(accessToken);
return true;
}
print('登录失败');
return false;
} catch (e) {
print('登录失败: $e');
return false;
}
}
// 使用示例
void main() async {
final success = await loginWithEmailCode('user@example.com', '123456');
if (success) {
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<String?> getFileUrl(String cloudObjectId) async {
/// 获取云存储文件的临时访问链接
final result = await cloudbase.request(
'POST',
'/v1/storages/get-objects-download-info',
body: [{'cloudObjectId': cloudObjectId}],
);
if (result != null && result.isNotEmpty) {
final downloadUrl = result[0]['downloadUrl'];
print('文件链接: $downloadUrl');
return downloadUrl;
}
return null;
}
// 使用示例
void main() async {
final fileUrl = await getFileUrl('cloud://xxx.png');
print(fileUrl);
}
import 'dart:io';
import 'package:http/http.dart' as http;
import 'cloudbase_client.dart';
Future<bool> downloadFile(String cloudObjectId, {String savePath = './'}) async {
/// 下载云存储文件到本地
// 1. 获取下载链接
final result = await cloudbase.request(
'POST',
'/v1/storages/get-objects-download-info',
body: [{'cloudObjectId': cloudObjectId}],
);
if (result == null || result.isEmpty) {
return false;
}
final downloadUrl = result[0]['downloadUrl'];
try {
// 2. 从URL中提取文件名
final uri = Uri.parse(downloadUrl);
final filename = uri.pathSegments.last.split('?').first;
// 3. 确定完整路径
String fullPath;
final saveDir = Directory(savePath);
if (await saveDir.exists() || savePath.endsWith('/')) {
fullPath = '$savePath/$filename';
} else {
fullPath = savePath;
}
// 4. 下载文件
final fileResponse = await http.get(Uri.parse(downloadUrl));
if (fileResponse.statusCode >= 200 && fileResponse.statusCode < 300) {
// 5. 保存到本地
final file = File(fullPath);
await file.writeAsBytes(fileResponse.bodyBytes);
print('下载成功! 文件已保存到: $fullPath');
return true;
}
print('下载失败: ${fileResponse.statusCode}');
return false;
} catch (e) {
print('下载失败: $e');
return false;
}
}
// 使用示例
void main() async {
// 下载到当前目录,使用原文件名
await downloadFile('cloud://xxx.png');
// 下载到指定目录
await downloadFile('cloud://xxx.png', savePath: './downloads/');
// 下载并重命名
await downloadFile('cloud://xxx.png', savePath: './my-image.png');
}
import 'cloudbase_client.dart';
Future<bool> deleteFile(dynamic cloudObjectIds) async {
/// 删除云存储文件
List<String> ids;
if (cloudObjectIds is String) {
ids = [cloudObjectIds];
} else if (cloudObjectIds is List<String>) {
ids = cloudObjectIds;
} else {
print('参数类型错误');
return false;
}
final data = ids.map((id) => {'cloudObjectId': id}).toList();
final result = await cloudbase.request('POST', '/v1/storages/delete-objects', body: data);
if (result != null) {
print('删除成功!');
return true;
}
return false;
}
// 使用示例
void main() async {
final result = await deleteFile('cloud://xxx.png');
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');
}
生图模型通过调用云函数来实现,在生图模型页面点击「一键创建云函数」,函数调用示例如下:
import 'cloudbase_client.dart';
Future<Map<String, dynamic>?> generateImage(String prompt) async {
/// 调用生图云函数
final result = await cloudbase.request(
'POST',
'/v1/functions/<YOUR_FUNCTION_NAME>/invoke',
body: {
'prompt': prompt,
},
);
if (result != null) {
final success = result['success'] ?? false;
if (success) {
// 生成成功
print('生成成功!');
print('图片URL: ${result['imageUrl']}');
print('优化后的提示词: ${result['revised_prompt']}');
// 使用图片
// 注意:图片URL有效期为24小时,请及时保存或转存
return result;
} else {
// 生成失败
print('生成失败: ${result['code']} ${result['message']}');
return null;
}
}
return null;
}
// 使用示例
void main() async {
final result = await generateImage('一只可爱的猫咪在阳光下玩耍');
if (result != null) {
print('图片URL: ${result['imageUrl']}');
}
}