diff --git a/lib/core/utils/synchrodata.dart b/lib/core/utils/synchrodata.dart index 3e3148829..f43f0bdde 100644 --- a/lib/core/utils/synchrodata.dart +++ b/lib/core/utils/synchrodata.dart @@ -71,8 +71,8 @@ class Synchrodata { } } - // 获取操作记录 - static Future startSynchro() async { + // 上传操作记录 + static Future uploadOperationRecords({bool isSynchro = false}) async { if (_isSynchro) return; _isSynchro = true; if (_records.isNotEmpty || _delids.isNotEmpty) { @@ -104,7 +104,14 @@ class Synchrodata { _storage.write("operation_delids", _delids); } } - var result = await Api.getOperationRecord(); + if (isSynchro) { + await _synchrodata(); + } _isSynchro = false; } + + // 同步数据 + static Future _synchrodata() async { + var result = await Api.getOperationRecord(); + } } diff --git a/lib/modules/meeting/controllers/meeting_controller.dart b/lib/modules/meeting/controllers/meeting_controller.dart index fc7f46938..d75d9e666 100644 --- a/lib/modules/meeting/controllers/meeting_controller.dart +++ b/lib/modules/meeting/controllers/meeting_controller.dart @@ -82,7 +82,7 @@ class MeetingController extends GetxController { } void onPopInvokedWithResult(didPop, result) { - Synchrodata.startSynchro(); + Synchrodata.uploadOperationRecords(isSynchro: true); } void _onScroll() { diff --git a/lib/modules/meeting/controllers/meeting_details_controller.dart b/lib/modules/meeting/controllers/meeting_details_controller.dart index 81c4c1841..310257ef5 100644 --- a/lib/modules/meeting/controllers/meeting_details_controller.dart +++ b/lib/modules/meeting/controllers/meeting_details_controller.dart @@ -233,26 +233,65 @@ class MeetingDetailsController extends GetxController String text = ''; for (var element in textList) { if (element['speaker'].isNotEmpty) { - text += '[${element['speaker']}]:'; + text += '[${element['speaker']}]: '; } text += '${element['content']}\n'; } allText = text; } if (allText.isEmpty) return; - await _aiServiceSummary(); + _aiServiceMessage(); } - Future _aiServiceSummary() async { - String summaryText = await DeapsoundAIService().sendMessage( - messages: [ - {'role': 'system', 'content': _systemPrompt}, - {'role': 'user', 'content': allText}, - ], - ); - SqfliteApi.editMeeting(id, {'tasktype': 3, 'summary': summaryText}); + void _aiServiceMessage() { + int awaitQuantity = 0; + int verifyQuantity = 0; + String summaryText = meetingDetails.value.summary; + String overviewText = meetingDetails.value.overview; + if (summaryText.isEmpty) { + verifyQuantity++; + DeapsoundAIService().sendMessage( + messages: [ + {'role': 'system', 'content': _systemPrompt}, + {'role': 'user', 'content': allText}, + ], + ).then((value) { + awaitQuantity++; + summaryText = value; + if (awaitQuantity >= verifyQuantity) { + _aiServiceValue(summaryText, overviewText); + } + }); + } + if (overviewText.isEmpty) { + verifyQuantity++; + DeapsoundAIService().sendMessage( + messages: [ + { + 'role': 'system', + 'content': '您将扮演一名会议事件归纳专家,能准确抓住会议中事件的关键点,并每个事件只需一句话精简总结。', + }, + {'role': 'user', 'content': allText}, + ], + ).then((value) { + awaitQuantity++; + overviewText = value; + if (awaitQuantity >= verifyQuantity) { + _aiServiceValue(summaryText, overviewText); + } + }); + } + } + + void _aiServiceValue(String summaryText, String overviewText) { + SqfliteApi.editMeeting(id, { + 'tasktype': 3, + 'summary': summaryText, + 'overview': overviewText, + }); meetingDetails.value.tasktype = 3; meetingDetails.value.summary = summaryText; + meetingDetails.value.overview = overviewText; meetingDetails.refresh(); } @@ -403,7 +442,7 @@ class MeetingDetailsController extends GetxController String speaker = ''; if (element['additions'].isNotEmpty) { speaker = 'Speaker ${element['additions']['speaker']}'; - text += '[$speaker]:'; + text += '[$speaker]: '; if (!personnel.contains(speaker)) { personnel += '[$speaker] '; } diff --git a/lib/modules/meeting/views/generate_bottom_sheet.dart b/lib/modules/meeting/views/generate_bottom_sheet.dart index 1e2c8568c..81013152a 100644 --- a/lib/modules/meeting/views/generate_bottom_sheet.dart +++ b/lib/modules/meeting/views/generate_bottom_sheet.dart @@ -284,6 +284,7 @@ class _GenerateBottomSheetState extends State { Get.back(); if (widget.isSummarizeAgain) { _controller.meetingDetails.value.tasktype = 2; + _controller.meetingDetails.value.summary = ''; _controller.meetingDetails.refresh(); } _controller.summaryCreate(); diff --git a/lib/modules/meeting/views/meeting_details_view.dart b/lib/modules/meeting/views/meeting_details_view.dart index 1ab644bc3..1217d09d2 100644 --- a/lib/modules/meeting/views/meeting_details_view.dart +++ b/lib/modules/meeting/views/meeting_details_view.dart @@ -259,7 +259,7 @@ class MeetingDetailsView extends GetView { child: Obx( () => Row( children: [ - _iconItem(Icons.summarize, '概述', 0), + _iconItem(Icons.summarize, '概览', 0), _iconItem(Icons.message, '转写', 1), _iconItem(Icons.article, '总结', 2), _iconItem(Icons.lan, '思维导图', 3), @@ -279,7 +279,14 @@ class MeetingDetailsView extends GetView { controller: controller.tabController, physics: const NeverScrollableScrollPhysics(), children: [ - const OverviewTab(), + Obx( + () => controller.isLoading.value + ? const SizedBox() + : controller.meetingDetails.value.tasktype == 1 || + controller.meetingDetails.value.tasktype == 2 + ? _meetingWait('正在分析...') + : const OverviewTab(), + ), Obx( () => controller.meetingDetails.value.tasktype == 1 ? _meetingWait('正在转写...') diff --git a/lib/modules/meeting/views/more_bottom_sheet.dart b/lib/modules/meeting/views/more_bottom_sheet.dart index 38e96f967..db1a92dff 100644 --- a/lib/modules/meeting/views/more_bottom_sheet.dart +++ b/lib/modules/meeting/views/more_bottom_sheet.dart @@ -25,22 +25,24 @@ class _MoreBottomSheetState extends State { mainAxisSize: MainAxisSize.min, children: [ SizedBox(height: 10.w), - if (_detailsController.meetingDetails.value.tasktype == 3) - _shareItem(Icons.refresh, '重新总结', onTap: () { - Get.back(); - Get.bottomSheet( - const GenerateBottomSheet( - isSummarizeAgain: true, - ), - isScrollControlled: true, - backgroundColor: Colors.grey[100], - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.vertical( - top: Radius.circular(12.r), - ), - ), - ); - }), + _shareItem(Icons.refresh, '重新总结', + onTap: _detailsController.meetingDetails.value.tasktype >= 3 + ? () { + Get.back(); + Get.bottomSheet( + const GenerateBottomSheet( + isSummarizeAgain: true, + ), + isScrollControlled: true, + backgroundColor: Colors.grey[100], + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + top: Radius.circular(12.r), + ), + ), + ); + } + : null), _shareItem(Icons.delete_outline, '删除', onTap: () async { _controller.deleteMeeting( _detailsController.meetingData.value.id, @@ -65,7 +67,7 @@ class _MoreBottomSheetState extends State { padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 15.w), margin: EdgeInsets.only(bottom: 10.w), decoration: BoxDecoration( - color: Colors.white, + color: onTap != null ? Colors.white : Colors.grey[200], borderRadius: BorderRadius.circular(12.r), ), child: Row( diff --git a/lib/modules/meeting/views/overview_tab.dart b/lib/modules/meeting/views/overview_tab.dart index 7f7b6064d..8210352c7 100644 --- a/lib/modules/meeting/views/overview_tab.dart +++ b/lib/modules/meeting/views/overview_tab.dart @@ -1,12 +1,28 @@ import 'package:flutter/material.dart'; +import 'package:get/get.dart'; -class OverviewTab extends StatelessWidget { +import '../controllers/meeting_details_controller.dart'; + +class OverviewTab extends StatefulWidget { const OverviewTab({super.key}); + @override + State createState() => _OverviewTabState(); +} + +class _OverviewTabState extends State { + final _controller = Get.find(); + @override Widget build(BuildContext context) { return SingleChildScrollView( - child: Text(''), + child: Column( + children: [ + Text('概览'), + Text('AI分析识别录音中的关键事件,让你选择重要事件进行AI生成。'), + Text(_controller.meetingDetails.value.overview), + ], + ), ); } } diff --git a/lib/modules/meeting/views/share_bottom_sheet.dart b/lib/modules/meeting/views/share_bottom_sheet.dart index 31db5bc54..bc59fd5bf 100644 --- a/lib/modules/meeting/views/share_bottom_sheet.dart +++ b/lib/modules/meeting/views/share_bottom_sheet.dart @@ -11,6 +11,7 @@ import 'package:path_provider/path_provider.dart'; import 'package:share_plus/share_plus.dart'; import 'package:webview_flutter/webview_flutter.dart'; +import '../../../core/utils/synchrodata.dart'; import '../controllers/meeting_details_controller.dart'; import '../controllers/mind_map_controller.dart'; @@ -80,6 +81,7 @@ class _ShareBottomSheetState extends State { isBorder: false, onTap: () async { Get.back(); + Synchrodata.uploadOperationRecords(); final GetStorage storage = GetStorage(); String token = storage.read("logintoken") ?? ''; String userId = ''; @@ -112,61 +114,77 @@ class _ShareBottomSheetState extends State { ), ]), _box([ - _shareItem(Icons.copy, '复制转写', onTap: () { - Get.back(); - _copy(_getAllText()); - }), - _shareItem(Icons.copy, '复制总结', isBorder: false, onTap: () { - Get.back(); - _copy(_controller.meetingDetails.value.summary); - }), + _shareItem(Icons.copy, '复制转写', + onTap: _controller.meetingDetails.value.tasktype >= 2 + ? () { + Get.back(); + _copy(_getAllText()); + } + : null), + _shareItem(Icons.copy, '复制总结', + isBorder: false, + onTap: _controller.meetingDetails.value.tasktype >= 3 + ? () { + Get.back(); + _copy(_controller.meetingDetails.value.summary); + } + : null), ]), _box([ _shareItem(Icons.multitrack_audio, '导出音频', onTap: () { Get.back(); _share(_controller.meetingData.value.filepath, '分享会议音频'); }), - _shareItem(Icons.message, '导出转写', onTap: () async { - Get.back(); - final tempDir = await getTemporaryDirectory(); - final file = File( - '${tempDir.path}/${_controller.meetingData.value.title} speaker.txt'); - String allText = _getAllText(); - await file.writeAsString(allText); - _share(file.path, '分享会议转写'); - }), - _shareItem(Icons.article, '导出总结', onTap: () async { - Get.back(); - final tempDir = await getTemporaryDirectory(); - final file = File( - '${tempDir.path}/${_controller.meetingData.value.title} summary.txt'); - await file.writeAsString( - _controller.meetingDetails.value.summary); - _share(file.path, '分享会议总结'); - }), + _shareItem(Icons.message, '导出转写', + onTap: _controller.meetingDetails.value.tasktype >= 2 + ? () async { + Get.back(); + final tempDir = await getTemporaryDirectory(); + final file = File( + '${tempDir.path}/${_controller.meetingData.value.title} speaker.txt'); + String allText = _getAllText(); + await file.writeAsString(allText); + _share(file.path, '分享会议转写'); + } + : null), + _shareItem(Icons.article, '导出总结', + onTap: _controller.meetingDetails.value.tasktype >= 3 + ? () async { + Get.back(); + final tempDir = await getTemporaryDirectory(); + final file = File( + '${tempDir.path}/${_controller.meetingData.value.title} summary.txt'); + await file.writeAsString( + _controller.meetingDetails.value.summary); + _share(file.path, '分享会议总结'); + } + : null), _shareItem( Icons.lan, '导出思维导图', isBorder: false, - onTap: () { - Get.back(); - final mindMapController = Get.find(); - if (mindMapController.isWebViewReady) { - mindMapController.webViewController - .runJavaScript('captureImage()'); - } else { - mindMapController.webViewController - .setNavigationDelegate( - NavigationDelegate( - onPageFinished: (String url) { - mindMapController.isWebViewReady = true; + onTap: _controller.meetingDetails.value.tasktype >= 3 + ? () { + Get.back(); + final mindMapController = + Get.find(); + if (mindMapController.isWebViewReady) { mindMapController.webViewController .runJavaScript('captureImage()'); - }, - ), - ); - } - }, + } else { + mindMapController.webViewController + .setNavigationDelegate( + NavigationDelegate( + onPageFinished: (String url) { + mindMapController.isWebViewReady = true; + mindMapController.webViewController + .runJavaScript('captureImage()'); + }, + ), + ); + } + } + : null, ), ]), ], @@ -180,6 +198,7 @@ class _ShareBottomSheetState extends State { Widget _box(List children) { return Container( margin: EdgeInsets.only(bottom: 10.w), + clipBehavior: Clip.hardEdge, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12.r), @@ -201,6 +220,7 @@ class _ShareBottomSheetState extends State { child: Container( padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 15.w), decoration: BoxDecoration( + color: onTap != null ? null : Colors.grey[200], border: isBorder ? Border( bottom: BorderSide( diff --git a/lib/modules/translation/controllers/translation_controller.dart b/lib/modules/translation/controllers/translation_controller.dart index 0fb6d465d..77d13af1d 100644 --- a/lib/modules/translation/controllers/translation_controller.dart +++ b/lib/modules/translation/controllers/translation_controller.dart @@ -366,7 +366,7 @@ class TranslationController extends GetxController { // 发送ble系统mic和dac(音乐或者通话远端)声音 bleManager.openA2DPDecoder(); _audioSourceType = true; - isTtsEnabled.value = true; + isTtsEnabled.value = false; Logger.info('发送ble系统mic和dac(音乐或者通话远端)声音'); } else { // 开始连续语音识别