346 lines
11 KiB
C#
346 lines
11 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using 報到系統客戶端.Data.Models;
|
|
using 報到系統客戶端.Data.Repositories;
|
|
using 報到系統客戶端.Models;
|
|
using 報到系統客戶端.Services;
|
|
|
|
namespace 報到系統客戶端.Data.Services
|
|
{
|
|
/// <summary>
|
|
/// 資料同步服務
|
|
/// 協調後端 API 和本地 SQLite 資料庫的資料同步
|
|
/// </summary>
|
|
public class DataSyncService
|
|
{
|
|
private readonly ClassesRepository _classesRepo;
|
|
private readonly SignUpsRepository _signUpsRepo;
|
|
|
|
public DataSyncService()
|
|
{
|
|
_classesRepo = new ClassesRepository();
|
|
_signUpsRepo = new SignUpsRepository();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 同步 Classes 資料(從 API 到本地)
|
|
/// </summary>
|
|
public async Task<bool> 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);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 同步 Classes 資料(同步版本)
|
|
/// </summary>
|
|
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);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 同步 SignUps 資料(從 API 到本地)
|
|
/// </summary>
|
|
public async Task<bool> 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);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 同步 SignUps 資料(同步版本)
|
|
/// </summary>
|
|
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);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 上傳本地 SignUps 簽到簽退資料到 API
|
|
/// </summary>
|
|
public async Task<bool> UploadSignUpsToApiAsync(int courseID)
|
|
{
|
|
try
|
|
{
|
|
var localItems = _signUpsRepo.GetByCourseID(courseID);
|
|
if (localItems.Count == 0)
|
|
return true;
|
|
|
|
// 轉換為 API 模型
|
|
var apiItems = new List<SignUpItem>();
|
|
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);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 上傳本地 SignUps 簽到簽退資料到 API(同步版本)
|
|
/// </summary>
|
|
public bool UploadSignUpsToApi(int courseID)
|
|
{
|
|
try
|
|
{
|
|
var localItems = _signUpsRepo.GetByCourseID(courseID);
|
|
if (localItems.Count == 0)
|
|
return true;
|
|
|
|
// 轉換為 API 模型
|
|
var apiItems = new List<SignUpItem>();
|
|
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);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 清除所有本地資料
|
|
/// </summary>
|
|
public void ClearAllLocalData()
|
|
{
|
|
try
|
|
{
|
|
DatabaseService.Instance.ClearAllTables();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new Exception($"清除本地資料失敗:{ex.Message}", ex);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 取得 Classes Repository
|
|
/// </summary>
|
|
public ClassesRepository GetClassesRepository()
|
|
{
|
|
return _classesRepo;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 取得 SignUps Repository
|
|
/// </summary>
|
|
public SignUpsRepository GetSignUpsRepository()
|
|
{
|
|
return _signUpsRepo;
|
|
}
|
|
}
|
|
}
|