import 'package:EasyDartModule/EasyDartModule.dart' as es; import 'package:ef/ef.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.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/component/tool/ClickableContainer.dart'; import 'package:vbvs_app/pages/device_bind/componnet/bind_dialog.dart'; import 'package:vbvs_app/pages/mh_page/homepage/controller/mht_home_controller.dart'; import 'package:vbvs_app/pages/sleep_report/chart/SnoreWaveform.dart'; //睡眠规律性 class NewSleepViewWidget extends StatefulWidget { var sleepReport; NewSleepViewWidget({super.key, required this.sleepReport}); @override State createState() => _NewSleepViewWidgetState(); } class _NewSleepViewWidgetState extends State { @override void setState(VoidCallback callback) { super.setState(callback); } @override void initState() { super.initState(); } @override void dispose() { super.dispose(); } @override Widget build(BuildContext context) { try { if (widget.sleepReport == null || widget.sleepReport is! Map || widget.sleepReport.isEmpty) { return Container(); } List showLabel = widget.sleepReport['sleepData']['type'] .where((item) => item['show'] != false) .toList(); final bsList = widget.sleepReport['bs'] as List; final deepSleep = bsList.firstWhere((e) => e['id'] == 111, orElse: () => null); final lightSleep = bsList.firstWhere((e) => e['id'] == 117, orElse: () => null); final snore = bsList.firstWhere((e) => e['id'] == 116, orElse: () => null); final movement = bsList.firstWhere((e) => e['id'] == 108, orElse: () => null); final leaveBed = bsList.firstWhere((e) => e['id'] == 114, orElse: () => null); final Map typeIdMap = { 0: 114, // 离床时长 1: 117, // 浅睡时长 2: 111, // 深睡时长 3: 108, // 频繁体动时长 4: 116, // 打鼾时长 }; List snoreValues = []; List lightSnore = widget.sleepReport['ssp']['data'][0]; List heavySnore = widget.sleepReport['ssp']['data'][1]; snoreValues = [...lightSnore, ...heavySnore]; snoreValues.sort((a, b) { return a['st'].compareTo(b['st']); }); Map time = MyUtils.diffHoursMinutesMap( widget.sleepReport['startTime'], widget.sleepReport['endTime']); int hour = time['hours']; int minutes = time['minutes']; final matched = bsList.firstWhere( (item) => item['id'] == 105, orElse: () => {}, ); List stages = widget.sleepReport['sleepData']['stages']; return Container( width: double.infinity, decoration: BoxDecoration( color: themeController.currentColor.sc5, borderRadius: BorderRadius.circular(AppConstants().normal_container_radius), ), child: Padding( padding: EdgeInsetsDirectional.fromSTEB(26.rpx, 10.rpx, 26.rpx, 44.rpx), child: Column( mainAxisSize: MainAxisSize.max, children: [ Container( child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( "睡眠规律性".tr, style: TextStyle( color: themeController.currentColor.sc3, fontSize: AppConstants().title_text_fontSize), ), ClickableContainer( backgroundColor: Colors.transparent, highlightColor: Colors.white, // 或设置为你需要的水波纹颜色 padding: EdgeInsetsDirectional.fromSTEB( 14.rpx, 0.rpx, 14.rpx, 0), // borderRadius: 0.rpx, // 圆形点击区域 onTap: () { showTipDialog( context, Container( child: Text( "睡眠规律性是指个体睡眠模式在时间、时长、环境等方面呈现出的稳定性和一致性,是衡量睡眠质量的重要指标之一。" .tr, style: TextStyle( fontSize: 26.rpx, color: Colors.black, ), ), ), backgroundColor: Color(0xFFFFFFFF), colors: [ Color(0XFF1592AA), Color(0xFF0C83A7), Color(0xFF006FA3) ], ); }, child: Container( padding: EdgeInsetsDirectional.fromSTEB( 0, 0.rpx, 0.rpx, 0), // 外部 padding 移到内部 width: 28.rpx, height: 28.rpx, child: SvgPicture.asset( 'assets/img/icon/explain.svg', fit: BoxFit.cover, color: themeController.currentColor.sc4, ), ), ), ], ), Row(mainAxisAlignment: MainAxisAlignment.end, children: [ OutlinedButton( onPressed: () { MHTHomeController homeController = Get.find(); Get.toNamed("/newSleepReportPage", arguments: { 'date': widget.sleepReport['endTime'], "mac": homeController.selectDevcie.value, 'type': 1, 'backgroundImg': 'assets/images/new_background.png', 'person_show': false, }); }, style: OutlinedButton.styleFrom( side: const BorderSide(color: Color(0XFF85F5FF)), foregroundColor: Color(0XFF85F5FF), minimumSize: Size(202.rpx, 62.rpx), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(6), ), ), child: Text('查看详情'.tr), ), ]) ], ), ), Container( alignment: Alignment(-1, 0), child: Text( "在床时长".tr + " ${formatDecimalHoursWithTr(matched['value'])}", style: TextStyle(color: Color(0xFF929699), fontSize: 20.rpx), ), ), SizedBox( height: 49.rpx, ), Padding( padding: EdgeInsetsDirectional.fromSTEB( 26.rpx, 0.rpx, 26.rpx, 0.rpx), child: SnoreChartContainer( snoreValues: snoreValues, barData: stages, startTime: widget.sleepReport['startTime'], endTime: widget.sleepReport['endTime'], showLabel: showLabel, ), ), SizedBox( height: 62.rpx, ), // Wrap( // spacing: 55.rpx, // runSpacing: 20.rpx, // children: showLabel.map((item) { // return Container( // padding: EdgeInsets.all(5.rpx), // child: Row( // mainAxisSize: MainAxisSize.min, // children: [ // Container( // width: 20.rpx, // height: 20.rpx, // decoration: BoxDecoration( // color: item["color"] == null || item["color"] == "" // ? Colors.transparent // : stringToColor(item["color"]), // borderRadius: BorderRadius.circular(10.rpx), // ), // ), // SizedBox(width: 17.rpx), // Text( // item["name"], // style: TextStyle( // color: Colors.white, // fontSize: 24.rpx, // ), // ), // ], // ), // ); // }).toList(), // ), Wrap( spacing: 55.rpx, runSpacing: 20.rpx, children: showLabel.map((item) { final int type = item["type"]; final int? targetId = typeIdMap[type]; // 在 bsList 中查找对应 id 的元素 final matchedItem = bsList.firstWhere( (e) => e["id"] == targetId, orElse: () => {}, ); final dynamic value = matchedItem?["value"]; final String displayValue = formatHourToHM(value); return Container( padding: EdgeInsets.all(5.rpx), child: Row( mainAxisSize: MainAxisSize.min, children: [ Container( width: 20.rpx, height: 20.rpx, decoration: BoxDecoration( color: item["color"] == null || item["color"] == "" ? Colors.transparent : stringToColor(item["color"]), borderRadius: BorderRadius.circular(10.rpx), ), ), SizedBox(width: 17.rpx), Text( value != null ? "${item["name"]} $displayValue" : "${item["name"]} -", style: TextStyle( color: Colors.white, fontSize: 24.rpx, ), ), ], ), ); }).toList(), ), ], ), ), ); } catch (e) { es.EasyDartModule.logger.error("打鼾监测绘制异常${e}"); return Container(); } } String formatDecimalHoursWithTr(double value) { int hours = value.floor(); // 小时整数部分 int minutes = ((value - hours) * 60).round(); // 小数转分钟 return "$hours${'小时'.tr}$minutes${'分钟'.tr}"; } List> formatSleepData(List bs) { List targetIds = [114, 117, 111, 108, 116]; return bs.where((item) { final id = item['id']; return id != null && targetIds.contains(id); }).map((item) { try { final rawValue = item['value']; String valueStr = ''; if (rawValue is num) { final double raw = rawValue.toDouble(); int hours = raw.floor(); int minutes = ((raw - hours) * 60).round(); if (hours > 0) valueStr += '$hours${'h'}'; if (minutes > 0) valueStr += '$minutes${'m'}'; if (valueStr.isEmpty) valueStr = '0${'m'}'; } else { valueStr = rawValue?.toString() ?? '0${'m'}'; } return { 'name': item['name'] ?? '', 'value': valueStr, 'color': item['color'], }; } catch (e) { return { 'name': item['name'] ?? '', 'value': '0${'m'}', 'color': item['color'], }; } }).toList(); } String formatHourToHM(dynamic value) { if (value == null) return "-"; if (value is num) { int hours = value.floor(); int minutes = ((value - hours) * 60).round(); if (hours > 0) { return "${hours}h ${minutes}m"; } else { return "${minutes}m"; } } return "-"; } }