You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
116 lines
3.2 KiB
116 lines
3.2 KiB
3 weeks ago
|
import 'package:dio/dio.dart';
|
||
|
import 'package:get/get.dart' hide MultipartFile, FormData;
|
||
|
import 'package:image_picker/image_picker.dart';
|
||
|
import 'package:path_provider/path_provider.dart';
|
||
|
import 'dart:io';
|
||
|
import '../models/problem_model.dart';
|
||
|
import '../services/local_database.dart';
|
||
|
|
||
|
class ProblemController extends GetxController {
|
||
|
final LocalDatabase _localDatabase = LocalDatabase();
|
||
|
final RxList<Problem> problems = <Problem>[].obs;
|
||
|
final RxBool isLoading = false.obs;
|
||
|
|
||
|
// 这个方法返回所有已选中的问题对象
|
||
|
List<Problem> get selectedProblems {
|
||
|
return problems.where((p) => p.isChecked.value).toList();
|
||
|
}
|
||
|
|
||
|
@override
|
||
|
void onInit() {
|
||
|
super.onInit();
|
||
|
loadProblems();
|
||
|
}
|
||
|
|
||
|
Future<void> loadProblems() async {
|
||
|
isLoading.value = true;
|
||
|
problems.value = await _localDatabase.getProblems();
|
||
|
isLoading.value = false;
|
||
|
}
|
||
|
|
||
|
Future<void> addProblem(
|
||
|
String description,
|
||
|
String location,
|
||
|
List<XFile> images,
|
||
|
) async {
|
||
|
try {
|
||
|
// 保存图片到本地
|
||
|
final List<String> imagePaths = [];
|
||
|
final directory = await getApplicationDocumentsDirectory();
|
||
|
|
||
|
for (var i = 0; i < images.length; i++) {
|
||
|
final String imagePath =
|
||
|
'${directory.path}/problem_${DateTime.now().millisecondsSinceEpoch}_$i.jpg';
|
||
|
final File imageFile = File(imagePath);
|
||
|
await imageFile.writeAsBytes(await images[i].readAsBytes());
|
||
|
imagePaths.add(imagePath);
|
||
|
}
|
||
|
|
||
|
final Problem problem = Problem(
|
||
|
description: description,
|
||
|
location: location,
|
||
|
imagePaths: imagePaths,
|
||
|
createdAt: DateTime.now(),
|
||
|
isUploaded: false,
|
||
|
);
|
||
|
|
||
|
await _localDatabase.insertProblem(problem);
|
||
|
problems.add(problem);
|
||
|
} catch (e) {
|
||
|
Get.snackbar('错误', '保存问题失败: $e');
|
||
|
rethrow;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Future<void> uploadProblem(Problem problem) async {
|
||
|
try {
|
||
|
final dio = Dio();
|
||
|
|
||
|
// 准备表单数据
|
||
|
final formData = FormData.fromMap({
|
||
|
'description': problem.description,
|
||
|
'location': problem.location,
|
||
|
'createdAt': problem.createdAt.toIso8601String(),
|
||
|
'boundInfo': problem.boundInfo ?? '',
|
||
|
});
|
||
|
|
||
|
// 添加图片文件
|
||
|
for (var path in problem.imagePaths) {
|
||
|
formData.files.add(
|
||
|
MapEntry('images', await MultipartFile.fromFile(path)),
|
||
|
);
|
||
|
}
|
||
|
|
||
|
final response = await dio.post(
|
||
|
'https://your-server.com/api/problems',
|
||
|
data: formData,
|
||
|
);
|
||
|
|
||
|
if (response.statusCode == 200) {
|
||
|
// 更新上传状态
|
||
|
problem.isUploaded = true;
|
||
|
await _localDatabase.updateProblem(problem);
|
||
|
problems.refresh();
|
||
|
|
||
|
Get.snackbar('成功', '问题已上传到服务器');
|
||
|
}
|
||
|
} catch (e) {
|
||
|
Get.snackbar('错误', '上传问题失败: $e');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Future<void> uploadAllUnuploaded() async {
|
||
|
final unuploaded = await _localDatabase.getUnuploadedProblems();
|
||
|
for (var problem in unuploaded) {
|
||
|
await uploadProblem(problem);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Future<void> bindInfoToProblem(int problemId, String info) async {
|
||
|
final problem = problems.firstWhere((p) => p.id == problemId);
|
||
|
problem.boundInfo = info;
|
||
|
await _localDatabase.updateProblem(problem);
|
||
|
problems.refresh();
|
||
|
}
|
||
|
}
|