Browse Source

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

newdev_shunjiawei
liwei1dao 12 months ago
parent
commit
f6dda46d9e
  1. 1
      lib/modules/meeting/controllers/meeting_controller.dart
  2. 13
      lib/modules/meeting/controllers/meeting_home_controller.dart
  3. 84
      lib/modules/meeting/views/template/template_edit_view.dart
  4. 13
      lib/modules/translation/controllers/translation_list_controller.dart

1
lib/modules/meeting/controllers/meeting_controller.dart

@ -5,6 +5,7 @@ import '../../../data/services/db/sqflite_api.dart';
import '../views/meeting_home_view.dart'; import '../views/meeting_home_view.dart';
import '../views/meeting_mine_view.dart'; import '../views/meeting_mine_view.dart';
// 会议模块控制器
class MeetingController extends GetxController { class MeetingController extends GetxController {
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();

13
lib/modules/meeting/controllers/meeting_home_controller.dart

@ -188,8 +188,10 @@ class MeetingHomeController extends GetxController {
Directory("${appDir.path}/DestAudio/"), Directory("${appDir.path}/DestAudio/"),
]; ];
// 目标目录:LocalAudio
final destDir = Directory("${appDir.path}/LocalAudio/"); final destDir = Directory("${appDir.path}/LocalAudio/");
if (!await destDir.exists()) { if (!await destDir.exists()) {
// 检查目标目录是否存在
await destDir.create(recursive: true); await destDir.create(recursive: true);
} }
@ -335,9 +337,14 @@ class MeetingHomeController extends GetxController {
EasyLoading.show(status: 'importing'.tr); // 对应中文:正在导入... EasyLoading.show(status: 'importing'.tr); // 对应中文:正在导入...
String fileName = ""; String fileName = "";
bool isParamProvided = filePath != null; // 更清晰的变量名 bool isParamProvided = filePath != null; // 更清晰的变量名
String audioType = 'IMPORT'; // 默认类型为IMPORT
if (filePath != null) { if (filePath != null) {
// 正确截取文件名(跨平台安全方式) // 正确截取文件名(跨平台安全方式)
fileName = path.basename(filePath); fileName = path.basename(filePath);
// 检查是否来自翻译模块
if (filePath.contains('/TranslatAudio/')) {
audioType = 'TRANSLAT'; // 设置为翻译音频类型
}
} else { } else {
FilePickerResult? result = await FilePicker.platform.pickFiles( FilePickerResult? result = await FilePicker.platform.pickFiles(
withData: false, withData: false,
@ -368,7 +375,8 @@ class MeetingHomeController extends GetxController {
} }
} }
final meetingId = await insertMeetingAudio(fileName, filePath); final meetingId =
await insertMeetingAudio(fileName, filePath, type: audioType);
if (isParamProvided) { if (isParamProvided) {
Get.toNamed(Routes.meetingDetails, arguments: { Get.toNamed(Routes.meetingDetails, arguments: {
@ -382,13 +390,14 @@ class MeetingHomeController extends GetxController {
String fileName, String fileName,
String filePath, { String filePath, {
bool isUpload = true, bool isUpload = true,
String type = 'IMPORT', //添加type参数,默认为'IMPORT'
}) async { }) async {
await _audioPlayer.setAudioSource(AudioSource.file(filePath)); await _audioPlayer.setAudioSource(AudioSource.file(filePath));
int seconds = _audioPlayer.duration?.inSeconds ?? 0; int seconds = _audioPlayer.duration?.inSeconds ?? 0;
int creationTime = DateTime.now().millisecondsSinceEpoch; int creationTime = DateTime.now().millisecondsSinceEpoch;
Map<String, Object?> data = { Map<String, Object?> data = {
'title': fileName, 'title': fileName,
'type': 'IMPORT', 'type': type, // 使用传入的type参数
'seconds': seconds, 'seconds': seconds,
'filepath': filePath, 'filepath': filePath,
'audiourl': '', 'audiourl': '',

84
lib/modules/meeting/views/template/template_edit_view.dart

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
@ -5,6 +7,7 @@ import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart'; import 'package:get_storage/get_storage.dart';
import '../../../../data/services/db/sqflite_api.dart'; import '../../../../data/services/db/sqflite_api.dart';
import '../../../../data/services/deapsound_ai_service.dart';
import '../../../../data/services/network/api.dart'; import '../../../../data/services/network/api.dart';
import '../../controllers/meeting_details_controller.dart'; import '../../controllers/meeting_details_controller.dart';
@ -27,6 +30,10 @@ class _TemplateEditViewState extends State<TemplateEditView> {
bool _isEnable = false; bool _isEnable = false;
final _deapsoundAI = DeapsoundAIService();
StreamSubscription? _aiResponseSubscription;
bool _isLoading = false;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -42,6 +49,7 @@ class _TemplateEditViewState extends State<TemplateEditView> {
_nameController.dispose(); _nameController.dispose();
_descController.dispose(); _descController.dispose();
_promptController.dispose(); _promptController.dispose();
_aiResponseSubscription?.cancel();
super.dispose(); super.dispose();
} }
@ -151,15 +159,42 @@ class _TemplateEditViewState extends State<TemplateEditView> {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Padding( Row(
padding: EdgeInsets.only(left: 10.w), mainAxisAlignment: MainAxisAlignment.spaceBetween,
child: Text( children: [
title, Padding(
style: TextStyle( padding: EdgeInsets.only(left: 10.w),
fontSize: 14.sp, child: Text(
color: isDarkMode ? Colors.white60 : Colors.black87, title,
style: TextStyle(
fontSize: 14.sp,
color: isDarkMode ? Colors.white60 : Colors.black87,
),
),
), ),
), if (maxLines > 1)
GestureDetector(
onTap: () {
_generateTemplatePrompt();
},
child: Container(
width: 26.w,
height: 26.w,
margin: EdgeInsets.only(right: 10.w),
decoration: BoxDecoration(
color: _isLoading
? const Color(0xFF4C3F91)
: const Color(0xFF6A5AE0),
borderRadius: BorderRadius.circular(26.r),
),
child: Icon(
_isLoading ? Icons.pause : Icons.smart_toy,
size: 18.w,
color: Colors.white,
),
),
),
],
), ),
Container( Container(
margin: EdgeInsets.only(top: 10.w, bottom: 20.w), margin: EdgeInsets.only(top: 10.w, bottom: 20.w),
@ -293,4 +328,37 @@ class _TemplateEditViewState extends State<TemplateEditView> {
}); });
EasyLoading.dismiss(); EasyLoading.dismiss();
} }
void _generateTemplatePrompt() {
if (_isLoading ||
_nameController.text.isEmpty ||
_descController.text.isEmpty) {
return;
}
_promptController.clear();
setState(() {
_isLoading = true;
});
final responseStream = _deapsoundAI.sendMessageStream(
messages: [
{'role': 'system', 'content': '名称:${_nameController.text}'},
{'role': 'system', 'content': '描述:${_descController.text}'},
{
'role': 'user',
'content':
'请基于以上名称与描述,生成一个高质量会议总结提示词(Prompt),用于指导模型对会议记录进行结构化总结。只返回提示词文本,不要提供示例或额外解释。',
},
],
);
_aiResponseSubscription = responseStream.listen(
(chunk) {
_promptController.text += chunk;
},
onDone: () {
setState(() {
_isLoading = false;
});
},
);
}
} }

13
lib/modules/translation/controllers/translation_list_controller.dart

@ -164,8 +164,8 @@ class TranslationListController extends GetxController {
return; return;
} }
// Directory exis // 获取音频文件列表并按修改时间降序排序(最新的在最上面)
files.value = dir final audioFiles = dir
.listSync() .listSync()
.where((f) => .where((f) =>
f is File && f is File &&
@ -176,6 +176,15 @@ class TranslationListController extends GetxController {
f.path.endsWith('.mp4') || f.path.endsWith('.mp4') ||
f.path.endsWith('.mov'))) f.path.endsWith('.mov')))
.toList(); .toList();
// 按文件修改时间降序排序,最新的录音文件在最上面
audioFiles.sort((a, b) {
final aStat = a.statSync();
final bStat = b.statSync();
return bStat.modified.compareTo(aStat.modified); // 降序排序
});
files.value = audioFiles;
} catch (e) { } catch (e) {
print("Error loading files: $e"); print("Error loading files: $e");
files.value = []; // Return empty list on error files.value = []; // Return empty list on error

Loading…
Cancel
Save