Commit 68deabfc authored by 张宏's avatar 张宏

首页开发

parent 15182754
This diff is collapsed.
......@@ -126,6 +126,7 @@
<entry key="characters">
<value>
<list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.dev/characters-1.4.0/lib" />
<option value="$USER_HOME$/.pub-cache/hosted/pub.dev/characters-1.4.1/lib" />
</list>
</value>
......@@ -246,7 +247,6 @@
<value>
<list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.dev/dio-5.9.2/lib" />
<option value="$USER_HOME$/.pub-cache/hosted/pub.dev/dio-5.9.1/lib" />
</list>
</value>
</entry>
......@@ -309,6 +309,7 @@
<entry key="flutter">
<value>
<list>
<option value="$PROJECT_DIR$/../../../../Flutter/flutter/packages/flutter/lib" />
<option value="$USER_HOME$/fvm/versions/3.41.9/packages/flutter/lib" />
</list>
</value>
......@@ -386,7 +387,7 @@
<entry key="flutter_localizations">
<value>
<list>
<option value="$USER_HOME$/fvm/versions/3.41.9/packages/flutter_localizations/lib" />
<option value="$PROJECT_DIR$/../../../../Flutter/flutter/packages/flutter_localizations/lib" />
</list>
</value>
</entry>
......@@ -463,6 +464,7 @@
<entry key="flutter_test">
<value>
<list>
<option value="$PROJECT_DIR$/../../../../Flutter/flutter/packages/flutter_test/lib" />
<option value="$USER_HOME$/fvm/versions/3.41.9/packages/flutter_test/lib" />
</list>
</value>
......@@ -505,7 +507,7 @@
<entry key="flutter_web_plugins">
<value>
<list>
<option value="$USER_HOME$/fvm/versions/3.41.9/packages/flutter_web_plugins/lib" />
<option value="$PROJECT_DIR$/../../../../Flutter/flutter/packages/flutter_web_plugins/lib" />
</list>
</value>
</entry>
......@@ -669,7 +671,6 @@
<value>
<list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.dev/logger-2.7.0/lib" />
<option value="$USER_HOME$/.pub-cache/hosted/pub.dev/logger-2.5.0/lib" />
</list>
</value>
</entry>
......@@ -690,6 +691,7 @@
<entry key="matcher">
<value>
<list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.dev/matcher-0.12.17/lib" />
<option value="$USER_HOME$/.pub-cache/hosted/pub.dev/matcher-0.12.19/lib" />
</list>
</value>
......@@ -697,6 +699,7 @@
<entry key="material_color_utilities">
<value>
<list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.dev/material_color_utilities-0.11.1/lib" />
<option value="$USER_HOME$/.pub-cache/hosted/pub.dev/material_color_utilities-0.13.0/lib" />
</list>
</value>
......@@ -999,6 +1002,7 @@
<entry key="sky_engine">
<value>
<list>
<option value="$PROJECT_DIR$/../../../../Flutter/flutter/bin/cache/pkg/sky_engine/lib" />
<option value="$USER_HOME$/fvm/versions/3.41.9/bin/cache/pkg/sky_engine/lib" />
</list>
</value>
......@@ -1091,6 +1095,7 @@
<entry key="test_api">
<value>
<list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.dev/test_api-0.7.7/lib" />
<option value="$USER_HOME$/.pub-cache/hosted/pub.dev/test_api-0.7.10/lib" />
</list>
</value>
......@@ -1327,6 +1332,7 @@
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/build_runner_core-7.3.2/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/built_collection-5.1.1/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/built_value-8.12.6/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/characters-1.4.0/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/characters-1.4.1/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/checked_yaml-2.0.4/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/cli_config-0.2.0/lib" />
......@@ -1344,7 +1350,6 @@
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/dart_webrtc-1.8.1/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/device_info_plus-12.4.0/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/device_info_plus_platform_interface-7.0.3/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/dio-5.9.1/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/dio-5.9.2/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/dio_web_adapter-2.1.2/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/equatable-2.0.8/lib" />
......@@ -1403,11 +1408,12 @@
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/lints-2.1.1/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/lints-4.0.0/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/loading_animation_widget-1.3.0/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/logger-2.5.0/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/logger-2.7.0/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/logging-1.3.0/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/marionette_flutter-0.5.0/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/matcher-0.12.17/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/matcher-0.12.19/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/material_color_utilities-0.11.1/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/material_color_utilities-0.13.0/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/meta-1.17.0/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/mime-2.0.0/lib" />
......@@ -1466,6 +1472,7 @@
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/term_glyph-1.2.2/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/test-1.30.0/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/test_api-0.7.10/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/test_api-0.7.7/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/test_core-0.6.16/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/timing-1.0.2/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/tint-2.0.1/lib" />
......@@ -1496,11 +1503,14 @@
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/xdg_directories-1.1.0/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/xml-6.6.1/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/yaml-3.1.3/lib" />
<root url="file://$PROJECT_DIR$/../../../../Flutter/flutter/bin/cache/pkg/sky_engine/lib" />
<root url="file://$PROJECT_DIR$/../../../../Flutter/flutter/packages/flutter/lib" />
<root url="file://$PROJECT_DIR$/../../../../Flutter/flutter/packages/flutter_localizations/lib" />
<root url="file://$PROJECT_DIR$/../../../../Flutter/flutter/packages/flutter_test/lib" />
<root url="file://$PROJECT_DIR$/../../../../Flutter/flutter/packages/flutter_web_plugins/lib" />
<root url="file://$USER_HOME$/fvm/versions/3.41.9/bin/cache/pkg/sky_engine/lib" />
<root url="file://$USER_HOME$/fvm/versions/3.41.9/packages/flutter/lib" />
<root url="file://$USER_HOME$/fvm/versions/3.41.9/packages/flutter_localizations/lib" />
<root url="file://$USER_HOME$/fvm/versions/3.41.9/packages/flutter_test/lib" />
<root url="file://$USER_HOME$/fvm/versions/3.41.9/packages/flutter_web_plugins/lib" />
</CLASSES>
<JAVADOC />
<SOURCES />
......
......@@ -145,24 +145,39 @@ class AlertInfoBO extends Equatable {
/// 用途:首页监护舱右侧设备菜单数据
/// 涉及页面:首页监护舱页面
class MonitoringMenuItemBO extends Equatable {
/// 菜单ID
final String id;
/// 菜单标题
final String title;
/// 菜单图标文案
/// 菜单图标(emoji或文字,用于旧版本兼容)
final String icon;
/// 菜单图标路径(新版本)
final String iconPath;
/// 是否为TSAAS特殊样式
final bool isTsaas;
const MonitoringMenuItemBO({
required this.id,
required this.title,
required this.icon,
this.icon = '',
this.iconPath = '',
this.isTsaas = false,
});
factory MonitoringMenuItemBO.fromJson(Map<String, dynamic> json) {
return MonitoringMenuItemBO(
id: json['id'] as String? ?? '',
title: json['title'] as String? ?? '',
icon: json['icon'] as String? ?? '',
iconPath: json['iconPath'] as String? ?? '',
isTsaas: json['isTsaas'] as bool? ?? false,
);
}
@override
List<Object?> get props => [title, icon];
List<Object?> get props => [id, title, icon, iconPath, isTsaas];
}
......@@ -82,16 +82,47 @@ class MonitoringMockData {
static List<MonitoringMenuItemBO> getMockMenuItems() {
return const [
MonitoringMenuItemBO(
title: '动物血压监测',
id: 'icu_central',
title: 'ICU中控',
icon: '🏥',
iconPath: 'lib/assets/menu/menu1.png',
),
MonitoringMenuItemBO(
id: 'blood_pressure',
title: '血压监测',
icon: '❤️',
iconPath: 'lib/assets/menu/menu2.png',
),
MonitoringMenuItemBO(
title: '多功能动物体征检测仪',
id: 'vital_signs',
title: '体征仪',
icon: '📏',
iconPath: 'lib/assets/menu/menu3.png',
),
MonitoringMenuItemBO(
title: '穿戴式多导心电监测系统',
id: 'ecg_system',
title: '多导心电系统',
icon: '💓',
iconPath: 'lib/assets/menu/menu4.png',
),
MonitoringMenuItemBO(
id: 'tsaas',
title: 'TSAAS',
icon: '🔵',
iconPath: 'lib/assets/menu/menu5.png',
isTsaas: true,
),
MonitoringMenuItemBO(
id: 'record',
title: '记录',
icon: '📝',
iconPath: 'lib/assets/menu/menu6.png',
),
MonitoringMenuItemBO(
id: 'settings',
title: '设置',
icon: '⚙️',
iconPath: 'lib/assets/menu/menu7.png',
),
];
}
......
......@@ -210,6 +210,41 @@ class MonitoringIndexCubit extends Cubit<MonitoringIndexState> {
/// 获取 P2P 视频播放控制器供 UI 层使用
P2pVideoService get p2pVideoService => _p2pVideoService;
// ==================== 菜单点击事件 ====================
/// 处理底部菜单点击
void onMenuItemTap(String menuId) {
debugPrint('[MonitoringIndexCubit] 菜单被点击: $menuId');
emit(state.copyWith(selectedMenuId: menuId));
// 根据菜单ID处理不同的逻辑
switch (menuId) {
case 'icu_central':
debugPrint('[MonitoringIndexCubit] 切换到ICU中控');
break;
case 'blood_pressure':
debugPrint('[MonitoringIndexCubit] 切换到血压监测');
break;
case 'vital_signs':
debugPrint('[MonitoringIndexCubit] 切换到体征仪');
break;
case 'ecg_system':
debugPrint('[MonitoringIndexCubit] 切换到多导心电系统');
break;
case 'tsaas':
debugPrint('[MonitoringIndexCubit] 切换到TSAAS');
break;
case 'record':
debugPrint('[MonitoringIndexCubit] 切换到记录');
break;
case 'settings':
debugPrint('[MonitoringIndexCubit] 切换到设置');
break;
default:
debugPrint('[MonitoringIndexCubit] 未知菜单: $menuId');
}
}
@override
Future<void> close() {
_webrtcStateSub?.cancel();
......
......@@ -31,6 +31,9 @@ class MonitoringIndexState extends Equatable {
/// P2P 模式是否已连接
final bool isP2pConnected;
/// 当前选中的菜单ID
final String? selectedMenuId;
const MonitoringIndexState({
this.status = MonitoringIndexStatus.initial,
this.isLoading = false,
......@@ -43,6 +46,7 @@ class MonitoringIndexState extends Equatable {
this.videoStreamMode = VideoStreamMode.p2p,
this.isSwitchingMode = false,
this.isP2pConnected = false,
this.selectedMenuId,
});
MonitoringIndexState copyWith({
......@@ -57,6 +61,7 @@ class MonitoringIndexState extends Equatable {
VideoStreamMode? videoStreamMode,
bool? isSwitchingMode,
bool? isP2pConnected,
String? selectedMenuId,
}) {
return MonitoringIndexState(
status: status ?? this.status,
......@@ -71,6 +76,7 @@ class MonitoringIndexState extends Equatable {
videoStreamMode: videoStreamMode ?? this.videoStreamMode,
isSwitchingMode: isSwitchingMode ?? this.isSwitchingMode,
isP2pConnected: isP2pConnected ?? this.isP2pConnected,
selectedMenuId: selectedMenuId ?? this.selectedMenuId,
);
}
......@@ -87,5 +93,6 @@ class MonitoringIndexState extends Equatable {
videoStreamMode,
isSwitchingMode,
isP2pConnected,
selectedMenuId,
];
}
......@@ -93,11 +93,31 @@ class _MonitoringIndexContentState extends State<MonitoringIndexContent> {
return Column(
children: [
Container(
height: topHeight.clamp(80.0, 104.0),
// height: topHeight.clamp(80.0, 104.0),
decoration: BoxDecoration(
// border: BoxBorder.all(width: 1.w,color: Colors.red)
),
child: const MonitoringTopStatusBar(),
child: Stack(
children: [
Positioned(
right: 10,
top:20,
child: Image.asset(
'lib/assets/monitoring/top_line.png',
width: 906.w,
height: 162.h,
),
),
Container(
height: topHeight.clamp(80.0, 104.0),
child: const MonitoringTopStatusBar(),
),
],
)
),
Expanded(
child: Container(
......@@ -113,7 +133,11 @@ class _MonitoringIndexContentState extends State<MonitoringIndexContent> {
decoration: BoxDecoration(
// border: BoxBorder.all(width: 1.w,color: Colors.red)
),
child: MonitoringBottomMenu(menuItems: state.menuItems),
child: MonitoringBottomMenu(
menuItems: state.menuItems,
selectedMenuId: state.selectedMenuId,
// onMenuItemTap: _monitoringIndexCubit.onMenuItemTap,
),
),
],
);
......
......@@ -2,16 +2,26 @@ import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:laki_icu_app/models/bo/monitoring_bo.dart';
typedef OnMenuItemTap = Function(String menuId);
class MonitoringBottomMenu extends StatelessWidget {
final List<MonitoringMenuItemBO> menuItems;
final String? selectedMenuId;
final OnMenuItemTap? onMenuItemTap;
const MonitoringBottomMenu({
super.key,
required this.menuItems,
this.selectedMenuId,
this.onMenuItemTap,
});
@override
Widget build(BuildContext context) {
// 将菜单项分成左侧、TSAAS特殊项、右侧
final leftItems = menuItems.where((item) => !item.isTsaas).take(4).toList();
final tsaasItem = menuItems.firstWhere((item) => item.isTsaas);
final rightItems = menuItems.where((item) => !item.isTsaas).skip(4).toList();
return Container(
decoration: const BoxDecoration(
......@@ -20,77 +30,135 @@ class MonitoringBottomMenu extends StatelessWidget {
fit: BoxFit.fill,
),
),
padding: EdgeInsets.symmetric(horizontal: 36.w, vertical: 16.h),
child: Row(
padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 12.h),
child: Stack(
children: [
// todo 这里需要绝对定位几个热区,用于点击
Container(
height: 100.h,
margin: EdgeInsets.only(top: 50.h),
decoration: BoxDecoration(
// border: Border.all(
// width: 1.w,
// color: Colors.red
// )
),
child: Row(
children: [
// 左侧4个菜单项
...leftItems.map((item) => _buildMenuItem(item)).toList(),
// 中间占位区域(TSAAS品牌部分通过Stack叠加)
const Spacer(),
// 右侧3个菜单项(包含TSAAS按钮)
_buildMenuItem(tsaasItem),
...rightItems.map((item) => _buildMenuItem(item)).toList(),
],
),
),
// 中间的TSAAS品牌标识
// _buildBrandCenter(),
],
),
);
}
Widget _buildBrandTitle() {
return Container(
height: 58.h,
constraints: BoxConstraints(minWidth: 190.w),
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('lib/assets/monitoring/title_bg_spacewalk.png'),
fit: BoxFit.fill,
),
),
alignment: Alignment.center,
child: Text(
'SPACE WALK',
style: TextStyle(
color: Colors.white,
fontSize: 22.sp,
fontWeight: FontWeight.w800,
letterSpacing: 2.5,
Widget _buildMenuItem(MonitoringMenuItemBO item) {
final isSelected = selectedMenuId == item.id;
return Padding(
padding: EdgeInsets.symmetric(horizontal: 40.w),
child: GestureDetector(
onTap: () {
debugPrint('[MonitoringBottomMenu] 点击菜单: ${item.id} (${item.title})');
// onMenuItemTap?.call(item.id);
},
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// 图标
Container(
width: 62.w,
height: 62.h,
decoration: BoxDecoration(
border: isSelected
? Border.all(color: const Color(0xFF00FFFF), width: 1.5.w)
: null,
borderRadius: BorderRadius.circular(item.isTsaas ? 22.w : 24.w),
),
child: Image.asset(
item.iconPath,
fit: BoxFit.contain,
),
),
SizedBox(height: 6.h),
// 文字
Text(
item.title,
style: TextStyle(
color: isSelected
? const Color(0xFF00FFFF)
: const Color(0xB3FFFFFF),
fontSize: 20.sp,
fontWeight: FontWeight.w400,
),
),
],
),
),
);
}
Widget _buildMenuButton(String icon, String title) {
return Container(
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 12.h),
decoration: BoxDecoration(
color: const Color(0x1A42D8FF),
borderRadius: BorderRadius.circular(18.r),
border: Border.all(color: const Color(0x665EE6FF), width: 1),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(icon, style: TextStyle(fontSize: 20.sp)),
SizedBox(width: 8.w),
Text(
title,
style: TextStyle(color: Colors.white, fontSize: 16.sp),
Widget _buildBrandCenter() {
return Center(
child: Container(
height: 72.h,
constraints: BoxConstraints(minWidth: 260.w),
padding: EdgeInsets.symmetric(horizontal: 24.w),
decoration: BoxDecoration(
gradient: const LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color(0xFF1A4B6F),
Color(0xFF0A1F30),
],
),
],
),
);
}
Widget _buildActionButton(IconData icon, String title) {
return Container(
padding: EdgeInsets.symmetric(horizontal: 14.w, vertical: 11.h),
decoration: BoxDecoration(
color: const Color(0x1420E5FF),
borderRadius: BorderRadius.circular(16.r),
border: Border.all(color: const Color(0x5542D8FF), width: 1),
),
child: Row(
children: [
Icon(icon, color: const Color(0xFF9DF5FF), size: 20.w),
SizedBox(width: 7.w),
Text(
title,
style: TextStyle(color: Colors.white70, fontSize: 15.sp),
borderRadius: BorderRadius.only(
topLeft: Radius.circular(32.w),
topRight: Radius.circular(32.w),
),
],
border: Border(
left: BorderSide(color: const Color(0xFF206090), width: 1.w),
right: BorderSide(color: const Color(0xFF206090), width: 1.w),
top: BorderSide(color: const Color(0xFF206090), width: 1.w),
),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'加邦TSAAS',
style: TextStyle(
color: const Color(0xFF00FFFF),
fontSize: 16.sp,
fontWeight: FontWeight.bold,
letterSpacing: 1.2,
),
),
Text(
'动物医疗监护舱',
style: TextStyle(
color: Colors.white.withValues(alpha: 0.9),
fontSize: 14.sp,
fontWeight: FontWeight.w400,
letterSpacing: 0.8,
),
),
],
),
),
);
}
......
......@@ -46,7 +46,7 @@ class MonitoringPetInfoCard extends StatelessWidget {
_buildDivider(),
SizedBox(height: 20.h),
_buildCareLevelBlock(info),
// const Spacer(),
SizedBox(height: 20.h),
_buildExitButton(),
],
);
......@@ -220,8 +220,8 @@ class MonitoringPetInfoCard extends StatelessWidget {
info.careLevel,
style: TextStyle(
color: Colors.white,
fontSize: 80.sp,
fontWeight: FontWeight.w900,
fontSize: 64.sp,
fontWeight: FontWeight.bold,
letterSpacing: 6.w,
shadows: const [
Shadow(
......
......@@ -16,31 +16,33 @@ class MonitoringTopStatusBar extends StatelessWidget {
padding: EdgeInsets.only(left: 32.w,bottom: 22.h),
child: Row(
children: [
// SizedBox(width: 18.w),
Text(
'总运行时长:9999h',
style: TextStyle(
color: Colors.white,
fontSize: 25.sp,
),
),
SizedBox(width: 32.w),
Text(
'环境温度:30.68',
style: TextStyle(
color: Colors.white,
fontSize: 25.sp,
),
),
SizedBox(width: 32.w),
Text(
'总制氧时长:500h',
style: TextStyle(
color: Colors.white,
fontSize: 25.sp,
),
),
// const Spacer(),
// SizedBox(width: 18.w),
Text(
'总运行时长:9999h',
style: TextStyle(
color: Colors.white,
fontSize: 25.sp,
),
),
SizedBox(width: 32.w),
Text(
'环境温度:30.68',
style: TextStyle(
color: Colors.white,
fontSize: 25.sp,
),
),
SizedBox(width: 32.w),
Text(
'总制氧时长:500h',
style: TextStyle(
color: Colors.white,
fontSize: 25.sp,
),
),
// const Spacer(),
],
),
);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment