Files
video/app/lib/providers/asset_provider.dart
T
2026-10-15 20:36:59 +08:00

186 lines
4.9 KiB
Dart

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<AssetRecord> 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<AssetRecord>? 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<AssetState> {
AssetNotifier() : super(const AssetState()) {
load();
}
static const _pageSize = 20;
Future<void> 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<void> setBizType(int? bizType) async {
if (bizType == state.bizType) return;
state = state.copyWith(bizType: () => bizType);
await load();
}
/// 触底加载下一页
Future<void> 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, AssetState>(
(_) => AssetNotifier(),
);
/// 提现记录状态(触底分页)
class WithdrawRecordsState {
const WithdrawRecordsState({
this.items = const [],
this.total = 0,
this.isLoading = false,
this.loadFailed = false,
this.loadingMore = false,
});
final List<WithdrawRecord> items;
final int total;
final bool isLoading;
final bool loadFailed;
final bool loadingMore;
bool get hasMore => items.length < total;
WithdrawRecordsState copyWith({
List<WithdrawRecord>? 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<WithdrawRecordsState> {
WithdrawRecordsNotifier() : super(const WithdrawRecordsState()) {
load();
}
static const _pageSize = 20;
Future<void> 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<void> 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(),
);