From fa387b90ce3aee0370943fcba8f5e85e38b99ff4 Mon Sep 17 00:00:00 2001 From: tanlongsheng <252620078@qq.com> Date: Mon, 7 Jul 2025 20:26:56 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8B=E8=BD=BDftp=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../meeting_connect_controller.dart | 50 +++++++++++++++++-- .../controllers/meeting_controller.dart | 26 +++++----- .../meeting/views/meeting_connect_view.dart | 23 +++++++++ 3 files changed, 84 insertions(+), 15 deletions(-) diff --git a/lib/modules/meeting/controllers/meeting_connect_controller.dart b/lib/modules/meeting/controllers/meeting_connect_controller.dart index 78029afec..26acb44c1 100644 --- a/lib/modules/meeting/controllers/meeting_connect_controller.dart +++ b/lib/modules/meeting/controllers/meeting_connect_controller.dart @@ -1,12 +1,17 @@ import 'dart:async'; +import 'dart:io'; import 'package:flutter_blue_plus/flutter_blue_plus.dart'; import 'package:get/get.dart'; +import 'package:path_provider/path_provider.dart'; import 'package:wifi_iot/wifi_iot.dart'; import '../../../core/utils/ftpconnect/ftpconnect.dart'; +import 'meeting_controller.dart'; class MeetingConnectController extends GetxController { + final _meetingController = Get.find(); + RxString stateStr = '搜索中...'.obs; RxBool isRescan = false.obs; RxBool isImportedFiles = false.obs; @@ -30,6 +35,11 @@ class MeetingConnectController extends GetxController { FTPConnect? _ftpConnect; + RxBool isDownload = false.obs; + RxDouble downloadProgress = 0.0.obs; + RxInt totalReceived = 0.obs; + RxInt fileSize = 0.obs; + @override void onInit() { super.onInit(); @@ -208,10 +218,44 @@ class MeetingConnectController extends GetxController { ); await _ftpConnect?.connect(); _ftpConnect?.listCommand = ListCommand.LIST; - List? _listDirectory = - await _ftpConnect?.listDirectoryContent(); - print(_listDirectory); + List? listDirectory = await _ftpConnect?.listDirectoryContent(); + if (listDirectory != null && listDirectory.isNotEmpty) { + isDownload.value = true; + int totalSize = listDirectory.fold( + 0, + (sum, entry) => sum + (entry.size ?? 0), + ); + for (var i = 0; i < listDirectory.length; i++) { + stateStr.value = '共${listDirectory.length}个文件,正在下载第${i + 1}个文件...'; + int previousSize = i > 0 ? listDirectory[i - 1].size ?? 0 : 0; + FTPEntry element = listDirectory[i]; + await _downloadFile(totalSize, previousSize, element); + } + stateStr.value = '下载完成,共${listDirectory.length}个文件'; + _disconnect(); + } + } + } + + Future _downloadFile( + int totalSize, int previousSize, FTPEntry entry) async { + final directory = await getApplicationDocumentsDirectory(); + final directoryDir = Directory('${directory.path}/RecordingPen'); + if (!await directoryDir.exists()) { + await directoryDir.create(recursive: true); } + final String filePath = '${directory.path}/RecordingPen/${entry.name}'; + final File localFile = File(filePath); + await _ftpConnect?.downloadFileWithRetry( + entry.name, + localFile, + onProgress: (double progress, int received, int size) { + downloadProgress.value = (previousSize + received) / totalSize; + totalReceived.value = received; + fileSize.value = size; + }, + ); + await _meetingController.insertMeetingAudio(entry.name, filePath, ''); } String _decodePassword(List data) { diff --git a/lib/modules/meeting/controllers/meeting_controller.dart b/lib/modules/meeting/controllers/meeting_controller.dart index b9767ee74..de9a05a63 100644 --- a/lib/modules/meeting/controllers/meeting_controller.dart +++ b/lib/modules/meeting/controllers/meeting_controller.dart @@ -190,13 +190,11 @@ class MeetingController extends GetxController { int addUp = 0; final appDir = await appDocDir; -// 定义源目录列表 final sourceDirs = [ Directory("${appDir.path}/MeetingAudio/"), Directory("${appDir.path}/DestAudio/"), ]; -// 创建目标目录(如果不存在) final destDir = Directory("${appDir.path}/LocalAudio/"); if (!await destDir.exists()) { await destDir.create(recursive: true); @@ -212,8 +210,6 @@ class MeetingController extends GetxController { } } -// 此时 allFiles 包含 MeetingAudio 和 DestAudio 目录下所有的文件 - for (final fileEntity in allFiles) { try { final file = File(fileEntity.path); @@ -334,9 +330,21 @@ class MeetingController extends GetxController { } } - await _audioPlayer.setAudioSource(AudioSource.file(filePath!)); var audiourl = await UploadOss.upload(filepath: filePath, rootDir: 'ExternalAudio'); + final meetingId = await insertMeetingAudio(fileName, filePath, audiourl); + + if (isParamProvided) { + Get.toNamed(Routes.meetingDetails, arguments: { + 'id': meetingId, + }); + } + EasyLoading.dismiss(); + } + + Future insertMeetingAudio( + String fileName, String filePath, String audiourl) async { + await _audioPlayer.setAudioSource(AudioSource.file(filePath)); int seconds = _audioPlayer.duration?.inSeconds ?? 0; int creationTime = DateTime.now().millisecondsSinceEpoch; Map data = { @@ -357,13 +365,7 @@ class MeetingController extends GetxController { }); addQuantity++; } - - if (isParamProvided) { - Get.toNamed(Routes.meetingDetails, arguments: { - 'id': meetingId, - }); - } - EasyLoading.dismiss(); + return meetingId; } Future _saveFile(PlatformFile file) async { diff --git a/lib/modules/meeting/views/meeting_connect_view.dart b/lib/modules/meeting/views/meeting_connect_view.dart index e8e86fad4..8adae6f11 100644 --- a/lib/modules/meeting/views/meeting_connect_view.dart +++ b/lib/modules/meeting/views/meeting_connect_view.dart @@ -89,6 +89,29 @@ class MeetingConnectView extends GetView { ) : const SizedBox(), ), + Obx(() => controller.isDownload.value + ? Column( + children: [ + Container( + width: 300.w, + height: 3.w, + margin: EdgeInsets.only(bottom: 10.w), + child: LinearProgressIndicator( + value: controller.downloadProgress.value, + valueColor: + const AlwaysStoppedAnimation(Colors.red), + ), + ), + Text( + '${controller.totalReceived.value} / ${controller.fileSize.value} bytes', + style: TextStyle( + fontSize: 14.sp, + color: isDarkMode ? Colors.white70 : Colors.black54, + ), + ), + ], + ) + : const SizedBox()), ], ), );