import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../services/asset_service.dart'; /// 资产页状态:资产钱包 + 收益明细(biz_type 筛选 + 触底分页) class AssetState { const AssetState({ this.wallet, this.records = const [], this.recordsTotal = 0, this.bizType, this.isLoading = false, this.loadFailed = false, this.loadingMore = false, }); final AssetWallet? wallet; final List records; final int recordsTotal; /// null = 全部 final int? bizType; final bool isLoading; final bool loadFailed; final bool loadingMore; bool get hasMore => records.length < recordsTotal; AssetState copyWith({ AssetWallet? wallet, List? records, int? recordsTotal, int? Function()? bizType, bool? isLoading, bool? loadFailed, bool? loadingMore, }) => AssetState( wallet: wallet ?? this.wallet, records: records ?? this.records, recordsTotal: recordsTotal ?? this.recordsTotal, bizType: bizType != null ? bizType() : this.bizType, isLoading: isLoading ?? this.isLoading, loadFailed: loadFailed ?? this.loadFailed, loadingMore: loadingMore ?? this.loadingMore, ); } class AssetNotifier extends StateNotifier { AssetNotifier() : super(const AssetState()) { load(); } static const _pageSize = 20; Future load() async { state = state.copyWith(isLoading: true, loadFailed: false); try { final wallet = await AssetService.fetchAssets(); final page = await AssetService.fetchRecords( page: 1, pageSize: _pageSize, bizType: state.bizType, ); state = state.copyWith( wallet: wallet, records: page.items, recordsTotal: page.total, isLoading: false, ); } catch (_) { state = state.copyWith(isLoading: false, loadFailed: true); } } /// 切换 biz_type 筛选并重载明细 Future setBizType(int? bizType) async { if (bizType == state.bizType) return; state = state.copyWith(bizType: () => bizType); await load(); } /// 触底加载下一页 Future loadMore() async { if (state.loadingMore || !state.hasMore || state.isLoading) return; state = state.copyWith(loadingMore: true); try { final page = await AssetService.fetchRecords( page: state.records.length ~/ _pageSize + 1, pageSize: _pageSize, bizType: state.bizType, ); state = state.copyWith( records: [...state.records, ...page.items], recordsTotal: page.total, loadingMore: false, ); } catch (_) { state = state.copyWith(loadingMore: false); } } } final assetProvider = StateNotifierProvider.autoDispose( (_) => AssetNotifier(), ); /// 提现记录状态(触底分页) class WithdrawRecordsState { const WithdrawRecordsState({ this.items = const [], this.total = 0, this.isLoading = false, this.loadFailed = false, this.loadingMore = false, }); final List items; final int total; final bool isLoading; final bool loadFailed; final bool loadingMore; bool get hasMore => items.length < total; WithdrawRecordsState copyWith({ List? items, int? total, bool? isLoading, bool? loadFailed, bool? loadingMore, }) => WithdrawRecordsState( items: items ?? this.items, total: total ?? this.total, isLoading: isLoading ?? this.isLoading, loadFailed: loadFailed ?? this.loadFailed, loadingMore: loadingMore ?? this.loadingMore, ); } class WithdrawRecordsNotifier extends StateNotifier { WithdrawRecordsNotifier() : super(const WithdrawRecordsState()) { load(); } static const _pageSize = 20; Future load() async { state = state.copyWith(isLoading: true, loadFailed: false); try { final page = await AssetService.fetchWithdrawRecords(pageSize: _pageSize); state = state.copyWith( items: page.items, total: page.total, isLoading: false, ); } catch (_) { state = state.copyWith(isLoading: false, loadFailed: true); } } Future loadMore() async { if (state.loadingMore || !state.hasMore || state.isLoading) return; state = state.copyWith(loadingMore: true); try { final page = await AssetService.fetchWithdrawRecords( page: state.items.length ~/ _pageSize + 1, pageSize: _pageSize, ); state = state.copyWith( items: [...state.items, ...page.items], total: page.total, loadingMore: false, ); } catch (_) { state = state.copyWith(loadingMore: false); } } } final withdrawRecordsProvider = StateNotifierProvider.autoDispose< WithdrawRecordsNotifier, WithdrawRecordsState>( (_) => WithdrawRecordsNotifier(), );