From 3af61b41b7683eea7852829157dd1c66f78a4b1c Mon Sep 17 00:00:00 2001 From: tanlongsheng <252620078@qq.com> Date: Mon, 7 Jul 2025 16:15:27 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BC=9A=E8=AE=AE=E5=8A=A9?= =?UTF-8?q?=E6=89=8B=E8=87=AA=E5=8A=A8=E8=BF=9E=E6=8E=A5ftp=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/core/utils/ftpconnect/src/ftp_entry.dart | 40 ++++++------------- .../meeting_connect_controller.dart | 37 +++++++++++------ 2 files changed, 37 insertions(+), 40 deletions(-) diff --git a/lib/core/utils/ftpconnect/src/ftp_entry.dart b/lib/core/utils/ftpconnect/src/ftp_entry.dart index bdf1a3623..fd241b4f4 100644 --- a/lib/core/utils/ftpconnect/src/ftp_entry.dart +++ b/lib/core/utils/ftpconnect/src/ftp_entry.dart @@ -27,11 +27,8 @@ class FTPEntry { r"(.+)$" //file/dir name[8] ); - static final regexpLISTSiiServers = RegExp(r"^(.{8}\s+.{7})\s+" //date[1] - r"(.{0,5})\s+" //type file or dir [2] - r"(\d{0,24})\s+" //size [3] - r"(.+)$" //file/ dir name [4] - ); + static final regexpLISTSiiServers = RegExp( + r"^(\d{2}-\d{2}-\d{4}\s+\d{2}:\d{2}[AP]M)\s+(\)?\s*(\d*)\s+(.+)$"); // Hide constructor FTPEntry._( @@ -218,35 +215,22 @@ class FTPEntry { int _uid = -1; Iterable matches = regexpLISTSiiServers.allMatches(responseLine); for (Match match in matches) { - //date - String date = - match.group(1)!.split(" ").fold('', (previousValue, element) { - //keep only one space and add fullyear if only last 2 digits in year - if (element.isEmpty) return previousValue; - if (previousValue.isEmpty) { - return element.length <= 8 - ? element.substring(0, 6) + - DateTime.now().year.toString().substring(0, 2) + - element.substring(6, 8) - : element; - } - return '$previousValue $element'; - }); + // 日期,合并多余空格 + String date = match.group(1)!.replaceAll(RegExp(r'\s+'), ' '); _modifyTime = DateFormat('MM-dd-yyyy hh:mma').parse(date); - //type - if (match.group(2)!.trim().isEmpty) { - _type = FTPEntryType.FILE; - } else if (match.group(2)!.toLowerCase().contains("dir")) { + // 类型 + if ((match.group(2) ?? '').trim().isNotEmpty) { _type = FTPEntryType.DIR; } else { - _type = FTPEntryType.LINK; + _type = FTPEntryType.FILE; } - //size - _size = int.tryParse(match.group(3)!) ?? 0; - //file/dir name - _name = match.group(4)!; + // 大小 + _size = int.tryParse(match.group(3) ?? '') ?? 0; + + // 文件/目录名 + _name = match.group(4)!.trim(); } return FTPEntry._(_name, _modifyTime, _persmission, _type, _size, _unique, _group, _gid, _mode, _owner, _uid, {}); diff --git a/lib/modules/meeting/controllers/meeting_connect_controller.dart b/lib/modules/meeting/controllers/meeting_connect_controller.dart index af101e1cb..78029afec 100644 --- a/lib/modules/meeting/controllers/meeting_connect_controller.dart +++ b/lib/modules/meeting/controllers/meeting_connect_controller.dart @@ -4,6 +4,8 @@ import 'package:flutter_blue_plus/flutter_blue_plus.dart'; import 'package:get/get.dart'; import 'package:wifi_iot/wifi_iot.dart'; +import '../../../core/utils/ftpconnect/ftpconnect.dart'; + class MeetingConnectController extends GetxController { RxString stateStr = '搜索中...'.obs; RxBool isRescan = false.obs; @@ -16,8 +18,8 @@ class MeetingConnectController extends GetxController { bool isScanFailed = false; - late BluetoothCharacteristic? _writeCharacteristic; - late StreamSubscription>? _valueReceivedSubscription; + BluetoothCharacteristic? _writeCharacteristic; + StreamSubscription>? _valueReceivedSubscription; String _wifiSSID = ''; String _wifiPassword = ''; @@ -26,6 +28,8 @@ class MeetingConnectController extends GetxController { String _ftpAccount = ''; String _ftpPassword = ''; + FTPConnect? _ftpConnect; + @override void onInit() { super.onInit(); @@ -56,6 +60,7 @@ class MeetingConnectController extends GetxController { _scanResultsSubscription.cancel(); _isScanningSubscription.cancel(); _valueReceivedSubscription?.cancel(); + _ftpConnect?.disconnect(); _stopScan(); _disconnect(); super.onClose(); @@ -86,6 +91,7 @@ class MeetingConnectController extends GetxController { } Future _disconnect() async { + await WiFiForIoTPlugin.forceWifiUsage(false); await WiFiForIoTPlugin.disconnect(); await _device?.disconnect(); } @@ -131,7 +137,6 @@ class MeetingConnectController extends GetxController { } void _listenData(List value) { - print('----$value--------'); int command = value[2]; switch (command) { case 0x0d: // 是否有导入文件 @@ -145,12 +150,12 @@ class MeetingConnectController extends GetxController { break; case 0x87: // Wi-Fi 开启/关闭 if (value[3] == 0x01 && value[4] == 0x01) { - _getWifi(); + sendData([0x5a, 0x01, 0x0b]); } break; case 0x0b: // WiFi 热点 SSID _wifiSSID = String.fromCharCodes(value.sublist(3, value.length - 2)); - _connectWifi(); + sendData([0x5a, 0x01, 0x0c]); break; case 0x0c: // WiFi 热点密码 _wifiPassword = _decodePassword(value); @@ -176,11 +181,6 @@ class MeetingConnectController extends GetxController { } } - void _getWifi() async { - await sendData([0x5a, 0x01, 0x0b]); - await sendData([0x5a, 0x01, 0x0c]); - } - void _connectWifi() async { if (_wifiSSID.isNotEmpty && _wifiPassword.isNotEmpty) { stateStr.value = '正在连接 Wi-Fi...'; @@ -189,16 +189,29 @@ class MeetingConnectController extends GetxController { password: _wifiPassword, security: NetworkSecurity.WPA, ); + await WiFiForIoTPlugin.forceWifiUsage(true); stateStr.value = 'Wi-Fi 连接成功'; sendData([0x5a, 0x01, 0x03]); } } - void _connectFtp() { + void _connectFtp() async { if (_ftpAddress.isNotEmpty && _ftpPort.isNotEmpty && _ftpAccount.isNotEmpty && - _ftpPassword.isNotEmpty) {} + _ftpPassword.isNotEmpty) { + _ftpConnect = FTPConnect( + _ftpAddress, + port: int.tryParse(_ftpPort) ?? 21, + user: _ftpAccount, + pass: _ftpPassword, + ); + await _ftpConnect?.connect(); + _ftpConnect?.listCommand = ListCommand.LIST; + List? _listDirectory = + await _ftpConnect?.listDirectoryContent(); + print(_listDirectory); + } } String _decodePassword(List data) {