|
|
|
@ -1,20 +1,24 @@ |
|
|
|
import 'package:flutter/material.dart'; |
|
|
|
import 'package:flutter/material.dart'; |
|
|
|
import 'package:get/get.dart'; |
|
|
|
import 'package:get/get.dart'; |
|
|
|
|
|
|
|
import 'package:problem_check_system/app/core/extensions/datetime_extension.dart'; |
|
|
|
import 'package:problem_check_system/app/core/models/form_mode.dart'; |
|
|
|
import 'package:problem_check_system/app/core/models/form_mode.dart'; |
|
|
|
import 'package:problem_check_system/app/core/routes/app_routes.dart'; |
|
|
|
import 'package:problem_check_system/app/core/routes/app_routes.dart'; |
|
|
|
import 'package:problem_check_system/app/features/problem/domain/entities/problem_entity.dart'; |
|
|
|
import 'package:problem_check_system/app/features/problem/domain/entities/problem_entity.dart'; |
|
|
|
import 'package:problem_check_system/app/features/problem/domain/entities/problem_list_item_entity.dart'; |
|
|
|
import 'package:problem_check_system/app/features/problem/domain/entities/problem_list_item_entity.dart'; |
|
|
|
|
|
|
|
import 'package:problem_check_system/app/features/problem/domain/repositories/problem_repository.dart'; |
|
|
|
import 'package:problem_check_system/app/features/problem/domain/usecases/get_all_problems_usecase.dart'; |
|
|
|
import 'package:problem_check_system/app/features/problem/domain/usecases/get_all_problems_usecase.dart'; |
|
|
|
|
|
|
|
import 'package:problem_check_system/app/features/problem/domain/usecases/resolve_conflict_usecase.dart'; |
|
|
|
|
|
|
|
import 'package:problem_check_system/app/features/problem/domain/usecases/sync_problems_usecase.dart'; |
|
|
|
|
|
|
|
|
|
|
|
class ProblemListController extends GetxController { |
|
|
|
class ProblemListController extends GetxController { |
|
|
|
final GetAllProblemsUsecase getAllProblemsUsecase; |
|
|
|
final GetAllProblemsUsecase getAllProblemsUsecase; |
|
|
|
// final SyncEnterprisesUsecase syncEnterprisesUsecase; |
|
|
|
final SyncProblemsUsecase syncProblemsUsecase; |
|
|
|
// final ResolveConflictUsecase resolveConflictUsecase; |
|
|
|
final ProblemResolveConflictUsecase problemResolveConflictUsecase; |
|
|
|
|
|
|
|
|
|
|
|
ProblemListController({ |
|
|
|
ProblemListController({ |
|
|
|
required this.getAllProblemsUsecase, |
|
|
|
required this.getAllProblemsUsecase, |
|
|
|
// required this.syncEnterprisesUsecase, |
|
|
|
required this.syncProblemsUsecase, |
|
|
|
// required this.resolveConflictUsecase, |
|
|
|
required this.problemResolveConflictUsecase, |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
final problemList = <ProblemListItemEntity>[].obs; |
|
|
|
final problemList = <ProblemListItemEntity>[].obs; |
|
|
|
@ -45,31 +49,32 @@ class ProblemListController extends GetxController { |
|
|
|
|
|
|
|
|
|
|
|
// --- 实现基类中定义的方法 --- |
|
|
|
// --- 实现基类中定义的方法 --- |
|
|
|
// 核心流程方法 |
|
|
|
// 核心流程方法 |
|
|
|
Future<void> loadAndSyncEnterprises() async { |
|
|
|
Future<void> loadAndSyncProblems() async { |
|
|
|
try { |
|
|
|
try { |
|
|
|
isLoading(true); |
|
|
|
isLoading(true); |
|
|
|
isSyncing(true); |
|
|
|
isSyncing(true); |
|
|
|
|
|
|
|
|
|
|
|
// // 步骤 1: 执行同步 |
|
|
|
// 步骤 1: 执行同步 |
|
|
|
// final syncResult = await syncEnterprisesUsecase(); |
|
|
|
final syncResult = await syncProblemsUsecase(); |
|
|
|
|
|
|
|
|
|
|
|
// // 步骤 2: 处理冲突 |
|
|
|
// 步骤 2: 处理冲突 |
|
|
|
// if (syncResult.hasConflicts) { |
|
|
|
if (syncResult.hasConflicts) { |
|
|
|
// // 如果有冲突,则逐个弹窗让用户选择 |
|
|
|
// 如果有冲突,则逐个弹窗让用户选择 |
|
|
|
// for (final conflict in syncResult.conflicts) { |
|
|
|
for (final conflict in syncResult.conflicts) { |
|
|
|
// final chosenVersion = await _showConflictDialog(conflict); |
|
|
|
final chosenVersion = await _showConflictDialog(conflict); |
|
|
|
// if (chosenVersion != null) { |
|
|
|
if (chosenVersion != null) { |
|
|
|
// // 用户做出了选择,更新本地数据 |
|
|
|
// 用户做出了选择,更新本地数据 |
|
|
|
// await resolveConflictUsecase(chosenVersion); |
|
|
|
await problemResolveConflictUsecase(chosenVersion); |
|
|
|
// } |
|
|
|
} |
|
|
|
// } |
|
|
|
} |
|
|
|
// } |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
isSyncing(false); |
|
|
|
isSyncing(false); |
|
|
|
|
|
|
|
|
|
|
|
// 步骤 3: 所有同步和冲突解决完毕后,从本地加载最终数据 |
|
|
|
// 步骤 3: 所有同步和冲突解决完毕后,从本地加载最终数据 |
|
|
|
await loadProblemItems(); |
|
|
|
await loadProblemItems(); |
|
|
|
} catch (e) { |
|
|
|
} catch (e) { |
|
|
|
|
|
|
|
Get.log('操作失败: $e'); |
|
|
|
Get.snackbar('错误', '操作失败: $e'); |
|
|
|
Get.snackbar('错误', '操作失败: $e'); |
|
|
|
} finally { |
|
|
|
} finally { |
|
|
|
isLoading(false); |
|
|
|
isLoading(false); |
|
|
|
@ -77,74 +82,76 @@ class ProblemListController extends GetxController { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// // [修改后] 弹出冲突选择对话框的辅助方法 |
|
|
|
// [修改后] 弹出冲突选择对话框的辅助方法 |
|
|
|
// Future<Enterprise?> _showConflictDialog(EnterpriseConflict conflict) { |
|
|
|
Future<ProblemEntity?> _showConflictDialog(ProblemConflict conflict) { |
|
|
|
// return Get.dialog<Enterprise>( |
|
|
|
return Get.dialog<ProblemEntity>( |
|
|
|
// AlertDialog( |
|
|
|
AlertDialog( |
|
|
|
// title: Text('数据冲突'), |
|
|
|
title: Text('数据冲突'), |
|
|
|
// content: Column( |
|
|
|
content: Column( |
|
|
|
// mainAxisSize: MainAxisSize.min, |
|
|
|
mainAxisSize: MainAxisSize.min, |
|
|
|
// crossAxisAlignment: CrossAxisAlignment.stretch, |
|
|
|
crossAxisAlignment: CrossAxisAlignment.stretch, |
|
|
|
// children: [ |
|
|
|
children: [ |
|
|
|
// Text('${conflict.localVersion.name} 服务器上的数据与本地数据不一致,请选择要保留的版本。'), |
|
|
|
Text( |
|
|
|
// const SizedBox(height: 24), |
|
|
|
'${conflict.localVersion.description} 服务器上的数据与本地数据不一致,请选择要保留的版本。', |
|
|
|
|
|
|
|
), |
|
|
|
// // --- 本地版本选择区 --- |
|
|
|
const SizedBox(height: 24), |
|
|
|
// Row( |
|
|
|
|
|
|
|
// children: [ |
|
|
|
// --- 本地版本选择区 --- |
|
|
|
// // 使用 Expanded 让主按钮填充可用空间 |
|
|
|
Row( |
|
|
|
// Expanded( |
|
|
|
children: [ |
|
|
|
// child: ElevatedButton( |
|
|
|
// 使用 Expanded 让主按钮填充可用空间 |
|
|
|
// child: Text( |
|
|
|
Expanded( |
|
|
|
// '使用客户端版本\n(修改于: ${conflict.localVersion.lastModifiedTime.toLocal().toDateTimeString2()})', |
|
|
|
child: ElevatedButton( |
|
|
|
// textAlign: TextAlign.center, |
|
|
|
child: Text( |
|
|
|
// ), |
|
|
|
'使用客户端版本\n(修改于: ${conflict.localVersion.lastModifiedTime.toLocal().toDateTimeString2()})', |
|
|
|
// onPressed: () => Get.back(result: conflict.localVersion), |
|
|
|
textAlign: TextAlign.center, |
|
|
|
// ), |
|
|
|
), |
|
|
|
// ), |
|
|
|
onPressed: () => Get.back(result: conflict.localVersion), |
|
|
|
// const SizedBox(width: 8), // 按钮间的间距 |
|
|
|
), |
|
|
|
// // 查看详情按钮 |
|
|
|
), |
|
|
|
// IconButton( |
|
|
|
const SizedBox(width: 8), // 按钮间的间距 |
|
|
|
// icon: const Icon(Icons.info_outline), |
|
|
|
// 查看详情按钮 |
|
|
|
// tooltip: '查看客户端版本详情', |
|
|
|
IconButton( |
|
|
|
// onPressed: () => navigateToDetailsView(conflict.localVersion), |
|
|
|
icon: const Icon(Icons.info_outline), |
|
|
|
// ), |
|
|
|
tooltip: '查看客户端版本详情', |
|
|
|
// ], |
|
|
|
onPressed: () => navigateToDetailsView(conflict.localVersion), |
|
|
|
// ), |
|
|
|
), |
|
|
|
// const SizedBox(height: 8), |
|
|
|
], |
|
|
|
|
|
|
|
), |
|
|
|
// // --- 服务器版本选择区 --- |
|
|
|
const SizedBox(height: 8), |
|
|
|
// Row( |
|
|
|
|
|
|
|
// children: [ |
|
|
|
// --- 服务器版本选择区 --- |
|
|
|
// Expanded( |
|
|
|
Row( |
|
|
|
// child: ElevatedButton( |
|
|
|
children: [ |
|
|
|
// style: ElevatedButton.styleFrom( |
|
|
|
Expanded( |
|
|
|
// backgroundColor: Get.theme.colorScheme.primary, |
|
|
|
child: ElevatedButton( |
|
|
|
// foregroundColor: Get.theme.colorScheme.onPrimary, |
|
|
|
style: ElevatedButton.styleFrom( |
|
|
|
// ), |
|
|
|
backgroundColor: Get.theme.colorScheme.primary, |
|
|
|
// child: Text( |
|
|
|
foregroundColor: Get.theme.colorScheme.onPrimary, |
|
|
|
// '使用服务器版本\n(修改于: ${conflict.serverVersion.lastModifiedTime.toLocal().toDateTimeString2()})', |
|
|
|
), |
|
|
|
// textAlign: TextAlign.center, |
|
|
|
child: Text( |
|
|
|
// ), |
|
|
|
'使用服务器版本\n(修改于: ${conflict.serverVersion.lastModifiedTime.toLocal().toDateTimeString2()})', |
|
|
|
// onPressed: () => Get.back(result: conflict.serverVersion), |
|
|
|
textAlign: TextAlign.center, |
|
|
|
// ), |
|
|
|
), |
|
|
|
// ), |
|
|
|
onPressed: () => Get.back(result: conflict.serverVersion), |
|
|
|
// const SizedBox(width: 8), |
|
|
|
), |
|
|
|
// IconButton( |
|
|
|
), |
|
|
|
// icon: const Icon(Icons.info_outline), |
|
|
|
const SizedBox(width: 8), |
|
|
|
// tooltip: '查看服务器版本详情', |
|
|
|
IconButton( |
|
|
|
// onPressed: () => |
|
|
|
icon: const Icon(Icons.info_outline), |
|
|
|
// navigateToDetailsView(conflict.serverVersion), |
|
|
|
tooltip: '查看服务器版本详情', |
|
|
|
// ), |
|
|
|
onPressed: () => |
|
|
|
// ], |
|
|
|
navigateToDetailsView(conflict.serverVersion), |
|
|
|
// ), |
|
|
|
), |
|
|
|
// ], |
|
|
|
], |
|
|
|
// ), |
|
|
|
), |
|
|
|
// ), |
|
|
|
], |
|
|
|
// // 设置为 false,防止用户点击对话框外部意外关闭它 |
|
|
|
), |
|
|
|
// barrierDismissible: false, |
|
|
|
), |
|
|
|
// ); |
|
|
|
// 设置为 false,防止用户点击对话框外部意外关闭它 |
|
|
|
// } |
|
|
|
barrierDismissible: false, |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void search() { |
|
|
|
void search() { |
|
|
|
loadProblemItems(); |
|
|
|
loadProblemItems(); |
|
|
|
|