import 'package:ef/ef.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.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/color/appFontsize.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/MyUtils.dart'; import 'package:vbvs_app/component/NullDataComponentWidget.dart'; import 'package:vbvs_app/component/tool/ClickableContainer.dart'; import 'package:vbvs_app/component/tool/TopSlideNotification.dart'; import 'package:vbvs_app/controller/mh_controller/message_controller.dart'; import 'package:vbvs_app/controller/theme_controller/ThemeController.dart'; import 'package:vbvs_app/pages/mh_page/MhMessageList.dart'; class MessagePage extends StatefulWidget { const MessagePage({super.key}); @override State createState() => _MessagePageState(); } class _MessagePageState extends State { ThemeController themeController = Get.find(); MhMessageController messageController = Get.find(); late PageController _pageController; @override void initState() { super.initState(); messageController.model.type = 1; _pageController = PageController(initialPage: messageController.model.type == 1 ? 0 : 1); messageController.getMessageStatus(); _fetchMessageData(); } void _fetchMessageData() { String type = messageController.model.type == 1 ? "app_vsm" : "app_system"; messageController.updateMessageStatus(type: type); messageController.getMessageList(type).then((response) { if (response.code != HttpStatusCodes.ok) { TopSlideNotification.show( // Get.context!, context, text: response.msg ?? "失败".tr, textColor: themeController.currentColor.sc9, ); } }); } void _onTabChanged(int index) { messageController.model.type = index == 0 ? 1 : 2; messageController.updateAll(); _fetchMessageData(); _pageController.animateToPage(index, duration: const Duration(milliseconds: 300), curve: Curves.easeInOut); } void _onPageChanged(int index) { int newType = index == 0 ? 1 : 2; if (messageController.model.type != newType) { messageController.model.type = newType; messageController.updateAll(); _fetchMessageData(); } } @override void dispose() { _pageController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle( statusBarColor: Colors.transparent, statusBarIconBrightness: Brightness.light, )); return LayoutBuilder( builder: (context, boxConstraints) => GestureDetector( // onTap: () => FocusScope.of(context).unfocus(),, child: Container( decoration: const BoxDecoration( image: DecorationImage( image: AssetImage('assets/images/new_background.png'), // 本地图片 fit: BoxFit.fill, // 填满整个 Container ), ), child: Scaffold( appBar: AppBar( backgroundColor: Colors.transparent, automaticallyImplyLeading: false, iconTheme: IconThemeData(color: themeController.currentColor.sc3), titleSpacing: 0, title: SizedBox( width: double.infinity, height: 180.rpx, child: Stack( alignment: Alignment.center, children: [ // 中间居中的标题 Text( '消息中心'.tr, textAlign: TextAlign.center, style: TextStyle( color: Colors.white, fontSize: 30.rpx, ), ), // 左侧图标 Positioned( left: 0.rpx, child: returnIconButtomNew(), ), ], ), ), actions: const [], centerTitle: false, ), backgroundColor: Colors.transparent, body: SafeArea( top: true, child: Padding( padding: EdgeInsets.only(top: 30.rpx), child: Column( children: [ SizedBox( height: 100.rpx, child: Stack( alignment: Alignment.bottomCenter, children: [ Row( children: [ // 第一个 Tab 占据屏幕一半 bodyMessage(), // 第二个 Tab 占据屏幕另一半 systemMessage(), ], ), Obx(() { double screenWidth = MediaQuery.of(context).size.width; double tabWidth = screenWidth / 2; double margin = 30.rpx; double lineWidth = tabWidth - 2 * margin; // 计算滑块左边距,保证滑块水平居中于对应tab的文字 double left = (messageController.model.type == 1 ? 0 : tabWidth) + margin; return AnimatedPositioned( duration: const Duration(milliseconds: 300), curve: Curves.easeInOut, bottom: 0, left: left, child: Container( width: lineWidth, height: 4.rpx, decoration: BoxDecoration( color: Color(0xFF84F5FF), borderRadius: BorderRadius.circular(2.rpx), ), ), ); }), ], ), ), Expanded( child: PageView( controller: _pageController, onPageChanged: _onPageChanged, children: [ Obx(() { final list = messageController.bodyMessageList; return list.isEmpty ? const NullDataWidget() : _buildMessageListView(list, "app_vsm"); }), Obx(() { final list = messageController.systemMessageList; return list.isEmpty ? const NullDataWidget() : _buildMessageListView(list, "app_system"); }), ], ), ), bottomIcon(context) ], ), )), ), ), ), ); } Container bottomIcon(BuildContext context) { return Container( height: 120.rpx, decoration: BoxDecoration( color: Color(0xFF003058), ), width: double.infinity, child: TextButton( onPressed: () async { if (messageController.model.type == 1) { messageController.updateMessageReadStatus(context, "app_vsm", all: true); } else { messageController.updateMessageReadStatus(context, "app_system", all: true); } }, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Baseline( baselineType: TextBaseline.alphabetic, baseline: AppFontsize.normal_text_size * 1.6, // 调整基线位置 child: SvgPicture.asset( 'assets/images/read_message.svg', width: 40.rpx, height: 40.rpx, )), SizedBox(width: 14.rpx), // 加号和文字间距 Text( '全部已读'.tr, style: TextStyle( fontFamily: 'Readex Pro', color: Colors.white, fontSize: 26.rpx, letterSpacing: 0, ), ), ], ), ), ); } Expanded systemMessage() { return Expanded( child: Align( alignment: Alignment.center, child: Obx(() { return ClickableContainer( padding: EdgeInsets.symmetric(horizontal: 16.rpx, vertical: 8.rpx), backgroundColor: Colors.transparent, highlightColor: themeController.currentColor.sc21, borderRadius: 8.rpx, onTap: () => _onTabChanged(1), child: Stack( alignment: Alignment.center, clipBehavior: Clip.none, children: [ Text( '系统消息'.tr, style: TextStyle( fontSize: AppConstants().title_text_fontSize, color: messageController.model.type == 1 ? Colors.white : Color(0xFF84F5FF), height: 1.0, ), ), Obx(() { if (messageController.model.system_message_read == 1) { return Positioned( top: -4.rpx, right: -14.rpx, child: Container( width: 15.rpx, height: 15.rpx, decoration: const BoxDecoration( color: Colors.red, shape: BoxShape.circle, ), ), ); } else { return const SizedBox.shrink(); } }), // final allHaveReadTime = // messageController.systemMessageList.any( // (item) => !item.containsKey('read_time'), // ); // return allHaveReadTime // ? Positioned( // top: -4, // right: -14, // child: Container( // width: 15.rpx, // height: 15.rpx, // decoration: const BoxDecoration( // color: Colors.red, // shape: BoxShape.circle, // ), // ), // ) // : const SizedBox.shrink(); ], ), ); }), ), ); } Expanded bodyMessage() { return Expanded( child: Align( alignment: Alignment.center, child: Obx(() { return ClickableContainer( padding: EdgeInsets.symmetric(horizontal: 16.rpx, vertical: 8.rpx), backgroundColor: Colors.transparent, highlightColor: themeController.currentColor.sc21, borderRadius: 8.rpx, onTap: () => _onTabChanged(0), child: Stack( alignment: Alignment.center, clipBehavior: Clip.none, children: [ Text( '体征消息'.tr, style: TextStyle( fontSize: AppConstants().title_text_fontSize, color: messageController.model.type == 2 ? Colors.white : Color(0xFF84F5FF), height: 1.0, ), ), // Obx(() { // return messageController.model.body_message_read == 1 // ? Positioned( // top: -4, // right: -14, // child: Container( // width: 15.rpx, // height: 15.rpx, // decoration: const BoxDecoration( // color: Colors.red, // shape: BoxShape.circle, // ), // ), // ) // : const SizedBox.shrink(); // }), Obx(() { if (messageController.model.body_message_read == 1) { return Positioned( top: -4.rpx, right: -14.rpx, child: Container( width: 15.rpx, height: 15.rpx, decoration: const BoxDecoration( color: Colors.red, shape: BoxShape.circle, ), ), ); } else { return const SizedBox.shrink(); } }), ], ), ); }), ), ); } Widget _buildMessageListView(List dataList, String type) { return NotificationListener( onNotification: (scrollInfo) { if (scrollInfo.metrics.pixels == scrollInfo.metrics.maxScrollExtent) { // 滑到底部,加载下一页 messageController.loadMore(type); } return true; }, child: ListView.builder( padding: EdgeInsets.symmetric(horizontal: 30.rpx, vertical: 30.rpx), itemCount: dataList.length, itemBuilder: (context, index) { return Padding( padding: EdgeInsets.only(bottom: 30.rpx), child: MhMessageListWidget(data: dataList[index]), ); }, ), ); } }