From 3c1ce06236b508488d63085829ae3aeb24948b1c Mon Sep 17 00:00:00 2001 From: lxm <1274844347@qq.com> Date: Wed, 29 Oct 2025 16:35:02 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat(translation):=20=E4=B8=BA=E9=9F=B3?= =?UTF-8?q?=E9=A2=91=E6=96=87=E4=BB=B6=E5=88=97=E8=A1=A8=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=8C=89=E4=BF=AE=E6=94=B9=E6=97=B6=E9=97=B4=E9=99=8D=E5=BA=8F?= =?UTF-8?q?=E6=8E=92=E5=BA=8F=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 为翻译模块的音频文件列表添加按修改时间降序排序功能,最新的文件显示在最上方 同时为会议模块添加音频类型区分,支持识别翻译模块的音频文件 --- .../meeting/controllers/meeting_controller.dart | 1 + .../controllers/meeting_home_controller.dart | 13 +++++++++++-- .../controllers/translation_list_controller.dart | 13 +++++++++++-- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/lib/modules/meeting/controllers/meeting_controller.dart b/lib/modules/meeting/controllers/meeting_controller.dart index f5ead752e..ba3e9494d 100644 --- a/lib/modules/meeting/controllers/meeting_controller.dart +++ b/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_mine_view.dart'; +// 会议模块控制器 class MeetingController extends GetxController { final GlobalKey scaffoldKey = GlobalKey(); diff --git a/lib/modules/meeting/controllers/meeting_home_controller.dart b/lib/modules/meeting/controllers/meeting_home_controller.dart index 522661d6f..fa2d1bf02 100644 --- a/lib/modules/meeting/controllers/meeting_home_controller.dart +++ b/lib/modules/meeting/controllers/meeting_home_controller.dart @@ -188,8 +188,10 @@ class MeetingHomeController extends GetxController { Directory("${appDir.path}/DestAudio/"), ]; + // 目标目录:LocalAudio final destDir = Directory("${appDir.path}/LocalAudio/"); if (!await destDir.exists()) { + // 检查目标目录是否存在 await destDir.create(recursive: true); } @@ -335,9 +337,14 @@ class MeetingHomeController extends GetxController { EasyLoading.show(status: 'importing'.tr); // 对应中文:正在导入... String fileName = ""; bool isParamProvided = filePath != null; // 更清晰的变量名 + String audioType = 'IMPORT'; // 默认类型为IMPORT if (filePath != null) { // 正确截取文件名(跨平台安全方式) fileName = path.basename(filePath); + // 检查是否来自翻译模块 + if (filePath.contains('/TranslatAudio/')) { + audioType = 'TRANSLAT'; // 设置为翻译音频类型 + } } else { FilePickerResult? result = await FilePicker.platform.pickFiles( 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) { Get.toNamed(Routes.meetingDetails, arguments: { @@ -382,13 +390,14 @@ class MeetingHomeController extends GetxController { String fileName, String filePath, { bool isUpload = true, + String type = 'IMPORT', //添加type参数,默认为'IMPORT' }) async { await _audioPlayer.setAudioSource(AudioSource.file(filePath)); int seconds = _audioPlayer.duration?.inSeconds ?? 0; int creationTime = DateTime.now().millisecondsSinceEpoch; Map data = { 'title': fileName, - 'type': 'IMPORT', + 'type': type, // 使用传入的type参数 'seconds': seconds, 'filepath': filePath, 'audiourl': '', diff --git a/lib/modules/translation/controllers/translation_list_controller.dart b/lib/modules/translation/controllers/translation_list_controller.dart index 2d4bffc19..a908bf6c4 100644 --- a/lib/modules/translation/controllers/translation_list_controller.dart +++ b/lib/modules/translation/controllers/translation_list_controller.dart @@ -164,8 +164,8 @@ class TranslationListController extends GetxController { return; } - // Directory exis - files.value = dir + // 获取音频文件列表并按修改时间降序排序(最新的在最上面) + final audioFiles = dir .listSync() .where((f) => f is File && @@ -176,6 +176,15 @@ class TranslationListController extends GetxController { f.path.endsWith('.mp4') || f.path.endsWith('.mov'))) .toList(); + + // 按文件修改时间降序排序,最新的录音文件在最上面 + audioFiles.sort((a, b) { + final aStat = a.statSync(); + final bStat = b.statSync(); + return bStat.modified.compareTo(aStat.modified); // 降序排序 + }); + + files.value = audioFiles; } catch (e) { print("Error loading files: $e"); files.value = []; // Return empty list on error From 011977e8e351d651401aec1ec8c3049ee7eebe94 Mon Sep 17 00:00:00 2001 From: tanlongsheng <252620078@qq.com> Date: Wed, 29 Oct 2025 19:06:13 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BC=9A=E8=AE=AE?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=E6=A8=A1=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../views/template/template_edit_view.dart | 84 +++++++++++++++++-- 1 file changed, 76 insertions(+), 8 deletions(-) diff --git a/lib/modules/meeting/views/template/template_edit_view.dart b/lib/modules/meeting/views/template/template_edit_view.dart index 6c69d3596..27dc4fb5c 100644 --- a/lib/modules/meeting/views/template/template_edit_view.dart +++ b/lib/modules/meeting/views/template/template_edit_view.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:flutter/material.dart'; import 'package:flutter_easyloading/flutter_easyloading.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 '../../../../data/services/db/sqflite_api.dart'; +import '../../../../data/services/deapsound_ai_service.dart'; import '../../../../data/services/network/api.dart'; import '../../controllers/meeting_details_controller.dart'; @@ -27,6 +30,10 @@ class _TemplateEditViewState extends State { bool _isEnable = false; + final _deapsoundAI = DeapsoundAIService(); + StreamSubscription? _aiResponseSubscription; + bool _isLoading = false; + @override void initState() { super.initState(); @@ -42,6 +49,7 @@ class _TemplateEditViewState extends State { _nameController.dispose(); _descController.dispose(); _promptController.dispose(); + _aiResponseSubscription?.cancel(); super.dispose(); } @@ -151,15 +159,42 @@ class _TemplateEditViewState extends State { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Padding( - padding: EdgeInsets.only(left: 10.w), - child: Text( - title, - style: TextStyle( - fontSize: 14.sp, - color: isDarkMode ? Colors.white60 : Colors.black87, + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: EdgeInsets.only(left: 10.w), + child: Text( + 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( margin: EdgeInsets.only(top: 10.w, bottom: 20.w), @@ -293,4 +328,37 @@ class _TemplateEditViewState extends State { }); 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; + }); + }, + ); + } }