From a4be8bc481037f2d9f6e1a6045a0218eca455936 Mon Sep 17 00:00:00 2001 From: lxm <1274844347@qq.com> Date: Sun, 20 Jul 2025 18:19:15 +0800 Subject: [PATCH] =?UTF-8?q?feat(ota=5Fupgrade):=20=E5=A2=9E=E5=BC=BA?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E6=8F=90=E7=A4=BA=E5=92=8CUI=E4=BA=A4?= =?UTF-8?q?=E4=BA=92=E4=BD=93=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 替换print为Logger输出日志 - 为所有snackbar添加统一样式和错误图标 - 改进电量不足和升级成功的对话框UI - 升级成功后添加跳转配对页面的引导 - 优化错误处理流程和用户提示 --- .../controllers/ota_upgrade_controller.dart | 257 ++++++++++++++++-- 1 file changed, 227 insertions(+), 30 deletions(-) diff --git a/lib/modules/ota_upgrade/controllers/ota_upgrade_controller.dart b/lib/modules/ota_upgrade/controllers/ota_upgrade_controller.dart index ef9bc97e8..907dd85f8 100644 --- a/lib/modules/ota_upgrade/controllers/ota_upgrade_controller.dart +++ b/lib/modules/ota_upgrade/controllers/ota_upgrade_controller.dart @@ -1,4 +1,6 @@ import 'package:classic_bluetooth/classic_bluetooth.dart'; +import '/routes/app_routes.dart'; +import 'package:logger/web.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:path/path.dart'; @@ -121,7 +123,17 @@ class OtaUpgradeController extends GetxController { // 实现更新逻辑... } catch (e) { errorMessage.value = e.toString(); - Get.snackbar('更新失败', e.toString()); + Get.snackbar( + '更新失败', + e.toString(), + snackPosition: SnackPosition.BOTTOM, + backgroundColor: Colors.red[600], + colorText: Colors.white, + icon: const Icon( + Icons.error_outline, + color: Colors.white, + ), + ); } } @@ -166,7 +178,7 @@ class OtaUpgradeController extends GetxController { // 从第三个 `.` 开始分割 final firstPart = firmwareParts.sublist(0, 3).join('.'); final secondPart = firmwareParts.sublist(3).join('.'); - print("firstPart${firstPart},secondPart=${secondPart}"); + Logger().d("firstPart${firstPart},secondPart=${secondPart}"); // 判断两部分是否一致 if (firstPart != secondPart) { throw "固件版本格式错误:${deviceInfo.firmwareVersion}"; @@ -174,7 +186,7 @@ class OtaUpgradeController extends GetxController { // 正常流程 currentVersion.value = firstPart; - print('getequipmentinfo,id: ${deviceInfo.firmwareProductId}'); + Logger().d('getequipmentinfo,id: ${deviceInfo.firmwareProductId}'); final connectedDevices = await ClassicBluetooth.getConnectedDevices(); if (connectedDevices.isNotEmpty) { @@ -192,7 +204,7 @@ class OtaUpgradeController extends GetxController { } final resp = OtaConfigResp.fromJson(response); - print('getequipmentinfo,resp.systemversion: ${resp.systemversion}'); + Logger().d('getequipmentinfo,resp.systemversion: ${resp.systemversion}'); latestVersion.value = resp.systemversion!; updatedescription.value = resp.updatedescription!; updatepackageaddress = resp.updatepackageaddress!; @@ -210,10 +222,17 @@ class OtaUpgradeController extends GetxController { } catch (e) { // 统一错误处理 errorMessage.value = e.toString(); - Get.snackbar('错误', e.toString(), - snackPosition: SnackPosition.BOTTOM, - backgroundColor: Colors.red, - colorText: Colors.white); + Get.snackbar( + '错误', + e.toString(), + snackPosition: SnackPosition.BOTTOM, + backgroundColor: Colors.red[600], + colorText: Colors.white, + icon: const Icon( + Icons.error_outline, + color: Colors.white, + ), + ); // 重要:重新抛出异常以便上层处理(可选) } finally { isFetchingDeviceInfo.value = false; @@ -237,7 +256,7 @@ class OtaUpgradeController extends GetxController { } return false; } catch (e) { - print('版本比较错误: $e'); + Logger().d('版本比较错误: $e'); return false; } } @@ -248,15 +267,35 @@ class OtaUpgradeController extends GetxController { if (latestVersion.value != "") { _showUpdateDialog(latestVersion.value); } else { - Get.snackbar('错误', '获取最新版本信息失败'); + Get.snackbar( + '错误', + '获取最新版本信息失败', + snackPosition: SnackPosition.BOTTOM, + backgroundColor: Colors.orange[800], + colorText: Colors.white, + icon: const Icon( + Icons.error_outline, + color: Colors.white, + ), + ); } } catch (e) { - Get.snackbar('错误', '获取版本信息失败'); + Get.snackbar( + '错误', + '获取版本信息失败', + snackPosition: SnackPosition.BOTTOM, + backgroundColor: Colors.orange[800], + colorText: Colors.white, + icon: const Icon( + Icons.error_outline, + color: Colors.white, + ), + ); } } void _showUpdateDialog(String latest) async { - print('显示更新对话框'); + Logger().d('显示更新对话框'); Get.dialog( AlertDialog( title: Text('发现新版本 $latest'), @@ -264,7 +303,7 @@ class OtaUpgradeController extends GetxController { actions: [ TextButton( onPressed: () async { - print('取消按钮被点击'); + Logger().d('取消按钮被点击'); Get.back(); Future.delayed(Duration(milliseconds: 300)); @@ -273,7 +312,7 @@ class OtaUpgradeController extends GetxController { ), TextButton( onPressed: () async { - print('更新按钮被点击'); + Logger().d('更新按钮被点击'); Get.back(); Future.delayed(Duration(milliseconds: 300)); @@ -341,7 +380,17 @@ class OtaUpgradeController extends GetxController { } } } catch (e) { - Get.snackbar('错误', '检查本地文件失败: $e'); + Get.snackbar( + '错误', + '检查本地文件失败: $e', + snackPosition: SnackPosition.BOTTOM, + backgroundColor: Colors.red[600], + colorText: Colors.white, + icon: Icon( + Icons.error_outline, + color: Colors.white, + ), + ); return; } @@ -363,12 +412,22 @@ class OtaUpgradeController extends GetxController { } } } catch (e) { - Get.snackbar('错误', '删除旧文件失败: $e'); + Get.snackbar( + '错误', + '删除旧文件失败: $e', + snackPosition: SnackPosition.BOTTOM, + backgroundColor: Colors.red[600], + colorText: Colors.white, + icon: Icon( + Icons.error_outline, + color: Colors.white, + ), + ); //isUpgrade.value = false; return; } - print('文件保存路径: $savePath'); + Logger().d('文件保存路径: $savePath'); detailedStatus.value = '开始下载固件包...'; final options = Options( @@ -394,7 +453,17 @@ class OtaUpgradeController extends GetxController { // Get.snackbar('下载完成', '文件已保存至: $savePath'); detailedStatus.value = '下载完成,准备升级...'; } else { - Get.snackbar('错误', '文件未找到,请检查写入权限'); + Get.snackbar( + '错误', + '文件未找到,请检查写入权限', + snackPosition: SnackPosition.BOTTOM, + backgroundColor: Colors.orange[600], + colorText: Colors.white, + icon: Icon( + Icons.error_outline, + color: Colors.white, + ), + ); detailedStatus.value = '下载失败'; showDetailedStatus.value = false; return; @@ -403,15 +472,45 @@ class OtaUpgradeController extends GetxController { startUpgrading(savePath); return; } on DioException catch (e) { - Get.snackbar('下载失败', '错误: ${e.message}'); + Get.snackbar( + '下载失败', + '错误: ${e.message}', + snackPosition: SnackPosition.BOTTOM, + backgroundColor: Colors.orange[600], + colorText: Colors.white, + icon: Icon( + Icons.error_outline, + color: Colors.white, + ), + ); } on FileSystemException catch (e) { - Get.snackbar('存储失败', '无法写入文件: ${e.message}'); + Get.snackbar( + '存储失败', + '无法写入文件: ${e.message}', + snackPosition: SnackPosition.BOTTOM, + backgroundColor: Colors.orange[600], + colorText: Colors.white, + icon: Icon( + Icons.error_outline, + color: Colors.white, + ), + ); } catch (e) { isDownloading.value = false; detailedStatus.value = '下载失败,请检查网络连接'; showDetailedStatus.value = false; - Get.snackbar('下载失败', '请检查网络连接: $e'); - print('下载失败: $e'); + Get.snackbar( + '下载失败', + '请检查网络连接: $e', + snackPosition: SnackPosition.BOTTOM, + backgroundColor: Colors.orange[600], + colorText: Colors.white, + icon: Icon( + Icons.error_outline, + color: Colors.white, + ), + ); + Logger().d('下载失败: $e'); } } @@ -442,8 +541,12 @@ class OtaUpgradeController extends GetxController { '电量检查失败', '无法获取设备信息,请检查设备连接', snackPosition: SnackPosition.BOTTOM, - backgroundColor: Colors.orange, + backgroundColor: Colors.orange[600], colorText: Colors.white, + icon: Icon( + Icons.warning_amber, + color: Colors.white, + ), ); return false; } @@ -460,14 +563,36 @@ class OtaUpgradeController extends GetxController { Get.dialog( AlertDialog( - title: Text('电量不足'), - content: Text(message), + title: Text( + '电量不足', + style: TextStyle( + color: Colors.orange[700], + fontWeight: FontWeight.w600, + ), + ), + content: Text( + message, + style: TextStyle( + color: Colors.orange[600], + ), + ), actions: [ TextButton( onPressed: () => Get.back(), - child: Text('确定'), + style: TextButton.styleFrom( + foregroundColor: Colors.orange[700], + ), + child: const Text('确定'), ), ], + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + side: BorderSide( + color: Colors.orange.withValues(alpha: 0.3), + width: 1, + ), + ), + backgroundColor: Colors.orange[50], ), ); return false; @@ -479,8 +604,12 @@ class OtaUpgradeController extends GetxController { '电量检查失败', '检查设备电量时发生错误:$e', snackPosition: SnackPosition.BOTTOM, - backgroundColor: Colors.red, + backgroundColor: Colors.orange[600], colorText: Colors.white, + icon: const Icon( + Icons.warning_amber, + color: Colors.white, + ), ); return false; } @@ -507,15 +636,83 @@ class OtaUpgradeController extends GetxController { isUpgrade.value = false; detailedStatus.value = '升级成功完成'; showDetailedStatus.value = false; - Get.snackbar('升级成功', '请退出重新连接设备'); - _getCurrentVersion(); + + // 升级成功,更新版本信息显示 + currentVersion.value = latestVersion.value; + isUpdateAvailable.value = false; + + // 显示升级成功对话框,引导用户重新配对 + Get.dialog( + AlertDialog( + title: Row( + children: [ + Icon( + Icons.check_circle, + color: Colors.green[600], + size: 28, + ), + SizedBox(width: 12), + Text( + '升级成功', + style: TextStyle( + color: Colors.green[700], + fontWeight: FontWeight.w600, + ), + ), + ], + ), + content: Text( + '固件升级已完成!\n\n设备需要重新配对才能正常使用,现在跳转到配对页面吗?', + style: TextStyle( + fontSize: 16, + height: 1.4, + ), + ), + actions: [ + TextButton( + onPressed: () { + Get.back(); // 关闭对话框 + }, + child: Text( + '稍后配对', + style: TextStyle(color: Colors.grey[600]), + ), + ), + ElevatedButton( + onPressed: () { + Get.back(); // 关闭对话框 + Get.toNamed(Routes.pairing); + }, + style: ElevatedButton.styleFrom( + backgroundColor: Colors.green[600], + foregroundColor: Colors.white, + ), + child: Text('立即配对'), + ), + ], + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + ), + barrierDismissible: false, // 防止用户意外关闭 + ); } if (event.event == 'onError') { type.value = UPGRADE_FAILED; isUpgrade.value = false; detailedStatus.value = '升级失败,错误码:${event.code}'; showDetailedStatus.value = false; - Get.snackbar('升级失败', '请检查设备连接或升级包,错误码:${event.code}'); + Get.snackbar( + '升级失败', + '请检查设备连接或升级包,错误码:${event.code}', + snackPosition: SnackPosition.BOTTOM, + backgroundColor: Colors.red[600], + colorText: Colors.white, + icon: Icon( + Icons.error_outline, + color: Colors.white, + ), + ); } if (event.event == 'NOCONNECTION') { type.value = CONNECTION_DISCONNECTION;