import 'package:ef/ef.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; import 'package:flutterflow_ui/flutterflow_ui.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/controller/sleep/sleep_report_controller.dart'; import 'package:vbvs_app/controller/theme_controller/ThemeController.dart'; import 'package:vbvs_app/pages/device_bind/componnet/bind_dialog.dart'; class SleepDataModuleWidget extends StatefulWidget { final Map data; final dynamic sleepReportData; // 可选参数,类型为 var/dynamic const SleepDataModuleWidget({ super.key, required this.data, this.sleepReportData, // 标记为可选参数 }); @override State createState() => _SleepDataModuleWidgetState(); } class _SleepDataModuleWidgetState 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) { ThemeController themeController = Get.find(); return ClickableContainer( backgroundColor: themeController.currentColor.sc5, highlightColor: themeController.currentColor.sc21, borderRadius: 20.rpx, padding: EdgeInsetsDirectional.fromSTEB(18.rpx, 10.rpx, 18.rpx, 10.rpx), onTap: () { if (widget.data['showTip'] != null && widget.data['showTip'] == true) { final String itemLevel = widget.data['code'] ?? ''; SleepReportController sleepReportController = Get.find(); var report = sleepReportController.sleepReport; List> levelGroups = []; if (widget.sleepReportData != null) { report.value = widget.sleepReportData; } if (report != null) { var colorMap = Map.from(report.value['info']['color']); var levelMap = Map.from(report.value['info']['level']); //修改渲染 for (var prefix in ['G', 'Y', 'R']) { List keys = colorMap.keys.where((k) => k.startsWith(prefix)).toList(); keys.sort(); // G1, G2, G3 List> items = keys.map((k) { return { "key": k, "color": colorMap[k], "level": levelMap[k] ?? "未知", }; }).toList(); levelGroups.add({ "levelName": items.first['level'], // 默认同组level一致 "items": items, }); } } showTipDialog( backgroundColor: stringToColor("#FFFFFF"), context, Container( constraints: BoxConstraints( maxHeight: 700.rpx, ), child: SingleChildScrollView( child: Column( children: [ Text( "${widget.data['name']}", style: TextStyle( color: stringToColor("#333333"), fontSize: 36.rpx, ), ), SizedBox( height: 17.rpx, ), Text( (widget.data['tips']?.toString().trim().isNotEmpty ?? false) ? widget.data['tips'].toString() : "未知数据".tr, style: TextStyle( color: stringToColor("#C8CBD2"), fontSize: 26.rpx, ), ), SizedBox( height: 37.rpx, ), Text( "${widget.data['value']}" + ((widget.data['unit'] == null || widget.data['unit'].toString().isEmpty) ? '' : widget.data['unit']), style: TextStyle( color: stringToColor("${widget.data['color']}"), fontSize: 60.rpx, ), ), SizedBox( height: 81.rpx, ), IntrinsicHeight( child: Row( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ for (int i = 0; i < levelGroups.length; i++) ...[ // 每个 levelGroup 区域 Expanded( child: Column( mainAxisSize: MainAxisSize.min, children: [ // Level 名称 Text( levelGroups[i]['levelName'], style: TextStyle( fontSize: 30.rpx, color: stringToColor("#333333"), fontWeight: FontWeight.bold, ), ), SizedBox(height: 38.rpx), // 颜色圆点 + key(包一层,和 svg 分离) Row( mainAxisAlignment: MainAxisAlignment.spaceAround, crossAxisAlignment: CrossAxisAlignment.start, // 上对齐,避免撑高分割线 children: levelGroups[i]['items'] .map((item) { final bool isSelected = (item['key'] == itemLevel); return Column( children: [ // 颜色圆点 + key(参与分割线高度) Column( children: [ Container( width: 20.rpx, height: 20.rpx, decoration: BoxDecoration( color: stringToColor( item['color']), shape: BoxShape.circle, ), ), SizedBox(height: 30.rpx), Text( item['key'], style: TextStyle( color: stringToColor("#333333"), fontSize: 20.rpx, ), ), ], ), // svg 箭头(不影响分割线高度) SizedBox(height: 20.rpx), isSelected ? SvgPicture.asset( 'assets/img/icon/triangle.svg', width: 18.rpx, height: 18.rpx, color: themeController .currentColor.sc9, ) : SizedBox(height: 18.rpx), ], ); }).toList(), ), ], ), ), // 分割线(只和主要内容等高) if (i != levelGroups.length - 1) Container( width: 1.rpx, color: Colors.grey.withOpacity(0.5), margin: EdgeInsets.symmetric(horizontal: 10.rpx), ), ] ], ), ), SizedBox( height: 71.rpx, ), RichText( text: TextSpan( children: [ TextSpan( text: "当前属于".tr, // 第一部分文本 style: TextStyle( color: Colors.black, // 你想要的样式 fontSize: 30.rpx, ), ), TextSpan( text: itemLevel, // 第二部分文本 style: TextStyle( color: stringToColor("${widget.data['color']}"), fontSize: 30.rpx, ), ), ], ), ), ], ), ), ), ); } if (widget.data['onto'] != null && widget.data['onto'] == true) { //跳转睡眠报告 Get.toNamed("/newSleepReportPage", arguments: { 'date': widget.data['time'] != null ? int.parse(widget.data['time'].toString()) : DateTime.now().millisecondsSinceEpoch, "mac": widget.data['mac'] != null && widget.data['mac'].isNotEmpty ? widget.data['mac'] : 'aaaaaaeeeeeq', 'type': 1, 'name': 'sleep', //'sleep', 'heartRate' 或 'breathe' 'itemName': widget.data['id'], 'person': widget.data['person'], }); } }, child: Container( width: MediaQuery.sizeOf(context).width * 0.267, constraints: BoxConstraints( minWidth: 200.rpx, minHeight: 161.rpx, ), child: Column( mainAxisSize: MainAxisSize.max, crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Text( '${widget.data['name']}', style: TextStyle( fontFamily: 'Inter', fontSize: 26.rpx, letterSpacing: 0.0, color: themeController.currentColor.sc3, ), maxLines: 1, overflow: TextOverflow.ellipsis, ), Row( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ // Expanded( // child: Row( // mainAxisSize: MainAxisSize.min, // crossAxisAlignment: CrossAxisAlignment.end, // children: [ // Text( // '${widget.data['value']}', // style: TextStyle( // fontFamily: 'Inter', // fontSize: 36.rpx, // letterSpacing: 0.0, // color: themeController.currentColor.sc3, // ), // maxLines: 1, // overflow: TextOverflow.ellipsis, // ), // Padding( // padding: // EdgeInsetsDirectional.fromSTEB(0, 0, 0, 10.rpx), // child: Text( // '${widget.data['unit'] ?? ''}', // style: FlutterFlowTheme.of(context) // .bodyMedium // .override( // fontFamily: 'Inter', // fontSize: AppConstants().small_text_fontSize, // letterSpacing: 0.0, // color: themeController.currentColor.sc3, // ), // maxLines: 1, // overflow: TextOverflow.ellipsis, // ), // ), // ], // ), // ), Expanded( child: Text.rich( TextSpan( children: [ TextSpan( text: '${widget.data['value']}', style: TextStyle( fontFamily: 'Inter', fontSize: 36.rpx, letterSpacing: 0.0, color: themeController.currentColor.sc3, ), ), WidgetSpan(child: SizedBox(width: 2.rpx)), // 可选间距 TextSpan( text: widget.data['unit'] != null ? '${widget.data['unit']}' : '', style: TextStyle( fontFamily: 'Inter', fontSize: AppConstants().small_text_fontSize, letterSpacing: 0.0, color: themeController.currentColor.sc3, ), ), ], ), maxLines: 1, style: TextStyle( color: themeController.currentColor.sc3), // 强制 ellipsis 颜色 overflow: TextOverflow.ellipsis, ), ), if (widget.data['level'] != null) ClickableContainer( backgroundColor: (widget.data['color'] == null || widget.data['color'].toString().isEmpty) ? Colors.transparent : stringToColor(widget.data['color']), highlightColor: themeController.currentColor.sc3, padding: EdgeInsets.symmetric( horizontal: 0.rpx, vertical: 0.rpx, ), borderRadius: 8.rpx, onTap: () { print('Button pressed ...'); }, child: Container( alignment: Alignment.center, constraints: BoxConstraints( minWidth: 43.rpx, minHeight: 25.rpx, ), child: Text( '${widget.data['level']}', style: TextStyle( fontFamily: 'Inter Tight', color: themeController.currentColor.sc3, letterSpacing: 0.0, fontSize: 15.rpx, ), ), ), ), ].divide(SizedBox(width: 0.rpx)), ), Text( "正常值".tr + '${(widget.data['range'] ?? '').toString().isEmpty ? '未知数据'.tr : widget.data['range']}', style: TextStyle( fontFamily: 'Inter', fontSize: AppConstants().small_text_fontSize, letterSpacing: 0.0, color: themeController.currentColor.sc4, ), maxLines: 1, overflow: TextOverflow.ellipsis, ), ], ), ), ); } }