Files
food_hub_app/lib/provider/food_provider.dart
2026-06-28 23:17:00 +08:00

414 lines
9.8 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 Recipe recipeFormItem;
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 resetRecipeForm() {
recipeFormItem = Recipe.getEmpty();
notifyListeners();
}
void initRecipeForm(Recipe recipe) {
recipeFormItem = recipe;
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> queryRecipeByUserId(int userId) async {
if (isLoading) return;
try {
isLoading = true;
error = null;
notifyListeners();
final result = await queryRecipeByUserApi(userId);
recipeSummaryList = result;
notifyListeners();
} catch (e) {
error = '加载数据失败: $e';
debugPrint('加载数据失败: $e');
} finally {
isLoading = false;
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> queryMomentByUserId(int userId) async {
if (isLoading) return;
try {
isLoading = true;
error = null;
notifyListeners();
final result = await queryMomentListByUserIdApi(userId);
momentList = result;
notifyListeners();
} 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();
}
}
}