更新界面布局

This commit is contained in:
wyf
2025-06-16 21:08:54 +08:00
parent acde8340a8
commit aa51d92d2b
19 changed files with 2595 additions and 1524 deletions

View File

@@ -39,6 +39,7 @@ class ServiceConstant {
static const String user_register = "/api/user/register";//用户注册
static const String user_forgot = "/api/user/forgot";//找回密码
static const String user_changePassword = "/api/user/changePassword";//修改密码
static const String personnel_info = "/api/personnel/info";//人员信息列表

View File

@@ -38,4 +38,10 @@ class AppConstants {
stringToColor("D9F0E9"), // 浅蓝
stringToColor("CEECE3"), // 浅蓝
];
List<Color> mhtNormalButton = [
stringToColor("1592AA"), // 浅蓝
stringToColor("0C83A7"), // 浅蓝
stringToColor("006FA3"), // 浅蓝
];
}

View File

@@ -123,7 +123,8 @@ class _SleepCalendarWidgetState extends State<SleepCalendarWidget> {
constraints: BoxConstraints(minHeight: 720.rpx),
decoration: const BoxDecoration(color: Color(0xFF242835)),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(65.rpx, 13.rpx, 65.rpx, 38.rpx),
// padding: EdgeInsetsDirectional.fromSTEB(65.rpx, 13.rpx, 65.rpx, 38.rpx),
padding: EdgeInsetsDirectional.fromSTEB(65.rpx, 0.rpx, 65.rpx, 0.rpx),
child: Obx(() {
final daysInMonth = calendarController.getDaysInMonth();
final calendarRows = calendarController.getCalendarRows(daysInMonth);

View File

@@ -341,6 +341,8 @@ class MyApp extends StatelessWidget {
Get.lazyPut(() => MHTBlueToothController()),
Get.lazyPut(() => MHTHomeController()),
Get.lazyPut(() => MHTDeviceCalibrationController()),
Get.lazyPut(() => SleepReportController()),
Get.lazyPut(() => CalendarController()),
]));
}

View File

@@ -834,8 +834,8 @@ void showWifiDialog(
Get.back();
},
child: Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0, 33.rpx, 0, 0.rpx),
padding: EdgeInsetsDirectional.fromSTEB(
20.rpx, 33.rpx, 20.rpx, 20.rpx),
child: SvgPicture.asset(
'assets/img/icon/close.svg',
width: 25.rpx,
@@ -851,7 +851,7 @@ void showWifiDialog(
alignment: AlignmentDirectional(0, 0),
child: Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0.rpx, 40.rpx, 0, 0),
EdgeInsetsDirectional.fromSTEB(0.rpx, 20.rpx, 0, 0),
child: Text(
title,
style: FlutterFlowTheme.of(context).bodyMedium.override(
@@ -870,7 +870,7 @@ void showWifiDialog(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CustomCard(
borderRadius: AppConstants().button_container_radius,
borderRadius: AppConstants().normal_container_radius,
onTap: () {
if (blueteethBindController.model.wifiPass == null ||
blueteethBindController.model.wifiPass!.isEmpty) {
@@ -884,10 +884,8 @@ void showWifiDialog(
Get.back();
}
},
colors: [
themeController.currentColor.sc1,
themeController.currentColor.sc2,
],
colors: AppConstants().mhtNormalButton,
gradientDirection: GradientDirection.vertical,
child: Container(
width: MediaQuery.sizeOf(context).width * 0.115,
height: MediaQuery.sizeOf(context).height * 0.055,
@@ -904,7 +902,7 @@ void showWifiDialog(
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
color: stringToColor("#333333"),
color: Colors.white,
fontFamily: 'Inter',
fontSize:
AppConstants().normal_text_fontSize,

View File

@@ -1,11 +1,9 @@
import 'dart:async';
import 'package:EasyDartModule/EasyDartModule.dart' as edm;
import 'package:EasyDartModule/base/logger/Logger.dart';
import 'package:easydevice/easydevice.dart';
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:vbvs_app/common/color/ServiceConstant.dart';
import 'package:vbvs_app/common/color/app_uri_status.dart';
@@ -16,7 +14,6 @@ import 'package:vbvs_app/common/util/requestWithLog.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/component/tool/CustomCard.dart';
import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
import 'package:vbvs_app/component/tool/cmd.dart';
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
import 'package:vbvs_app/model/BleDeviceData.dart';
import 'package:vbvs_app/model/api_response.dart';
@@ -473,7 +470,6 @@ class _DeviceComponentWidgetState extends State<DeviceComponentWidget> {
var read = bledevice.getresource('fff0/fff1');
await read!.characteristic.setNotifyValue(true);
var write = bledevice.getresource('fff0/fff2');
for (int attempt = 0; attempt < maxRetries; attempt++) {

View File

@@ -32,6 +32,7 @@ class MHTDeviceCalibrationController
RxString tips = "".obs;
RxInt flag = 0.obs; //0没有开始 1校准中 2.校准完成 3.校准失败
RxString statusContext = "".obs;
RxBool another = false.obs;
RxInt cd = 10000.obs;

View File

@@ -158,18 +158,25 @@ class _MHTBindDeviceTypePageState extends State<MHTBindDeviceTypePage> {
}
Map data = {
"reg":reg,
"type":type,
"reg": reg,
"type": type,
};
return CustomCard(
borderRadius: 20.rpx,
onTap: () {
if (type == 2) {
TopSlideNotification.show(
context,
text: "当前类型不支持绑定".tr,
);
return;
}
MHTBlueToothController mhtBlueToothController = Get.find();
mhtBlueToothController.model.deviceType = type.toInt();
Get.toNamed("/mHTBlueteethDevicePage", arguments: data);
},
colors: [Colors.white],
child: Container(
child: Container(
width: double.infinity,
height: MediaQuery.sizeOf(context).height * 0.135,
constraints: BoxConstraints(minHeight: 220.rpx),

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -205,11 +205,10 @@ class _MHTWifiPageState extends State<MHTWifiPage> {
Positioned(
right: 20.rpx,
child: CustomCard(
gradientDirection: GradientDirection.vertical,
borderRadius: 20.rpx,
onTap: _navigateToNextPage,
colors: [
stringToColor("#84F5FF"),
],
colors: AppConstants().mhtButtongradientColors,
child: Container(
width: 130.rpx,
height: 60.rpx,
@@ -222,7 +221,7 @@ class _MHTWifiPageState extends State<MHTWifiPage> {
.titleSmall
.override(
fontFamily: 'Inter Tight',
color: stringToColor("#011D33"),
color: stringToColor("#003058"),
letterSpacing: 0.0,
),
),

View File

@@ -8,6 +8,7 @@ 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';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/common/util/requestWithLog.dart';
import 'package:vbvs_app/model/api_response.dart';
part 'mht_home_controller.g.dart'; // 由json_serializable自动生成的部分
@@ -38,11 +39,14 @@ class MHTHomeController extends GetControllerEx<MHTHomeModel> {
RxInt bindDeviceNum = 0.obs; //设备数量
RxMap deviceList = {}.obs; //设备列表
RxMap<String, List<dynamic>> sleepReportData = <String, List<dynamic>>{}.obs;
RxMap<String, List<dynamic>> sleepReportData =
<String, List<dynamic>>{}.obs; //睡眠报告
RxList personnelList = [].obs; //人员信息列表
RxString keyWord = "".obs;
String wifiMac = "";
var sleepDays = [].obs;
Future<ApiResponse> getDeviceNum() async {
try {
@@ -194,95 +198,95 @@ class MHTHomeController extends GetControllerEx<MHTHomeModel> {
return ApiResponse(code: -1, msg: "未知错误".tr); // Default return statement
}
Future<ApiResponse> getSleepReport() async {
try {
sleepReportData.value = {};
ApiResponse<Map<String, List<dynamic>>> apiResponse = ApiResponse(
code: -1,
msg: "请求失败".tr,
);
// Future<ApiResponse> getSleepReport() async {
// try {
// sleepReportData.value = {};
// ApiResponse<Map<String, List<dynamic>>> apiResponse = ApiResponse(
// code: -1,
// msg: "请求失败".tr,
// );
if (deviceList.value.isEmpty) {
return ApiResponse(
code: HttpStatusCodes.ok,
msg: "请求成功".tr,
);
}
// if (deviceList.value.isEmpty) {
// return ApiResponse(
// code: HttpStatusCodes.ok,
// msg: "请求成功".tr,
// );
// }
String serviceAddress = ServiceConstant.service_address;
String serviceName = ServiceConstant.server_service;
String serviceApi = ServiceConstant.sleep_report;
// String serviceAddress = ServiceConstant.service_address;
// String serviceName = ServiceConstant.server_service;
// String serviceApi = ServiceConstant.sleep_report;
// for (var device in deviceList.value) {
// String mac = device['mac'] ?? "";
// if (mac.isEmpty) continue;
// // for (var device in deviceList.value) {
// // String mac = device['mac'] ?? "";
// // if (mac.isEmpty) continue;
// sleepReportData[mac] = []; // 初始化当前设备的数据列表
// // sleepReportData[mac] = []; // 初始化当前设备的数据列表
// String queryUrl =
// "$serviceAddress$serviceName$serviceApi?mac=$mac&time=${DateTime.now().millisecondsSinceEpoch}";
// // String queryUrl =
// // "$serviceAddress$serviceName$serviceApi?mac=$mac&time=${DateTime.now().millisecondsSinceEpoch}";
// try {
// String? language = "";
// if (languageController.selectLanguage != null) {
// language = languageController.selectLanguage.value!.language_code;
// }
// if (language != null && language.isNotEmpty) {
// if (queryUrl.contains("?")) {
// queryUrl += "&lang=$language";
// } else {
// queryUrl += "?lang=$language";
// }
// }
// var response = await EasyDartModule.dio.get(queryUrl);
// if (response != null) {
// var responseData = response.data is String
// ? jsonDecode(response.data)
// : response.data;
// // try {
// // String? language = "";
// // if (languageController.selectLanguage != null) {
// // language = languageController.selectLanguage.value!.language_code;
// // }
// // if (language != null && language.isNotEmpty) {
// // if (queryUrl.contains("?")) {
// // queryUrl += "&lang=$language";
// // } else {
// // queryUrl += "?lang=$language";
// // }
// // }
// // var response = await EasyDartModule.dio.get(queryUrl);
// // if (response != null) {
// // var responseData = response.data is String
// // ? jsonDecode(response.data)
// // : response.data;
// ApiResponse res =
// ApiResponse.fromJson(responseData, (object) => object);
// // ApiResponse res =
// // ApiResponse.fromJson(responseData, (object) => object);
// if (res.code == HttpStatusCodes.ok && res.data != null) {
// // 确保数据是一个列表
// if (res.data is List) {
// sleepReportData[mac] = List.from(res.data);
// } else {
// sleepReportData[mac] = [res.data];
// }
// }
// }
// } catch (e) {
// EasyDartModule.logger.warning("请求设备 $mac 的睡眠数据失败: $e");
// }
// }
if (sleepReportData.value.isNotEmpty) {
// 遍历 Map 中的每一个键值对
sleepReportData.value.forEach((key, report) {
// 确保 report 列表不为空
if (report.isNotEmpty) {
// 获取该列表的最后一个元素
var lastElement = report.last;
// // if (res.code == HttpStatusCodes.ok && res.data != null) {
// // // 确保数据是一个列表
// // if (res.data is List) {
// // sleepReportData[mac] = List.from(res.data);
// // } else {
// // sleepReportData[mac] = [res.data];
// // }
// // }
// // }
// // } catch (e) {
// // EasyDartModule.logger.warning("请求设备 $mac 的睡眠数据失败: $e");
// // }
// // }
// if (sleepReportData.value.isNotEmpty) {
// // 遍历 Map 中的每一个键值对
// sleepReportData.value.forEach((key, report) {
// // 确保 report 列表不为空
// if (report.isNotEmpty) {
// // 获取该列表的最后一个元素
// var lastElement = report.last;
// 给最后一个元素添加 selected 属性
lastElement['selected'] = true; // 假设每个元素是一个 Map 类型
}
});
}
// // 给最后一个元素添加 selected 属性
// lastElement['selected'] = true; // 假设每个元素是一个 Map 类型
// }
// });
// }
updateAll();
// updateAll();
return ApiResponse(
code: HttpStatusCodes.ok,
msg: "请求成功".tr,
data: sleepReportData,
);
} catch (e) {
EasyDartModule.logger.info("设备请求列表异常: $e");
DailyLogUtils.writeLog("设备请求列表异常: $e");
return ApiResponse(code: -1, msg: "未知错误".tr, data: {});
}
}
// return ApiResponse(
// code: HttpStatusCodes.ok,
// msg: "请求成功".tr,
// data: sleepReportData,
// );
// } catch (e) {
// EasyDartModule.logger.info("设备请求列表异常: $e");
// DailyLogUtils.writeLog("设备请求列表异常: $e");
// return ApiResponse(code: -1, msg: "未知错误".tr, data: {});
// }
// }
updateDeviceShow(device) async {
try {
@@ -327,4 +331,94 @@ class MHTHomeController extends GetControllerEx<MHTHomeModel> {
}
return ApiResponse(code: -1, msg: "未知错误".tr); // Default return statement
}
//查询人员信息列表
Future<void> getPersonList() async {
ApiResponse apiResponse = ApiResponse(code: -1, msg: "设备.设备列表请求失败".tr);
String serviceAddress = ServiceConstant.service_address;
String serviceName = ServiceConstant.server_service;
String serviceApi = ServiceConstant.personnel_info;
// 初始URL
String queryUrl = "$serviceAddress$serviceName$serviceApi";
await requestWithLog(
logTitle: "请求人员信息列表",
method: MyHttpMethod.get,
queryUrl: queryUrl,
onSuccess: (res) {
personnelList.value = res.data ?? [];
},
onFailure: (res) {
EasyDartModule.logger.warning("请求人员信息列表失败: ${res.msg}");
},
);
}
Future<void> getSleeps(String? mac) async {
String serviceAddress = ServiceConstant.service_address;
String serviceName = ServiceConstant.server_service;
String serviceApi = ServiceConstant.sleep_report;
String queryUrl = "$serviceAddress$serviceName$serviceApi";
// 当前时间的毫秒时间戳
int timestamp = DateTime.now().millisecondsSinceEpoch;
// 拼接参数
List<String> queryParams = [];
if (mac != null && mac.isNotEmpty) {
queryParams.add("mac=$mac");
}
queryParams.add("time=$timestamp");
if (queryParams.isNotEmpty) {
queryUrl += "?${queryParams.join("&")}";
}
await requestWithLog(
logTitle: "请求睡眠信息列表",
method: MyHttpMethod.get,
queryUrl: queryUrl,
onSuccess: (res) {
if (res.data != null && res.data is List) {
List<dynamic> rawList = res.data;
List<Map<String, dynamic>> processedList =
rawList.map<Map<String, dynamic>>((item) {
Map<String, dynamic> map = Map<String, dynamic>.from(item);
// 取出 time
String? timeStr = map['time'];
int? timeMillis = timeStr != null ? int.tryParse(timeStr) : null;
if (timeMillis != null) {
DateTime dateTime =
DateTime.fromMillisecondsSinceEpoch(timeMillis);
// 格式化 week 和 date
String week = MyUtils.formatDateTimeWeek(dateTime);
String date = MyUtils.formatDateTimeDay(dateTime);
// 添加到 map 中
map['week'] = week;
map['date'] = date;
}
return map;
}).toList();
// 赋值给 sleepDays
sleepDays.value = processedList;
} else {
// 为空时直接赋空数组
sleepDays.value = [];
}
// 更新UI
updateAll();
},
onFailure: (res) {
EasyDartModule.logger.warning("请求睡眠信息列表失败: ${res.msg}");
},
);
}
}

View File

@@ -28,36 +28,20 @@ class _NewHomePageState extends State<NewHomePage> {
double borderRadius = 16.rpx;
var formFieldController = FormFieldController<String>(null);
var personInfo = {}.obs;
GlobalController gloablController = Get.find();
WeatherModelController weatherModelController = Get.find();
var sleepDays = [].obs;
var sleep_mac = "".obs;
Map scoreColor = {
"-1": "#d3d3d3",
"1": "#4e8408",
"2": "#7bbb33",
"3": "#e15b8d",
"4": "#ff0000",
};
Map scoreName = {
"-1": "暂无",
"1": "优秀",
"2": "良好",
"3": "合格",
"4": "注意",
};
var selectedDayIndex = (6).obs;
@override
void initState() {
super.initState();
if (userInfoController.model.login == 1) {
//查询人员信息列表
deviceController.getPersonList();
//请求绑定设备列表
homeController.getSleepReport();
// homeController.getSleepReport();
deviceController.getDeviceNum().then((apiResponse) {
if (apiResponse.code != HttpStatusCodes.ok) {
TopSlideNotification.show(
@@ -76,10 +60,15 @@ class _NewHomePageState extends State<NewHomePage> {
);
} else {
//请求睡眠报告
deviceController.getSleepReport();
// deviceController.getSleepReport();
}
});
}
WidgetsBinding.instance.addPostFrameCallback((_) {
if (homeController.sleepDays.value.isNotEmpty) {
selectedDayIndex.value = homeController.sleepDays.value.length - 1;
}
});
}
getWeekName(int i) {
@@ -121,7 +110,7 @@ class _NewHomePageState extends State<NewHomePage> {
);
} else {
//请求睡眠报告
deviceController.getSleepReport();
// deviceController.getSleepReport();
}
});
int login = userInfoController.model.login!;
@@ -242,502 +231,6 @@ class _NewHomePageState extends State<NewHomePage> {
),
),
),
// Obx(() {
// return Container(
// padding: EdgeInsets.only(left: 30.rpx, right: 30.rpx),
// child: Column(
// children: [
// if (gloablController.model.deviceList.length > 0)
// Container(
// child: Column(
// children: [
// Container(
// width: MediaQuery.sizeOf(context).width,
// decoration: BoxDecoration(
// color: Colors.white,
// borderRadius: BorderRadius.circular(
// borderRadius),
// ),
// child: Column(
// mainAxisSize: MainAxisSize.max,
// children: [
// Padding(
// padding: EdgeInsetsDirectional
// .fromSTEB(30.rpx, 16.rpx,
// 16.rpx, 8.rpx),
// child: Container(
// width:
// MediaQuery.sizeOf(context)
// .width,
// height:
// MediaQuery.sizeOf(context)
// .height *
// 0.065,
// decoration: BoxDecoration(
// color: FlutterFlowTheme.of(
// context)
// .secondaryBackground,
// ),
// child: Row(
// mainAxisSize:
// MainAxisSize.max,
// mainAxisAlignment:
// MainAxisAlignment
// .spaceBetween,
// children: [
// ValueListenableBuilder(
// valueListenable:
// formFieldController,
// builder: (c, a, s) =>
// FlutterFlowDropDown<
// String>(
// controller:
// formFieldController,
// options: gloablController
// .model.JunheDevices
// .map<String>((d) =>
// "${d["mac"]}")
// .toList(),
// optionLabels:
// gloablController
// .model
// .JunheDevices
// .map<String>(
// (d) {
// var s = d["name"] ??
// d["mac"];
// if (s == null) {
// return "";
// } else {
// return "$s";
// }
// }).toList(),
// onChanged: (val) {
// // print("$val");
// // if (val == null) {
// // sleepDays.value = [];
// // } else {
// // getSleeps(
// // formFieldController
// // .value);
// // }
// // // sleep_mac.value = val!;
// },
// width: 360.rpx,
// height: 72.rpx,
// maxHeight: 200.rpx,
// textStyle: TextStyle(
// fontSize: 28.rpx,
// overflow:
// TextOverflow
// .ellipsis),
// hintText: '',
// icon: Icon(
// Icons
// .keyboard_arrow_down_rounded,
// color: FlutterFlowTheme
// .of(context)
// .secondaryText,
// size: 48.rpx,
// ),
// fillColor:
// stringToColor(
// "#F3F5F6"),
// elevation: 2,
// borderColor:
// stringToColor(
// "#F3F5F6"),
// borderWidth: 2,
// borderRadius: 18,
// margin:
// EdgeInsetsDirectional
// .fromSTEB(
// 32.rpx,
// 8.rpx,
// 32.rpx,
// 8.rpx),
// hidesUnderline: true,
// isOverButton: false,
// isSearchable: false,
// isMultiSelect: false,
// ),
// ),
// InkWell(
// onTap: () {
// // if (formFieldController
// // .value !=
// // null) {
// // Get.toNamed(
// // "/sleepWebview",
// // arguments: [
// // formFieldController
// // .value
// // ]);
// // }
// },
// child: Row(
// mainAxisSize:
// MainAxisSize.max,
// children: [
// Text(
// '睡眠报告',
// style: FlutterFlowTheme
// .of(context)
// .bodyMedium
// .override(
// fontFamily:
// 'Readex Pro',
// letterSpacing:
// 0,
// fontSize:
// 30.rpx),
// ),
// SizedBox(
// width: 12.rpx,
// ),
// SvgPicture.asset(
// "assets/images/table.svg",
// width: 28.rpx,
// height: 28.rpx),
// SizedBox(
// width: 20.rpx,
// ),
// ],
// ),
// ),
// ],
// ),
// ),
// ),
// Container(
// padding: EdgeInsets.only(
// top: 0.rpx,
// bottom: 20.rpx,
// left: 16.rpx,
// right: 16.rpx),
// width: double.infinity,
// decoration: BoxDecoration(),
// child: Row(
// mainAxisSize: MainAxisSize.max,
// crossAxisAlignment:
// CrossAxisAlignment.start,
// children: [
// ...List.generate(
// sleepDays.value.length,
// (index) {
// var day = sleepDays[index];
// return Expanded(
// child: Container(
// padding:
// EdgeInsets.only(
// top: 10.rpx,
// bottom: 20.rpx),
// width: 100,
// // decoration: BoxDecoration(
// // color: index == 2
// // ? stringToColor("#F3F5F6")
// // : Colors.white,
// // borderRadius:
// // BorderRadius.circular(
// // borderRadius),
// // ),
// child: Column(
// mainAxisSize:
// MainAxisSize.max,
// mainAxisAlignment:
// MainAxisAlignment
// .start,
// crossAxisAlignment:
// CrossAxisAlignment
// .center,
// children: [
// Text(
// day['week'],
// style: FlutterFlowTheme
// .of(context)
// .bodyMedium
// .override(
// fontFamily:
// 'Readex Pro',
// fontSize:
// 30.rpx,
// letterSpacing:
// 0,
// ),
// ),
// Text(
// day['date'],
// style: FlutterFlowTheme
// .of(context)
// .bodyMedium
// .override(
// fontFamily:
// 'Readex Pro',
// letterSpacing:
// 0,
// fontSize:
// 24.rpx,
// ),
// ),
// SizedBox(
// height: 6.rpx,
// ),
// Column(
// children: [
// Row(
// mainAxisSize:
// MainAxisSize
// .max,
// mainAxisAlignment:
// MainAxisAlignment
// .center,
// children: [
// Text(
// '${day['score'] ?? "-"}',
// style: FlutterFlowTheme.of(
// context)
// .bodyMedium
// .override(
// fontFamily:
// 'Readex Pro',
// fontSize:
// 48.rpx,
// letterSpacing:
// 0,
// ),
// ),
// if (day['score'] !=
// null)
// SizedBox(
// width: 2
// .rpx,
// ),
// if (day['score'] !=
// null)
// Text(
// '分',
// style: FlutterFlowTheme.of(context)
// .bodyMedium
// .override(
// fontFamily: 'Readex Pro',
// letterSpacing: 0,
// fontSize: 26.rpx,
// ),
// ),
// ],
// ),
// Container(
// width:
// 120.rpx,
// height:
// 52.rpx,
// decoration:
// BoxDecoration(
// color: stringToColor(
// day['scoreColor'] ??
// "#f3f5f6"),
// borderRadius:
// BorderRadius.circular(
// 26.rpx),
// shape: BoxShape
// .rectangle,
// ),
// alignment:
// Alignment
// .center,
// child: Text(
// '${day['scoreType'] ?? "暂无"}',
// style: FlutterFlowTheme.of(
// context)
// .bodyMedium
// .override(
// fontFamily:
// 'Readex Pro',
// color: day['scoreType'] != null
// ? Colors.white
// : stringToColor("#ced1d7"),
// letterSpacing:
// 0,
// fontSize:
// 28.rpx,
// ),
// ),
// )
// ],
// )
// ],
// ),
// ),
// );
// })
// ],
// ),
// ),
// ],
// ),
// ),
// ...List.generate(
// gloablController.model.deviceList
// .length, (index) {
// var device = gloablController
// .model.deviceList[index];
// String rname = device['roomName'];
// if (index != 0) {
// String lrname = gloablController
// .model.deviceList[index - 1]
// ["roomName"];
// if (lrname == rname) {
// rname = "";
// }
// }
// return Column(children: [
// Padding(
// padding:
// EdgeInsetsDirectional.fromSTEB(
// 20.rpx, 20.rpx, 0, 0),
// child: Container(
// decoration: BoxDecoration(),
// alignment:
// AlignmentDirectional(-1, 0),
// child: rname.isNotEmpty
// ? Text(
// "$rname",
// style: FlutterFlowTheme
// .of(context)
// .bodyMedium
// .override(
// fontFamily:
// 'Readex Pro',
// color: Colors.white,
// fontSize: 32.rpx,
// letterSpacing: 0,
// ),
// )
// : SizedBox(
// height: 10.rpx,
// ),
// ),
// ),
// // getDeviceList(context, device)
// ]);
// }),
// Padding(
// padding: EdgeInsetsDirectional.fromSTEB(
// 0, 40.rpx, 0, 100.rpx),
// child: Container(
// width:
// MediaQuery.sizeOf(context).width,
// height: 84.rpx,
// decoration: BoxDecoration(),
// child: FFButtonWidget(
// onPressed: () {
// // print('Button pressed ...');
// // Get.toNamed("/homeDeviceType");
// },
// text: '添加新设备'.tr,
// icon: Icon(
// Icons.add,
// size: 60.rpx,
// ),
// options: FFButtonOptions(
// height: 80.rpx,
// padding: EdgeInsetsDirectional
// .fromSTEB(
// 48.rpx, 0, 48.rpx, 0),
// iconPadding: EdgeInsetsDirectional
// .fromSTEB(0, 0, 0, 0),
// color: stringToColor("#182B7C"),
// textStyle:
// FlutterFlowTheme.of(context)
// .titleSmall
// .override(
// fontFamily:
// 'Readex Pro',
// color: Colors.white,
// letterSpacing: 0,
// fontSize: 30.rpx),
// elevation: 3,
// borderSide: BorderSide(
// color: Colors.transparent,
// width: 1,
// ),
// borderRadius:
// BorderRadius.circular(
// borderRadius),
// ),
// ),
// ),
// ),
// ],
// ),
// ),
// if (gloablController.model.deviceList.length == 0)
// Padding(
// padding: EdgeInsetsDirectional.fromSTEB(
// 0, 0, 0, 80.rpx),
// child: ClickableContainer(
// backgroundColor: Colors.transparent,
// highlightColor: Colors.transparent,
// padding: EdgeInsets.all(0),
// onTap: () {
// if (userInfoController.model.login ==
// null ||
// userInfoController.model.login == 0) {
// TopSlideNotification.show(context,
// text: "请先登录".tr,
// textColor: themeController
// .currentColor.sc9);
// Get.toNamed("/loginPage");
// } else {
// Get.toNamed("/mHTDeviceTypePage");
// }
// },
// child: Container(
// width: MediaQuery.sizeOf(context).width,
// height: 302.rpx,
// padding: EdgeInsets.only(
// top: 90.rpx, bottom: 80.rpx),
// decoration: BoxDecoration(
// borderRadius:
// BorderRadius.circular(borderRadius),
// border: Border.all(
// color:
// stringToColor("#85F5FF"), // 边框颜色
// width: 1.rpx, // 边框宽度
// ),
// ),
// child: Column(
// mainAxisSize: MainAxisSize.max,
// mainAxisAlignment:
// MainAxisAlignment.center,
// children: [
// SvgPicture.asset(
// 'assets/images/icon/add.svg',
// width: 42.rpx,
// height: 42.rpx,
// ),
// SizedBox(
// height: 32.rpx,
// ),
// Text(
// '添加一台新设备'.tr,
// style: TextStyle(
// color: stringToColor("#85F5FF"),
// fontSize: AppConstants()
// .normal_text_fontSize,
// letterSpacing: 0,
// ),
// ),
// ],
// ),
// ),
// ),
// ),
// ],
// ),
// );
// }),
//未登录
Obx(() {
if (userInfoController.model.login! == null ||
@@ -807,9 +300,343 @@ class _NewHomePageState extends State<NewHomePage> {
Obx(() {
if (userInfoController.model.login! != null &&
userInfoController.model.login! == 1) {
final list = deviceController.personnelList.value;
// 当数据第一次到达时自动赋值
if (list.isNotEmpty &&
formFieldController.value == null) {
formFieldController.value = list[0]["mac"];
personInfo.value = list[0];
deviceController
.getSleeps(formFieldController.value);
}
return SingleChildScrollView(
child: Column(
children: [
if (homeController.personnelList.value.length !=
0)
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
30.rpx, 40.rpx, 30.rpx, 10.rpx),
child: Container(
width: MediaQuery.sizeOf(context).width,
height:
MediaQuery.sizeOf(context).height *
0.184,
constraints: BoxConstraints(
minHeight: 350.rpx,
),
decoration: BoxDecoration(
color: stringToColor("#003058"),
borderRadius:
BorderRadius.circular(20.rpx),
),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(
30.rpx,
16.rpx,
16.rpx,
25.rpx),
child: Container(
width: MediaQuery.sizeOf(context)
.width,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
ScrollbarTheme(
data: ScrollbarThemeData(
thumbColor:
MaterialStateProperty
.all(Colors
.transparent),
trackColor:
MaterialStateProperty
.all(Colors
.transparent),
trackBorderColor:
MaterialStateProperty
.all(Colors
.transparent),
),
child:
ValueListenableBuilder(
valueListenable:
formFieldController,
builder: (c, a, s) =>
FlutterFlowDropDown<
String>(
controller:
formFieldController,
options: deviceController
.personnelList.value
.map<String>((d) =>
"${d["mac"]}")
.toList(),
optionLabels:
deviceController
.personnelList
.value
.map<String>(
(d) {
var s = d["name"] ??
d["mac"];
if (s == null) {
return "";
} else {
return "$s";
}
}).toList(),
onChanged: (val) {
final list =
deviceController
.personnelList
.value;
final selectedPerson =
list.firstWhere(
(element) =>
element[
'mac'] ==
val,
orElse: () =>
null, // 防止找不到时报错
);
personInfo.value =
selectedPerson;
selectedDayIndex =
(6).obs;
print("$val");
if (val == null) {
homeController
.sleepDays
.value = [];
} else {
deviceController
.getSleeps(
formFieldController
.value);
}
},
width: 300.rpx,
height: 81.rpx,
maxHeight: 300.rpx,
textStyle: TextStyle(
fontSize: 28.rpx,
overflow: TextOverflow
.ellipsis,
color: Colors.white,
),
hintText: '',
icon: Icon(
Icons
.keyboard_arrow_down_rounded,
color: stringToColor(
"#FFFFFF"),
size: 30.rpx,
),
fillColor:
stringToColor(
"#184468"),
elevation: 2,
borderColor:
Colors.transparent,
borderWidth: 2,
borderRadius: 18,
margin:
EdgeInsetsDirectional
.fromSTEB(
32.rpx,
8.rpx,
32.rpx,
8.rpx),
hidesUnderline: true,
isOverButton: false,
isSearchable: false,
isMultiSelect: false,
),
),
),
InkWell(
onTap: () {
if (formFieldController
.value !=
null) {
Get.toNamed(
"/sleepWebview",
arguments: [
formFieldController
.value
]);
}
},
child: Row(
mainAxisSize:
MainAxisSize.max,
children: [
SizedBox(
width: 12.rpx,
),
SvgPicture.asset(
"assets/images/table.svg",
width: 28.rpx,
height: 28.rpx,
color: stringToColor(
"#FFFFFF"),
),
SizedBox(
width: 20.rpx,
),
],
),
),
],
),
),
),
Container(
padding: EdgeInsets.only(
top: 0.rpx,
bottom: 20.rpx,
left: 16.rpx,
right: 16.rpx,
),
width: double.infinity,
decoration: BoxDecoration(),
child: Obx(() => Row(
mainAxisSize:
MainAxisSize.max,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
...List.generate(
homeController
.sleepDays
.value
.length, (index) {
var day = homeController
.sleepDays[index];
bool isSelected =
selectedDayIndex
.value ==
index;
return Expanded(
child: GestureDetector(
onTap: () {
selectedDayIndex
.value = index;
int? timeMillis =
parseToInt(day[
'time']); // 使用我们刚才封装的安全转换函数
Get.toNamed(
"/newSleepReportPage",
arguments: {
'date':
timeMillis,
'mac':
formFieldController
.value!,
'type': 1,
"person":
personInfo
.value,
'backgroundImg':
'assets/images/new_background.png',
// 'backgroundColor':stringToColor("#003058"),
},
);
},
child: Container(
padding:
EdgeInsets.only(
top: 10.rpx,
bottom: 20.rpx,
),
width: 90.rpx,
decoration:
BoxDecoration(
color: isSelected
? stringToColor(
"#184468")
: Colors
.transparent,
borderRadius:
BorderRadius
.circular(
8.rpx),
),
child: Column(
mainAxisSize:
MainAxisSize
.max,
mainAxisAlignment:
MainAxisAlignment
.start,
crossAxisAlignment:
CrossAxisAlignment
.center,
children: [
Text(
day['week'],
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily:
'Readex Pro',
fontSize:
30.rpx,
letterSpacing:
0,
color: stringToColor(
"#FFFFFF"),
),
),
SizedBox(
height:
12.rpx),
Text(
day['date'],
// "哈哈",
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily:
'Readex Pro',
letterSpacing:
0,
fontSize:
22.rpx,
color: stringToColor(
"#929699"),
),
),
SizedBox(
height:
39.rpx),
buildScoreOrIcon(
day['score']),
],
),
),
),
);
})
],
)),
),
],
),
),
),
if (homeController.bindDeviceNum.value != 0)
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
@@ -1011,6 +838,40 @@ class _NewHomePageState extends State<NewHomePage> {
],
);
}
Widget buildScoreOrIcon(dynamic score) {
return SizedBox(
width: 50.rpx,
height: 50.rpx,
child: Center(
child: (score != null)
? FittedBox(
child: Text(
'${score['socre']}',
style: TextStyle(
fontFamily: 'Readex Pro',
fontSize: 40.rpx,
letterSpacing: 0,
color: Colors.white,
),
),
)
: SvgPicture.asset(
'assets/img/icon/close.svg',
width: 25.rpx,
height: 25.rpx,
color: themeController.currentColor.sc3,
),
),
);
}
int? parseToInt(dynamic value) {
if (value == null) return null;
if (value is int) return value;
if (value is String) return int.tryParse(value);
return null;
}
}
class ScoreItem {

View File

@@ -46,7 +46,7 @@ class _AdviceComponnetWidgetState extends State<AdviceComponnetWidget> {
Container(
width: double.infinity,
decoration: BoxDecoration(
color: stringToColor("#313541"),
color: stringToColor("#313541").withOpacity(0.6),
borderRadius: BorderRadius.circular(20.rpx),
),
child: Padding(

View File

@@ -6,9 +6,9 @@ import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
class SleepRadarChart extends StatelessWidget {
final List<Map<String, dynamic>> data;
final List<Map<String, dynamic>> data;
const SleepRadarChart({Key? key, required this.data}) : super(key: key);
const SleepRadarChart({Key? key, required this.data}) : super(key: key);
// const SleepRadarChart({
// Key? key,
@@ -30,48 +30,52 @@ const SleepRadarChart({Key? key, required this.data}) : super(key: key);
}
Widget _buildRadarChart() {
return AspectRatio(
aspectRatio: 1.3,
child: RadarChart(
RadarChartData(
dataSets: [
// 今日数据
RadarDataSet(
dataEntries: data.map((e) => RadarEntry(value: (e['t'] as num).toDouble())).toList(),
borderColor: stringToColor("#00C1AA"),
borderWidth: 2,
fillColor: Colors.transparent,
entryRadius: 0,
),
// 昨日数据
RadarDataSet(
dataEntries: data.map((e) => RadarEntry(value: (e['y'] as num).toDouble())).toList(),
borderColor: stringToColor("#FFD251"),
borderWidth: 2,
fillColor: Colors.transparent,
entryRadius: 0,
),
],
radarBackgroundColor: stringToColor("#343844"),
radarBorderData: BorderSide(
color: themeController.currentColor.sc4, width: 0.5.rpx),
radarShape: RadarShape.polygon,
titlePositionPercentageOffset: 0.2,
titleTextStyle: TextStyle(
fontSize: AppConstants().normal_text_fontSize,
color: themeController.currentColor.sc3),
getTitle: (index, angle) {
return RadarChartTitle(text: data[index]['name'] ?? '未知'.tr);
},
tickCount: 5,
ticksTextStyle: const TextStyle(color: Colors.transparent, fontSize: 10),
gridBorderData: BorderSide(color: Colors.transparent, width: 1),
tickBorderData: BorderSide(
color: themeController.currentColor.sc4, width: 0.5.rpx),
return AspectRatio(
aspectRatio: 1.3,
child: RadarChart(
RadarChartData(
dataSets: [
// 今日数据
RadarDataSet(
dataEntries: data
.map((e) => RadarEntry(value: (e['t'] as num).toDouble()))
.toList(),
borderColor: stringToColor("#00C1AA"),
borderWidth: 2,
fillColor: Colors.transparent,
entryRadius: 0,
),
// 昨日数据
RadarDataSet(
dataEntries: data
.map((e) => RadarEntry(value: (e['y'] as num).toDouble()))
.toList(),
borderColor: stringToColor("#FFD251"),
borderWidth: 2,
fillColor: Colors.transparent,
entryRadius: 0,
),
],
radarBackgroundColor: stringToColor("#343844").withOpacity(0.6),
radarBorderData: BorderSide(
color: themeController.currentColor.sc4, width: 0.5.rpx),
radarShape: RadarShape.polygon,
titlePositionPercentageOffset: 0.2,
titleTextStyle: TextStyle(
fontSize: AppConstants().normal_text_fontSize,
color: themeController.currentColor.sc3),
getTitle: (index, angle) {
return RadarChartTitle(text: data[index]['name'] ?? '未知'.tr);
},
tickCount: 5,
ticksTextStyle:
const TextStyle(color: Colors.transparent, fontSize: 10),
gridBorderData: BorderSide(color: Colors.transparent, width: 1),
tickBorderData: BorderSide(
color: themeController.currentColor.sc4, width: 0.5.rpx),
),
swapAnimationDuration: const Duration(milliseconds: 400),
),
swapAnimationDuration: const Duration(milliseconds: 400),
),
);
}
);
}
}

View File

@@ -383,7 +383,7 @@ class _NewSleepReportPageState extends State<NewSleepReportPage> {
CrossAxisAlignment.end,
children: [
Text(
'实时体征.姓名'.tr,
'姓名'.tr,
style:
FlutterFlowTheme.of(context)
.bodyMedium
@@ -396,7 +396,7 @@ class _NewSleepReportPageState extends State<NewSleepReportPage> {
),
),
Text(
'实时体征.年龄'.tr,
'年龄'.tr,
style:
FlutterFlowTheme.of(context)
.bodyMedium
@@ -463,7 +463,7 @@ class _NewSleepReportPageState extends State<NewSleepReportPage> {
CrossAxisAlignment.end,
children: [
Text(
'实时体征.设备ID'.tr,
'设备ID'.tr,
style:
FlutterFlowTheme.of(context)
.bodyMedium
@@ -476,7 +476,7 @@ class _NewSleepReportPageState extends State<NewSleepReportPage> {
),
),
Text(
'实时体征.体重'.tr,
'体重'.tr,
style:
FlutterFlowTheme.of(context)
.bodyMedium

View File

@@ -108,14 +108,19 @@ class _NewSleepReportPageState extends State<NewSleepReportPage> {
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/img/bgNoImg.png'), // 本地图片
fit: BoxFit.fill, // 填满整个 Container
image: (widget.data['backgroundImg'] != null &&
widget.data['backgroundImg'].toString().isNotEmpty)
? AssetImage(widget.data['backgroundImg'])
: AssetImage('assets/img/bgNoImg.png') as ImageProvider,
fit: BoxFit.fill,
),
),
child: Scaffold(
backgroundColor: Colors.transparent, // 背景透明
appBar: AppBar(
backgroundColor: themeController.currentColor.sc17,
backgroundColor: widget.data['backgroundColor'] != null
? widget.data['backgroundColor'].withOpacity(0.8)
: themeController.currentColor.sc5,
automaticallyImplyLeading: false,
iconTheme: IconThemeData(color: themeController.currentColor.sc3),
titleSpacing: 0,
@@ -162,7 +167,10 @@ class _NewSleepReportPageState extends State<NewSleepReportPage> {
minHeight: 90.rpx,
),
decoration: BoxDecoration(
color: themeController.currentColor.sc5),
color: widget.data['backgroundColor'] != null
? widget.data['backgroundColor']
: themeController.currentColor.sc5,
),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
30.rpx, 15.rpx, 30.rpx, 15.rpx),
@@ -377,7 +385,10 @@ class _NewSleepReportPageState extends State<NewSleepReportPage> {
padding: EdgeInsetsDirectional.fromSTEB(
30.rpx, 0.rpx, 30.rpx, 58.rpx),
child: ClickableContainer(
backgroundColor: themeController.currentColor.sc5,
backgroundColor:
widget.data['backgroundColor'] != null
? widget.data['backgroundColor']
: themeController.currentColor.sc5,
highlightColor:
themeController.currentColor.sc5, // 或你希望的点击水波纹颜色
borderRadius: AppConstants()
@@ -399,7 +410,7 @@ class _NewSleepReportPageState extends State<NewSleepReportPage> {
CrossAxisAlignment.end,
children: [
Text(
'实时体征.姓名'.tr,
'姓名'.tr,
style:
FlutterFlowTheme.of(context)
.bodyMedium
@@ -412,7 +423,7 @@ class _NewSleepReportPageState extends State<NewSleepReportPage> {
),
),
Text(
'实时体征.年龄'.tr,
'年龄'.tr,
style:
FlutterFlowTheme.of(context)
.bodyMedium
@@ -487,7 +498,7 @@ class _NewSleepReportPageState extends State<NewSleepReportPage> {
CrossAxisAlignment.end,
children: [
Text(
'实时体征.设备ID'.tr,
'设备ID'.tr,
style:
FlutterFlowTheme.of(context)
.bodyMedium
@@ -500,7 +511,7 @@ class _NewSleepReportPageState extends State<NewSleepReportPage> {
),
),
Text(
'实时体征.体重'.tr,
'体重'.tr,
style:
FlutterFlowTheme.of(context)
.bodyMedium

View File

@@ -16,7 +16,6 @@ import 'package:vbvs_app/pages/mh_page/device/mht_blueteeth_device_page.dart';
import 'package:vbvs_app/pages/mh_page/device/mht_device_calibration.dart';
import 'package:vbvs_app/pages/mh_page/device/mht_wifi_page.dart';
import 'package:vbvs_app/pages/mh_page/device_list.dart';
import 'package:vbvs_app/pages/mh_page/device_people_info.dart';
import 'package:vbvs_app/pages/mh_page/device_share_page.dart';
import 'package:vbvs_app/pages/mh_page/edit_bed.dart';
import 'package:vbvs_app/pages/mh_page/user/page/edit_userinfo_page.dart';
@@ -33,8 +32,7 @@ import 'package:vbvs_app/pages/mh_page/smys.dart';
import 'package:vbvs_app/pages/mh_page/user/page/find_password_page.dart';
import 'package:vbvs_app/pages/mh_page/user/page/mht_login_page.dart';
import 'package:vbvs_app/pages/mh_page/user/page/update_password_page.dart';
import '../pages/mh_page/bluetooth.dart';
import 'package:vbvs_app/pages/sleep_report/new_sleep_report_page.dart';
import '../pages/mh_page/edit_address_page.dart';
import '../pages/mh_page/message_page.dart';
import '../pages/mh_page/new_settingPage.dart';
@@ -79,6 +77,8 @@ var mhroutes = {
"/mHTwifiPage": (contxt, {arguments}) => MHTWifiPage(deviceInfo: arguments),
"/calibrationPage": (contxt) => MHTCalibrationPage(),
"/bindDeviceSuccess": (contxt) => BindDeviceSuccess(),
"/newSleepReportPage": (contxt, {arguments}) =>
NewSleepReportPage(data: arguments),
};
var mhonGenerateRoute = (RouteSettings settings) {
final String? name = settings.name; // 获取路由名称,如 /news 或 /search