151 lines
3.4 KiB
Dart
151 lines
3.4 KiB
Dart
/// OSS配置提供者接口
|
||
///
|
||
/// 定义获取OSS配置信息的标准接口,支持动态配置和静态配置
|
||
abstract class ConfigProvider {
|
||
/// 获取OSS端点
|
||
Future<String> getEndpoint();
|
||
|
||
/// 获取存储桶名称
|
||
Future<String> getBucketName();
|
||
|
||
/// 获取上传目录前缀
|
||
Future<String> getDirectory();
|
||
|
||
/// 获取访问域名
|
||
/// 如果为null,则使用默认的 https://{bucket}.{endpoint}
|
||
Future<String?> getDomain();
|
||
|
||
/// 获取配置信息是否有效
|
||
Future<bool> isValid();
|
||
|
||
/// 刷新配置信息
|
||
Future<void> refresh();
|
||
}
|
||
|
||
/// 静态配置提供者
|
||
/// 使用固定的配置信息
|
||
class StaticConfigProvider implements ConfigProvider {
|
||
final String endpoint;
|
||
final String bucketName;
|
||
final String directory;
|
||
final String? domain;
|
||
|
||
const StaticConfigProvider({
|
||
required this.endpoint,
|
||
required this.bucketName,
|
||
this.directory = 'uploads',
|
||
this.domain,
|
||
});
|
||
|
||
@override
|
||
Future<String> getEndpoint() async => endpoint;
|
||
|
||
@override
|
||
Future<String> getBucketName() async => bucketName;
|
||
|
||
@override
|
||
Future<String> getDirectory() async => directory;
|
||
|
||
@override
|
||
Future<String?> getDomain() async => domain;
|
||
|
||
@override
|
||
Future<bool> isValid() async => true;
|
||
|
||
@override
|
||
Future<void> refresh() async {
|
||
// 静态配置不需要刷新
|
||
}
|
||
}
|
||
|
||
/// 动态配置提供者
|
||
/// 支持从服务端动态获取配置信息
|
||
class DynamicConfigProvider implements ConfigProvider {
|
||
OSSConfig? _config;
|
||
DateTime? _lastUpdate;
|
||
final Duration _cacheTimeout;
|
||
final Future<OSSConfig> Function() _configGetter;
|
||
|
||
DynamicConfigProvider({
|
||
required Future<OSSConfig> Function() configGetter,
|
||
Duration cacheTimeout = const Duration(hours: 1),
|
||
}) : _configGetter = configGetter,
|
||
_cacheTimeout = cacheTimeout;
|
||
|
||
@override
|
||
Future<String> getEndpoint() async {
|
||
await _ensureConfig();
|
||
return _config!.endpoint;
|
||
}
|
||
|
||
@override
|
||
Future<String> getBucketName() async {
|
||
await _ensureConfig();
|
||
return _config!.bucketName;
|
||
}
|
||
|
||
@override
|
||
Future<String> getDirectory() async {
|
||
await _ensureConfig();
|
||
return _config!.directory;
|
||
}
|
||
|
||
@override
|
||
Future<String?> getDomain() async {
|
||
await _ensureConfig();
|
||
return _config!.domain;
|
||
}
|
||
|
||
@override
|
||
Future<bool> isValid() async {
|
||
if (_config == null || _lastUpdate == null) return false;
|
||
return DateTime.now().difference(_lastUpdate!) < _cacheTimeout;
|
||
}
|
||
|
||
@override
|
||
Future<void> refresh() async {
|
||
_config = await _configGetter();
|
||
_lastUpdate = DateTime.now();
|
||
}
|
||
|
||
/// 确保配置信息有效
|
||
Future<void> _ensureConfig() async {
|
||
if (!await isValid()) {
|
||
await refresh();
|
||
}
|
||
}
|
||
}
|
||
|
||
/// OSS配置模型
|
||
class OSSConfig {
|
||
final String endpoint;
|
||
final String bucketName;
|
||
final String directory;
|
||
final String? domain;
|
||
|
||
const OSSConfig({
|
||
required this.endpoint,
|
||
required this.bucketName,
|
||
this.directory = 'uploads',
|
||
this.domain,
|
||
});
|
||
|
||
factory OSSConfig.fromJson(Map<String, dynamic> json) {
|
||
return OSSConfig(
|
||
endpoint: json['endpoint'] as String,
|
||
bucketName: json['bucketName'] as String,
|
||
directory: json['directory'] as String? ?? 'uploads',
|
||
domain: json['domain'] as String?,
|
||
);
|
||
}
|
||
|
||
Map<String, dynamic> toJson() {
|
||
return {
|
||
'endpoint': endpoint,
|
||
'bucketName': bucketName,
|
||
'directory': directory,
|
||
if (domain != null) 'domain': domain,
|
||
};
|
||
}
|
||
}
|