|
|
||
|---|---|---|
| .dart_tool | ||
| example | ||
| lib | ||
| .flutter-plugins-dependencies | ||
| README.md | ||
| pubspec.lock | ||
| pubspec.yaml | ||
| test_object_key.dart | ||
README.md
YX OSS
一个专注于核心功能的阿里云 OSS (Object Storage Service) Flutter 客户端库,提供纯净的文件上传下载能力。
🎯 设计理念
单一职责:本库专注于 OSS 核心操作 - 文件上传、下载和管理。故意排除了 UI 组件、图片压缩、文件选择等功能,保持简洁性和灵活性。
最小依赖:仅包含 OSS 操作的必需依赖,让您可以自由选择自己的 UI 和工具库。
✨ 核心特性
认证与配置
- 🔐 多种认证方式:静态密钥、STS临时凭证、预签名URL
- ⚙️ 动态配置:运行时配置更新和缓存
- 🔌 可插拔提供者:灵活的认证和配置提供者架构
上传与下载
- 📤 断点续传:支持大文件的断点续传,本地存储断点信息
- 🧩 分片上传:大文件自动分片处理,支持并发上传
- 📊 进度监控:实时上传下载进度跟踪
- ⚡ 预签名URL:支持客户端直接上传,服务端控制权限
可靠性与错误处理
- 🔄 重试机制:指数退避重试失败操作
- 🛡️ 类型安全错误处理:完整的错误类型和处理
- ❌ 取消支持:可取消正在进行的操作
- 📝 统一日志:可配置的日志系统,支持自定义处理器
架构特点
- 🎯 零耦合:不依赖特定项目架构
- 📱 跨平台:支持 iOS、Android、Web、Desktop
- 🏗️ 清洁架构:依赖注入和关注点分离
- 🔧 项目集成:提供现成的项目集成适配器
🚀 快速开始
安装
在你的 pubspec.yaml 文件中添加依赖:
dependencies:
yx_oss: ^1.0.0
然后运行:
flutter pub get
基础用法
import 'package:yx_oss/yx_oss.dart';
// 1. 创建认证提供者
final authProvider = StaticAuthProvider(
accessKeyId: 'your_access_key_id',
accessKeySecret: 'your_access_key_secret',
);
// 2. 创建配置提供者
final configProvider = StaticConfigProvider(
endpoint: 'oss-cn-hangzhou.aliyuncs.com',
bucketName: 'your-bucket-name',
directory: 'uploads',
);
// 3. 创建客户端配置
final config = YxOSSConfig(
authProvider: authProvider,
configProvider: configProvider,
logConfig: LogConfig(
enabled: true,
level: LogLevel.info,
logError: true,
),
);
// 4. 创建OSS客户端
final client = YxOSSClient(config);
// 5. 初始化客户端
await client.initialize();
// 6. 上传文件
final fileData = Uint8List.fromList('Hello, World!'.codeUnits);
final result = await client.uploadBytes(
fileData,
'my-file.txt',
options: UploadOptions(
callbacks: UploadCallbacks(
onProgress: (sent, total) {
print('进度: ${(sent / total * 100).toStringAsFixed(1)}%');
},
onSuccess: (result) {
print('上传成功: ${result.url}');
},
),
),
);
// 7. 释放资源
client.dispose();
📖 详细文档
认证方式
1. 静态认证 (Static Authentication)
适用于开发测试环境或简单应用场景:
final authProvider = StaticAuthProvider(
accessKeyId: 'your_access_key_id',
accessKeySecret: 'your_access_key_secret',
);
2. STS临时凭证 (STS Authentication)
适用于生产环境,提供更安全的权限控制:
// 从服务器获取STS凭证的函数
Future<STSCredentials> getSTSCredentials() async {
// 调用你的后端API获取STS凭证
final response = await http.get('/api/sts-credentials');
return STSCredentials.fromJson(response.data);
}
final authProvider = STSAuthProvider(
accessKeyId: stsCredentials.accessKeyId,
accessKeySecret: stsCredentials.accessKeySecret,
securityToken: stsCredentials.securityToken,
expiration: stsCredentials.expiration,
credentialsGetter: getSTSCredentials, // 自动刷新过期凭证
);
3. 项目集成认证 (Project Integration)
适用于现有项目集成,从后端API获取配置:
// 使用项目集成适配器
final manager = ProjectOSSManager(myApiImpl);
await manager.initialize();
// 直接使用,自动处理认证和配置
final fileUrl = await manager.uploadFile(
filePath,
onProgress: (sent, total) => print('进度: $sent/$total'),
type: 1, // 文件类型
);
配置管理
1. 静态配置 (Static Configuration)
final configProvider = StaticConfigProvider(
endpoint: 'oss-cn-hangzhou.aliyuncs.com',
bucketName: 'your-bucket-name',
directory: 'uploads',
domain: 'https://your-custom-domain.com', // 可选
);
2. 动态配置 (Dynamic Configuration)
支持从服务器动态获取配置,适用于多环境部署:
final configProvider = DynamicConfigProvider(
configGetter: () async {
final response = await http.get('/api/oss-config');
return OSSConfig.fromJson(response.data);
},
cacheTimeout: const Duration(hours: 1), // 配置缓存时间
);
日志配置
新增统一的日志系统,支持级别控制和自定义处理器:
final config = YxOSSConfig(
authProvider: authProvider,
configProvider: configProvider,
logConfig: LogConfig(
enabled: true,
level: LogLevel.warning, // 只记录警告及以上级别
logRequest: false, // 是否记录HTTP请求
logResponse: false, // 是否记录HTTP响应
logError: true, // 是否记录错误
customHandler: (message, level) {
// 自定义日志处理,可接入你的日志系统
myLogger.log(level.name, message);
},
),
);
上传选项
final options = UploadOptions(
// 基础选项
overwrite: true, // 是否覆盖同名文件
contentType: 'image/jpeg', // 文件MIME类型
enableResume: true, // 启用断点续传
// 访问控制
acl: ACLMode.publicRead, // 访问权限
storageClass: StorageClass.standard, // 存储类型
// 自定义元数据
metadata: {
'author': 'YX OSS',
'version': '1.0.0',
},
// 分片上传配置
enableMultipart: true, // 启用分片上传
partSize: 10 * 1024 * 1024, // 分片大小 (10MB)
multipartThreshold: 100 * 1024 * 1024, // 分片阈值 (100MB)
concurrency: 3, // 并发上传数
// 回调函数
callbacks: UploadCallbacks(
onStart: () => print('开始上传'),
onProgress: (sent, total) {
final progress = (sent / total * 100).toStringAsFixed(1);
print('上传进度: $progress%');
},
onSuccess: (result) => print('上传成功: ${result.url}'),
onError: (error) => print('上传失败: ${error.message}'),
onComplete: () => print('上传完成'),
),
);
断点续传
支持大文件的断点续传功能:
// 启用断点续传的上传
final result = await client.uploadFile(
largeFilePath,
options: UploadOptions(
enableResume: true,
callbacks: UploadCallbacks(
onProgress: (sent, total) {
print('断点续传进度: ${(sent/total*100).toInt()}%');
},
),
),
);
// 获取可恢复的上传任务
final resumableTasks = await client.getResumableTasks();
for (final task in resumableTasks) {
print('可恢复任务: ${task.objectKey}, 进度: ${task.uploadedSize}/${task.totalSize}');
}
// 恢复指定任务
final resumeResult = await client.resumeUpload(taskId);
// 清理过期的断点续传数据
await client.cleanupExpiredData(maxAgeDays: 7);
错误处理
库提供了完整的错误类型定义:
try {
final result = await client.uploadBytes(data, 'file.txt');
print('上传成功: ${result.url}');
} catch (e) {
if (e is OSSError) {
switch (e.type) {
case OSSErrorType.network:
print('网络错误: ${e.message}');
break;
case OSSErrorType.authentication:
print('认证错误: ${e.message}');
break;
case OSSErrorType.permission:
print('权限错误: ${e.message}');
break;
case OSSErrorType.server:
print('服务器错误: ${e.message}');
break;
default:
print('其他错误: ${e.message}');
}
// 检查是否可重试
if (e.isRetryable) {
print('此错误可以重试');
}
}
}
🔧 高级配置
完整配置示例
final config = YxOSSConfig(
authProvider: authProvider,
configProvider: configProvider,
// 超时配置
timeoutConfig: TimeoutConfig(
connectTimeout: 30000, // 30秒连接超时
sendTimeout: 600000, // 10分钟发送超时
receiveTimeout: 600000, // 10分钟接收超时
),
// 重试配置
retryConfig: RetryConfig(
maxRetries: 5, // 最多重试5次
initialInterval: 500, // 初始间隔500ms
backoffMultiplier: 2.0, // 指数退避因子
maxInterval: 30000, // 最大间隔30秒
enableExponentialBackoff: true, // 启用指数退避
),
// 日志配置
logConfig: LogConfig(
enabled: true,
level: LogLevel.debug,
logRequest: true, // 记录请求详情
logResponse: true, // 记录响应详情
logError: true, // 记录错误详情
customHandler: (message, level) {
// 自定义日志处理
print('[YX_OSS] ${level.name.toUpperCase()}: $message');
},
),
);
🏗️ 项目集成
使用项目集成适配器
库提供了现成的项目集成适配器,可以快速集成到现有项目中:
// 1. 实现服务器API接口
class MyOSSApiImpl implements YxOssServerInterface {
@override
Future<YxOSSConfigModel> getOssConfig() async {
// 从你的后端获取OSS配置
final response = await http.get('/api/oss-config');
return YxOSSConfigModel.fromJson(response.data);
}
@override
Future<YxOSSSignModel> getOssSign({String? objectName, int? type}) async {
// 从你的后端获取预签名URL
final response = await http.post('/api/oss-sign', {
'objectName': objectName,
'type': type,
});
return YxOSSSignModel.fromJson(response.data);
}
@override
Future<bool> deleteOSSFile({required String filePath}) async {
// 删除文件
final response = await http.delete('/api/oss-file', {
'filePath': filePath,
});
return response.statusCode == 200;
}
}
// 2. 使用项目集成管理器
final ossManager = ProjectOSSManager(MyOSSApiImpl());
await ossManager.initialize();
// 3. 上传文件(自动使用预签名URL)
final fileUrl = await ossManager.uploadFile(
filePath,
onProgress: (sent, total) {
print('上传进度: ${(sent/total*100).toInt()}%');
},
type: 1, // 文件类型:1-普通上传,2-资料收集等
);
// 4. 上传字节数组
final fileUrl = await ossManager.uploadBytes(
fileBytes,
'example.jpg',
onProgress: (sent, total) => print('进度: $sent/$total'),
type: 1,
);
// 5. 删除文件
final success = await ossManager.deleteFile(fileUrl);
// 6. 断点续传相关
final tasks = await ossManager.getResumableTasks();
final resumeResult = await ossManager.resumeUpload(taskId);
await ossManager.cleanupExpiredData(maxAgeDays: 7);
集成到应用生命周期
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late final ProjectOSSManager ossManager;
@override
void initState() {
super.initState();
ossManager = ProjectOSSManager(MyOSSApiImpl());
}
Future<void> initializeOSS() async {
try {
await ossManager.initialize();
print('OSS初始化成功');
} catch (e) {
print('OSS初始化失败: $e');
}
}
@override
void dispose() {
ossManager.dispose();
super.dispose();
}
// ... 其他代码
}
🌍 区域支持
库内置了常用的阿里云OSS区域配置:
// 中国大陆区域
CommonRegions.hangzhou // 华东1 (杭州)
CommonRegions.beijing // 华北2 (北京)
CommonRegions.shanghai // 华东2 (上海)
CommonRegions.shenzhen // 华南1 (深圳)
CommonRegions.chengdu // 西南1 (成都)
// 海外区域
CommonRegions.singapore // 亚太东南1 (新加坡)
CommonRegions.sydney // 亚太东南2 (悉尼)
CommonRegions.tokyo // 亚太东北1 (东京)
CommonRegions.virginia // 美国东部1 (弗吉尼亚)
CommonRegions.london // 欧洲西部1 (伦敦)
🔄 迁移指南
从Legacy OSS迁移
如果你正在从现有的OSS实现迁移到YX OSS:
原项目代码
// 原项目可能是这样的
final ossClient = AliyunOssClientUtils();
await ossClient.uploadFile(file, fileName);
YX OSS代码
// 迁移到YX OSS - 使用项目集成适配器
final ossManager = ProjectOSSManager(apiImpl);
await ossManager.initialize();
final fileUrl = await ossManager.uploadFile(filePath);
迁移优势
- 解耦合: YX OSS是完全独立的库,不依赖项目特定的代码
- 更好的错误处理: 类型安全的错误处理机制
- 断点续传: 完整的断点续传支持
- 灵活配置: 支持多种认证和配置方式
- 统一日志: 可配置的日志系统
- 更好的测试: 所有组件都可以独立测试
📚 API文档
核心类
YxOSSClient- OSS客户端主类YxOSSConfig- 客户端配置ProjectOSSManager- 项目集成管理器
接口
AuthProvider- 认证提供者接口ConfigProvider- 配置提供者接口ResumeStorage- 断点续传存储接口YxOssServerInterface- 服务器API接口
模型
UploadOptions- 上传选项UploadResult- 上传结果OSSError- 错误类型
工具
YxOSSFileUtils- 文件工具类OssLogger- 日志工具
🧪 测试
// 运行测试
flutter test
// 运行集成测试
flutter test integration_test/
开发环境设置
- Fork 项目
- 创建功能分支
- 提交更改
- 创建 Pull Request
📈 更新日志
v1.0.0
- ✅ 核心OSS上传下载功能
- ✅ 多种认证方式支持
- ✅ 断点续传功能
- ✅ 项目集成适配器
- ✅ 统一日志系统
- ✅ 完整的错误处理
- ✅ 类型安全的API设计
YX OSS - 让 Flutter OSS 上传更简单、更可靠! 🚀