import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:maibu_satabot_v2/features/v2/home/presentation/bloc/home_v2_bloc.dart'; import 'package:maibu_satabot_v2/features/v2/home/presentation/bloc/home_v2_event.dart'; import 'package:maibu_satabot_v2/features/v2/home/presentation/bloc/home_v2_state.dart'; import 'package:maibu_satabot_v2/features/v2/home/presentation/widgets/power_card.dart'; import 'package:maibu_satabot_v2/features/v2/home/presentation/widgets/stats_grid.dart'; import 'package:maibu_satabot_v2/features/v2/home/presentation/widgets/work_order_card.dart'; import 'package:maibu_satabot_v2/features/v2/home/presentation/widgets/quick_entry_card.dart'; import 'package:maibu_satabot_v2/features/v2/home/presentation/widgets/power_trend_chart.dart'; import 'package:maibu_satabot_v2/features/v2/home/presentation/widgets/plant_overview_card.dart'; class HomeV2Page extends StatefulWidget { const HomeV2Page({super.key}); @override State createState() => _HomeV2PageState(); } class _HomeV2PageState extends State { late HomeV2Bloc _bloc; String _selectedPlant = '示例光伏电站'; final List _plantList = [ '示例光伏电站', '一号光伏电站', '二号光伏电站', '三号光伏电站', ]; @override void initState() { super.initState(); _bloc = context.read(); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color(0xFFF5F7FA), body: BlocBuilder( builder: (context, state) { if (state is HomeV2Error) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const Icon(Icons.error_outline, size: 48, color: Color(0xFF86909C)), const SizedBox(height: 16), Text(state.message), const SizedBox(height: 16), ElevatedButton( onPressed: () => _bloc.add(const HomeV2LoadData()), child: const Text('重试'), ), ], ), ); } if (state is HomeV2Loaded) { return RefreshIndicator( onRefresh: () async { _bloc.add(const HomeV2Refresh()); }, child: CustomScrollView( slivers: [ SliverAppBar( pinned: true, backgroundColor: Colors.white, elevation: 0, automaticallyImplyLeading: false, flexibleSpace: FlexibleSpaceBar( background: Container( padding: const EdgeInsets.fromLTRB(16, 40, 16, 16), color: Colors.white, child: Row( children: [ Expanded( child: InkWell( onTap: _showPlantSelector, child: Row( mainAxisSize: MainAxisSize.min, children: [ Flexible( child: Text( _selectedPlant, maxLines: 1, overflow: TextOverflow.ellipsis, style: const TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: Color(0xFF1D2129), ), ), ), const SizedBox(width: 4), const Icon(Icons.arrow_drop_down, size: 20, color: Color(0xFF1D2129)), ], ), ), ), IconButton( icon: const Icon(Icons.qr_code_scanner, size: 24, color: Color(0xFF1D2129)), onPressed: () => print('点击扫码'), ), ], ), ), ), ), SliverPadding( padding: const EdgeInsets.fromLTRB(16, 8, 16, 40), sliver: SliverList( delegate: SliverChildListDelegate([ const SizedBox(height: 16), // 天气和告警 Row( children: [ Expanded( child: Container( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), decoration: BoxDecoration( color: const Color(0xFFF2F3F5), borderRadius: BorderRadius.circular(8), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ const Icon(Icons.cloud_queue, size: 16, color: Color(0xFF165DFF)), const SizedBox(width: 6), const Text( '多云 28°C', style: TextStyle( fontSize: 13, color: Color(0xFF4E5969), ), ), ], ), ), ), const SizedBox(width: 8), Expanded( child: Container( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), decoration: BoxDecoration( color: const Color(0xFFFFF0F0), borderRadius: BorderRadius.circular(8), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ const Icon(Icons.warning_amber_rounded, size: 16, color: Color(0xFFF53F3F)), const SizedBox(width: 6), const Expanded( child: Text( '紧急告警', style: TextStyle( fontSize: 13, color: Color(0xFFF53F3F), ), ), ), const SizedBox(width: 4), const Icon(Icons.arrow_forward_ios, size: 12, color: Color(0xFFF53F3F)), ], ), ), ), ], ), const SizedBox(height: 16), PowerCard(data: state.homeData), const SizedBox(height: 10), StatsGrid(data: state.homeData), const SizedBox(height: 10), PlantOverviewCard(overview: state.homeData.plantOverview), const SizedBox(height: 10), WorkOrderCard(stats: state.homeData.workOrderStats), const SizedBox(height: 10), QuickEntryCard(), const SizedBox(height: 10), PowerTrendChart( data: state.homeData.powerTrendData, trendType: state.trendType, onToggleType: (type) => _bloc.add(HomeV2ToggleTrendType(type)), ), const SizedBox(height: 40), ]), ), ), ], ), ); } return const SizedBox(); }, ), ); } @override void didChangeDependencies() { super.didChangeDependencies(); // 首次进入时自动加载数据,但不显示转圈 if (_bloc.state is HomeV2Initial) { _bloc.add(const HomeV2LoadData()); } } void _showPlantSelector() { showModalBottomSheet( context: context, backgroundColor: Colors.white, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.vertical(top: Radius.circular(16)), ), builder: (context) { return Container( padding: const EdgeInsets.all(14), child: Column( mainAxisSize: MainAxisSize.min, children: [ const Text( '选择电站', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: Color(0xFF1D2129), ), ), const SizedBox(height: 14), ..._plantList.map((plant) => ListTile( title: Text(plant), trailing: _selectedPlant == plant ? const Icon(Icons.check, color: Color(0xFF165DFF)) : null, onTap: () { setState(() { _selectedPlant = plant; }); Navigator.pop(context); }, )), ], ), ); }, ); } }