Commit 75c1ef0e authored by 张宏's avatar 张宏

tab调整

parent 168178cd
...@@ -27,6 +27,10 @@ class HomeIndexCubit extends Cubit<HomeIndexState> { ...@@ -27,6 +27,10 @@ class HomeIndexCubit extends Cubit<HomeIndexState> {
} }
} }
Future<void> reloadDashboard() async {
loadDashboard();
}
void _emitFromDashboard(AlertDashboardBO dashboard) { void _emitFromDashboard(AlertDashboardBO dashboard) {
emit(state.copyWith( emit(state.copyWith(
isLoading: false, isLoading: false,
...@@ -91,4 +95,4 @@ class HomeIndexCubit extends Cubit<HomeIndexState> { ...@@ -91,4 +95,4 @@ class HomeIndexCubit extends Cubit<HomeIndexState> {
return const Color.fromRGBO(26, 188, 156, 1.0); return const Color.fromRGBO(26, 188, 156, 1.0);
} }
} }
} }
\ No newline at end of file
...@@ -12,16 +12,43 @@ import 'package:smart_hotel_app/views/home/index/widget/temperature_block.dart'; ...@@ -12,16 +12,43 @@ import 'package:smart_hotel_app/views/home/index/widget/temperature_block.dart';
import 'package:smart_hotel_app/views/home/index/widget/voltage_operate_block.dart'; import 'package:smart_hotel_app/views/home/index/widget/voltage_operate_block.dart';
@RoutePage() @RoutePage()
class HomeView extends StatelessWidget { class HomeView extends StatefulWidget {
const HomeView({super.key}); const HomeView({super.key});
@override @override
State<HomeView> createState() => _HomeViewState();
}
class _HomeViewState extends State<HomeView> with AutoRouteAwareStateMixin<HomeView> {
@override
void didChangeDependencies() {
super.didChangeDependencies();
// Subscribe to tab router events
final tabsRouter = AutoTabsRouter.of(context);
tabsRouter.addListener(_onTabChange);
}
@override
void dispose() {
final tabsRouter = AutoTabsRouter.of(context);
tabsRouter.removeListener(_onTabChange);
super.dispose();
}
void _onTabChange() {
final tabsRouter = AutoTabsRouter.of(context);
// Check if this tab is now active
if (tabsRouter.activeIndex == 0) {
// Reload data when tab is activated
context.read<HomeIndexCubit>().reloadDashboard();
}
}
@override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider( return LayoutBuilder(
create: (_) => HomeIndexCubit(), builder: (context, constraints) {
child: LayoutBuilder( return SingleChildScrollView(
builder: (context, constraints) {
return SingleChildScrollView(
child: ConstrainedBox( child: ConstrainedBox(
constraints: BoxConstraints( constraints: BoxConstraints(
minHeight: constraints.maxHeight, minHeight: constraints.maxHeight,
...@@ -55,7 +82,6 @@ class HomeView extends StatelessWidget { ...@@ -55,7 +82,6 @@ class HomeView extends StatelessWidget {
), ),
); );
}, },
),
); );
} }
...@@ -96,4 +122,4 @@ class HomeView extends StatelessWidget { ...@@ -96,4 +122,4 @@ class HomeView extends StatelessWidget {
} }
return blocks; return blocks;
} }
} }
\ No newline at end of file
...@@ -125,7 +125,7 @@ class TemperatureBlock extends StatelessWidget { ...@@ -125,7 +125,7 @@ class TemperatureBlock extends StatelessWidget {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Text( Text(
'${currentVoltage}V', '${currentVoltage}',
style: TextStyle( style: TextStyle(
fontSize: 40.sp, fontSize: 40.sp,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
...@@ -148,7 +148,7 @@ class TemperatureBlock extends StatelessWidget { ...@@ -148,7 +148,7 @@ class TemperatureBlock extends StatelessWidget {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Text( Text(
'${currentCurrent}A', '${currentCurrent}',
style: TextStyle( style: TextStyle(
fontSize: 40.sp, fontSize: 40.sp,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
......
import 'package:auto_route/auto_route.dart'; import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:smart_hotel_app/routes/app_router.gr.dart'; import 'package:smart_hotel_app/routes/app_router.gr.dart';
import 'package:smart_hotel_app/views/home/index/cubit/home_index_cubit.dart';
import 'package:smart_hotel_app/views/report/index/cubit/report_index_cubit.dart';
import 'package:smart_hotel_app/views/service/index/cubit/service_index_cubit.dart';
@RoutePage() @RoutePage()
class DefaultLayoutView extends StatefulWidget { class DefaultLayoutView extends StatefulWidget {
...@@ -14,7 +18,13 @@ class DefaultLayoutView extends StatefulWidget { ...@@ -14,7 +18,13 @@ class DefaultLayoutView extends StatefulWidget {
class _DefaultLayoutViewState extends State<DefaultLayoutView> { class _DefaultLayoutViewState extends State<DefaultLayoutView> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return AutoTabsScaffold( return MultiBlocProvider(
providers: [
BlocProvider(create: (_) => HomeIndexCubit()),
BlocProvider(create: (_) => ServiceIndexCubit()),
BlocProvider(create: (_) => ReportIndexCubit()),
],
child: AutoTabsScaffold(
routes: const [HomeRoute(), ServiceIndexRoute(), ReportIndexRoute(), ProfileRoute()], routes: const [HomeRoute(), ServiceIndexRoute(), ReportIndexRoute(), ProfileRoute()],
transitionBuilder: (context, child, animation) => child, transitionBuilder: (context, child, animation) => child,
bottomNavigationBuilder: (context, tabsRouter) { bottomNavigationBuilder: (context, tabsRouter) {
...@@ -92,6 +102,7 @@ class _DefaultLayoutViewState extends State<DefaultLayoutView> { ...@@ -92,6 +102,7 @@ class _DefaultLayoutViewState extends State<DefaultLayoutView> {
), ),
); );
}, },
),
); );
} }
} }
...@@ -23,6 +23,10 @@ class EnergyCubit extends Cubit<EnergyState> { ...@@ -23,6 +23,10 @@ class EnergyCubit extends Cubit<EnergyState> {
} }
} }
Future<void> reloadData() async {
loadData();
}
EnergyState _mapAnalysisToState(EnergyAnalysisBO data) { EnergyState _mapAnalysisToState(EnergyAnalysisBO data) {
// 计算今日变化百分比 // 计算今日变化百分比
double todayChange = 0; double todayChange = 0;
......
...@@ -24,6 +24,10 @@ class ReportIndexCubit extends Cubit<ReportIndexState> { ...@@ -24,6 +24,10 @@ class ReportIndexCubit extends Cubit<ReportIndexState> {
} }
} }
Future<void> reloadData() async {
loadData();
}
ReportIndexState _mapOverviewToState(DashboardOverviewBO overview) { ReportIndexState _mapOverviewToState(DashboardOverviewBO overview) {
// 今日用电指标 // 今日用电指标
final elec = overview.electricityToday; final elec = overview.electricityToday;
......
...@@ -12,14 +12,41 @@ import 'package:smart_hotel_app/views/report/index/widget/room_status_distributi ...@@ -12,14 +12,41 @@ import 'package:smart_hotel_app/views/report/index/widget/room_status_distributi
import 'package:smart_hotel_app/views/report/index/widget/weekly_power_chart.dart'; import 'package:smart_hotel_app/views/report/index/widget/weekly_power_chart.dart';
@RoutePage() @RoutePage()
class ReportIndexView extends StatelessWidget { class ReportIndexView extends StatefulWidget {
const ReportIndexView({super.key}); const ReportIndexView({super.key});
@override @override
State<ReportIndexView> createState() => _ReportIndexViewState();
}
class _ReportIndexViewState extends State<ReportIndexView> with AutoRouteAwareStateMixin<ReportIndexView> {
@override
void didChangeDependencies() {
super.didChangeDependencies();
// Subscribe to tab router events
final tabsRouter = AutoTabsRouter.of(context);
tabsRouter.addListener(_onTabChange);
}
@override
void dispose() {
final tabsRouter = AutoTabsRouter.of(context);
tabsRouter.removeListener(_onTabChange);
super.dispose();
}
void _onTabChange() {
final tabsRouter = AutoTabsRouter.of(context);
// Check if this tab is now active (index 2)
if (tabsRouter.activeIndex == 2) {
// Reload data when tab is activated
context.read<ReportIndexCubit>().reloadData();
}
}
@override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider( return BlocBuilder<ReportIndexCubit, ReportIndexState>(
create: (_) => ReportIndexCubit(),
child: BlocBuilder<ReportIndexCubit, ReportIndexState>(
builder: (context, state) { builder: (context, state) {
if (state.isLoading) { if (state.isLoading) {
return Container( return Container(
...@@ -95,7 +122,6 @@ class ReportIndexView extends StatelessWidget { ...@@ -95,7 +122,6 @@ class ReportIndexView extends StatelessWidget {
}, },
); );
}, },
),
); );
} }
} }
...@@ -28,6 +28,13 @@ class ServiceIndexCubit extends Cubit<ServiceIndexState> { ...@@ -28,6 +28,13 @@ class ServiceIndexCubit extends Cubit<ServiceIndexState> {
]); ]);
} }
Future<void> reloadAll() async {
await Future.wait([
loadStatistics(),
loadFloorAndAreas(),
]);
}
/// 加载客房服务看板-统计数据(待响应、入住中、空闲可清洁) /// 加载客房服务看板-统计数据(待响应、入住中、空闲可清洁)
Future<void> loadStatistics() async { Future<void> loadStatistics() async {
emit(state.copyWith(isLoading: true, error: null)); emit(state.copyWith(isLoading: true, error: null));
...@@ -231,4 +238,4 @@ class ServiceIndexCubit extends Cubit<ServiceIndexState> { ...@@ -231,4 +238,4 @@ class ServiceIndexCubit extends Cubit<ServiceIndexState> {
} }
return null; return null;
} }
} }
\ No newline at end of file
...@@ -9,14 +9,41 @@ import 'package:smart_hotel_app/views/service/index/widget/service_head_block.da ...@@ -9,14 +9,41 @@ import 'package:smart_hotel_app/views/service/index/widget/service_head_block.da
import 'package:smart_hotel_app/views/service/index/widget/service_stats_block.dart'; import 'package:smart_hotel_app/views/service/index/widget/service_stats_block.dart';
@RoutePage() @RoutePage()
class ServiceIndexView extends StatelessWidget { class ServiceIndexView extends StatefulWidget {
const ServiceIndexView({super.key}); const ServiceIndexView({super.key});
@override @override
State<ServiceIndexView> createState() => _ServiceIndexViewState();
}
class _ServiceIndexViewState extends State<ServiceIndexView> with AutoRouteAwareStateMixin<ServiceIndexView> {
@override
void didChangeDependencies() {
super.didChangeDependencies();
// Subscribe to tab router events
final tabsRouter = AutoTabsRouter.of(context);
tabsRouter.addListener(_onTabChange);
}
@override
void dispose() {
final tabsRouter = AutoTabsRouter.of(context);
tabsRouter.removeListener(_onTabChange);
super.dispose();
}
void _onTabChange() {
final tabsRouter = AutoTabsRouter.of(context);
// Check if this tab is now active (index 1)
if (tabsRouter.activeIndex == 1) {
// Reload data when tab is activated
context.read<ServiceIndexCubit>().reloadAll();
}
}
@override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider( return LayoutBuilder(
create: (_) => ServiceIndexCubit(),
child: LayoutBuilder(
builder: (context, constraints) { builder: (context, constraints) {
return SingleChildScrollView( return SingleChildScrollView(
child: ConstrainedBox( child: ConstrainedBox(
...@@ -46,7 +73,6 @@ class ServiceIndexView extends StatelessWidget { ...@@ -46,7 +73,6 @@ class ServiceIndexView extends StatelessWidget {
), ),
); );
}, },
),
); );
} }
} }
\ No newline at end of file
# 智慧酒店 App 技术方案 # 智慧酒店 App 技术方案
...@@ -47,7 +47,36 @@ ...@@ -47,7 +47,36 @@
└─────────────────────────────────────────────┘ └─────────────────────────────────────────────┘
``` ```
### 2.2 依赖注入 ### 2.3 Provider 分层结构
项目通过 `MultiBlocProvider` 的嵌套实现不同作用域的状态管理:
```
MaterialApp (main.dart)
└─ MultiBlocProvider (全局)
├─ AuthBloc ← 所有页面都能访问
├─ LoginRoute() ← 可以 read<AuthBloc>
└─ DefaultLayoutRoute() ← 可以 read<AuthBloc>
└─ MultiBlocProvider (仅主页范围)
├─ HomeIndexCubit ← 仅在 tab 页面内可访问
├─ ServiceIndexCubit ← 仅在 tab 页面内可访问
├─ ReportIndexCubit ← 仅在 tab 页面内可访问
└─ AutoTabsScaffold
├─ HomeView ← 可以 read<AuthBloc> + read<HomeIndexCubit>
├─ ServiceView ← 可以 read<AuthBloc> + read<ServiceIndexCubit>
├─ ReportView ← 可以 read<AuthBloc> + read<ReportIndexCubit>
└─ ProfileView ← 可以 read<AuthBloc>(但不能读上面三个Cubit)
```
| 层级 | 定义位置 | 作用域 | 提供者 | 特点 |
|------|---------|--------|--------|------|
| 全局 Provider | `main.dart` | 整个 App | `AuthBloc`(认证) | `.value()` 复用已有实例,App 存活期间一直存在 |
| 主页 Provider | `default_view.dart` | 仅底部 Tab 页面 | `HomeIndexCubit``ServiceIndexCubit``ReportIndexCubit` | `create` 创建新实例,仅在主页存活期间存在 |
**子 `MultiBlocProvider` 可以访问父 `MultiBlocProvider` 提供的内容**(tab 页面中 `context.read<AuthBloc>()` 依然有效),反过来不行(`AuthBloc` 里不能读取业务 Cubit)。
项目未使用 DI 框架(如 get_it),而是采用 **手动注入** 方式。在 `main.dart``_MyAppState.initState()` 中集中创建核心单例,通过构造函数向下传递。 项目未使用 DI 框架(如 get_it),而是采用 **手动注入** 方式。在 `main.dart``_MyAppState.initState()` 中集中创建核心单例,通过构造函数向下传递。
......
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