From f1a279cf57c288c97b2b01d512d1980609e533af Mon Sep 17 00:00:00 2001 From: Songzex <2402265378@qq.com> Date: Mon, 18 May 2026 17:18:58 +0800 Subject: [PATCH] =?UTF-8?q?v2=E7=89=88=E6=9C=AC=E7=9A=84=E9=A6=96=E9=A1=B5?= =?UTF-8?q?=E7=95=8C=E9=9D=A2=E5=BC=80=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/core/di/injection.dart | 11 ++ lib/core/router/app_router.dart | 9 +- .../entities/running_status_entity.dart | 28 +++++ .../main_container/domain/tab_config.dart | 18 ++- .../presentation/cubit/tab_config_cubit.dart | 6 + .../presentation/main_wrapper.dart | 108 +++++++++--------- .../pages/custom_main_container.dart | 3 + .../presentation/pages/tab_settings_page.dart | 8 +- .../my/presentation/pages/my_page.dart | 2 +- .../presentation/widgets/top_status_bar.dart | 8 +- 10 files changed, 133 insertions(+), 68 deletions(-) diff --git a/lib/core/di/injection.dart b/lib/core/di/injection.dart index 492a556b..90c533d1 100644 --- a/lib/core/di/injection.dart +++ b/lib/core/di/injection.dart @@ -56,6 +56,11 @@ import '../../features/remote_control/data/datasources/remote_http_datasource.da import '../../features/remote_control/data/datasources/remote_tcp_datasource.dart'; import '../../features/remote_control/domain/usecase/remote_control_usecase.dart'; import '../../features/remote_control/presentation/bloc/remote_control_cubit.dart'; +import '../../features/v2/home/data/datasources/home_remote_datasource.dart'; +import '../../features/v2/home/data/repositories/home_repository_impl.dart'; +import '../../features/v2/home/domain/repositories/home_repository.dart'; +import '../../features/v2/home/domain/usecases/get_home_data_usecase.dart'; +import '../../features/v2/home/presentation/bloc/home_v2_bloc.dart'; import '../app/app_user_cubit.dart'; import '../localization/locale_cubit.dart'; import '../../features/home/presentation/bloc/permission_request_bloc.dart'; @@ -183,6 +188,12 @@ Future init() async { sl.registerLazySingleton(() => RequestControlPermissionUseCase(sl())); + /// Home V2 + sl.registerLazySingleton(() => HomeRemoteDataSourceImpl()); + sl.registerLazySingleton(() => HomeRepositoryImpl(sl())); + sl.registerLazySingleton(() => GetHomeDataUseCase(sl())); + sl.registerFactory(() => HomeV2Bloc(sl())); + /// 5. 状态管理 (Cubit/Bloc) sl.registerLazySingleton(() => AppUserCubit()); // AuthCubit 依赖它,必须先注册 diff --git a/lib/core/router/app_router.dart b/lib/core/router/app_router.dart index 0c8bff72..f2938dce 100644 --- a/lib/core/router/app_router.dart +++ b/lib/core/router/app_router.dart @@ -5,8 +5,8 @@ import 'package:maibu_satabot_v2/features/auth/presentation/pages/login_page.dar import 'package:maibu_satabot_v2/features/auth/presentation/routes/auth_routes.dart'; import 'package:maibu_satabot_v2/features/devices/domain/entities/device_entity.dart'; import 'package:maibu_satabot_v2/features/home/presentation/routes/home_routes.dart'; +import 'package:maibu_satabot_v2/features/main_container/presentation/pages/tab_settings_page.dart'; import 'package:maibu_satabot_v2/features/my/presentation/routes/my_routes.dart'; -import 'package:maibu_satabot_v2/features/my/presentation/routes/settings_routes.dart'; import 'package:maibu_satabot_v2/features/waring_center/presentation/routes/warning_center_routes.dart'; import '../../features/auth/presentation/bloc/auth_cubit.dart'; @@ -48,13 +48,18 @@ GoRouter createRouter(AuthCubit authCubit) { GoRoute( path: RoutePaths.home, builder: (context, state) => const MainWrapper(), + routes: [ + GoRoute( + path: 'settings', + builder: (context, state) => const TabSettingsPage(), + ), + ], ), ...AuthRoutes.routes, ...HomeRoutes.routes, ...AiRoutes.routes, ...MyRoutes.routes, - ...SettingsRoutes.routes, ...WarningCenterRoutes.routes, ], ); diff --git a/lib/features/devices/domain/entities/running_status_entity.dart b/lib/features/devices/domain/entities/running_status_entity.dart index edbb3a2c..cc93eda7 100644 --- a/lib/features/devices/domain/entities/running_status_entity.dart +++ b/lib/features/devices/domain/entities/running_status_entity.dart @@ -1,6 +1,9 @@ // lib/features/devices/domain/entities/running_status_entity.dart import 'package:equatable/equatable.dart'; +import 'package:get_it/get_it.dart'; + +import '../../../../core/logging/i_logger_service.dart'; class RunningStatusEntity extends Equatable { // === 基础电气信息 (字段 0-6) === @@ -68,6 +71,31 @@ class RunningStatusEntity extends Equatable { /// 从字段数组创建实体 (核心解析方法) factory RunningStatusEntity.fromFields(List fields) { + final logger = GetIt.I(); + logger.logWithLevel( + '字段总数: ${fields.length}', + level: 'DEBUG', + shouldLog: true, + ); + + if (fields.length > 14) { + logger.logWithLevel( + 'qual原始值(fields[14]): "${fields[14]}"', + level: 'DEBUG', + shouldLog: true, + ); + logger.logWithLevel( + 'satelliteCnt(fields[13]): "${fields[13]}"', + level: 'DEBUG', + shouldLog: true, + ); + logger.logWithLevel( + 'headingStatus(fields[15]): "${fields[15]}"', + level: 'DEBUG', + shouldLog: true, + ); + } + // 确保至少有 24 个字段,不足的用默认值填充 while (fields.length < 24) { fields.add(''); diff --git a/lib/features/main_container/domain/tab_config.dart b/lib/features/main_container/domain/tab_config.dart index e9cf9688..26ad0713 100644 --- a/lib/features/main_container/domain/tab_config.dart +++ b/lib/features/main_container/domain/tab_config.dart @@ -78,13 +78,21 @@ class TabConfig extends Equatable { static TabConfig defaultConfig() { return const TabConfig( items: [ + TabConfigItem( + id: 'home_v2', + name: '首页V2', + nameEn: 'Home V2', + icon: 'home_rounded', + isEnabled: false, + order: 1, + ), TabConfigItem( id: 'home', name: '状态', nameEn: 'Status', icon: 'grid_view_rounded', isEnabled: true, - order: 1, + order: 2, ), TabConfigItem( id: 'ai', @@ -92,15 +100,15 @@ class TabConfig extends Equatable { nameEn: 'AI', icon: 'auto_awesome_rounded', isEnabled: true, - order: 2, + order: 3, ), TabConfigItem( id: 'warning', - name: '告警中心', + name: '告警', nameEn: 'Alerts', icon: 'warning_amber_rounded', isEnabled: true, - order: 3, + order: 4, ), TabConfigItem( id: 'my', @@ -108,7 +116,7 @@ class TabConfig extends Equatable { nameEn: 'Profile', icon: 'person_rounded', isEnabled: true, - order: 4, + order: 5, ), ], ); diff --git a/lib/features/main_container/presentation/cubit/tab_config_cubit.dart b/lib/features/main_container/presentation/cubit/tab_config_cubit.dart index 4de78e0b..3cc5e00e 100644 --- a/lib/features/main_container/presentation/cubit/tab_config_cubit.dart +++ b/lib/features/main_container/presentation/cubit/tab_config_cubit.dart @@ -78,6 +78,12 @@ class TabConfigCubit extends Cubit { } } + void resetToDefault() { + final defaultConfig = TabConfig.defaultConfig(); + _saveConfig(defaultConfig); + emit(TabConfigLoaded(defaultConfig)); + } + TabConfig? getConfig() { if (state is TabConfigLoaded) { return (state as TabConfigLoaded).config; diff --git a/lib/features/main_container/presentation/main_wrapper.dart b/lib/features/main_container/presentation/main_wrapper.dart index f5cfba96..60e2d55f 100644 --- a/lib/features/main_container/presentation/main_wrapper.dart +++ b/lib/features/main_container/presentation/main_wrapper.dart @@ -1,13 +1,14 @@ -import 'dart:ui'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:google_nav_bar/google_nav_bar.dart'; import 'package:maibu_satabot_v2/features/main_container/presentation/cubit/tab_config_cubit.dart'; import 'package:maibu_satabot_v2/features/main_container/domain/tab_config.dart'; import 'package:maibu_satabot_v2/features/home/presentation/pages/home_page.dart'; +import 'package:maibu_satabot_v2/features/v2/home/presentation/pages/home_v2_page.dart'; +import 'package:maibu_satabot_v2/features/v2/home/presentation/bloc/home_v2_bloc.dart'; import 'package:maibu_satabot_v2/features/ai/presentation/pages/ai_page.dart'; import 'package:maibu_satabot_v2/features/waring_center/presentation/pages/warning_center_page.dart'; import 'package:maibu_satabot_v2/features/my/presentation/pages/my_page.dart'; +import 'package:maibu_satabot_v2/core/di/injection.dart'; class MainWrapper extends StatefulWidget { const MainWrapper({super.key}); @@ -28,6 +29,8 @@ class _MainWrapperState extends State { IconData _getIconData(String iconName) { switch (iconName) { + case 'home_rounded': + return Icons.home_rounded; case 'grid_view_rounded': return Icons.grid_view_rounded; case 'auto_awesome_rounded': @@ -43,6 +46,11 @@ class _MainWrapperState extends State { Widget _buildCurrentPage(TabConfigItem tab) { switch (tab.id) { + case 'home_v2': + return BlocProvider( + create: (context) => sl(), + child: const HomeV2Page(), + ); case 'home': return const HomePage(); case 'ai': @@ -92,67 +100,57 @@ class _MainWrapperState extends State { children: enabledItems.map((tab) => _buildCurrentPage(tab)).toList(), ), bottomNavigationBar: Container( - margin: const EdgeInsets.fromLTRB(20, 0, 20, 10), decoration: BoxDecoration( - borderRadius: BorderRadius.circular(32), + color: Colors.white, boxShadow: [ BoxShadow( - color: Colors.black.withOpacity(0.12), - blurRadius: 30, - offset: const Offset(0, 10), + color: Colors.black.withOpacity(0.08), + blurRadius: 10, + offset: const Offset(0, -2), ), ], ), - child: ClipRRect( - borderRadius: BorderRadius.circular(32), - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 16, sigmaY: 16), - child: Container( - decoration: BoxDecoration( - color: Colors.white.withOpacity(0.4), - borderRadius: BorderRadius.circular(32), - border: Border.all( - color: Colors.black.withOpacity(0.08), - width: 0.5, - ), - ), - child: SafeArea( - top: false, - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 10, - vertical: 8, - ), - child: GNav( - rippleColor: Colors.transparent, - hoverColor: Colors.transparent, - gap: 10, - activeColor: Colors.white, - tabBackgroundColor: Colors.black, - color: Colors.black87, - iconSize: 24, - padding: const EdgeInsets.symmetric( - horizontal: 18, - vertical: 10, - ), - duration: const Duration(milliseconds: 300), - selectedIndex: _currentIndex, - onTabChange: (index) { - setState(() { - _currentIndex = index; - }); - _pageController.jumpToPage(index); - }, - tabs: enabledItems.map((item) { - return GButton( - icon: _getIconData(item.icon), - text: item.name, - ); - }).toList(), + child: SafeArea( + top: false, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: enabledItems.asMap().entries.map((entry) { + final index = entry.key; + final item = entry.value; + final isSelected = _currentIndex == index; + + return Expanded( + child: InkWell( + onTap: () { + setState(() { + _currentIndex = index; + }); + _pageController.jumpToPage(index); + }, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const SizedBox(height: 8), + Icon( + _getIconData(item.icon), + size: 24, + color: isSelected ? Colors.blue : Colors.grey, + ), + const SizedBox(height: 4), + Text( + item.name, + style: TextStyle( + fontSize: 11, + color: isSelected ? Colors.blue : Colors.grey, + fontWeight: isSelected ? FontWeight.w600 : FontWeight.normal, + ), + ), + const SizedBox(height: 8), + ], ), ), - ), - ), + ); + }).toList(), ), ), ), diff --git a/lib/features/main_container/presentation/pages/custom_main_container.dart b/lib/features/main_container/presentation/pages/custom_main_container.dart index 87483510..1f3fffcc 100644 --- a/lib/features/main_container/presentation/pages/custom_main_container.dart +++ b/lib/features/main_container/presentation/pages/custom_main_container.dart @@ -5,6 +5,7 @@ import 'package:maibu_satabot_v2/features/home/presentation/pages/home_page.dart import 'package:maibu_satabot_v2/features/my/presentation/pages/my_page.dart'; import 'package:maibu_satabot_v2/features/main_container/presentation/bloc/tab_config_cubit.dart'; import 'package:maibu_satabot_v2/features/main_container/presentation/widgets/custom_bottom_nav_bar.dart'; +import 'package:maibu_satabot_v2/features/v2/home/presentation/pages/home_v2_page.dart'; import '../../../waring_center/presentation/pages/warning_center_page.dart'; @@ -53,6 +54,8 @@ class _CustomMainContainerState extends State with Automati List _buildPages(List enabledTabs) { return enabledTabs.map((tab) { switch (tab.id) { + case 'home_v2': + return const HomeV2Page(); case 'home': return const HomePage(); case 'ai': diff --git a/lib/features/main_container/presentation/pages/tab_settings_page.dart b/lib/features/main_container/presentation/pages/tab_settings_page.dart index 1c6c820a..aea75775 100644 --- a/lib/features/main_container/presentation/pages/tab_settings_page.dart +++ b/lib/features/main_container/presentation/pages/tab_settings_page.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:maibu_satabot_v2/features/main_container/presentation/bloc/tab_config_cubit.dart'; +import 'package:maibu_satabot_v2/features/main_container/presentation/cubit/tab_config_cubit.dart'; import 'package:cc_ui_kit/cc_ui_kit.dart'; class TabSettingsPage extends StatelessWidget { @@ -17,6 +17,10 @@ class TabSettingsPage extends StatelessWidget { ), body: BlocBuilder( builder: (context, state) { + if (state is! TabConfigLoaded) { + return const Center(child: CircularProgressIndicator()); + } + final tabs = state.config.items; return ListView.builder( @@ -60,6 +64,8 @@ class TabSettingsPage extends StatelessWidget { IconData _getIconData(String iconName) { switch (iconName) { + case 'home_rounded': + return Icons.home_rounded; case 'grid_view_rounded': return Icons.grid_view_rounded; case 'auto_awesome_rounded': diff --git a/lib/features/my/presentation/pages/my_page.dart b/lib/features/my/presentation/pages/my_page.dart index 3af60c35..5dcd7e1c 100644 --- a/lib/features/my/presentation/pages/my_page.dart +++ b/lib/features/my/presentation/pages/my_page.dart @@ -102,7 +102,7 @@ class MyPage extends StatelessWidget { title: Text(AppLocalizations.of(context).translate('my.settings'), style: const TextStyle(color: Colors.black)), trailing: const Icon(Icons.arrow_forward, color: Colors.black), onTap: () { - context.push(RoutePaths.settings); + context.push('/home/settings'); }, ), diff --git a/lib/features/remote_control/presentation/widgets/top_status_bar.dart b/lib/features/remote_control/presentation/widgets/top_status_bar.dart index 7d35a223..7a65a8ce 100644 --- a/lib/features/remote_control/presentation/widgets/top_status_bar.dart +++ b/lib/features/remote_control/presentation/widgets/top_status_bar.dart @@ -381,15 +381,15 @@ class TopStatusBar extends StatelessWidget { child: CCExpandSlider( label: " ", // 3. 图标适配旋转后的方向(仍用上下箭头,旋转后变为左右)因为外边旋转了 90度 参数传递也要转换 - svgStart: "assets/svgs/remote_flame_minus.svg", // 旋转后→左箭头 + svgStart: "assets/svgs/remote_flame_plus.svg", // 旋转后→左箭头assets/svgs/remote_flame_minus.svg svgCenter: "assets/svgs/remote_flame.svg", - svgEnd: "assets/svgs/remote_flame_plus.svg", // 旋转后→右箭头 + svgEnd: "assets/svgs/remote_flame_minus.svg", // 旋转后→右箭头assets/svgs/remote_flame_plus.svg // 4. 放大图标尺寸,解决拥挤 iconSize: iconSize, // 保留原有业务逻辑 - onStart: () => _handleSliderAction(label, "start", context), + onStart: () =>_handleSliderAction(label, "end", context),//_handleSliderAction(label, "start", context) onCenter: () => _handleSliderAction(label, "center", context), - onEnd: () => _handleSliderAction(label, "end", context), + onEnd: () => _handleSliderAction(label, "start", context),//_handleSliderAction(label, "end", context) ), ), ),