Browse Source

feat(meeting): 添加会议ASR任务使用统计功能

在MeetingTaskService中添加会议ASR任务的使用统计记录功能,包括任务提交和完成时的数据收集。同时在UsageStatsService中实现相关统计数据的存储和更新逻辑。
newdev_shunjiawei
lxm 11 months ago
parent
commit
134537fba4
  1. 37
      lib/data/services/meeting/meeting_task_service.dart
  2. 65
      lib/data/services/usage_stats_service.dart

37
lib/data/services/meeting/meeting_task_service.dart

@ -1,4 +1,5 @@
import 'dart:convert';
import 'dart:io';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
@ -9,6 +10,8 @@ import '../../../core/utils/synchrodata.dart';
import '../db/sqflite_api.dart';
import '../deapsound_ai_service.dart';
import 'meeting_upload_service.dart';
import '../usage_stats_service.dart';
import '../../models/meeting_usage_stats.dart';
///会议任务服务类,负责管理会议音频的转写任务处理流程,包括任务提交、状态轮询、结果处理和AI分析等功能。
class MeetingTaskService extends GetxService {
@ -117,6 +120,30 @@ class MeetingTaskService extends GetxService {
taskId = await _submitTask(audiourl, isSpeaker, language);
}
await SqfliteApi.editMeeting(id, {'tasktype': 1, 'taskid': taskId});
try {
final detail = await SqfliteApi.getMeetingDetails(id);
final seconds = (detail['seconds'] ?? 0) as int;
final filepath = (detail['filepath'] ?? '') as String;
int fileSizeBytes = 0;
if (filepath.isNotEmpty) {
try {
fileSizeBytes = await File(filepath).length();
} catch (_) {}
}
final record = MeetingAsrRecord(
id: taskId,
meetingId: id,
taskId: taskId,
audioSeconds: seconds,
fileSizeBytes: fileSizeBytes,
language: language,
submitTimestamp: DateTime.now().millisecondsSinceEpoch,
status: asrStatusProcessing,
transcriptBytes: 0,
completeTimestamp: 0,
);
Get.find<UsageStatsService>().addMeetingAsrRecord(record);
} catch (_) {}
_taskList.add({
'id': id,
'taskid': taskId,
@ -373,6 +400,16 @@ class MeetingTaskService extends GetxService {
_storage.write("meeting_task_list", _taskList);
_storage.write("meeting_task_finish_list", taskFinishList);
}
try {
final details = await SqfliteApi.getMeetingDetails(id);
final tid = (details['taskid'] ?? '') as String;
final transcriptBytes = utf8.encode(text).length;
Get.find<UsageStatsService>().completeMeetingAsrRecord(
id: tid,
transcriptBytes: transcriptBytes,
completeTimestamp: DateTime.now().millisecondsSinceEpoch,
);
} catch (_) {}
// 触发AI分析,分别请求总结和概览
aiServiceMessage(id, text, prompt, outline);

65
lib/data/services/usage_stats_service.dart

@ -2,6 +2,7 @@ import 'dart:convert';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
import '../models/translation_usage_stats.dart';
import '../models/meeting_usage_stats.dart';
import '../../core/utils/logger.dart';
import 'network/api.dart';
import '../models/goods.dart';
@ -12,6 +13,7 @@ import '../models/user_Info.dart';
class UsageStatsService extends GetxService {
static const String _storageKey = 'usage_stats';
static const String _dailyStatsKey = 'daily_translation_stats';
static const String _meetingDailyKey = 'daily_meeting_asr_stats';
final GetStorage _storage = GetStorage();
@ -67,6 +69,69 @@ class UsageStatsService extends GetxService {
return 'anonymous';
}
MeetingAsrDailyStats _loadMeetingDaily(String dateKey) {
final data = _storage.read('${_meetingDailyKey}_$dateKey');
if (data != null) {
return MeetingAsrDailyStats.fromJson(Map<String, dynamic>.from(data));
}
return MeetingAsrDailyStats(
date: dateKey, userId: getCurrentUserId(), items: []);
}
void _saveMeetingDaily(MeetingAsrDailyStats stats) {
_storage.write('${_meetingDailyKey}_${stats.date}', stats.toJson());
}
String _formatDate(DateTime d) {
final y = d.year;
final m = d.month.toString().padLeft(2, '0');
final day = d.day.toString().padLeft(2, '0');
return '$y-$m-$day';
}
void addMeetingAsrRecord(MeetingAsrRecord record) {
final dateKey = _formatDate(
DateTime.fromMillisecondsSinceEpoch(record.submitTimestamp));
final daily = _loadMeetingDaily(dateKey);
final idx = daily.items.indexWhere((e) => e.id == record.id);
if (idx >= 0) {
daily.items[idx] = record;
} else {
daily.items.add(record);
}
_saveMeetingDaily(daily);
}
void completeMeetingAsrRecord({
required String id,
required int transcriptBytes,
required int completeTimestamp,
}) {
final now = DateTime.now();
for (int i = 0; i < 3; i++) {
final dateKey = _formatDate(now.subtract(Duration(days: i)));
final daily = _loadMeetingDaily(dateKey);
final idx = daily.items.indexWhere((e) => e.id == id);
if (idx >= 0) {
final old = daily.items[idx];
daily.items[idx] = MeetingAsrRecord(
id: old.id,
meetingId: old.meetingId,
taskId: old.taskId,
audioSeconds: old.audioSeconds,
fileSizeBytes: old.fileSizeBytes,
language: old.language,
submitTimestamp: old.submitTimestamp,
status: asrStatusCompleted,
transcriptBytes: transcriptBytes,
completeTimestamp: completeTimestamp,
);
_saveMeetingDaily(daily);
return;
}
}
}
/// 记录翻译API调用
void recordTranslationApiCall({
required String sourceText,

Loading…
Cancel
Save