|
|
|
|
@ -1,3 +1,4 @@
|
|
|
|
|
import 'package:flutter/foundation.dart'; |
|
|
|
|
import 'package:get/get.dart'; |
|
|
|
|
import 'package:problem_check_system/app/core/models/sync_status.dart'; |
|
|
|
|
import 'package:problem_check_system/app/core/repositories/syncable_repository.dart'; |
|
|
|
|
@ -35,7 +36,7 @@ class SyncService extends GetxService {
|
|
|
|
|
void registerRepository<T extends SyncableEntity>( |
|
|
|
|
SyncableRepository<T> repository, |
|
|
|
|
) { |
|
|
|
|
print('[SyncService] Registering repository for type: $T'); |
|
|
|
|
debugPrint('[SyncService] Registering repository for type: $T'); |
|
|
|
|
_repositories[T] = repository; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -46,7 +47,7 @@ class SyncService extends GetxService {
|
|
|
|
|
/// 1. **上传阶段**: 推送所有本地的待创建、待更新、待删除的记录。 |
|
|
|
|
/// 2. **下载阶段**: 为每个已注册的实体类型,拉取自上次同步以来的服务器更新。 |
|
|
|
|
Future<void> performFullSync() async { |
|
|
|
|
print('[SyncService] === Starting Full Sync Cycle ==='); |
|
|
|
|
debugPrint('[SyncService] === Starting Full Sync Cycle ==='); |
|
|
|
|
|
|
|
|
|
// 阶段一: 上传本地所有待处理的更改 |
|
|
|
|
await _pushAllPendingChanges(); |
|
|
|
|
@ -54,7 +55,7 @@ class SyncService extends GetxService {
|
|
|
|
|
// 阶段二: 下载所有已注册的实体的服务器更新 |
|
|
|
|
await _pullAllServerUpdates(); |
|
|
|
|
|
|
|
|
|
print('[SyncService] === Full Sync Cycle Finished ==='); |
|
|
|
|
debugPrint('[SyncService] === Full Sync Cycle Finished ==='); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// --- 私有辅助方法 --- /// |
|
|
|
|
@ -62,18 +63,18 @@ class SyncService extends GetxService {
|
|
|
|
|
/// **上传阶段** |
|
|
|
|
/// 获取所有本地待同步的项,并逐个进行同步。 |
|
|
|
|
Future<void> _pushAllPendingChanges() async { |
|
|
|
|
print('[SyncService] >> Phase 1: Pushing local changes...'); |
|
|
|
|
debugPrint('[SyncService] >> Phase 1: Pushing local changes...'); |
|
|
|
|
|
|
|
|
|
// 注意: 您需要实现一个方法来获取所有 feature 的待同步项。 |
|
|
|
|
// 这里我们假设有一个 `_getAllPendingItems()` 方法。 |
|
|
|
|
final List<SyncableEntity> allPendingItems = await _getAllPendingItems(); |
|
|
|
|
|
|
|
|
|
if (allPendingItems.isEmpty) { |
|
|
|
|
print('[SyncService] No local changes to push.'); |
|
|
|
|
debugPrint('[SyncService] No local changes to push.'); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
print( |
|
|
|
|
debugPrint( |
|
|
|
|
'[SyncService] Found ${allPendingItems.length} pending items to push.', |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
@ -81,19 +82,19 @@ class SyncService extends GetxService {
|
|
|
|
|
try { |
|
|
|
|
await _syncSingleItem(item); |
|
|
|
|
} catch (e) { |
|
|
|
|
print( |
|
|
|
|
debugPrint( |
|
|
|
|
'[SyncService] ERROR: Failed to push item ${item.id} of type ${item.runtimeType}. Error: $e', |
|
|
|
|
); |
|
|
|
|
// 关键: 单个项目失败不应中断整个上传流程,继续尝试下一个。 |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
print('[SyncService] << Push phase completed.'); |
|
|
|
|
debugPrint('[SyncService] << Push phase completed.'); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// **下载阶段** |
|
|
|
|
/// 遍历所有已注册的仓库,并为每个仓库执行拉取操作。 |
|
|
|
|
Future<void> _pullAllServerUpdates() async { |
|
|
|
|
print('[SyncService] >> Phase 2: Pulling server updates...'); |
|
|
|
|
debugPrint('[SyncService] >> Phase 2: Pulling server updates...'); |
|
|
|
|
|
|
|
|
|
// 记录本次同步周期开始的时间。如果某个类型的拉取成功,这将是它的新时间戳。 |
|
|
|
|
final DateTime syncCycleStartTime = DateTime.now().toUtc(); |
|
|
|
|
@ -108,7 +109,7 @@ class SyncService extends GetxService {
|
|
|
|
|
entityType, |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
print( |
|
|
|
|
debugPrint( |
|
|
|
|
'[SyncService] Pulling updates for $entityType since: ${lastSyncTimestamp ?? 'the beginning'}', |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
@ -120,17 +121,17 @@ class SyncService extends GetxService {
|
|
|
|
|
entityType, |
|
|
|
|
syncCycleStartTime, |
|
|
|
|
); |
|
|
|
|
print( |
|
|
|
|
debugPrint( |
|
|
|
|
'[SyncService] Successfully pulled and updated timestamp for $entityType.', |
|
|
|
|
); |
|
|
|
|
} catch (e) { |
|
|
|
|
print( |
|
|
|
|
debugPrint( |
|
|
|
|
'[SyncService] ERROR: Failed to pull updates for $entityType. Error: $e', |
|
|
|
|
); |
|
|
|
|
// 关键: 一个类型的拉取失败不应中断其他类型的同步。 |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
print('[SyncService] << Pull phase completed.'); |
|
|
|
|
debugPrint('[SyncService] << Pull phase completed.'); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// 根据单个项目的同步状态,委托给对应的仓库执行操作。 |
|
|
|
|
@ -138,13 +139,13 @@ class SyncService extends GetxService {
|
|
|
|
|
final repository = _repositories[item.runtimeType]; |
|
|
|
|
|
|
|
|
|
if (repository == null) { |
|
|
|
|
print( |
|
|
|
|
debugPrint( |
|
|
|
|
'[SyncService] WARNING: No repository registered for type ${item.runtimeType}. Skipping item ${item.id}.', |
|
|
|
|
); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
print( |
|
|
|
|
debugPrint( |
|
|
|
|
'[SyncService] Pushing item ${item.id} (${item.runtimeType}) with status ${item.syncStatus.name}...', |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
@ -162,7 +163,6 @@ class SyncService extends GetxService {
|
|
|
|
|
// 这不应该发生在待处理列表中,但为了安全起见,我们忽略它。 |
|
|
|
|
break; |
|
|
|
|
case SyncStatus.untracked: |
|
|
|
|
// TODO: Handle this case. |
|
|
|
|
throw UnimplementedError(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
@ -178,7 +178,7 @@ class SyncService extends GetxService {
|
|
|
|
|
// final enterprises = await enterpriseLocalDataSource.getPendingEnterprises(); |
|
|
|
|
// return [...problems, ...enterprises]; |
|
|
|
|
|
|
|
|
|
print( |
|
|
|
|
debugPrint( |
|
|
|
|
'[SyncService] WARNING: _getAllPendingItems() is not implemented. Returning empty list.', |
|
|
|
|
); |
|
|
|
|
return []; // 返回空列表以防止错误 |
|
|
|
|
|