You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

157 lines
4.5 KiB

import 'dart:io';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
import '../../../core/utils/logger.dart';
import '../../../core/utils/upload_oss.dart';
import '../network/api.dart';
import '../usage_stats_service.dart';
import '../db/sqflite_api.dart';
import 'meeting_task_service.dart';
/// 管理会议音频文件上传服务
class MeetingUploadService extends GetxService {
final _taskService = Get.find<MeetingTaskService>();
final GetStorage _storage = GetStorage();
RxInt meetingId = 0.obs;
RxDouble uploadProgress = 0.0.obs;
RxList uploadList = [].obs;
bool _isUpload = false;
int _handled = 0; //队列处理指针,表示当前循环语句处理的任务数量
@override
void onInit() {
super.onInit();
_getUploadList();
}
void cancelUpload() {
_isUpload = false;
_handled = 0;
uploadList.clear();
_storage.remove("meeting_upload_list");
}
void _getUploadList() {
uploadList.value = _storage.read("meeting_upload_list") ?? [];
executeUpload();
}
/// 添加待上传的音频文件
void addUpload(
int id,
String filePath,
String rootDir, {
bool isUpload = true,
}) async {
int fileSize = 0;
try {
fileSize = await File(filePath).length();
} catch (_) {}
uploadList.add({
'id': id,
'filepath': filePath,
'rootdir': rootDir,
'audiourl': '',
'isTask': false,
'formlanguage': '',
'tolanguage': '',
'isdistinguishspeaker': true,
'templateid': 0,
'fileSizeBytes': fileSize,
});
_storage.write("meeting_upload_list", uploadList);
if (isUpload) {
executeUpload();
}
}
void executeUpload() async {
if (_isUpload) return;
_isUpload = true;
_handled = 0;
while (_handled < uploadList.length) {
Map element = uploadList[_handled];
_handled++;
if (element['audiourl'].isEmpty) {
meetingId.value = element['id'];
try {
int totalProgress = 0;
final audiourl = await UploadOss.upload(
filepath: element['filepath'],
rootDir: element['rootdir'],
onSendProgress: (int count, int total) {
// uploadProgress.value = count / total;
totalProgress = total;
uploadProgress.value = total > 0 ? count / total : 0.0;
},
);
await Api.upRecordEchomeet({
'id': element['id'],
'audiourl': audiourl,
});
await SqfliteApi.editMeetingTitle(
element['id'],
{'audiourl': audiourl},
);
try {
// 记录对象存储用量
final svc = Get.isRegistered<UsageStatsService>()
? Get.find<UsageStatsService>()
: Get.put(UsageStatsService(), permanent: true);
int fileSizeBytes = 0;
try {
fileSizeBytes = element['fileSizeBytes'] ?? 0;
} catch (_) {}
final transferred =
totalProgress > 0 ? totalProgress : fileSizeBytes;
svc.recordMeetingObjectStorage(
meetingId: element['id'],
storageUrl: audiourl,
storageBytes: fileSizeBytes,
transferBytes: transferred,
uploadTimestamp: DateTime.now().millisecondsSinceEpoch,
);
} catch (e) {
Logger.w('MeetingOSrecord', '对象存储用量记录失败: $e');
}
if (element['isTask']) {
await _taskService.submitTask(
element['id'],
element['formlanguage'],
element['tolanguage'],
element['isdistinguishspeaker'],
element['templateid'],
);
}
element['audiourl'] = audiourl;
uploadProgress.value = 0.0;
_storage.write("meeting_upload_list", uploadList);
} catch (e) {
Logger.error('Upload failed: $e');
}
}
}
meetingId.value = 0;
_isUpload = false;
}
void removeUpload(int id, {bool isDeleteTask = false}) {
Map uploadData = uploadList.firstWhere(
(element) => element['id'] == id,
orElse: () => {},
);
if (uploadData.isNotEmpty) {
if (isDeleteTask || uploadData['audiourl'].isNotEmpty) {
uploadList.remove(uploadData);
_storage.write("meeting_upload_list", uploadList);
if (uploadList.isEmpty) {
_handled = 0;
}
}
}
}
}