Files
tuiche/lib/pages/mh_page/message_page.dart
2025-07-25 10:26:30 +08:00

408 lines
14 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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<MessagePage> createState() => _MessagePageState();
}
class _MessagePageState extends State<MessagePage> {
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(
'消息中心',
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);
}),
Obx(() {
final list = messageController.systemMessageList;
return list.isEmpty
? const NullDataWidget()
: _buildMessageListView(list);
}),
],
),
),
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(
'全部已读',
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.zero,
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.zero,
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) {
return Container(
width: double.infinity,
padding: EdgeInsets.symmetric(horizontal: 30.rpx),
child: SingleChildScrollView(
child: Column(
children: [
SizedBox(height: 30.rpx),
...dataList
.map((item) => MhMessageListWidget(data: item))
.toList()
.divide(SizedBox(height: 30.rpx)),
SizedBox(height: 30.rpx),
],
),
),
);
}
}