import 'package:dio/dio.dart'; import 'package:get/get.dart' hide MultipartFile, FormData; import 'dart:io'; import 'package:path/path.dart' as path; import '../../../data/models/problem_model.dart'; import '../../../data/providers/local_database.dart'; class ProblemController extends GetxController { final LocalDatabase _localDatabase; final RxList problems = [].obs; final RxBool isLoading = false.obs; final Dio _dio; // 依赖注入,由 bindings 传入所有依赖 ProblemController({required LocalDatabase localDatabase, required Dio dio}) : _localDatabase = localDatabase, _dio = dio; // 获取所有已选中的问题对象 List get selectedProblems { return problems.where((p) => p.isChecked.value).toList(); } // 获取未上传的问题 List get unuploadedProblems { return problems.where((p) => !p.isUploaded).toList(); } @override void onInit() { super.onInit(); loadProblems(); } Future loadProblems() async { isLoading.value = true; try { problems.value = await _localDatabase.getProblems(); } catch (e) { Get.snackbar('错误', '加载问题失败: $e'); rethrow; } finally { isLoading.value = false; } } /// 在本地数据库和GetX列表中添加一个新问题 Future addProblem(Problem problem) async { try { // 确保问题有ID if (problem.id == null) { problem = problem.copyWith( id: DateTime.now().millisecondsSinceEpoch.toString(), ); } await _localDatabase.insertProblem(problem); problems.add(problem); } catch (e) { Get.snackbar('错误', '保存问题失败: $e'); rethrow; } } /// 在本地数据库和GetX列表中更新一个现有问题 Future updateProblem(Problem problem) async { try { await _localDatabase.updateProblem(problem); final index = problems.indexWhere((p) => p.id == problem.id); if (index != -1) { problems[index] = problem; } } catch (e) { Get.snackbar('错误', '更新问题失败: $e'); rethrow; } } /// 删除单个问题 Future deleteProblem(Problem problem) async { try { if (problem.id != null) { await _localDatabase.deleteProblem(problem.id!); // 从本地列表中移除 problems.remove(problem); // 删除关联的图片文件 await _deleteProblemImages(problem); } } catch (e) { Get.snackbar('错误', '删除问题失败: $e'); rethrow; } } /// 批量删除选中的问题 Future deleteSelectedProblems() async { final problemsToDelete = selectedProblems; if (problemsToDelete.isEmpty) { Get.snackbar('提示', '请至少选择一个问题进行删除'); return; } try { for (var problem in problemsToDelete) { await deleteProblem(problem); } Get.snackbar('成功', '已删除${problemsToDelete.length}个问题'); } catch (e) { Get.snackbar('错误', '删除问题失败: $e'); } } /// 删除问题关联的图片文件 Future _deleteProblemImages(Problem problem) async { for (var imagePath in problem.imagePaths) { try { final file = File(imagePath); if (await file.exists()) { await file.delete(); } } catch (e) { print('删除图片失败: $imagePath, 错误: $e'); } } } /// 上传单个问题到服务器 Future uploadProblem(Problem problem) async { try { final formData = FormData.fromMap({ 'description': problem.description, 'location': problem.location, 'createdAt': problem.createdAt.toIso8601String(), 'boundInfo': problem.boundInfo ?? '', }); // 添加图片文件 for (var imagePath in problem.imagePaths) { final file = File(imagePath); if (await file.exists()) { formData.files.add( MapEntry( 'images', await MultipartFile.fromFile( imagePath, filename: path.basename(imagePath), ), ), ); } } final response = await _dio.post( 'https://your-server.com/api/problems', data: formData, options: Options( sendTimeout: const Duration(seconds: 30), receiveTimeout: const Duration(seconds: 30), ), ); if (response.statusCode == 200) { // 标记为已上传 final updatedProblem = problem.copyWith(isUploaded: true); await updateProblem(updatedProblem); return true; } else { throw Exception('服务器返回错误状态码: ${response.statusCode}'); } } on DioException catch (e) { if (e.type == DioExceptionType.connectionTimeout || e.type == DioExceptionType.receiveTimeout) { Get.snackbar('网络超时', '请检查网络连接后重试'); } else { Get.snackbar('网络错误', '上传问题失败: ${e.message}'); } return false; } catch (e) { Get.snackbar('错误', '上传问题失败: $e'); return false; } } /// 批量上传所有未上传的问题 Future uploadAllUnuploaded() async { final unuploaded = unuploadedProblems; if (unuploaded.isEmpty) { Get.snackbar('提示', '没有需要上传的问题'); return; } isLoading.value = true; int successCount = 0; for (var problem in unuploaded) { final success = await uploadProblem(problem); if (success) { successCount++; } // 添加短暂延迟,避免服务器压力过大 await Future.delayed(const Duration(milliseconds: 500)); } isLoading.value = false; if (successCount > 0) { Get.snackbar('成功', '已成功上传$successCount个问题'); } if (successCount < unuploaded.length) { Get.snackbar('部分成功', '有${unuploaded.length - successCount}个问题上传失败'); } } /// 绑定信息到问题 Future bindInfoToProblem(String id, String info) async { try { final problem = problems.firstWhere((p) => p.id == id); final updatedProblem = problem.copyWith(boundInfo: info); await updateProblem(updatedProblem); Get.snackbar('成功', '信息已绑定'); } catch (e) { Get.snackbar('错误', '未找到问题或绑定失败: $e'); } } /// 清除所有选中的状态 void clearSelections() { for (var problem in problems) { problem.isChecked.value = false; } } }