Commit 97313115 authored by 张宏's avatar 张宏

parent e4085511
......@@ -4,9 +4,13 @@ import '../models/bo/alert_list_bo.dart';
class AlertListRepository {
/// 获取告警列表
Future<ResponseModel<AlertListBO>> getList() {
Future<ResponseModel<AlertListBO>> getList({
required int pageSize,
required int pageNum,
}) {
return DioRequest.instance.get<AlertListBO>(
'/app/alert/list',
'/app/alert/list',
queryParameters: {'pageSize': pageSize, 'pageNum': pageNum},
fromJsonT: (data) =>
AlertListBO.fromJson(data as Map<String, dynamic>),
);
......
......@@ -7,8 +7,11 @@ class AlertListService {
AlertListService({required AlertListRepository repository})
: _repository = repository;
Future<AlertListBO> getList() async {
final result = await _repository.getList();
Future<AlertListBO> getList({required int pageSize, required int pageNum}) async {
final result = await _repository.getList(
pageSize: pageSize,
pageNum: pageNum,
);
if (result.success && result.data != null) {
return result.data!;
}
......
......@@ -9,29 +9,34 @@ import 'package:smart_hotel_app/views/home/abnormal_list/cubit/abnormal_list_sta
class AbnormalListCubit extends Cubit<AbnormalListState> {
final AlertListService _service;
static const int _pageSize = 20;
AbnormalListCubit()
: _service = AlertListService(
repository: AlertListRepository(),
),
super(const AbnormalListState()) {
loadList();
}
super(const AbnormalListState());
Future<void> loadList() async {
emit(const AbnormalListState(isLoading: true));
try {
final alertList = await _service.getList();
emit(AbnormalListState(
alarmList:
alertList.rows.map((e) => AlarmItem.fromAlertListItemBO(e)).toList(),
/// 供 PagingController.fetchPage 回调使用,每次加载新的一页
Future<List<AlarmItem>> fetchPage(int pageKey) async {
final alertList = await _service.getList(
pageSize: _pageSize,
pageNum: pageKey,
);
// 首頁時更新 tab 统计数
if (pageKey == 1) {
emit(state.copyWith(
allCount: alertList.tabCount.all,
pendingCount: alertList.tabCount.pending,
processedCount: alertList.tabCount.processed,
falseAlarmCount: alertList.tabCount.falseAlarm,
));
} catch (e) {
emit(AbnormalListState(error: e.toString()));
}
return alertList.rows
.map((e) => AlarmItem.fromAlertListItemBO(e))
.toList();
}
void setFilter(AlarmStatus filter) {
......
......@@ -61,7 +61,6 @@ class AbnormalListState extends Equatable {
final bool isLoading;
final String? error;
final AlarmStatus currentFilter;
final List<AlarmItem> alarmList;
final int allCount;
final int pendingCount;
final int processedCount;
......@@ -71,7 +70,6 @@ class AbnormalListState extends Equatable {
this.isLoading = false,
this.error,
this.currentFilter = AlarmStatus.all,
this.alarmList = const [],
this.allCount = 0,
this.pendingCount = 0,
this.processedCount = 0,
......@@ -82,7 +80,6 @@ class AbnormalListState extends Equatable {
bool? isLoading,
String? error,
AlarmStatus? currentFilter,
List<AlarmItem>? alarmList,
int? allCount,
int? pendingCount,
int? processedCount,
......@@ -92,7 +89,6 @@ class AbnormalListState extends Equatable {
isLoading: isLoading ?? this.isLoading,
error: error,
currentFilter: currentFilter ?? this.currentFilter,
alarmList: alarmList ?? this.alarmList,
allCount: allCount ?? this.allCount,
pendingCount: pendingCount ?? this.pendingCount,
processedCount: processedCount ?? this.processedCount,
......@@ -100,19 +96,11 @@ class AbnormalListState extends Equatable {
);
}
List<AlarmItem> get filteredList {
if (currentFilter == AlarmStatus.all) {
return alarmList;
}
return alarmList.where((item) => item.status == currentFilter).toList();
}
@override
List<Object?> get props => [
isLoading,
error,
currentFilter,
alarmList,
allCount,
pendingCount,
processedCount,
......
......@@ -2,6 +2,7 @@ import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
import 'package:smart_hotel_app/views/home/abnormal_list/cubit/abnormal_list_cubit.dart';
import 'package:smart_hotel_app/views/home/abnormal_list/cubit/abnormal_list_state.dart';
import 'package:smart_hotel_app/views/home/abnormal_list/widget/alarm_list_item.dart';
......@@ -15,101 +16,176 @@ class AbnormalListView extends StatelessWidget {
Widget build(BuildContext context) {
return BlocProvider(
create: (_) => AbnormalListCubit(),
child: Scaffold(
backgroundColor: const Color.fromRGBO(242, 243, 245, 1),
appBar: AppBar(
backgroundColor: Colors.white,
elevation: 0,
leading: IconButton(
icon: const Icon(Icons.arrow_back_ios,
color: Color.fromRGBO(100, 116, 139, 1)),
onPressed: () {
context.popRoute();
},
),
title: Text(
'告警信息',
style: TextStyle(
color: const Color.fromRGBO(10, 13, 20, 1),
fontSize: 32.sp,
fontWeight: FontWeight.w200,
),
),
centerTitle: true,
),
body: BlocBuilder<AbnormalListCubit, AbnormalListState>(
builder: (context, state) {
final cubit = context.read<AbnormalListCubit>();
child: const _AbnormalListBody(),
);
}
}
if (state.isLoading) {
return const Center(child: CircularProgressIndicator());
}
class _AbnormalListBody extends StatefulWidget {
const _AbnormalListBody();
if (state.error != null) {
return Center(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 28.w),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'加载失败: ${state.error}',
style: TextStyle(
fontSize: 28.sp,
color: const Color.fromRGBO(255, 100, 101, 1),
),
textAlign: TextAlign.center,
),
SizedBox(height: 24.h),
ElevatedButton(
onPressed: () => cubit.loadList(),
child: Text('重新加载', style: TextStyle(fontSize: 28.sp)),
),
],
),
),
);
}
@override
State<_AbnormalListBody> createState() => _AbnormalListBodyState();
}
class _AbnormalListBodyState extends State<_AbnormalListBody> {
late final PagingController<int, AlarmItem> _pagingController;
@override
void initState() {
super.initState();
_pagingController = PagingController<int, AlarmItem>(
getNextPageKey: (state) {
if (state.keys == null || state.keys!.isEmpty) return 1;
return state.lastPageIsEmpty ? null : state.nextIntPageKey;
},
fetchPage: (pageKey) =>
context.read<AbnormalListCubit>().fetchPage(pageKey),
);
}
@override
void dispose() {
_pagingController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final cubit = context.read<AbnormalListCubit>();
return SingleChildScrollView(
padding: EdgeInsets.symmetric(horizontal: 28.w),
child: Column(
children: [
FilterTabBlock(
currentFilter: state.currentFilter,
onFilterChanged: cubit.setFilter,
allCount: state.allCount,
pendingCount: state.pendingCount,
processedCount: state.processedCount,
falseAlarmCount: state.falseAlarmCount,
return BlocBuilder<AbnormalListCubit, AbnormalListState>(
builder: (context, state) {
return Scaffold(
backgroundColor: const Color.fromRGBO(242, 243, 245, 1),
appBar: AppBar(
backgroundColor: Colors.white,
elevation: 0,
leading: IconButton(
icon: const Icon(Icons.arrow_back_ios,
color: Color.fromRGBO(100, 116, 139, 1)),
onPressed: () {
context.popRoute();
},
),
title: Text(
'告警信息',
style: TextStyle(
color: const Color.fromRGBO(10, 13, 20, 1),
fontSize: 32.sp,
fontWeight: FontWeight.w200,
),
),
centerTitle: true,
),
body: PagingListener<int, AlarmItem>(
controller: _pagingController,
builder: (context, pagingState, fetchNextPage) {
return CustomScrollView(
slivers: [
SliverToBoxAdapter(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 28.w),
child: Column(
children: [
FilterTabBlock(
currentFilter: state.currentFilter,
onFilterChanged: cubit.setFilter,
allCount: state.allCount,
pendingCount: state.pendingCount,
processedCount: state.processedCount,
falseAlarmCount: state.falseAlarmCount,
),
SizedBox(height: 10.h),
],
),
),
),
SizedBox(height: 10.h),
if (state.filteredList.isEmpty)
Padding(
padding: EdgeInsets.only(top: 60.h),
child: Text(
'暂无数据',
style: TextStyle(
fontSize: 28.sp,
color: const Color.fromRGBO(100, 116, 139, 1),
SliverPadding(
padding: EdgeInsets.symmetric(horizontal: 28.w),
sliver: PagedSliverList<int, AlarmItem>(
state: pagingState,
fetchNextPage: fetchNextPage,
builderDelegate:
PagedChildBuilderDelegate<AlarmItem>(
firstPageErrorIndicatorBuilder: (_) => Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'加载失败: ${pagingState.error}',
style: TextStyle(
fontSize: 28.sp,
color: const Color.fromRGBO(
255, 100, 101, 1),
),
textAlign: TextAlign.center,
),
SizedBox(height: 24.h),
ElevatedButton(
onPressed: fetchNextPage,
child: Text('重新加载',
style:
TextStyle(fontSize: 28.sp)),
),
],
),
),
noItemsFoundIndicatorBuilder: (_) => Padding(
padding: EdgeInsets.only(top: 60.h),
child: Text(
'暂无数据',
style: TextStyle(
fontSize: 28.sp,
color: const Color.fromRGBO(
100, 116, 139, 1),
),
),
),
newPageErrorIndicatorBuilder: (_) => Center(
child: Padding(
padding:
EdgeInsets.symmetric(vertical: 20.h),
child: Column(
children: [
Text(
'加载失败: ${pagingState.error}',
style: TextStyle(
fontSize: 24.sp,
color: const Color.fromRGBO(
255, 100, 101, 1),
),
),
SizedBox(height: 12.h),
TextButton(
onPressed: fetchNextPage,
child: Text('重试',
style:
TextStyle(fontSize: 24.sp)),
),
],
),
),
),
itemBuilder: (_, item, __) {
return AlarmListItem(
item: item,
onTap: (i) =>
cubit.onAlarmItemTap(i, context),
);
},
),
)
else
...state.filteredList.map((item) {
return AlarmListItem(
item: item,
onTap: (i) =>
cubit.onAlarmItemTap(i, context),
);
}).toList(),
SizedBox(height: 30.h),
),
),
SliverToBoxAdapter(
child: SizedBox(height: 30.h),
),
],
),
);
},
),
),
);
},
),
);
},
);
}
}
\ No newline at end of file
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