363 lines
8.7 KiB
Dart
363 lines
8.7 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_common/models/common_model.dart';
|
|
import 'package:food_hub_app/apis/moment.dart';
|
|
import 'package:food_hub_app/apis/recipe.dart';
|
|
import 'package:food_hub_app/apis/stats.dart';
|
|
import 'package:food_hub_app/models/moment.dart';
|
|
import 'package:food_hub_app/models/recipe.dart';
|
|
import 'package:food_hub_app/models/stats.dart';
|
|
import 'package:food_hub_app/utils/date_util.dart';
|
|
import 'package:food_hub_app/utils/index.dart';
|
|
import 'package:food_hub_app/views/record.dart';
|
|
|
|
class FoodProvider with ChangeNotifier {
|
|
late RecordTab currentRecordTab = RecordTab.recipe;
|
|
late FoodRecord recordFormItem;
|
|
late Moment momentFormItem;
|
|
|
|
late bool isEditing;
|
|
bool isLoading = false;
|
|
String? error;
|
|
|
|
String queryCategory = '全部菜系';
|
|
late List<String> categoryList = [];
|
|
late List<RecipeSummary> recipeSummaryList = [];
|
|
|
|
int selectYear = DateTime.now().year;
|
|
DateTime selectedDay = DateTime.now();
|
|
DateTime focusedDay = DateTime.now();
|
|
|
|
late List<FoodRecord> recordList = [];
|
|
late List<FoodRecord> selectRecordList = [];
|
|
|
|
late SummaryStats summaryStats = SummaryStats(
|
|
recipeCount: 0,
|
|
categoryCount: 0,
|
|
workCount: 0,
|
|
);
|
|
late double averageRecordCount = 0;
|
|
late List<ChartData> recordStats = [];
|
|
late List<ChartData> categoryStats = [];
|
|
late List<ChartData> rankStats = [];
|
|
|
|
List<Moment> momentList = [];
|
|
int currentPage = 1;
|
|
final int pageSize = 5;
|
|
bool hasMore = true;
|
|
|
|
void resetRecordForm() {
|
|
recordFormItem = FoodRecord.getEmpty();
|
|
notifyListeners();
|
|
}
|
|
|
|
void initRecordForm(FoodRecord record) {
|
|
recordFormItem = record;
|
|
notifyListeners();
|
|
}
|
|
|
|
void updateRecordFormItem({String? name, String? date, String? imageUrl}) {
|
|
if (name != null) recordFormItem.name = name;
|
|
if (date != null) recordFormItem.date = date;
|
|
if (imageUrl != null) recordFormItem.imageUrl = imageUrl;
|
|
notifyListeners();
|
|
}
|
|
|
|
void updateMomentFormItem({String? content}) {
|
|
if (content != null) momentFormItem.content = content;
|
|
notifyListeners();
|
|
}
|
|
|
|
void addMomentFormImage(List<String> imageUrls) {
|
|
momentFormItem.imageList.addAll(imageUrls);
|
|
notifyListeners();
|
|
}
|
|
|
|
void removeMomentFormImage(int index) {
|
|
momentFormItem.imageList.removeAt(index);
|
|
notifyListeners();
|
|
}
|
|
|
|
void resetMomentForm() {
|
|
momentFormItem = Moment.getEmpty();
|
|
notifyListeners();
|
|
}
|
|
|
|
void initMomentForm(Moment moment) {
|
|
momentFormItem = moment;
|
|
notifyListeners();
|
|
}
|
|
|
|
Future<void> onRecordTabChange() async {
|
|
switch (currentRecordTab) {
|
|
case RecordTab.recipe:
|
|
await refreshRecipeList();
|
|
break;
|
|
case RecordTab.calendar:
|
|
case RecordTab.timeline:
|
|
await refreshRecordList();
|
|
break;
|
|
}
|
|
}
|
|
|
|
Future<void> queryCategoryList() async {
|
|
try {
|
|
error = null;
|
|
notifyListeners();
|
|
|
|
final result = await queryCategoryApi();
|
|
categoryList.clear();
|
|
categoryList.add('全部菜系');
|
|
categoryList.addAll(result);
|
|
} catch (e) {
|
|
error = '加载数据失败: $e';
|
|
debugPrint('加载数据失败: $e');
|
|
} finally {
|
|
notifyListeners();
|
|
}
|
|
}
|
|
|
|
Future<void> refreshRecipeList() async {
|
|
if (isLoading) return;
|
|
|
|
try {
|
|
isLoading = true;
|
|
error = null;
|
|
notifyListeners();
|
|
|
|
final category = queryCategory == '全部菜系' ? '' : queryCategory;
|
|
final result = await queryRecipeApi(RecipeQuery(category: category));
|
|
recipeSummaryList = result;
|
|
} catch (e) {
|
|
error = '加载数据失败: $e';
|
|
debugPrint('加载数据失败: $e');
|
|
} finally {
|
|
isLoading = false;
|
|
notifyListeners();
|
|
}
|
|
}
|
|
|
|
Future<void> refreshRecordList() async {
|
|
if (isLoading) return;
|
|
|
|
if (currentRecordTab == RecordTab.recipe) return;
|
|
|
|
try {
|
|
isLoading = true;
|
|
error = null;
|
|
notifyListeners();
|
|
|
|
late String startDate;
|
|
late String endDate;
|
|
|
|
switch (currentRecordTab) {
|
|
case RecordTab.calendar:
|
|
startDate = getFirstDayOfMonth(focusedDay);
|
|
endDate = getLastDayOfMonth(focusedDay);
|
|
break;
|
|
case RecordTab.timeline:
|
|
startDate = '$selectYear-01-01';
|
|
endDate = '$selectYear-12-31';
|
|
break;
|
|
case RecordTab.recipe:
|
|
break;
|
|
}
|
|
|
|
final result = await queryRecordApi(startDate, endDate);
|
|
|
|
recordList = result;
|
|
|
|
if (recordList.isNotEmpty) {
|
|
selectedDay = DateTime.parse(recordList.last.date);
|
|
} else {
|
|
selectedDay = focusedDay;
|
|
}
|
|
|
|
refreshSelectRecord();
|
|
} catch (e) {
|
|
error = '加载数据失败: $e';
|
|
debugPrint('加载数据失败: $e');
|
|
} finally {
|
|
isLoading = false;
|
|
notifyListeners();
|
|
}
|
|
}
|
|
|
|
Future<bool> handleRecord() async {
|
|
if (isLoading) return true;
|
|
|
|
try {
|
|
isLoading = true;
|
|
error = null;
|
|
notifyListeners();
|
|
|
|
if (isEditing) {
|
|
await updateRecordApi(recordFormItem.id!, recordFormItem);
|
|
} else {
|
|
await addRecordApi(recordFormItem);
|
|
}
|
|
return true;
|
|
} catch (e) {
|
|
error = '处理数据失败: $e';
|
|
debugPrint('处理数据失败: $e');
|
|
return false;
|
|
} finally {
|
|
isLoading = false;
|
|
notifyListeners();
|
|
}
|
|
}
|
|
|
|
Future<bool> deleteRecord() async {
|
|
if (isLoading) return true;
|
|
|
|
try {
|
|
isLoading = true;
|
|
error = null;
|
|
notifyListeners();
|
|
|
|
await deleteRecordApi(recordFormItem.id!);
|
|
return true;
|
|
} catch (e) {
|
|
error = '处理数据失败: $e';
|
|
debugPrint('处理数据失败: $e');
|
|
return false;
|
|
} finally {
|
|
isLoading = false;
|
|
notifyListeners();
|
|
}
|
|
}
|
|
|
|
void refreshSelectRecord() {
|
|
selectRecordList =
|
|
recordList
|
|
.where((record) => record.date == formatDateTime(selectedDay))
|
|
.toList();
|
|
}
|
|
|
|
Future<void> refreshFoodStats() async {
|
|
if (isLoading) return;
|
|
|
|
try {
|
|
isLoading = true;
|
|
error = null;
|
|
notifyListeners();
|
|
|
|
final statsResult = await queryStatsApi();
|
|
final recordStatsResult = await queryRecordStatsApi();
|
|
final categoryStatsResult = await queryCategoryStatsApi();
|
|
final rankStatsResult = await queryRankStatsApi();
|
|
|
|
summaryStats = statsResult;
|
|
recordStats = recordStatsResult;
|
|
categoryStats = categoryStatsResult;
|
|
rankStats = rankStatsResult;
|
|
|
|
if (recordStats.isNotEmpty) {
|
|
double sumValue = recordStats.fold(
|
|
0.0,
|
|
(sum, item) => sum + item.value,
|
|
);
|
|
averageRecordCount = sumValue / recordStats.length;
|
|
}
|
|
} catch (e) {
|
|
error = '加载数据失败: $e';
|
|
debugPrint('加载数据失败: $e');
|
|
} finally {
|
|
isLoading = false;
|
|
notifyListeners();
|
|
}
|
|
}
|
|
|
|
Future<void> queryMomentByPage({bool isRefresh = true}) async {
|
|
if (isLoading) return;
|
|
|
|
try {
|
|
if (currentPage == 1) {
|
|
isLoading = true;
|
|
}
|
|
|
|
error = null;
|
|
notifyListeners();
|
|
|
|
// 如果是刷新,重置页码
|
|
if (isRefresh) {
|
|
currentPage = 1;
|
|
}
|
|
|
|
final result = await queryMomentByPageApi(currentPage, pageSize);
|
|
|
|
// 更新数据
|
|
if (isRefresh) {
|
|
momentList = result.records;
|
|
} else {
|
|
momentList.addAll(result.records);
|
|
}
|
|
|
|
// 判断是否还有更多数据
|
|
hasMore = result.current < result.pages;
|
|
if (hasMore) {
|
|
currentPage++;
|
|
}
|
|
} catch (e) {
|
|
error = '加载数据失败: $e';
|
|
debugPrint('加载数据失败: $e');
|
|
} finally {
|
|
isLoading = false;
|
|
notifyListeners();
|
|
}
|
|
}
|
|
|
|
Future<void> loadMoreMomentList() async {
|
|
if (hasMore && !isLoading) {
|
|
await queryMomentByPage(isRefresh: false);
|
|
}
|
|
}
|
|
|
|
Future<void> refreshMomentList() async {
|
|
await queryMomentByPage(isRefresh: true);
|
|
}
|
|
|
|
Future<bool> handleMoment() async {
|
|
if (isLoading) return true;
|
|
|
|
try {
|
|
isLoading = true;
|
|
error = null;
|
|
notifyListeners();
|
|
|
|
if (isEditing) {
|
|
await updateMomentApi(momentFormItem.id!, momentFormItem);
|
|
} else {
|
|
await addMomentApi(momentFormItem);
|
|
}
|
|
return true;
|
|
} catch (e) {
|
|
error = '处理数据失败: $e';
|
|
debugPrint('处理数据失败: $e');
|
|
return false;
|
|
} finally {
|
|
isLoading = false;
|
|
notifyListeners();
|
|
}
|
|
}
|
|
|
|
Future<bool> deleteMoment() async {
|
|
if (isLoading) return true;
|
|
|
|
try {
|
|
isLoading = true;
|
|
error = null;
|
|
notifyListeners();
|
|
|
|
await deleteMomentApi(momentFormItem.id!);
|
|
return true;
|
|
} catch (e) {
|
|
error = '处理数据失败: $e';
|
|
debugPrint('处理数据失败: $e');
|
|
return false;
|
|
} finally {
|
|
isLoading = false;
|
|
notifyListeners();
|
|
}
|
|
}
|
|
}
|