This commit is contained in:
macbook_max
2026-10-15 20:36:59 +08:00
commit 6bf949949c
7923 changed files with 1369582 additions and 0 deletions
+145
View File
@@ -0,0 +1,145 @@
import 'package:dio/dio.dart';
import '../core/network/api_client.dart';
import '../core/network/endpoints.dart';
/// 上传发布服务(《03-接口文档》5.5 / 5.6 / 5.8)
/// 开发环境链路:upload/token(server 中转模式)→ upload/file(multipart)→ 发布
class UploadService {
UploadService._();
/// 5.8 分类列表(发布时选择)
static Future<List<VideoCategory>> fetchCategories() async {
final data = await ApiClient.get<List<dynamic>>(Endpoints.categories);
return data
.whereType<Map<String, dynamic>>()
.map(VideoCategory.fromJson)
.toList();
}
/// 5.5 获取上传凭证(开发环境返回 server 中转模式)
static Future<UploadTokenInfo> fetchUploadToken({
required String fileName,
required int fileSize,
}) async {
final data = await ApiClient.post<Map<String, dynamic>>(
Endpoints.uploadToken,
data: {'file_name': fileName, 'file_size': fileSize},
);
return UploadTokenInfo.fromJson(data);
}
/// 5.5 配套:multipart 中转上传(字段 object_key + file)
static Future<UploadFileResult> uploadFile({
required String objectKey,
required String filePath,
required String fileName,
void Function(int sent, int total)? onProgress,
}) async {
final data = await ApiClient.post<Map<String, dynamic>>(
Endpoints.uploadFile,
data: FormData.fromMap({
'object_key': objectKey,
'file': await MultipartFile.fromFile(filePath, filename: fileName),
}),
onSendProgress: onProgress,
);
return UploadFileResult.fromJson(data);
}
/// 5.6 发布视频
static Future<PublishResult> publish({
required String objectKey,
required String title,
String description = '',
required int categoryId,
List<String> tags = const [],
}) async {
final data = await ApiClient.post<Map<String, dynamic>>(
Endpoints.publish,
data: {
'object_key': objectKey,
'title': title,
'description': description,
'category_id': categoryId,
'tags': tags,
},
);
return PublishResult.fromJson(data);
}
}
/// 视频分类
class VideoCategory {
VideoCategory({required this.categoryId, required this.name});
final int categoryId;
final String name;
factory VideoCategory.fromJson(Map<String, dynamic> json) => VideoCategory(
categoryId: (json['category_id'] as num?)?.toInt() ?? 0,
name: (json['name'] as String?) ?? '',
);
}
/// 上传凭证(server 中转模式)
class UploadTokenInfo {
UploadTokenInfo({
required this.uploadType,
required this.objectKey,
required this.uploadUrl,
});
final String uploadType; // server / oss_sts
final String objectKey;
final String uploadUrl;
factory UploadTokenInfo.fromJson(Map<String, dynamic> json) =>
UploadTokenInfo(
uploadType: (json['upload_type'] as String?) ?? '',
objectKey: (json['object_key'] as String?) ?? '',
uploadUrl: (json['upload_url'] as String?) ?? '',
);
}
/// 中转上传结果
class UploadFileResult {
UploadFileResult({
required this.objectKey,
required this.url,
required this.fileSize,
});
final String objectKey;
final String url;
final int fileSize;
factory UploadFileResult.fromJson(Map<String, dynamic> json) =>
UploadFileResult(
objectKey: (json['object_key'] as String?) ?? '',
url: (json['url'] as String?) ?? '',
fileSize: (json['file_size'] as num?)?.toInt() ?? 0,
);
}
/// 发布结果
class PublishResult {
PublishResult({
required this.videoId,
required this.status,
required this.statusText,
required this.isPriority,
});
final int videoId;
final int status; // 0转码中 1待审核 2已发布 3拒绝 4下架 5转码失败
final String statusText;
final bool isPriority; // 会员优先转码
factory PublishResult.fromJson(Map<String, dynamic> json) => PublishResult(
videoId: (json['video_id'] as num?)?.toInt() ?? 0,
status: (json['status'] as num?)?.toInt() ?? 0,
statusText: (json['status_text'] as String?) ?? '',
isPriority: (json['is_priority'] as bool?) ?? false,
);
}