diff --git a/android/version.properties b/android/version.properties index cdeab51..8ba4970 100644 --- a/android/version.properties +++ b/android/version.properties @@ -2,6 +2,6 @@ # flutter.android.versionName=2.0.5 # flutter.android.versionCode=11 -# 智慧眠花糖版本信息 -flutter.android.versionName=2.0.8 -flutter.android.versionCode=12 \ No newline at end of file +# 智慧眠花糖版本信息【最新,未提交商店】 +flutter.android.versionName=2.0.9 +flutter.android.versionCode=13 \ No newline at end of file diff --git a/assets/file.json b/assets/file.json index ddc19b9..0757712 100644 --- a/assets/file.json +++ b/assets/file.json @@ -1,3 +1,3 @@ [ - "assets/miniapp/mhtControl_1.0.87.zip" + "assets/miniapp/mhtControl_1.0.89.zip" ] \ No newline at end of file diff --git a/assets/miniapp/mhtControl_1.0.87.zip b/assets/miniapp/mhtControl_1.0.89.zip similarity index 97% rename from assets/miniapp/mhtControl_1.0.87.zip rename to assets/miniapp/mhtControl_1.0.89.zip index aad3054..dc648ae 100644 Binary files a/assets/miniapp/mhtControl_1.0.87.zip and b/assets/miniapp/mhtControl_1.0.89.zip differ diff --git a/lib/common/color/ServiceConstant.dart b/lib/common/color/ServiceConstant.dart index a4ba35a..b57eca3 100644 --- a/lib/common/color/ServiceConstant.dart +++ b/lib/common/color/ServiceConstant.dart @@ -2,7 +2,7 @@ class ServiceConstant { // static const String baseHost = "zhmht.swes.com.cn:27021"; //服务地址 眠花糖测试地址 static const String baseHost = "zhmht.swes.com.cn:27020"; //服务地址 眠花糖正式地址 // static const String baseHost = "vsbs-test.he-info.cn"; //服务地址 本地测试地址 - // static const String baseHost = "vsbst-api.he-info.cn";//服务地址 + // static const String baseHost = "vsbst-api.he-info.com";//服务地址 // static const String service_address = "http://$baseHost"; static const String service_address = "https://$baseHost"; diff --git a/lib/common/util/requestWithLog.dart b/lib/common/util/requestWithLog.dart index e76172b..6eddf34 100644 --- a/lib/common/util/requestWithLog.dart +++ b/lib/common/util/requestWithLog.dart @@ -93,6 +93,7 @@ Future requestWithLog({ EasyDartModule.logger.error("$logTitle 失败->$e"); DailyLogUtils.writeError("$logTitle 失败->$e"); onFailure?.call(apiResponse); + apiResponse.msg = e.toString(); return apiResponse; } } diff --git a/lib/main.dart b/lib/main.dart index 6999b8e..0c243fa 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -6,8 +6,10 @@ import 'package:EasyDartModule/base/logger/Logger.dart'; import 'package:EasyDartModule/base/websocket/WebSocket.dart'; import 'package:easyweb/utils/appmanger.dart'; import 'package:ef/ef.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:fluwx/fluwx.dart'; import 'package:get_storage/get_storage.dart'; @@ -98,6 +100,8 @@ Future main() async { await initLanguageSetting(); WidgetsFlutterBinding.ensureInitialized(); + initServiceAddress(); + ApiService.init(); await GetStorage.init(); // 初始化登录 @@ -111,7 +115,7 @@ Future main() async { // 检查网络 Checknetwork.checkNetwork(); // 微信开放平台注册 - initWX(); + await initWX(); // // 初始化 flutter_xupdate android app 更新 // initXUpdate(); @@ -124,6 +128,20 @@ Future main() async { }); } +//初始化服务器地址 +void initServiceAddress() { + if (AppConstants().ent_type == APPPackageType.MHT.code) { + // 眠花糖 + ServiceConstant.baseHost = "zhmht.swes.com.cn:27020"; + } else if (AppConstants().ent_type == APPPackageType.TH.code) { + // 太和 + ServiceConstant.baseHost = "vsbst-api.he-info.com"; + } else { + //默认 + ServiceConstant.baseHost = "vsbst-api.he-info.com"; + } +} + // languageCode 系统默认语言码 en/zh loadLanguageSetting(String? languageCode) async { int code = AppConstants().ent_type; @@ -185,17 +203,46 @@ initLanguageSetting() async { } // 初始化微信开放平台注册 +// Future initWX() async { +// Fluwx fluwx = Fluwx(); +// fluwx.registerApi( +// //请填写自己的微信appid +// // appId: "wxeb2688220799e2c5", //太和 +// appId: "wx929c548fea6af9c7", //眠花糖 +// doOnAndroid: true, +// doOnIOS: true, +// // universalLink: "https://app.he-info.com/theh/", +// universalLink: "https://zhmht.swes.com.cn/app/", +// ); +// } + Future initWX() async { - Fluwx fluwx = Fluwx(); - fluwx.registerApi( - //请填写自己的微信appid - appId: "wxeb2688220799e2c5", //太和 - // appId: "wx929c548fea6af9c7", //眠花糖 + final fluwx = Fluwx(); + + String appId = ""; + String universalLink = ""; + + if (AppConstants().ent_type == APPPackageType.MHT.code) { + // 眠花糖 + appId = "wx929c548fea6af9c7"; + universalLink = "https://zhmht.swes.com.cn/app/"; + } else if (AppConstants().ent_type == APPPackageType.TH.code) { + // 太和 + appId = "wxeb2688220799e2c5"; + universalLink = "https://app.he-info.com/theh/"; + } else { + ef.log("[initWX] 未匹配到有效的包类型 ent_type=${AppConstants().ent_type}"); + return; + } + + await fluwx.registerApi( + appId: appId, doOnAndroid: true, doOnIOS: true, - universalLink: "https://app.he-info.com/theh/", - // universalLink: "https://zhmht.swes.com.cn/app/", + universalLink: universalLink, ); + + ef.log("[initWX] 微信注册完成 -> appId: $appId, link: $universalLink"); } Timer? _messageTimer; @@ -628,11 +675,8 @@ messageStatus() async { void initEasyDartModule() { try { EasyDartModule.init( - loggerConfig: - // LoggerConfig(host: ServiceConstant.logService, serviceName: "智慧眠花糖在线2025-10-9"), - LoggerConfig( - host: ServiceConstant.logService, - serviceName: "太和e护在线2025-10-14"), + loggerConfig: LoggerConfig( + host: ServiceConstant.logService, serviceName: "眠花糖在线2025-10-28"), webSocketConfig: WebSocketConfig(ServiceConstant.webSocketService, (data) { // 接收到服务消息 diff --git a/lib/pages/main_bottom/component/main_page_b_bottom_change.dart b/lib/pages/main_bottom/component/main_page_b_bottom_change.dart index 25a91de..236b3e1 100644 --- a/lib/pages/main_bottom/component/main_page_b_bottom_change.dart +++ b/lib/pages/main_bottom/component/main_page_b_bottom_change.dart @@ -12,6 +12,7 @@ import 'package:vbvs_app/common/util/MyUtils.dart'; import 'package:vbvs_app/component/tool/TopSlideNotification.dart'; import 'package:vbvs_app/controller/mh_controller/mh_language_controller.dart'; import 'package:vbvs_app/controller/user_info_controller.dart'; +import 'package:vbvs_app/enum/APPPackageType.dart'; import 'package:vbvs_app/model/WebSocketMessage.dart'; import 'package:vbvs_app/pages/common/bezier_bottom_navigation_bar.dart'; import 'package:vbvs_app/pages/common/selectDialog.dart'; @@ -126,27 +127,29 @@ class _HomePageState extends State final getStorage = GetStorage(); @override Widget build(BuildContext context) { - Future.delayed(const Duration(milliseconds: 0), () { - String? isShowYingShiDialog = getStorage.read("isShowYingShiDialog"); - if (isShowYingShiDialog == null || isShowYingShiDialog != "true") { - String btnName = "同意".tr; - String cancelName = "取消".tr; - if (Platform.isAndroid) { - cancelName = "退出".tr; - } - showCustomConfirmOfWebViewDialog(context, "隐私协议".tr, getPrivacy(1), - btnName: btnName, showCancel: true, cancelName: cancelName) - .then((e) { - if (e == "confirm") { - getStorage.write("isShowYingShiDialog", "true"); - } else { - if (cancelName == "退出") { - SystemNavigator.pop(); - } + if (AppConstants().ent_type == APPPackageType.MHT.code) { + Future.delayed(const Duration(milliseconds: 0), () { + String? isShowYingShiDialog = getStorage.read("isShowYingShiDialog"); + if (isShowYingShiDialog == null || isShowYingShiDialog != "true") { + String btnName = "同意".tr; + String cancelName = "取消".tr; + if (Platform.isAndroid) { + cancelName = "退出".tr; } - }); - } - }); + showCustomConfirmOfWebViewDialog(context, "隐私协议".tr, getPrivacy(1), + btnName: btnName, showCancel: true, cancelName: cancelName) + .then((e) { + if (e == "confirm") { + getStorage.write("isShowYingShiDialog", "true"); + } else { + if (cancelName == "退出") { + SystemNavigator.pop(); + } + } + }); + } + }); + } return Obx(() { final currentLanguage = languageController.selectLanguage.value; // 监听此变量变化 diff --git a/lib/pages/main_bottom/main_page_bottom_change.dart b/lib/pages/main_bottom/main_page_bottom_change.dart index ad7c7f3..952a753 100644 --- a/lib/pages/main_bottom/main_page_bottom_change.dart +++ b/lib/pages/main_bottom/main_page_bottom_change.dart @@ -269,7 +269,6 @@ // } // } - import 'dart:async'; import 'dart:io'; @@ -286,6 +285,7 @@ import 'package:vbvs_app/controller/main_bottom/main_page_controller.dart'; import 'package:vbvs_app/controller/message/message_controller.dart'; import 'package:vbvs_app/controller/theme_controller/ThemeController.dart'; import 'package:vbvs_app/controller/user_info_controller.dart'; +import 'package:vbvs_app/enum/APPPackageType.dart'; import 'package:vbvs_app/enum/LoginStatus.dart'; import 'package:vbvs_app/pages/common/selectDialog.dart'; import 'package:vbvs_app/pages/main_bottom/e_page.dart'; @@ -315,12 +315,10 @@ class MainPageBottomChange extends GetView { bottomItems = [ getBottomNavigationBarItem("assets/img/menu/home.svg", "assets/img/menu/n_home.svg", "菜单.首页".tr), - getBottomNavigationBarItem("assets/img/menu/e.svg", - "assets/img/menu/n_e.svg", "菜单.小e".tr), getBottomNavigationBarItem( - "assets/img/menu/message.svg", - "assets/img/menu/n_message.svg", - "菜单.消息".tr, + "assets/img/menu/e.svg", "assets/img/menu/n_e.svg", "菜单.小e".tr), + getBottomNavigationBarItem("assets/img/menu/message.svg", + "assets/img/menu/n_message.svg", "菜单.消息".tr, showBadge: (messageController.model.body_message_read == 1 || messageController.model.system_message_read == 1)), getBottomNavigationBarItem("assets/img/menu/mine.svg", @@ -335,10 +333,8 @@ class MainPageBottomChange extends GetView { bottomItems = [ getBottomNavigationBarItem("assets/img/menu/home.svg", "assets/img/menu/n_home.svg", "菜单.首页".tr), - getBottomNavigationBarItem( - "assets/img/menu/message.svg", - "assets/img/menu/n_message.svg", - "菜单.消息".tr, + getBottomNavigationBarItem("assets/img/menu/message.svg", + "assets/img/menu/n_message.svg", "菜单.消息".tr, showBadge: (messageController.model.body_message_read == 1 || messageController.model.system_message_read == 1)), getBottomNavigationBarItem("assets/img/menu/mine.svg", @@ -391,24 +387,26 @@ class MainPageBottomChange extends GetView { @override Widget build(BuildContext context) { - Future.delayed(const Duration(milliseconds: 0), () { - String? isShowYingShiDialog = getStorage.read("isShowYingShiDialog"); - if (isShowYingShiDialog == null || isShowYingShiDialog != "true") { - String btnName = "同意".tr; - String cancelName = "取消".tr; - if (Platform.isAndroid) cancelName = "退出".tr; + if (AppConstants().ent_type == APPPackageType.TH.code) { + Future.delayed(const Duration(milliseconds: 0), () { + String? isShowYingShiDialog = getStorage.read("isShowYingShiDialog"); + if (isShowYingShiDialog == null || isShowYingShiDialog != "true") { + String btnName = "同意".tr; + String cancelName = "取消".tr; + if (Platform.isAndroid) cancelName = "退出".tr; - showCustomConfirmOfWebViewDialog(context, "隐私协议".tr, getPrivacy(1), - btnName: btnName, showCancel: true, cancelName: cancelName) - .then((e) { - if (e == "confirm") { - getStorage.write("isShowYingShiDialog", "true"); - } else { - if (cancelName == "退出") SystemNavigator.pop(); - } - }); - } - }); + showCustomConfirmOfWebViewDialog(context, "隐私协议".tr, getPrivacy(1), + btnName: btnName, showCancel: true, cancelName: cancelName) + .then((e) { + if (e == "confirm") { + getStorage.write("isShowYingShiDialog", "true"); + } else { + if (cancelName == "退出") SystemNavigator.pop(); + } + }); + } + }); + } return PopScope( canPop: false, @@ -436,7 +434,8 @@ class MainPageBottomChange extends GetView { return Scaffold( body: IndexedStack( index: currentIndex, - children: arr.map((page) => SizedBox.expand(child: page)).toList(), + children: + arr.map((page) => SizedBox.expand(child: page)).toList(), ), ); } else { @@ -451,7 +450,8 @@ class MainPageBottomChange extends GetView { backgroundColor: Colors.transparent, body: IndexedStack( index: currentIndex, - children: arr.map((page) => SizedBox.expand(child: page)).toList(), + children: + arr.map((page) => SizedBox.expand(child: page)).toList(), ), bottomNavigationBar: Theme( data: Theme.of(context).copyWith( @@ -497,7 +497,8 @@ class MainPageBottomChange extends GetView { Get.currentRoute == '/messagePage') { Get.back(); } - Future.delayed(const Duration(milliseconds: 100), () { + Future.delayed(const Duration(milliseconds: 100), + () { Get.toNamed("/otherLoginPage"); }); }); @@ -505,7 +506,8 @@ class MainPageBottomChange extends GetView { } if (controller.model.currentIndex != index) { - globalController.model.hideBottomNavigationBar = false; + globalController.model.hideBottomNavigationBar = + false; globalController.updateAll(); } @@ -527,7 +529,8 @@ class MainPageBottomChange extends GetView { Future _handleBackPressed(BuildContext context) async { final currentTime = DateTime.now(); if (_lastBackPressedTime == null || - currentTime.difference(_lastBackPressedTime!) > const Duration(seconds: 2)) { + currentTime.difference(_lastBackPressedTime!) > + const Duration(seconds: 2)) { _lastBackPressedTime = currentTime; TopSlideNotification.show(context, text: "滑动退出提醒".tr); return false; diff --git a/lib/pages/mh_page/Vital_signs_sensor.dart b/lib/pages/mh_page/Vital_signs_sensor.dart index e16752b..2727de4 100644 --- a/lib/pages/mh_page/Vital_signs_sensor.dart +++ b/lib/pages/mh_page/Vital_signs_sensor.dart @@ -106,53 +106,53 @@ class _VitalSignsSensorState extends State { left: 0.rpx, child: returnIconButtomNew(), ), - // Positioned( - // right: 0.rpx, - // child: ClickableContainer( - // backgroundColor: Colors.transparent, - // highlightColor: Colors.transparent, - // padding: EdgeInsets.symmetric( - // horizontal: 30.rpx, vertical: 30.rpx), - // onTap: () { - // // TopSlideNotification.show(context); - // //检测蓝牙是否开启,没有开启提示开启蓝牙 - // //如果已经开启,则进行x秒的蓝牙扫描 - // BluetoothHelper.listenBluetoothState((isOn) { - // mhtBlueToothController.model.bluetooth = isOn; - // mhtBlueToothController.updateAll(); - // if (!isOn) { - // mhtBlueToothController.model.blueRawData = []; - // mhtBlueToothController - // .model.deviceDataStatus = []; - // mhtBlueToothController.updateAll(); - // _showBluetoothNotEnabledDialog(); - // } - // }); - // _checkBluetoothPermission(); - // }, - // child: Obx(() { - // return SizedBox( - // width: 34.rpx, - // height: mhtBlueToothController.isScanning.value - // ? 34.rpx - // : 24.rpx, - // child: mhtBlueToothController.isScanning.value - // ? CircularProgressIndicator( - // strokeWidth: 2, - // valueColor: - // AlwaysStoppedAnimation( - // themeController.currentColor.sc3, - // ), - // ) - // : SvgPicture.asset( - // 'assets/img/icon/upgrade.svg', - // fit: BoxFit.cover, - // color: Colors.white, - // ), - // ); - // }), - // ), - // ), + Positioned( + right: 0.rpx, + child: ClickableContainer( + backgroundColor: Colors.transparent, + highlightColor: Colors.transparent, + padding: EdgeInsets.symmetric( + horizontal: 30.rpx, vertical: 30.rpx), + onTap: () { + // TopSlideNotification.show(context); + //检测蓝牙是否开启,没有开启提示开启蓝牙 + //如果已经开启,则进行x秒的蓝牙扫描 + BluetoothHelper.listenBluetoothState((isOn) { + mhtBlueToothController.model.bluetooth = isOn; + mhtBlueToothController.updateAll(); + if (!isOn) { + mhtBlueToothController.model.blueRawData = []; + mhtBlueToothController + .model.deviceDataStatus = []; + mhtBlueToothController.updateAll(); + _showBluetoothNotEnabledDialog(); + } + }); + _checkBluetoothPermission(); + }, + child: Obx(() { + return SizedBox( + width: 34.rpx, + height: mhtBlueToothController.isScanning.value + ? 34.rpx + : 24.rpx, + child: mhtBlueToothController.isScanning.value + ? CircularProgressIndicator( + strokeWidth: 2, + valueColor: + AlwaysStoppedAnimation( + themeController.currentColor.sc3, + ), + ) + : SvgPicture.asset( + 'assets/img/icon/upgrade.svg', + fit: BoxFit.cover, + color: Colors.white, + ), + ); + }), + ), + ), ], ), ), diff --git a/lib/pages/mh_page/device/component/DeviceComponentWidget.dart b/lib/pages/mh_page/device/component/DeviceComponentWidget.dart index 3036e56..90b11cb 100644 --- a/lib/pages/mh_page/device/component/DeviceComponentWidget.dart +++ b/lib/pages/mh_page/device/component/DeviceComponentWidget.dart @@ -5,6 +5,7 @@ import 'package:easydevice/easydevice.dart'; import 'package:ef/ef.dart'; import 'package:flutter/material.dart'; import 'package:flutterflow_ui/flutterflow_ui.dart'; +import 'package:mhtctrl/mhtctrl.dart'; import 'package:vbvs_app/common/color/ServiceConstant.dart'; import 'package:vbvs_app/common/color/app_uri_status.dart'; import 'package:vbvs_app/common/util/DailyLogUtils.dart'; @@ -18,6 +19,8 @@ import 'package:vbvs_app/controller/theme_controller/ThemeController.dart'; import 'package:vbvs_app/model/BleDeviceData.dart'; import 'package:vbvs_app/model/api_response.dart'; import 'package:vbvs_app/pages/mh_page/component/mht_bind_dialog.dart'; +import 'package:vbvs_app/pages/mh_page/device/component/tool/BedControlService.dart'; +import 'package:vbvs_app/pages/mh_page/device/component/tool/DeviceType.dart'; import 'package:vbvs_app/pages/mh_page/device/controller/mht_bluetooth_controller.dart'; import 'package:vbvs_app/pages/mh_page/device/model/BlueToothDataModel.dart'; import 'package:vbvs_app/pages/mh_page/homepage/controller/mht_home_controller.dart'; @@ -42,6 +45,8 @@ class _DeviceComponentWidgetState extends State { MHTBlueToothController blueteethBindController = Get.find(); MHTHomeController homeController = Get.find(); var lisObj; + late MattressControlService service; + late BedControlService bedService; @override Widget build(BuildContext context) { @@ -232,6 +237,8 @@ class _DeviceComponentWidgetState extends State { TopSlideNotification.show(context, text: response.msg!); if (response.code == HttpStatusCodes.ok) { + //关闭闹钟和打鼾干预 + // resetLastDeviceConfig(widget.bleDevice); homeController.getPersonList(); //请求绑定设备列表 // homeController.getSleepReport(); @@ -761,6 +768,49 @@ class _DeviceComponentWidgetState extends State { throw Exception("获取MAC超时".tr); } + + //重置设备闹钟数据和打鼾干预 + // void resetLastDeviceConfig(BlueToothDataModel bleDevice) { + // int deviceType = bleDevice.type; + // if (deviceType == 2) { + // //床垫 + // service = MattressControlService((pkg) async { + // var bytes = pkg.toBytes(); + // String serviceCode = ""; + // if (bleDevice != null) { + // if (deviceType == DeviceType.smartBed.value) { + // serviceCode = "ffe0/ffe1"; + // } + // if (deviceType == DeviceType.smartMattress.value) { + // serviceCode = "fff0/fff2"; + // } + // } + // if (bytes[7] != 0x00) { + // //打印bytes + // String hex = bytes.toString(); + // print("--------->" + hex); + // String hexString = bytes + // .map((e) => e.toRadixString(16).padLeft(2, '0')) + // .join(' ') + // .toUpperCase(); + // print("--------->hex->" + hexString); + // } + // int aa = await blueteethBindController.currentDevice! + // .write(bleDevice.mac, serviceCode, bytes, withresponse: true); + // ef.log(bytes.toString()); + // return aa == 0 ? true : false; + // }); + // } else if (deviceType == 3) { + // //床 + // bedService = BedControlService(_writeToDevice); // 初始化 + // } + // } + + // Future _writeToDevice(Uint8List pkg) async { + // int result = await bleToolController.ble + // .write(macAddress.value, "ffe0/ffe1", pkg, withresponse: true); + // return result == 0; + // } } String parseMacFromBleResponse(List data) { diff --git a/lib/pages/mh_page/device/component/tool/BedControlService.dart b/lib/pages/mh_page/device/component/tool/BedControlService.dart new file mode 100644 index 0000000..6c2912e --- /dev/null +++ b/lib/pages/mh_page/device/component/tool/BedControlService.dart @@ -0,0 +1,512 @@ +import 'dart:async'; +import 'dart:typed_data'; +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:mhtctrl/mhtctrl.dart'; + +class BedControlService { + // 协议常量 + static const List frameHeader = [0xFF, 0xFF, 0xFF, 0xFF, 0x05]; + static const int minFrameLength = 11; + + final Future Function(Uint8List) _writeFn; + final StreamController _statusController = + StreamController.broadcast(); + + Stream get statusStream => _statusController.stream; + + BedControlService(this._writeFn); + + // 校验和计算(根据协议文档硬编码) + static List _getChecksum(int commandCode) { + final checksumMap = { + 0x00: [0xD7, 0x00], // 停止 + 0x01: [0x16, 0xC0], // 头部上升 + 0x02: [0x56, 0xC1], // 头部下降 + 0x03: [0x97, 0x01], // 背部上升 + 0x04: [0xD6, 0xC3], // 背部下降 + 0x05: [0x17, 0x03], // 观影模式 + 0x06: [0x57, 0x02], // 腿部上升 + 0x07: [0x96, 0xC2], // 腿部下降 + 0x08: [0xD6, 0xC6], // 复位 + 0x09: [0x17, 0x06], // 零重力 + 0x0A: [0x57, 0x07], // 记忆1 + 0x0B: [0x96, 0xC7], // 记忆2 + 0x0C: [0xC7, 0x04], // 童锁 + 0x0D: [0x16, 0xC5], // 臀部上升 + 0x0E: [0x56, 0xC4], // 臀部下降 + 0x0F: [0x97, 0x04], // 止鼾 + 0x10: [0xD6, 0xCC], // 背部按摩+ + 0x11: [0x17, 0x0C], // 背部按摩- + 0x12: [0x57, 0x0D], // 腿部按摩+ + 0x13: [0x96, 0xCD], // 腿部按摩- + 0x14: [0xD7, 0x0F], // 按摩频率+ + 0x15: [0x16, 0xCF], // 按摩频率- + 0x16: [0x56, 0xCE], // 按摩时间10min + 0x17: [0x97, 0x0E], // 按摩时间20min + 0x18: [0xD7, 0x0A], // 按摩时间30min + 0x19: [0x16, 0xCA], // 灯光10min + 0x1A: [0x56, 0xCB], // 灯光8H + 0x1B: [0x97, 0x0B], // 灯光10H + 0x1C: [0xD6, 0xC9], // 按摩停止 + 0x2B: [0x97, 0x1F], // 背腿同上 + 0x2C: [0xD6, 0xDD], // 背腿同下 + 0x48: [0xD7, 0x36], // 阅读模式 + 0x49: [0x16, 0xF6], // 舒压模式 + 0x4E: [0x57, 0x34], // 瑜伽模式 + 0x6A: [0x57, 0x2F], // 助眠模式 + 0x50: [0xD7, 0x3C], // 背部按摩强度1 + 0x51: [0x16, 0xFC], // 背部按摩强度2 + 0x52: [0x56, 0xFD], // 背部按摩强度3 + 0x54: [0xD6, 0xFF], // 腿部按摩强度1 + 0x55: [0x17, 0x3F], // 腿部按摩强度2 + 0x56: [0x57, 0x3E], // 腿部按摩强度3 + 0x57: [0x96, 0xFE], // 按摩频率1 + 0x58: [0xD6, 0xFA], // 按摩频率2 + 0x59: [0x17, 0x3A], // 按摩频率3 + 0x5A: [0x57, 0x3B], // 按摩频率4 + 0x4F: [0x96, 0xF4], // 停止背 + 0x53: [0x97, 0x3D], // 停止腿 + 0x47: [0x87, 0x33], // 休闲模式 + 0xE6: [0x46, 0x8B], // 腰部放松 + 0xE5: [0x06, 0x8A], // 腿部放松 + }; + return checksumMap[commandCode] ?? [0x00, 0x00]; + } + + // 基础指令构建(11字节完整格式) + Uint8List _buildCommand(int byte5, int byte6, int byte7, int byte8) { + final data = Uint8List(11); + data.setAll(0, frameHeader); // FF FF FF FF 05 + data[5] = byte5; + data[6] = byte6; + data[7] = byte7; + data[8] = byte8; + final checksum = _getChecksum(byte8); + data[9] = checksum[0]; // 校验和高字节 + data[10] = checksum[1]; // 校验和低字节 + return data; + } + + // 进度控制指令构建(特殊格式) + Uint8List _buildProgressCommand(int progress, int baseCmd, int commandCode) { + final data = Uint8List(11); + data.setAll(0, frameHeader); + data[5] = progress; + data[6] = baseCmd >> 8; + data[7] = baseCmd & 0xFF; + data[8] = commandCode; + final checksum = _getChecksum(commandCode); + data[9] = checksum[0]; + data[10] = checksum[1]; + return data; + } + + //====== 指令集 ======// + + // 1. 遥控器上报功能(固定10字节) + Future enableRemoteReport() => _sendCommand( + [0xFF, 0xFF, 0xFF, 0xFF, 0x05, 0x00, 0x00, 0xF2, 0x56, 0x85]); + + // 2. 基础控制指令 + Future stop() => _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x00)); + Future moveHeadUp() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x01)); + Future moveHeadDown() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x02)); + Future moveBackUp() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x03)); + Future moveBackDown() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x04)); + Future moveLegUp() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x06)); + Future moveLegDown() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x07)); + Future moveHipUp() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x0D)); + Future moveHipDown() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x0E)); + Future resetPosition() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x08)); + + // 3. 预设模式指令 + Future setMovieMode([int progress = 0]) => progress > 0 + ? _sendCommand(_buildProgressCommand(progress, 0x0500, 0x05)) + : _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x05)); + + Future setZeroGravity([int progress = 0]) => progress > 0 + ? _sendCommand(_buildProgressCommand(progress, 0x0900, 0x09)) + : _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x09)); + + Future setAntiSnore([int progress = 0]) => progress > 0 + ? _sendCommand(_buildProgressCommand(progress, 0x0F00, 0x0F)) + : _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x0F)); + + //一键放松 + Future setSleepAssist() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x6A)); + // 休闲模式 + Future setXiuxianMode() => + _sendCommand(_buildCommand(0x00, 0x05, 0x00, 0x47)); + + // 腰部放松 + Future setYaoRelaxMode() => + _sendCommand(_buildCommand(0x00, 0x05, 0x00, 0xE6)); + + // 腿部放松 + Future setLegRelaxMode() => + _sendCommand(_buildCommand(0x00, 0x05, 0x00, 0xE5)); + Future setReadingMode() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x48)); + Future setRelaxMode() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x49)); + Future setYogaMode() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x4E)); + + // 4. 记忆功能 + Future saveMemory(int slot) { + assert(slot >= 1 && slot <= 2); + return _sendCommand( + _buildCommand(0x00, 0x00, 0x00, slot == 1 ? 0x0A : 0x0B)); + } + + // 5. 按摩控制 + Future increaseBackMassage() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x10)); + Future decreaseBackMassage() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x11)); + Future increaseLegMassage() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x12)); + Future decreaseLegMassage() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x13)); + Future increaseMassageFreq() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x14)); + Future decreaseMassageFreq() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x15)); + + Future setMassageTime(int minutes) { + final cmd = switch (minutes) { + 10 => _buildCommand(0x00, 0x00, 0x00, 0x16), + 20 => _buildCommand(0x00, 0x00, 0x00, 0x17), + 30 => _buildCommand(0x00, 0x00, 0x00, 0x18), + _ => _buildCommand(0x00, 0x00, 0x00, 0x16), + }; + return _sendCommand(cmd); + } + + Future stopMassage() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x1C)); + + // 6. 灯光控制 + Future toggleLight10Min() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x19)); + Future toggleLight8H() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x1A)); + Future toggleLight10H() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x1B)); + + // 7. 组合控制 + Future moveBothUp() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x2B)); + Future moveBothDown() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x2C)); + + // 8. 童锁功能(固定11字节) + Future toggleChildLock() => _sendCommand( + [0xFF, 0xFF, 0xFF, 0xFF, 0x05, 0x00, 0x05, 0x00, 0x0C, 0xC7, 0x04]); + + // 背部按摩强度控制 + Future setBackMassageLevel1() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x50)); + Future setBackMassageLevel2() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x51)); + Future setBackMassageLevel3() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x52)); + +// 腿部按摩强度控制 + Future setLegMassageLevel1() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x54)); + Future setLegMassageLevel2() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x55)); + Future setLegMassageLevel3() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x56)); + + //按摩时间 + Future setMassageTime10Min() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x16)); + Future setMassageTime20Min() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x17)); + Future setMassageTime30Min() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x18)); + + Future setMassageFrequency1() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x57)); + Future setMassageFrequency2() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x58)); + Future setMassageFrequency3() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x59)); + Future setMassageFrequency4() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x5A)); + + Future stopLeg() => _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x53)); + Future stopBack() => + _sendCommand(_buildCommand(0x00, 0x00, 0x00, 0x4F)); + //====== 核心方法 ======// + Future _sendCommand(List command) async { + debugPrint( + '发送指令: ${command.map((e) => e.toRadixString(16).padLeft(2, '0'))}'); + try { + return await _writeFn(Uint8List.fromList(command)); + } catch (e) { + debugPrint('指令发送失败: $e'); + return false; + } + } + + void parseResponse(List data) { + if (data.length >= minFrameLength && data[0] == 0xFF && data[1] == 0xFF) { + // 设备上报帧处理(第7字节为0x06) + if (data[7] == 0x06) { + final functionCode = data[8]; + debugPrint('收到设备上报: 功能码=${functionCode.toRadixString(16)}'); + } + _statusController.add(BedStatus.fromBytes(data)); + } + } + + void dispose() => _statusController.close(); + + Future setAlarm({ + required bool isStart, + required List wakeTime, + required List weeks, + required bool isMassage, + required bool isBell, + }) async { + // 1. 参数校验 + if (wakeTime.length != 2 || weeks.length != 7) { + debugPrint('参数错误:唤醒时间或星期数不符'.tr); + return false; + } + + // 2. 构造指令(固定头 + 动态数据) + final arr = [ + 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x02, 0x13, // 固定头 + isStart ? 0x01 : 0xA1, // 开关状态 + int.parse(wakeTime[0], radix: 16), // 小时(16进制) + int.parse(wakeTime[1], radix: 16), // 分钟(16进制) + 0x00, // 保留位 + ]; + + // 3. 计算星期掩码 + final weekValues = weeks.map((w) => int.tryParse(w) ?? 0).toList(); + final weekMask = weekValues[0] * 2 + // 周一 + weekValues[1] * 4 + // 周二 + weekValues[2] * 8 + // 周三 + weekValues[3] * 16 + // 周四 + weekValues[4] * 32 + // 周五 + weekValues[5] * 64 + // 周六 + weekValues[6] * 128; // 周日 + arr.addAll([ + weekMask, + weekMask > 1 ? 1 : 0, // 是否重复 + 0x01, // 固定值 + isMassage ? 1 : 0, + isBell ? 1 : 0, + ]); + + // 4. 计算校验和(小端序) + _addSumInEnd(arr); + + // 5. 发送指令并等待响应 + debugPrint('闹钟指令: ${arr.map((e) => e.toRadixString(16).padLeft(2, '0'))}'); + return await _writeFn(Uint8List.fromList(arr)); + } + + List _calculateChecksum(List data) { + int sum = 0; + for (var byte in data) { + sum += byte; + } + return [sum & 0xFF, (sum >> 8) & 0xFF]; + } + + void _addSumInEnd(List arr) { + int sum = arr.fold(0, (acc, byte) => acc + byte); + arr.add(sum & 0xFF); // 低字节 + arr.add((sum >> 8) & 0xFF); // 高字节 + } + + Future setDeviceTime(DateTime dateTime) async { + // 1. 参数校验 + // if (dateTime.year < 2000 || dateTime.year > 2099) { + // debugPrint('年份必须在2000-2099之间'); + // return false; + // } + + DateTime date = DateTime.now(); + // 2. 构造基础指令数据(不含校验和) + final arr = [ + 0xFF, 0xFF, 0xFF, 0xFF, // 帧头 (0-3) + 0x01, 0x00, 0x01, 0x11, // 功能标识:时间校验 (4-7) + ]; + + arr.add(int.parse("${date.hour}", radix: 16)); + arr.add(int.parse("${date.minute}", radix: 16)); + arr.add(int.parse("${date.second}", radix: 16)); + arr.add(int.parse("${date.weekday}", radix: 16)); + arr.add(int.parse("${date.year}".substring(2), radix: 16)); + arr.add(int.parse("${date.month}", radix: 16)); + arr.add(int.parse("${date.day}", radix: 16)); + + // 3. 计算并添加校验和(低字节在前) + _addSumInEnd(arr); + + // 4. 发送指令 + debugPrint( + '时间校验指令: ${arr.map((e) => e.toRadixString(16).padLeft(2, '0')).join(' ')}'); + debugPrint('设置时间: ${dateTime.toString()}'); + return _sendCommand(arr); + } + + /// 将DateTime的weekday(1-7)转换为协议要求的星期值 + /// DateTime.weekday: 1=Monday, 2=Tuesday, ..., 7=Sunday + /// 协议要求: 1=周一, 2=周二, ..., 7=周日 + int _getWeekdayValue(int weekday) { + // 由于DateTime的weekday已经是1=周一, 7=周日,直接返回即可 + return weekday; + } + + /// 使用当前系统时间同步设备时间 + Future syncDeviceTime() async { + final now = DateTime.now(); + debugPrint('开始同步设备时间: ${now.toString()}'); + return await setDeviceTime(now); + } + + /// 设置自定义时间(部分参数可选) + Future setCustomTime({ + int? hour, + int? minute, + int? second = 0, + int? year, + int? month, + int? day, + }) async { + final now = DateTime.now(); + final targetTime = DateTime( + year ?? now.year, + month ?? now.month, + day ?? now.day, + hour ?? now.hour, + minute ?? now.minute, + second ?? 0, + ); + + debugPrint('设置自定义时间: ${targetTime.toString()}'); + return await setDeviceTime(targetTime); + } + + /// 快速设置时间(仅小时和分钟) + Future setTime(int hour, int minute) async { + return await setCustomTime(hour: hour, minute: minute, second: 0); + } + + /// 设置日期(年、月、日) + Future setDate(int year, int month, int day) async { + return await setCustomTime(year: year, month: month, day: day); + } + + Future exec({ + required ProtocolDoExecFunc func, + ProtocolOnStatusFunc? onstatus, + int retry = 3, + Duration timeout = const Duration(seconds: 3), + }) async { + for (int i = 0; i < retry; i++) { + try { + if (i > 0) { + //缓一下 + await Future.delayed(Duration(milliseconds: 100)); + } + var re = await func(); + if (onstatus == null || re == false) return re; + //等待 + dynamic status = await statusStream.first.timeout(timeout); + bool ok = onstatus(status); + if (ok) { + return true; + } + } catch (e) { + e; + if (onstatus == null) return false; + } + } + return false; + } +} + +// BedStatus类保持不变... + +// 床状态模型 +class BedStatus { + final bool headUp; + final bool headDown; + final bool backUp; + final bool backDown; + final bool legUp; + final bool legDown; + final bool hipUp; + final bool hipDown; + final bool massageOn; + final int massageLevel; + final int massageTimeRemaining; + final bool isChildLocked; + + const BedStatus({ + required this.headUp, + required this.headDown, + required this.backUp, + required this.backDown, + required this.legUp, + required this.legDown, + required this.hipUp, + required this.hipDown, + required this.massageOn, + required this.massageLevel, + required this.massageTimeRemaining, + required this.isChildLocked, + }); + + factory BedStatus.fromBytes(List data) { + return BedStatus( + headUp: (data[5] & 0x01) != 0, + headDown: (data[5] & 0x02) != 0, + backUp: (data[6] & 0x01) != 0, + backDown: (data[6] & 0x02) != 0, + legUp: (data[7] & 0x01) != 0, + legDown: (data[7] & 0x02) != 0, + hipUp: (data[8] & 0x01) != 0, + hipDown: (data[8] & 0x02) != 0, + massageOn: (data[9] & 0x0F) != 0, + massageLevel: (data[9] >> 4) & 0x0F, + massageTimeRemaining: data.length > 10 ? data[10] : 0, + isChildLocked: data.length > 11 ? (data[11] & 0x80) != 0 : false, + ); + } + + static const defaultStatus = BedStatus( + headUp: false, + headDown: false, + backUp: false, + backDown: false, + legUp: false, + legDown: false, + hipUp: false, + hipDown: false, + massageOn: false, + massageLevel: 0, + massageTimeRemaining: 0, + isChildLocked: false, + ); +} diff --git a/lib/pages/mh_page/device/component/tool/DeviceType.dart b/lib/pages/mh_page/device/component/tool/DeviceType.dart new file mode 100644 index 0000000..48672ff --- /dev/null +++ b/lib/pages/mh_page/device/component/tool/DeviceType.dart @@ -0,0 +1,40 @@ + +import 'package:ef/ef.dart'; + +enum DeviceType { + smartBed, // 2: 智能床 + smartMattress // 3: 智能床垫 +} + +extension DeviceTypeExtension on DeviceType { + /// 获取整型值 + int get value { + switch (this) { + case DeviceType.smartBed: + return 2; + case DeviceType.smartMattress: + return 3; + } + } + + /// 根据整型值解析为枚举 + static DeviceType? fromInt(int? type) { + switch (type) { + case 2: + return DeviceType.smartBed; + case 3: + return DeviceType.smartMattress; + default: + return null; + } + } + + String get description { + switch (this) { + case DeviceType.smartBed: + return "智能电动床".tr; + case DeviceType.smartMattress: + return "律动智能床垫".tr; + } + } +} diff --git a/lib/pages/mh_page/device/controller/mht_bluetooth_controller.dart b/lib/pages/mh_page/device/controller/mht_bluetooth_controller.dart index 97d14c5..c6ddef4 100644 --- a/lib/pages/mh_page/device/controller/mht_bluetooth_controller.dart +++ b/lib/pages/mh_page/device/controller/mht_bluetooth_controller.dart @@ -74,9 +74,9 @@ class MHTBlueToothController extends GetControllerEx { RxBool isScanning = false.obs; RxMap localUpgradeMac = {}.obs; //mac 进度 - String? currentUpgradeVersion;//最新版本号 - String? currentUpgradeName;//最新固件名 - String? currentUpgradeUrl;//最新固件名 + String? currentUpgradeVersion; //最新版本号 + String? currentUpgradeName; //最新固件名 + String? currentUpgradeUrl; //最新固件名 void startStatusPolling() { updateDeviceStatus().then((res) { @@ -264,7 +264,8 @@ class MHTBlueToothController extends GetControllerEx { return ApiResponse(code: -1, msg: "未知错误".tr); } - saveHabitData(sleepData) async { + Future saveHabitData(sleepData) async { + bool resFlag = false; String serviceAddress = ServiceConstant.service_address; String serviceName = ServiceConstant.server_service; String serviceApi = ServiceConstant.user_setting; @@ -281,7 +282,14 @@ class MHTBlueToothController extends GetControllerEx { method: MyHttpMethod.put, queryUrl: queryUrl, data: data, + onSuccess: (res) { + resFlag = true; + }, + onFailure: (res) { + resFlag = false; + }, ); + return resFlag; } Future loadHabitDataApi(String mac, {int time = 3}) async { diff --git a/lib/pages/mh_page/device/mht_wifi_page.dart b/lib/pages/mh_page/device/mht_wifi_page.dart index 64cc8e8..11ba834 100644 --- a/lib/pages/mh_page/device/mht_wifi_page.dart +++ b/lib/pages/mh_page/device/mht_wifi_page.dart @@ -24,6 +24,7 @@ import 'package:vbvs_app/controller/user_info_controller.dart'; import 'package:vbvs_app/model/BleDeviceData.dart'; import 'package:vbvs_app/pages/device_bind/blueteeth_device_page.dart'; import 'package:vbvs_app/pages/mh_page/component/mht_bind_dialog.dart'; +import 'package:vbvs_app/pages/mh_page/device/controller/mht_bluetooth_controller.dart'; import 'package:vbvs_app/pages/mh_page/device/model/BlueToothDataModel.dart'; import 'package:EasyDartModule/EasyDartModule.dart' as edm; @@ -39,6 +40,7 @@ class _MHTWifiPageState extends State { GlobalController globalController = Get.find(); UserInfoController userInfoController = Get.find(); BlueteethBindController blueteethBindController = Get.find(); + MHTBlueToothController mhtBlueToothController = Get.find(); PersonController personController = Get.find(); ThemeController themeController = Get.find(); var lisObj; @@ -226,6 +228,7 @@ class _MHTWifiPageState extends State { onBack: () { // Get.offAllNamed('/mHTBlueteethDevicePage', // arguments: widget.deviceInfo.type); + blueteethBindController.currentDevice?.disconnect(); Get.back(); }, ), @@ -928,6 +931,14 @@ class _MHTWifiPageState extends State { } } else { wifiStatus = false; + if (needSuccess) { + haveSuccess = true; + TopSlideNotification.show( + context, + text: "配网失败".tr, + textColor: themeController.currentColor.sc9, + ); + } } blueteethBindController.wifiStatus.value = wifiStatus ? 1 : 0; } catch (e) { @@ -1348,6 +1359,9 @@ class _MHTWifiPageState extends State { await blueteethBindController.currentDevice!.disconnect(); // blueteethBindController.currentDevice = null; } + if (mhtBlueToothController.currentDevice != null) { + await mhtBlueToothController.currentDevice!.disconnect(); + } DailyLogUtils.writeLog("关闭蓝牙连接成功".tr); } catch (e) { DailyLogUtils.writeError("关闭蓝牙连接失败: $e"); diff --git a/lib/pages/mh_page/device/mht_wifi_page_after.dart b/lib/pages/mh_page/device/mht_wifi_page_after.dart index 07200f7..74b2d0b 100644 --- a/lib/pages/mh_page/device/mht_wifi_page_after.dart +++ b/lib/pages/mh_page/device/mht_wifi_page_after.dart @@ -891,6 +891,14 @@ class _MHTWifiAfterPageState extends State { } } else { wifiStatus = false; + if (needSuccess) { + haveSuccess = true; + TopSlideNotification.show( + context, + text: "配网失败".tr, + textColor: themeController.currentColor.sc9, + ); + } } blueteethBindController.wifiStatus.value = wifiStatus ? 1 : 0; } catch (e) { diff --git a/lib/pages/mh_page/homepage/new_Home_page.dart b/lib/pages/mh_page/homepage/new_Home_page.dart index 9c27146..9334bde 100644 --- a/lib/pages/mh_page/homepage/new_Home_page.dart +++ b/lib/pages/mh_page/homepage/new_Home_page.dart @@ -87,6 +87,11 @@ class _NewHomePageState extends State { if (AppConstants().ent_type != APPPackageType.MHT.code) { return; } + if (userInfoController.model.login! == null || + userInfoController.model.login! == 0) { + //未登录 + return; + } showTipUpgradeDialog( context, Column( diff --git a/lib/pages/mh_page/new_settingPage.dart b/lib/pages/mh_page/new_settingPage.dart index c4ea039..b3cca13 100644 --- a/lib/pages/mh_page/new_settingPage.dart +++ b/lib/pages/mh_page/new_settingPage.dart @@ -253,7 +253,7 @@ class _SettingPageState extends State { ), ].divide(SizedBox(width: 22.rpx)), ), - Text('SWES2025.10.28', + Text('SWES2025.10.31', style: TextStyle( color: Colors.white, fontSize: 26.rpx, diff --git a/lib/pages/mh_page/test/WebviewTestModel.dart b/lib/pages/mh_page/test/WebviewTestModel.dart index 43b1206..3b10530 100644 --- a/lib/pages/mh_page/test/WebviewTestModel.dart +++ b/lib/pages/mh_page/test/WebviewTestModel.dart @@ -58,7 +58,7 @@ class WebviewTestController extends GetControllerEx { }, onLoadResource: (controller, resource) { // sourceTime = web.requestTimestamp; - // ef.log("[请求资源时间]${web.requestTimestamp}");` + // ef.log("[请求资源时间]${web.requestTimestamp}"); // _startMonitoringIfNeeded(); }, ), @@ -216,7 +216,7 @@ class WebviewTestController extends GetControllerEx { ef.log('更新睡眠习惯: $args[0]'); try { MHTBlueToothController blueToothController = Get.find(); - await blueToothController.saveHabitData(args[0]); + return await blueToothController.saveHabitData(args[0]); } catch (e) { ef.log("[更新睡眠习惯失败]:$e"); }