diff --git a/assets/file.json b/assets/file.json index e20e2ff..df7873a 100644 --- a/assets/file.json +++ b/assets/file.json @@ -1,3 +1,3 @@ [ - "assets/miniapp/mhtControl_1.0.84.zip" + "assets/miniapp/mhtControl_1.0.85.zip" ] \ No newline at end of file diff --git a/assets/mhlangs/en_US.json b/assets/mhlangs/en_US.json index 0c3f687..bf1acee 100644 --- a/assets/mhlangs/en_US.json +++ b/assets/mhlangs/en_US.json @@ -626,5 +626,6 @@ "立即升级": "Upgrade Now", "取消升级": "Cancel Upgrade", "通知设置": "Notification Setting", - "睡眠报告通知":"Sleep Report Notification" + "睡眠报告通知":"Sleep Report Notification", + "糖管家":"SweetyKeeper" } \ No newline at end of file diff --git a/assets/mhlangs/zh_CN.json b/assets/mhlangs/zh_CN.json index 08a3f32..4104747 100644 --- a/assets/mhlangs/zh_CN.json +++ b/assets/mhlangs/zh_CN.json @@ -626,5 +626,6 @@ "立即升级": "立即升级", "取消升级": "取消升级", "通知设置": "通知设置", - "睡眠报告通知":"睡眠报告通知" + "睡眠报告通知":"睡眠报告通知", + "糖管家": "糖管家" } \ No newline at end of file diff --git a/assets/mhlangs/zh_TW.json b/assets/mhlangs/zh_TW.json index 959c078..2108e49 100644 --- a/assets/mhlangs/zh_TW.json +++ b/assets/mhlangs/zh_TW.json @@ -625,5 +625,6 @@ "立即升级": "立即升級", "取消升级": "取消升級", "通知设置": "通知設置", - "睡眠报告通知":"睡眠報告通知" + "睡眠报告通知":"睡眠報告通知", + "糖管家":"糖管家" } \ No newline at end of file diff --git a/assets/miniapp/mhtControl_1.0.84.zip b/assets/miniapp/mhtControl_1.0.85.zip similarity index 97% rename from assets/miniapp/mhtControl_1.0.84.zip rename to assets/miniapp/mhtControl_1.0.85.zip index a1fb208..353c150 100644 Binary files a/assets/miniapp/mhtControl_1.0.84.zip and b/assets/miniapp/mhtControl_1.0.85.zip differ diff --git a/lib/component/tool/cmd.dart b/lib/component/tool/cmd.dart index 70781e5..401951b 100644 --- a/lib/component/tool/cmd.dart +++ b/lib/component/tool/cmd.dart @@ -82,8 +82,10 @@ Future sendWifiSetting(wifiItem, String password, THapp tHapp) async { try { edm.EasyDartModule.logger.info("发送wifi配置指令"); DailyLogUtils.writeLog("发送wifi配置指令->"); + // String cmd = "vtouch save update -a -i .wifi.sta.auth=${wifiItem['auth']} " + // ".wifi.sta.ssid=${wifiItem['ssid']} .wifi.sta.pwd=$password"; String cmd = "vtouch save update -a -i .wifi.sta.auth=${wifiItem['auth']} " - ".wifi.sta.ssid=${wifiItem['ssid']} .wifi.sta.pwd=$password"; + ".wifi.sta.ssid=\"${wifiItem['ssid']}\" .wifi.sta.pwd=\"$password\""; final success = await tHapp.send(cmd, true, (log) { if (log.log.contains("update parm is successful")) { print("[wifi456]:" + log.log); @@ -189,7 +191,7 @@ Future getDeviceNetVersion(THapp tHapp, int times) async { } ss.over = false; return false; - }, times,15000); + }, times, 15000); return netType; } catch (e) { diff --git a/lib/controller/mh_controller/device_list_controller.dart b/lib/controller/mh_controller/device_list_controller.dart index d16d710..c5aea4f 100644 --- a/lib/controller/mh_controller/device_list_controller.dart +++ b/lib/controller/mh_controller/device_list_controller.dart @@ -126,6 +126,8 @@ class DeviceListController extends GetControllerEx { } else { msg = '删除成功'.tr; } + //删除用户的自定义配置 + delDeviceSleepHabit(device); }, onFailure: (res) { if (type == 1) { @@ -161,4 +163,43 @@ class DeviceListController extends GetControllerEx { }, ); } + + void delDeviceSleepHabit(Map device) { + String serviceAddress = ServiceConstant.service_address; + String serviceName = ServiceConstant.server_service; + String serviceApi = ServiceConstant.user_setting; + String type = "sleep_habit_${formatMacAddress(device['mac'])}"; + String queryUrl = + "${serviceAddress}${serviceName}${serviceApi}?type=${type}"; + requestWithLog( + logTitle: "删除设备自定义配置", + method: MyHttpMethod.delete, + queryUrl: queryUrl, + onSuccess: (res) { + print(res); + }, + onFailure: (res) { + print(res); + }, + ); + } + + String formatMacAddress(String input) { + if (input.isEmpty) return input; + + // 1. 移除所有非16进制字符(去掉冒号、空格、破折号等) + String clean = input.replaceAll(RegExp(r'[^a-fA-F0-9]'), ''); + + // 2. 如果长度不足12,左侧补0(MAC地址长度固定12) + clean = clean.padLeft(12, '0'); + + // 3. 按2个字符一组,拼接冒号 + List parts = []; + for (int i = 0; i < 12; i += 2) { + parts.add(clean.substring(i, i + 2).toUpperCase()); + } + + // 4. 返回格式化字符串 + return parts.join(':'); + } } diff --git a/lib/pages/main_bottom/message_page.dart b/lib/pages/main_bottom/message_page.dart index 617923d..95a6e59 100644 --- a/lib/pages/main_bottom/message_page.dart +++ b/lib/pages/main_bottom/message_page.dart @@ -1,7 +1,6 @@ import 'package:ef/ef.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:flutterflow_ui/flutterflow_ui.dart'; import 'package:vbvs_app/common/color/appConstants.dart'; import 'package:vbvs_app/common/color/app_uri_status.dart'; import 'package:vbvs_app/common/util/FitTool.dart'; diff --git a/lib/pages/mh_page/homepage/new_Home_page.dart b/lib/pages/mh_page/homepage/new_Home_page.dart index 6260617..9c27146 100644 --- a/lib/pages/mh_page/homepage/new_Home_page.dart +++ b/lib/pages/mh_page/homepage/new_Home_page.dart @@ -16,6 +16,7 @@ import 'package:vbvs_app/controller/user_info_controller.dart'; import 'package:vbvs_app/controller/weather/weather_controller.dart'; import 'package:vbvs_app/enum/APPPackageType.dart'; import 'package:vbvs_app/pages/main_bottom/component/main_page_b_bottom_change.dart'; +import 'package:vbvs_app/pages/mh_page/FloatingSvgIcon.dart'; import 'package:vbvs_app/pages/mh_page/component/mht_bind_dialog.dart'; import 'package:vbvs_app/pages/mh_page/homepage/component/HomeDeviceWidget.dart'; import 'package:vbvs_app/pages/mh_page/homepage/controller/mht_home_controller.dart'; @@ -229,21 +230,20 @@ class _NewHomePageState extends State { child: userInfo(userInfoController.model.login), ); }), - // const Spacer(), // 左右分隔 - // FloatingSvgIcon( - // assetPath: 'assets/img/icon/xiaoyi.svg', - // width: 60.rpx, - // height: 60.rpx, - // onTap: () { - // // print("点击了小鹅图标"); - // if (userInfoController.model.login == 0) { - // Get.toNamed("/loginPage"); - // } - // Get.toNamed("/xiaoEPage", - // arguments: - // "https://xiaoe.he-info.cn/?mac=b43a45c3ddf4"); - // }, - // ), + const Spacer(), // 左右分隔 + FloatingSvgIcon( + assetPath: 'assets/img/icon/xiaoyi.svg', + width: 60.rpx, + height: 60.rpx, + onTap: () { + // print("点击了小鹅图标"); + if (userInfoController.model.login == 0) { + Get.toNamed("/loginPage"); + } + Get.toNamed("/xiaoEPage", + arguments: "https://xiaoe.he-info.cn/"); + }, + ), SizedBox(width: 40.rpx), ], ), @@ -538,7 +538,7 @@ class _NewHomePageState extends State { size: 30.rpx, ), fillColor: stringToColor( - "##011D33"), + "#011D33"), elevation: 2, borderColor: Colors.transparent, diff --git a/lib/pages/mh_page/new_settingPage.dart b/lib/pages/mh_page/new_settingPage.dart index 0d849a8..3ff855f 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('SWES3.513.4', + Text('SWES2025.9.8', style: TextStyle( color: Colors.white, fontSize: 26.rpx, diff --git a/lib/pages/xiaoe/xiaoe_page.dart b/lib/pages/xiaoe/xiaoe_page.dart index 8136bc5..75aac1f 100644 --- a/lib/pages/xiaoe/xiaoe_page.dart +++ b/lib/pages/xiaoe/xiaoe_page.dart @@ -1,23 +1,228 @@ +import 'dart:convert'; + import 'package:ef/ef.dart'; import 'package:flutter/material.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:vbvs_app/common/color/ServiceConstant.dart'; +import 'package:vbvs_app/common/color/appConstants.dart'; import 'package:vbvs_app/common/util/FitTool.dart'; import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/common/util/requestWithLog.dart'; import 'package:vbvs_app/controller/device/blueteeth_bind_controller.dart'; import 'package:vbvs_app/controller/device/device_type_controller.dart'; import 'package:vbvs_app/controller/main_bottom/global_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:EasyDartModule/EasyDartModule.dart' as edm; + +// class XiaoEPage extends StatefulWidget { +// var sleepUri; +// XiaoEPage({super.key, required this.sleepUri}); + +// @override +// State createState() => _XiaoEPageState(); +// } + +// class _XiaoEPageState extends State { +// GlobalController globalController = Get.find(); +// UserInfoController userInfoController = Get.find(); +// BlueteethBindController blueteethBindController = Get.find(); +// ThemeController themeController = Get.find(); +// DeviceTypeController deviceTypeController = Get.find(); + +// ValueNotifier isPageLoading = ValueNotifier(true); +// RxList deviceList = [].obs; +// RxString finalUri = RxString(''); + +// @override +// void initState() { +// super.initState(); +// getDeviceList(); +// } + +// @override +// void dispose() { +// // 清理 ValueNotifier +// isPageLoading.dispose(); +// super.dispose(); +// } + +// @override +// Widget build(BuildContext context) { +// return LayoutBuilder( +// builder: (context, bodySize) => GestureDetector( +// // onTap: () => FocusScope.of(context).unfocus(),, +// child: Container( +// decoration: BoxDecoration( +// image: DecorationImage( +// // image: AssetImage('assets/img/bgNoImg.png'), // 本地图片 +// image: AssetImage('assets/images/new_background.png'), // 本地图片 +// fit: BoxFit.fill, // 填满整个 Container +// ), +// ), +// child: Scaffold( +// backgroundColor: Colors.transparent, // 背景透明 +// appBar: AppBar( +// // backgroundColor: themeController.currentColor.sc17, +// backgroundColor: Colors.transparent, +// automaticallyImplyLeading: false, +// iconTheme: IconThemeData(color: themeController.currentColor.sc3), +// titleSpacing: 0, +// title: Container( +// width: double.infinity, +// height: 180.rpx, +// child: Stack( +// alignment: Alignment.center, +// children: [ +// /// 居中标题 +// Text( +// '糖管家'.tr, +// style: TextStyle( +// fontFamily: 'Readex Pro', +// color: themeController.currentColor.sc3, +// letterSpacing: 0, +// fontSize: 30.rpx, +// ), +// ), + +// /// 左边返回按钮 +// Positioned( +// left: 0, +// child: returnIconButtomNew(), +// ), +// ], +// ), +// ), +// ), +// body: SafeArea( +// top: true, +// child: Obx(() { +// String sleepUri = finalUri.value; +// ef.log('finalUri: $sleepUri'); +// return Stack( +// children: [ +// InAppWebView( +// key: UniqueKey(), +// initialUrlRequest: URLRequest(url: WebUri(sleepUri)), +// onLoadStart: (controller, url) { +// // 页面开始加载时显示加载指示器 +// isPageLoading.value = true; +// }, +// onLoadStop: (controller, url) { +// // 页面加载完成后隐藏加载指示器 +// isPageLoading.value = false; +// }, +// initialOptions: InAppWebViewGroupOptions( +// crossPlatform: InAppWebViewOptions( +// transparentBackground: true, // ✅ 背景透明 +// ), +// ), +// ), +// ValueListenableBuilder( +// valueListenable: isPageLoading, +// builder: (context, isLoading, child) { +// return isLoading +// ? Center( +// child: CircularProgressIndicator( +// strokeWidth: 2, +// valueColor: AlwaysStoppedAnimation( +// themeController.currentColor.sc1, +// ), +// ), // 加载指示器 +// ) +// : SizedBox.shrink(); +// }, +// ), +// ], +// ); +// }), +// ), +// ), +// ), +// ), +// ); +// } + +// Future getDeviceList() async { +// String serviceAddress = ServiceConstant.service_address; +// String serviceName = ServiceConstant.server_service; +// String serviceApi = ServiceConstant.personnel_info; + +// // 初始URL +// String queryUrl = "$serviceAddress$serviceName$serviceApi"; +// await requestWithLog( +// logTitle: "请求人员信息列表".tr, +// method: MyHttpMethod.get, +// queryUrl: queryUrl, +// onSuccess: (res) { +// List rawList = res.data ?? []; +// List> newList = rawList.map((item) { +// String mac = item['mac'] ?? ''; +// String name = (item['person'] != null && +// item['person']['name'] != null && +// item['person']['name'].toString().trim().isNotEmpty) +// ? item['person']['name'] + "_${mac}" +// : '未命名'.tr + "_${mac}"; +// return { +// 'mac': mac, +// 'name': name, +// }; +// }).toList(); +// deviceList.value = newList; + +// // 拼接参数 person +// if (deviceList.isNotEmpty) { +// // JSON 编码整个 deviceList 对象数组 +// String personParam = Uri.encodeComponent(jsonEncode(deviceList)); +// finalUri.value = "${widget.sleepUri}?person=$personParam"; +// } else { +// finalUri.value = widget.sleepUri; +// } +// }, +// onFailure: (res) { +// edm.EasyDartModule.logger.warning("请求人员信息列表失败: ${res.msg}"); +// }, +// ); +// String? language = ""; +// if (AppConstants().ent_type == APPPackageType.MHT.code) { +// if (mhLanguageController.selectLanguage != null) { +// language = mhLanguageController.selectLanguage.value!.language_code; +// } +// } else { +// if (languageController.selectLanguage != null) { +// language = languageController.selectLanguage.value!.language_code; +// } +// } +// if (language != null && language.isNotEmpty) { +// if (finalUri.value.contains("?")) { +// finalUri.value += "&lang=$language"; +// } else { +// finalUri.value += "?lang=$language"; +// } +// } +// if (finalUri.value.contains("?")) { +// finalUri.value += "&code=mht"; +// } else { +// finalUri.value += "?code=mht"; +// } +// ef.log("msg"); +// edm.EasyDartModule.logger.info("finalUri: ${finalUri.value}"); +// ef.log("finalUri: ${finalUri.value}"); +// } +// } class XiaoEPage extends StatefulWidget { - var sleepUri; - XiaoEPage({super.key, required this.sleepUri}); + final String sleepUri; + const XiaoEPage({super.key, required this.sleepUri}); @override State createState() => _XiaoEPageState(); } -class _XiaoEPageState extends State { +class _XiaoEPageState extends State + with AutomaticKeepAliveClientMixin { + // ✅ 保持页面状态 GlobalController globalController = Get.find(); UserInfoController userInfoController = Get.find(); BlueteethBindController blueteethBindController = Get.find(); @@ -25,47 +230,51 @@ class _XiaoEPageState extends State { DeviceTypeController deviceTypeController = Get.find(); ValueNotifier isPageLoading = ValueNotifier(true); + RxList deviceList = [].obs; + RxString finalUri = RxString(''); + + @override + bool get wantKeepAlive => true; // ✅ 开启页面缓存 @override void initState() { super.initState(); + getDeviceList(); } @override void dispose() { - // 清理 ValueNotifier isPageLoading.dispose(); super.dispose(); } @override Widget build(BuildContext context) { + super.build(context); // ✅ 必须调用,保证 keepAlive 生效 return LayoutBuilder( builder: (context, bodySize) => GestureDetector( - // onTap: () => FocusScope.of(context).unfocus(),, child: Container( decoration: BoxDecoration( - image: DecorationImage( - image: AssetImage('assets/img/bgNoImg.png'), // 本地图片 - fit: BoxFit.fill, // 填满整个 Container + image: const DecorationImage( + image: AssetImage('assets/images/new_background.png'), + fit: BoxFit.fill, ), ), child: Scaffold( - backgroundColor: Colors.transparent, // 背景透明 + backgroundColor: Colors.transparent, appBar: AppBar( - backgroundColor: themeController.currentColor.sc17, + backgroundColor: Colors.transparent, automaticallyImplyLeading: false, iconTheme: IconThemeData(color: themeController.currentColor.sc3), titleSpacing: 0, - title: Container( + title: SizedBox( width: double.infinity, height: 180.rpx, child: Stack( alignment: Alignment.center, children: [ - /// 居中标题 Text( - '小e'.tr, + '糖管家'.tr, style: TextStyle( fontFamily: 'Readex Pro', color: themeController.currentColor.sc3, @@ -73,8 +282,6 @@ class _XiaoEPageState extends State { fontSize: 30.rpx, ), ), - - /// 左边返回按钮 Positioned( left: 0, child: returnIconButtomNew(), @@ -85,41 +292,125 @@ class _XiaoEPageState extends State { ), body: SafeArea( top: true, - child: Stack( - children: [ - InAppWebView( - key: UniqueKey(), - initialUrlRequest: URLRequest(url: WebUri(widget.sleepUri)), - onLoadStart: (controller, url) { - // 页面开始加载时显示加载指示器 - isPageLoading.value = true; - }, - onLoadStop: (controller, url) { - // 页面加载完成后隐藏加载指示器 - isPageLoading.value = false; - }, - ), - ValueListenableBuilder( - valueListenable: isPageLoading, - builder: (context, isLoading, child) { - return isLoading - ? Center( - child: CircularProgressIndicator( - strokeWidth: 2, - valueColor: AlwaysStoppedAnimation( - themeController.currentColor.sc1, + child: Obx(() { + String sleepUri = finalUri.value; + ef.log('finalUri: $sleepUri'); + + if (sleepUri.isEmpty) { + return Center( + child: CircularProgressIndicator( + strokeWidth: 2, + valueColor: AlwaysStoppedAnimation( + themeController.currentColor.sc1, + ), + ), + ); + } + + return Stack( + children: [ + InAppWebView( + key: UniqueKey(), + initialUrlRequest: URLRequest(url: WebUri(sleepUri)), + onLoadStart: (controller, url) { + isPageLoading.value = true; + }, + onLoadStop: (controller, url) { + isPageLoading.value = false; + }, + initialOptions: InAppWebViewGroupOptions( + crossPlatform: InAppWebViewOptions( + transparentBackground: true, + ), + ), + ), + ValueListenableBuilder( + valueListenable: isPageLoading, + builder: (context, isLoading, child) { + return isLoading + ? Center( + child: CircularProgressIndicator( + strokeWidth: 2, + valueColor: AlwaysStoppedAnimation( + themeController.currentColor.sc1, + ), ), - ), // 加载指示器 - ) - : SizedBox.shrink(); - }, - ), - ], - ), + ) + : const SizedBox.shrink(); + }, + ), + ], + ); + }), ), ), ), ), ); } + + Future getDeviceList() async { + String serviceAddress = ServiceConstant.service_address; + String serviceName = ServiceConstant.server_service; + String serviceApi = ServiceConstant.personnel_info; + + String queryUrl = "$serviceAddress$serviceName$serviceApi"; + await requestWithLog( + logTitle: "请求人员信息列表".tr, + method: MyHttpMethod.get, + queryUrl: queryUrl, + onSuccess: (res) { + List rawList = res.data ?? []; + List> newList = rawList.map((item) { + String mac = item['mac'] ?? ''; + String name = (item['person'] != null && + item['person']['name'] != null && + item['person']['name'].toString().trim().isNotEmpty) + ? item['person']['name'] + "_$mac" + : '未命名'.tr + "_$mac"; + return {'mac': mac, 'name': name}; + }).toList(); + + deviceList.value = newList; + + if (deviceList.isNotEmpty) { + String personParam = Uri.encodeComponent(jsonEncode(deviceList)); + finalUri.value = "${widget.sleepUri}?person=$personParam"; + } else { + finalUri.value = widget.sleepUri; + } + }, + onFailure: (res) { + edm.EasyDartModule.logger.warning("请求人员信息列表失败: ${res.msg}"); + }, + ); + + String? language = ""; + if (AppConstants().ent_type == APPPackageType.MHT.code) { + if (mhLanguageController.selectLanguage != null) { + language = mhLanguageController.selectLanguage.value!.language_code; + } + } else { + if (languageController.selectLanguage != null) { + language = languageController.selectLanguage.value!.language_code; + } + } + + if (language != null && language.isNotEmpty) { + if (finalUri.value.contains("?")) { + finalUri.value += "&lang=$language"; + } else { + finalUri.value += "?lang=$language"; + } + } + + if (finalUri.value.contains("?")) { + finalUri.value += "&code=mht"; + } else { + finalUri.value += "?code=mht"; + } + + edm.EasyDartModule.logger.info("finalUri: ${finalUri.value}"); + ef.log("finalUri: ${finalUri.value}"); + } }