Browse Source

Merge branch 'new_dev' of https://github.com/deepcloud2048/deep_voice into new_dev

newdev_shunjiawei
lxm 1 year ago
parent
commit
5c3145b95c
  1. 13
      lib/core/utils/synchrodata.dart
  2. 2
      lib/modules/meeting/controllers/meeting_controller.dart
  3. 61
      lib/modules/meeting/controllers/meeting_details_controller.dart
  4. 1
      lib/modules/meeting/views/generate_bottom_sheet.dart
  5. 11
      lib/modules/meeting/views/meeting_details_view.dart
  6. 36
      lib/modules/meeting/views/more_bottom_sheet.dart
  7. 20
      lib/modules/meeting/views/overview_tab.dart
  8. 106
      lib/modules/meeting/views/share_bottom_sheet.dart
  9. 2
      lib/modules/translation/controllers/translation_controller.dart

13
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();
}
}

2
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() {

61
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<void> _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] ';
}

1
lib/modules/meeting/views/generate_bottom_sheet.dart

@ -284,6 +284,7 @@ class _GenerateBottomSheetState extends State<GenerateBottomSheet> {
Get.back();
if (widget.isSummarizeAgain) {
_controller.meetingDetails.value.tasktype = 2;
_controller.meetingDetails.value.summary = '';
_controller.meetingDetails.refresh();
}
_controller.summaryCreate();

11
lib/modules/meeting/views/meeting_details_view.dart

@ -259,7 +259,7 @@ class MeetingDetailsView extends GetView<MeetingDetailsController> {
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<MeetingDetailsController> {
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('正在转写...')

36
lib/modules/meeting/views/more_bottom_sheet.dart

@ -25,22 +25,24 @@ class _MoreBottomSheetState extends State<MoreBottomSheet> {
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<MoreBottomSheet> {
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(

20
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<OverviewTab> createState() => _OverviewTabState();
}
class _OverviewTabState extends State<OverviewTab> {
final _controller = Get.find<MeetingDetailsController>();
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Text(''),
child: Column(
children: [
Text('概览'),
Text('AI分析识别录音中的关键事件,让你选择重要事件进行AI生成。'),
Text(_controller.meetingDetails.value.overview),
],
),
);
}
}

106
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<ShareBottomSheet> {
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<ShareBottomSheet> {
),
]),
_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<MindMapController>();
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<MindMapController>();
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<ShareBottomSheet> {
Widget _box(List<Widget> 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<ShareBottomSheet> {
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(

2
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 {
// 开始连续语音识别

Loading…
Cancel
Save