using System; using System.Collections.Generic; using System.Threading.Tasks; using 報到系統客戶端.Data.Models; using 報到系統客戶端.Data.Repositories; using 報到系統客戶端.Models; using 報到系統客戶端.Services; namespace 報到系統客戶端.Data.Services { /// /// 資料同步服務 /// 協調後端 API 和本地 SQLite 資料庫的資料同步 /// public class DataSyncService { private readonly ClassesRepository _classesRepo; private readonly SignUpsRepository _signUpsRepo; public DataSyncService() { _classesRepo = new ClassesRepository(); _signUpsRepo = new SignUpsRepository(); } /// /// 同步 Classes 資料(從 API 到本地) /// public async Task SyncClassesFromApiAsync() { try { // 從 API 查詢資料 var response = await ClassesService.SearchClassesAsync(); if (!response.Success) return false; // 轉換資料 dynamic dataObj = response.Data; if (dataObj == null) return false; _classesRepo.DeleteAll(); // 插入資料 foreach (var item in dataObj) { try { // 轉換為本地模型 var apiModel = (ClassesItem)item; var localItem = LocalClassesItem.ConvertFromApiModel(apiModel); // 檢查是否已存在 var existing = _classesRepo.GetById(localItem.ID); if (existing != null) { _classesRepo.Update(localItem); } else { _classesRepo.Insert(localItem); } } catch { // 忽略單筆資料錯誤,繼續同步其他資料 } } return true; } catch (Exception ex) { throw new Exception($"同步 Classes 資料失敗:{ex.Message}", ex); } } /// /// 同步 Classes 資料(同步版本) /// public bool SyncClassesFromApi() { try { // 從 API 查詢資料 var response = ClassesService.SearchClasses(); if (!response.Success) return false; // 轉換資料 dynamic dataObj = response.Data; if (dataObj == null) return false; _classesRepo.DeleteAll(); // 插入資料 foreach (var item in dataObj) { try { // 轉換為本地模型 var apiModel = (ClassesItem)item; var localItem = LocalClassesItem.ConvertFromApiModel(apiModel); // 檢查是否已存在 var existing = _classesRepo.GetById(localItem.ID); if (existing != null) { _classesRepo.Update(localItem); } else { _classesRepo.Insert(localItem); } } catch { // 忽略單筆資料錯誤,繼續同步其他資料 } } return true; } catch (Exception ex) { throw new Exception($"同步 Classes 資料失敗:{ex.Message}", ex); } } /// /// 同步 SignUps 資料(從 API 到本地) /// public async Task SyncSignUpsFromApiAsync(int courseID, int pageIndex, int pageSize) { try { // 從 API 查詢資料 var response = await SignUpService.SearchSignUpsAsync(pageIndex, pageSize, courseID); if (!response.Success) return false; // 轉換資料 dynamic dataObj = response.Data; if (dataObj == null) return false; // 如果第一頁,先清除該課程的本地資料 if (pageIndex == 1) { var existingList = _signUpsRepo.GetByCourseID(courseID); foreach (var item in existingList) { _signUpsRepo.Delete(item.ID); } } // 插入資料 foreach (var item in dataObj) { try { // 轉換為本地模型 var apiModel = (SignUpItem)item; var localItem = LocalSignUpItem.ConvertFromApiModel(apiModel); // 檢查是否已存在 var existing = _signUpsRepo.GetById(localItem.ID); if (existing != null) { _signUpsRepo.Update(localItem); } else { _signUpsRepo.Insert(localItem); } } catch { // 忽略單筆資料錯誤,繼續同步其他資料 } } return true; } catch (Exception ex) { throw new Exception($"同步 SignUps 資料失敗:{ex.Message}", ex); } } /// /// 同步 SignUps 資料(同步版本) /// public bool SyncSignUpsFromApi(int courseID, int pageIndex, int pageSize) { try { // 從 API 查詢資料 var response = SignUpService.SearchSignUps(pageIndex, pageSize, courseID); if (!response.Success) return false; // 轉換資料 dynamic dataObj = response.Data; if (dataObj == null) return false; // 如果第一頁,先清除該課程的本地資料 if (pageIndex == 1) { var existingList = _signUpsRepo.GetByCourseID(courseID); foreach (var item in existingList) { _signUpsRepo.Delete(item.ID); } } // 插入資料 foreach (var item in dataObj) { try { // 轉換為本地模型 var apiModel = (SignUpItem)item; var localItem = LocalSignUpItem.ConvertFromApiModel(apiModel); // 檢查是否已存在 var existing = _signUpsRepo.GetById(localItem.ID); if (existing != null) { _signUpsRepo.Update(localItem); } else { _signUpsRepo.Insert(localItem); } } catch { // 忽略單筆資料錯誤,繼續同步其他資料 } } return true; } catch (Exception ex) { throw new Exception($"同步 SignUps 資料失敗:{ex.Message}", ex); } } /// /// 上傳本地 SignUps 簽到簽退資料到 API /// public async Task UploadSignUpsToApiAsync(int courseID) { try { var localItems = _signUpsRepo.GetByCourseID(courseID); if (localItems.Count == 0) return true; // 轉換為 API 模型 var apiItems = new List(); foreach (var item in localItems) { apiItems.Add(LocalSignUpItem.ConvertToApiModel(item)); } // 上傳到 API var response = await SignUpService.UploadSignUpsAsync(courseID, apiItems); return response.Success; } catch (Exception ex) { throw new Exception($"上傳 SignUps 資料失敗:{ex.Message}", ex); } } /// /// 上傳本地 SignUps 簽到簽退資料到 API(同步版本) /// public bool UploadSignUpsToApi(int courseID) { try { var localItems = _signUpsRepo.GetByCourseID(courseID); if (localItems.Count == 0) return true; // 轉換為 API 模型 var apiItems = new List(); foreach (var item in localItems) { apiItems.Add(LocalSignUpItem.ConvertToApiModel(item)); } // 上傳到 API var response = SignUpService.UploadSignUps(courseID, apiItems); return response.Success; } catch (Exception ex) { throw new Exception($"上傳 SignUps 資料失敗:{ex.Message}", ex); } } /// /// 清除所有本地資料 /// public void ClearAllLocalData() { try { DatabaseService.Instance.ClearAllTables(); } catch (Exception ex) { throw new Exception($"清除本地資料失敗:{ex.Message}", ex); } } /// /// 取得 Classes Repository /// public ClassesRepository GetClassesRepository() { return _classesRepo; } /// /// 取得 SignUps Repository /// public SignUpsRepository GetSignUpsRepository() { return _signUpsRepo; } } }