更新小e

This commit is contained in:
wyf
2025-09-18 17:52:02 +08:00
parent 2efbd5df57
commit 676c51f339
11 changed files with 405 additions and 69 deletions

View File

@@ -1,3 +1,3 @@
[ [
"assets/miniapp/mhtControl_1.0.84.zip" "assets/miniapp/mhtControl_1.0.85.zip"
] ]

View File

@@ -626,5 +626,6 @@
"立即升级": "Upgrade Now", "立即升级": "Upgrade Now",
"取消升级": "Cancel Upgrade", "取消升级": "Cancel Upgrade",
"通知设置": "Notification Setting", "通知设置": "Notification Setting",
"睡眠报告通知":"Sleep Report Notification" "睡眠报告通知":"Sleep Report Notification",
"糖管家":"SweetyKeeper"
} }

View File

@@ -626,5 +626,6 @@
"立即升级": "立即升级", "立即升级": "立即升级",
"取消升级": "取消升级", "取消升级": "取消升级",
"通知设置": "通知设置", "通知设置": "通知设置",
"睡眠报告通知":"睡眠报告通知" "睡眠报告通知":"睡眠报告通知",
"糖管家": "糖管家"
} }

View File

@@ -625,5 +625,6 @@
"立即升级": "立即升級", "立即升级": "立即升級",
"取消升级": "取消升級", "取消升级": "取消升級",
"通知设置": "通知設置", "通知设置": "通知設置",
"睡眠报告通知":"睡眠報告通知" "睡眠报告通知":"睡眠報告通知",
"糖管家":"糖管家"
} }

View File

@@ -82,8 +82,10 @@ Future<bool> sendWifiSetting(wifiItem, String password, THapp tHapp) async {
try { try {
edm.EasyDartModule.logger.info("发送wifi配置指令"); edm.EasyDartModule.logger.info("发送wifi配置指令");
DailyLogUtils.writeLog("发送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']} " 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) { final success = await tHapp.send(cmd, true, (log) {
if (log.log.contains("update parm is successful")) { if (log.log.contains("update parm is successful")) {
print("[wifi456]:" + log.log); print("[wifi456]:" + log.log);
@@ -189,7 +191,7 @@ Future<String> getDeviceNetVersion(THapp tHapp, int times) async {
} }
ss.over = false; ss.over = false;
return false; return false;
}, times,15000); }, times, 15000);
return netType; return netType;
} catch (e) { } catch (e) {

View File

@@ -126,6 +126,8 @@ class DeviceListController extends GetControllerEx<DeviceListModel> {
} else { } else {
msg = '删除成功'.tr; msg = '删除成功'.tr;
} }
//删除用户的自定义配置
delDeviceSleepHabit(device);
}, },
onFailure: (res) { onFailure: (res) {
if (type == 1) { if (type == 1) {
@@ -161,4 +163,43 @@ class DeviceListController extends GetControllerEx<DeviceListModel> {
}, },
); );
} }
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左侧补0MAC地址长度固定12
clean = clean.padLeft(12, '0');
// 3. 按2个字符一组拼接冒号
List<String> parts = [];
for (int i = 0; i < 12; i += 2) {
parts.add(clean.substring(i, i + 2).toUpperCase());
}
// 4. 返回格式化字符串
return parts.join(':');
}
} }

View File

@@ -1,7 +1,6 @@
import 'package:ef/ef.dart'; import 'package:ef/ef.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.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/appConstants.dart';
import 'package:vbvs_app/common/color/app_uri_status.dart'; import 'package:vbvs_app/common/color/app_uri_status.dart';
import 'package:vbvs_app/common/util/FitTool.dart'; import 'package:vbvs_app/common/util/FitTool.dart';

View File

@@ -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/controller/weather/weather_controller.dart';
import 'package:vbvs_app/enum/APPPackageType.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/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/component/mht_bind_dialog.dart';
import 'package:vbvs_app/pages/mh_page/homepage/component/HomeDeviceWidget.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'; import 'package:vbvs_app/pages/mh_page/homepage/controller/mht_home_controller.dart';
@@ -229,21 +230,20 @@ class _NewHomePageState extends State<NewHomePage> {
child: userInfo(userInfoController.model.login), child: userInfo(userInfoController.model.login),
); );
}), }),
// const Spacer(), // 左右分隔 const Spacer(), // 左右分隔
// FloatingSvgIcon( FloatingSvgIcon(
// assetPath: 'assets/img/icon/xiaoyi.svg', assetPath: 'assets/img/icon/xiaoyi.svg',
// width: 60.rpx, width: 60.rpx,
// height: 60.rpx, height: 60.rpx,
// onTap: () { onTap: () {
// // print("点击了小鹅图标"); // print("点击了小鹅图标");
// if (userInfoController.model.login == 0) { if (userInfoController.model.login == 0) {
// Get.toNamed("/loginPage"); Get.toNamed("/loginPage");
// } }
// Get.toNamed("/xiaoEPage", Get.toNamed("/xiaoEPage",
// arguments: arguments: "https://xiaoe.he-info.cn/");
// "https://xiaoe.he-info.cn/?mac=b43a45c3ddf4"); },
// }, ),
// ),
SizedBox(width: 40.rpx), SizedBox(width: 40.rpx),
], ],
), ),
@@ -538,7 +538,7 @@ class _NewHomePageState extends State<NewHomePage> {
size: 30.rpx, size: 30.rpx,
), ),
fillColor: stringToColor( fillColor: stringToColor(
"##011D33"), "#011D33"),
elevation: 2, elevation: 2,
borderColor: borderColor:
Colors.transparent, Colors.transparent,

View File

@@ -253,7 +253,7 @@ class _SettingPageState extends State<SettingPage> {
), ),
].divide(SizedBox(width: 22.rpx)), ].divide(SizedBox(width: 22.rpx)),
), ),
Text('SWES3.513.4', Text('SWES2025.9.8',
style: TextStyle( style: TextStyle(
color: Colors.white, color: Colors.white,
fontSize: 26.rpx, fontSize: 26.rpx,

View File

@@ -1,23 +1,228 @@
import 'dart:convert';
import 'package:ef/ef.dart'; import 'package:ef/ef.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.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/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.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/blueteeth_bind_controller.dart';
import 'package:vbvs_app/controller/device/device_type_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/main_bottom/global_controller.dart';
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart'; import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
import 'package:vbvs_app/controller/user_info_controller.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<XiaoEPage> createState() => _XiaoEPageState();
// }
// class _XiaoEPageState extends State<XiaoEPage> {
// GlobalController globalController = Get.find();
// UserInfoController userInfoController = Get.find();
// BlueteethBindController blueteethBindController = Get.find();
// ThemeController themeController = Get.find();
// DeviceTypeController deviceTypeController = Get.find();
// ValueNotifier<bool> isPageLoading = ValueNotifier<bool>(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<bool>(
// valueListenable: isPageLoading,
// builder: (context, isLoading, child) {
// return isLoading
// ? Center(
// child: CircularProgressIndicator(
// strokeWidth: 2,
// valueColor: AlwaysStoppedAnimation<Color>(
// themeController.currentColor.sc1,
// ),
// ), // 加载指示器
// )
// : SizedBox.shrink();
// },
// ),
// ],
// );
// }),
// ),
// ),
// ),
// ),
// );
// }
// Future<void> 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<dynamic> rawList = res.data ?? [];
// List<Map<String, dynamic>> 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 { class XiaoEPage extends StatefulWidget {
var sleepUri; final String sleepUri;
XiaoEPage({super.key, required this.sleepUri}); const XiaoEPage({super.key, required this.sleepUri});
@override @override
State<XiaoEPage> createState() => _XiaoEPageState(); State<XiaoEPage> createState() => _XiaoEPageState();
} }
class _XiaoEPageState extends State<XiaoEPage> { class _XiaoEPageState extends State<XiaoEPage>
with AutomaticKeepAliveClientMixin {
// ✅ 保持页面状态
GlobalController globalController = Get.find(); GlobalController globalController = Get.find();
UserInfoController userInfoController = Get.find(); UserInfoController userInfoController = Get.find();
BlueteethBindController blueteethBindController = Get.find(); BlueteethBindController blueteethBindController = Get.find();
@@ -25,47 +230,51 @@ class _XiaoEPageState extends State<XiaoEPage> {
DeviceTypeController deviceTypeController = Get.find(); DeviceTypeController deviceTypeController = Get.find();
ValueNotifier<bool> isPageLoading = ValueNotifier<bool>(true); ValueNotifier<bool> isPageLoading = ValueNotifier<bool>(true);
RxList deviceList = [].obs;
RxString finalUri = RxString('');
@override
bool get wantKeepAlive => true; // ✅ 开启页面缓存
@override @override
void initState() { void initState() {
super.initState(); super.initState();
getDeviceList();
} }
@override @override
void dispose() { void dispose() {
// 清理 ValueNotifier
isPageLoading.dispose(); isPageLoading.dispose();
super.dispose(); super.dispose();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
super.build(context); // ✅ 必须调用,保证 keepAlive 生效
return LayoutBuilder( return LayoutBuilder(
builder: (context, bodySize) => GestureDetector( builder: (context, bodySize) => GestureDetector(
// onTap: () => FocusScope.of(context).unfocus(),,
child: Container( child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
image: DecorationImage( image: const DecorationImage(
image: AssetImage('assets/img/bgNoImg.png'), // 本地图片 image: AssetImage('assets/images/new_background.png'),
fit: BoxFit.fill, // 填满整个 Container fit: BoxFit.fill,
), ),
), ),
child: Scaffold( child: Scaffold(
backgroundColor: Colors.transparent, // 背景透明 backgroundColor: Colors.transparent,
appBar: AppBar( appBar: AppBar(
backgroundColor: themeController.currentColor.sc17, backgroundColor: Colors.transparent,
automaticallyImplyLeading: false, automaticallyImplyLeading: false,
iconTheme: IconThemeData(color: themeController.currentColor.sc3), iconTheme: IconThemeData(color: themeController.currentColor.sc3),
titleSpacing: 0, titleSpacing: 0,
title: Container( title: SizedBox(
width: double.infinity, width: double.infinity,
height: 180.rpx, height: 180.rpx,
child: Stack( child: Stack(
alignment: Alignment.center, alignment: Alignment.center,
children: [ children: [
/// 居中标题
Text( Text(
'小e'.tr, '糖管家'.tr,
style: TextStyle( style: TextStyle(
fontFamily: 'Readex Pro', fontFamily: 'Readex Pro',
color: themeController.currentColor.sc3, color: themeController.currentColor.sc3,
@@ -73,8 +282,6 @@ class _XiaoEPageState extends State<XiaoEPage> {
fontSize: 30.rpx, fontSize: 30.rpx,
), ),
), ),
/// 左边返回按钮
Positioned( Positioned(
left: 0, left: 0,
child: returnIconButtomNew(), child: returnIconButtomNew(),
@@ -85,19 +292,37 @@ class _XiaoEPageState extends State<XiaoEPage> {
), ),
body: SafeArea( body: SafeArea(
top: true, top: true,
child: Stack( child: Obx(() {
String sleepUri = finalUri.value;
ef.log('finalUri: $sleepUri');
if (sleepUri.isEmpty) {
return Center(
child: CircularProgressIndicator(
strokeWidth: 2,
valueColor: AlwaysStoppedAnimation<Color>(
themeController.currentColor.sc1,
),
),
);
}
return Stack(
children: [ children: [
InAppWebView( InAppWebView(
key: UniqueKey(), key: UniqueKey(),
initialUrlRequest: URLRequest(url: WebUri(widget.sleepUri)), initialUrlRequest: URLRequest(url: WebUri(sleepUri)),
onLoadStart: (controller, url) { onLoadStart: (controller, url) {
// 页面开始加载时显示加载指示器
isPageLoading.value = true; isPageLoading.value = true;
}, },
onLoadStop: (controller, url) { onLoadStop: (controller, url) {
// 页面加载完成后隐藏加载指示器
isPageLoading.value = false; isPageLoading.value = false;
}, },
initialOptions: InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(
transparentBackground: true,
),
),
), ),
ValueListenableBuilder<bool>( ValueListenableBuilder<bool>(
valueListenable: isPageLoading, valueListenable: isPageLoading,
@@ -109,17 +334,83 @@ class _XiaoEPageState extends State<XiaoEPage> {
valueColor: AlwaysStoppedAnimation<Color>( valueColor: AlwaysStoppedAnimation<Color>(
themeController.currentColor.sc1, themeController.currentColor.sc1,
), ),
), // 加载指示器 ),
) )
: SizedBox.shrink(); : const SizedBox.shrink();
}, },
), ),
], ],
), );
}),
), ),
), ),
), ),
), ),
); );
} }
Future<void> 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<dynamic> rawList = res.data ?? [];
List<Map<String, dynamic>> 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}");
}
} }