add
This commit is contained in:
@@ -0,0 +1,185 @@
|
||||
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(),
|
||||
);
|
||||
Reference in New Issue
Block a user