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/home_page/SleepDataModuleWidget.dart'; import 'package:vbvs_app/component/home_page/SleepDateWidget.dart'; import 'package:vbvs_app/component/tool/ClickableContainer.dart'; import 'package:vbvs_app/component/tool/TopSlideNotification.dart'; import 'package:vbvs_app/controller/device/body_device_controller.dart'; import 'package:vbvs_app/controller/theme_controller/ThemeController.dart'; import 'package:vbvs_app/enum/DataStatus.dart'; class DynamicReportDetailWidget extends StatefulWidget { final List sleepDateWidgets; final List sleepDataModuleWidgets; final Map targetDevice; const DynamicReportDetailWidget({ Key? key, required this.sleepDateWidgets, required this.sleepDataModuleWidgets, required this.targetDevice, }) : super(key: key); @override State createState() => _DynamicReportDetailWidgetState(); } class _DynamicReportDetailWidgetState extends State { final ThemeController themeController = Get.find(); final ScrollController _scrollController = ScrollController(); bool _hasScrolled = false; BodyDeviceController bodyDeviceController = Get.find(); @override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) { Future.delayed(Duration(milliseconds: 1000), () { if (!_hasScrolled && _scrollController.hasClients // && _scrollController.position.maxScrollExtent > 0 ) { _scrollController.animateTo( _scrollController.position.maxScrollExtent, duration: Duration(milliseconds: 300), curve: Curves.easeOut, ); _hasScrolled = true; } }); }); } @override Widget build(BuildContext context) { return Padding( padding: EdgeInsetsDirectional.fromSTEB(0, 0.rpx, 0, 0.rpx), child: Container( width: double.infinity, decoration: BoxDecoration( color: themeController.currentColor.sc5, borderRadius: BorderRadius.circular(AppConstants().normal_container_radius), ), child: Padding( padding: EdgeInsetsDirectional.fromSTEB(30.rpx, 30.rpx, 30.rpx, 30.rpx), child: Column( mainAxisSize: MainAxisSize.max, children: [ _buildHeader(context, widget.targetDevice), SizedBox(height: 33.rpx), _buildSleepDateWidgets(), SizedBox(height: 20.rpx), if (!AppConstants.is_test_account) _buildSleepDataModuleWidgets(), ], ), ), ), ); } Widget _buildHeader(BuildContext context, Map targetDevice) { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ ClickableContainer( backgroundColor: Colors.transparent, highlightColor: themeController.currentColor.sc3.withOpacity(0.2), borderRadius: 0, padding: EdgeInsets.zero, onTap: () async { await Get.toNamed("/bodyDevice", arguments: targetDevice); }, child: Container( constraints: BoxConstraints( maxWidth: MediaQuery.sizeOf(context).width * 0.5, ), child: Text( '${targetDevice['person']?['name'] == null ? '未命名'.tr : targetDevice['person']['name']}', style: TextStyle( fontFamily: 'Inter', fontSize: 30.rpx, letterSpacing: 0.0, color: themeController.currentColor.sc3, ), maxLines: 1, overflow: TextOverflow.ellipsis, ), ), ), if (!AppConstants.is_test_account) ClickableContainer( backgroundColor: Colors.transparent, highlightColor: themeController.currentColor.sc3, borderRadius: 0, padding: EdgeInsets.zero, onTap: () { String mac = targetDevice['mac']; List selectedWidgets = widget.sleepDateWidgets .where((w) => w.isSelected == true) .toList(); if (selectedWidgets.isNotEmpty) { DateTime dateTime = DateTime.fromMillisecondsSinceEpoch( int.parse(selectedWidgets[0].time!)); String time = MyUtils.formatBindTime(dateTime); // String sleepReportUrl = // "${ServiceConstant.sleep_report_url}?mac=$mac&token=${ServiceConstant.sleep_token}&date=$time"; // Get.toNamed("/sleepReportPage", arguments: sleepReportUrl); Get.toNamed("/newSleepReportPage", arguments: { 'date': dateTime != null ? dateTime.millisecondsSinceEpoch : DateTime.now().millisecondsSinceEpoch, "mac": mac, 'type': 1, 'name': 'sleep', //'sleep', 'heartRate' 或 'breathe' // 'itemName': widget.data['id'], 'person': widget.targetDevice['person'], }); } else { TopSlideNotification.show(context, text: "当前暂无数据".tr, textColor: themeController.currentColor.sc9); } }, child: Row( children: [ Text( '首页.报告详情'.tr, style: TextStyle( fontFamily: 'Inter', fontSize: 26.rpx, letterSpacing: 0.0, color: themeController.currentColor.sc3, ), ), Padding( padding: EdgeInsetsDirectional.fromSTEB(0, 6.rpx, 0, 0.rpx), child: SvgPicture.asset( 'assets/img/icon/arrow_right.svg', width: 14.rpx, height: 14.rpx, color: themeController.currentColor.sc3, ), ), ].divide(SizedBox(width: 22.rpx)), ), ), ], ); } Widget _buildSleepDateWidgets() { return Container( width: double.infinity, child: SingleChildScrollView( controller: _scrollController, scrollDirection: Axis.horizontal, child: Row( children: widget.sleepDateWidgets .map((widget) => widget) .toList() .divide(SizedBox(width: 20.rpx)), ), ), ); } Widget _buildSleepDataModuleWidgets() { // homePageSleepFlag //widget.targetDevice['mac'] if (bodyDeviceController.homePageSleepFlag[widget.targetDevice['mac']] == DataStatus.Loading.code) { return Container( height: 200.rpx, alignment: Alignment.center, child: CircularProgressIndicator( color: themeController.currentColor.sc1, ), ); } if (widget.sleepDataModuleWidgets.isEmpty) { return Container( height: 200.rpx, alignment: Alignment.center, child: Text( '暂无数据'.tr, style: TextStyle( fontFamily: 'Inter', fontSize: 28.rpx, color: themeController.currentColor.sc4, ), ), ); } // if (widget.sleepDataModuleWidgets.isEmpty) { // return Container( // height: 200.rpx, // alignment: Alignment.center, // child: CircularProgressIndicator( // color: themeController.currentColor.sc1, // ), // ); // } // return Container( // width: double.infinity, // height: 200.rpx, // child: SingleChildScrollView( // scrollDirection: Axis.horizontal, // child: Row( // children: widget.sleepDataModuleWidgets // .map((widget) => widget) // .toList() // .divide(SizedBox(width: 14.rpx)), // ), // ), // ); var aa = widget.sleepDataModuleWidgets // 过滤:当 data 中存在 'show' 且其为 false 时排除该元素 .where((item) => item.data?['show'] != false) // 保持元素本身(SleepDataModuleWidget) .map((item) => item) .toList(); return Container( width: double.infinity, height: 200.rpx, child: SingleChildScrollView( scrollDirection: Axis.horizontal, child: Row( children: // 保留你原来的 divide 间隔处理 aa.divide(SizedBox(width: 14.rpx)), ), ), ); } void resetScroll() { _hasScrolled = false; if (_scrollController.hasClients) { _scrollController.jumpTo(0); } } }