chore: 首次簽入 Thinkyu ASP.NET 專案
- 加入 Visual Studio / ASP.NET .gitignore - 排除建置輸出、IDE 設定、NuGet packages、大型 MSI 安裝檔
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace 報到系統客戶端.Data.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 本地 BPSN 表資料項目
|
||||
/// 對應後端 DAC_BPSN.cs 的 BPSNItem
|
||||
/// </summary>
|
||||
public class LocalBPSNItem
|
||||
{
|
||||
[JsonProperty("BPENO")]
|
||||
public string BPENO { get; set; }
|
||||
|
||||
[JsonProperty("BPNME")]
|
||||
public string BPNME { get; set; }
|
||||
|
||||
[JsonProperty("BPAWD")]
|
||||
public string BPAWD { get; set; }
|
||||
|
||||
[JsonProperty("Is系統管理群組")]
|
||||
public bool Is系統管理群組 { get; set; }
|
||||
|
||||
[JsonProperty("Is客戶管理群組")]
|
||||
public bool Is客戶管理群組 { get; set; }
|
||||
|
||||
[JsonProperty("Is現場工作群組")]
|
||||
public bool Is現場工作群組 { get; set; }
|
||||
|
||||
[JsonProperty("Is查詢群組")]
|
||||
public bool Is查詢群組 { get; set; }
|
||||
|
||||
[JsonProperty("CreatedAt")]
|
||||
public DateTime CreatedAt { get; set; }
|
||||
|
||||
[JsonProperty("UpdatedAt")]
|
||||
public DateTime UpdatedAt { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace 報到系統客戶端.Data.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 本地 CheckIn 表資料項目
|
||||
/// 簽到簽退紀錄表
|
||||
/// </summary>
|
||||
public class LocalCheckInItem
|
||||
{
|
||||
[JsonProperty("ID")]
|
||||
public int ID { get; set; }
|
||||
|
||||
[JsonProperty("CourseID")]
|
||||
public int CourseID { get; set; }
|
||||
|
||||
[JsonProperty("Name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[JsonProperty("Mobile")]
|
||||
public string Mobile { get; set; }
|
||||
|
||||
[JsonProperty("SignUpType")]
|
||||
public string SignUpType { get; set; }
|
||||
|
||||
[JsonProperty("IDNumber")]
|
||||
public string IDNumber { get; set; }
|
||||
|
||||
[JsonProperty("IDType")]
|
||||
public string IDType { get; set; }
|
||||
|
||||
[JsonProperty("MealType")]
|
||||
public string MealType { get; set; }
|
||||
|
||||
[JsonProperty("Email")]
|
||||
public string Email { get; set; }
|
||||
|
||||
[JsonProperty("LossJobTimes")]
|
||||
public int? LossJobTimes { get; set; }
|
||||
|
||||
[JsonProperty("Gender")]
|
||||
public string Gender { get; set; }
|
||||
|
||||
[JsonProperty("AgreementStatus")]
|
||||
public string AgreementStatus { get; set; }
|
||||
|
||||
[JsonProperty("CheckInType")]
|
||||
public string CheckInType { get; set; }
|
||||
|
||||
[JsonProperty("CheckInTime")]
|
||||
public string CheckInTime { get; set; }
|
||||
|
||||
[JsonProperty("UploadTime")]
|
||||
public DateTime? UploadTime { get; set; }
|
||||
|
||||
[JsonProperty("CreatedAt")]
|
||||
public DateTime CreatedAt { get; set; }
|
||||
|
||||
[JsonProperty("UpdatedAt")]
|
||||
public DateTime UpdatedAt { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace 報到系統客戶端.Data.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 本地 Classes 表資料項目
|
||||
/// 對應後端 DAC_Classes1.cs 的 ClassesItem
|
||||
/// </summary>
|
||||
public class LocalClassesItem
|
||||
{
|
||||
[JsonProperty("ID")]
|
||||
public int ID { get; set; }
|
||||
|
||||
[JsonProperty("CourseCode")]
|
||||
public string CourseCode { get; set; }
|
||||
|
||||
[JsonProperty("CourseName")]
|
||||
public string CourseName { get; set; }
|
||||
|
||||
[JsonProperty("CourseDate")]
|
||||
public string CourseDate { get; set; }
|
||||
|
||||
[JsonProperty("CourseLocation")]
|
||||
public string CourseLocation { get; set; }
|
||||
|
||||
[JsonProperty("NotificationTemplate")]
|
||||
public string NotificationTemplate { get; set; }
|
||||
|
||||
[JsonProperty("AgreedTerms")]
|
||||
public string AgreedTerms { get; set; }
|
||||
|
||||
[JsonProperty("StartTime")]
|
||||
public string StartTime { get; set; }
|
||||
|
||||
[JsonProperty("EndTime")]
|
||||
public string EndTime { get; set; }
|
||||
|
||||
[JsonProperty("CreatedAt")]
|
||||
public DateTime CreatedAt { get; set; }
|
||||
|
||||
[JsonProperty("UpdatedAt")]
|
||||
public DateTime UpdatedAt { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public string DisplayText {
|
||||
get {
|
||||
return string.Format("[{0}] ({1:yyyy-MM-dd} {2}) {3} ", CourseCode, CourseDate, StartTime, CourseName);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 從後端 API 模型轉換
|
||||
/// </summary>
|
||||
public static LocalClassesItem ConvertFromApiModel(報到系統客戶端.Models.ClassesItem apiModel)
|
||||
{
|
||||
if (apiModel == null) return null;
|
||||
|
||||
return new LocalClassesItem
|
||||
{
|
||||
ID = apiModel.ID,
|
||||
CourseCode = apiModel.CourseCode,
|
||||
CourseName = apiModel.CourseName,
|
||||
CourseDate = apiModel.CourseDate.ToString("yyyy-MM-dd"),
|
||||
CourseLocation = apiModel.CourseLocation,
|
||||
NotificationTemplate = apiModel.NotificationTemplate,
|
||||
AgreedTerms = apiModel.AgreedTerms,
|
||||
StartTime = apiModel.StartTime,
|
||||
EndTime = apiModel.EndTime,
|
||||
CreatedAt = DateTime.Now,
|
||||
UpdatedAt = DateTime.Now
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace 報到系統客戶端.Data.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 本地 SignUps 表資料項目
|
||||
/// 對應後端 DAC_SignUp1.cs 的 SignUpItem
|
||||
/// </summary>
|
||||
public class LocalSignUpItem
|
||||
{
|
||||
[JsonProperty("ID")]
|
||||
public int ID { get; set; }
|
||||
|
||||
[JsonProperty("CourseID")]
|
||||
public int CourseID { get; set; }
|
||||
|
||||
[JsonProperty("SeqNo")]
|
||||
public int SeqNo { get; set; }
|
||||
|
||||
[JsonProperty("Name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[JsonProperty("Mobile")]
|
||||
public string Mobile { get; set; }
|
||||
|
||||
[JsonProperty("QRCode")]
|
||||
public string QRCode { get; set; }
|
||||
|
||||
[JsonProperty("SignUpType")]
|
||||
public string SignUpType { get; set; }
|
||||
|
||||
[JsonProperty("IDNumber")]
|
||||
public string IDNumber { get; set; }
|
||||
|
||||
[JsonProperty("IDType")]
|
||||
public string IDType { get; set; }
|
||||
|
||||
[JsonProperty("MealType")]
|
||||
public string MealType { get; set; }
|
||||
|
||||
[JsonProperty("Email")]
|
||||
public string Email { get; set; }
|
||||
|
||||
[JsonProperty("LossJobTimes")]
|
||||
public int? LossJobTimes { get; set; }
|
||||
|
||||
[JsonProperty("Gender")]
|
||||
public string Gender { get; set; }
|
||||
|
||||
[JsonProperty("AgreementStatus")]
|
||||
public string AgreementStatus { get; set; }
|
||||
|
||||
[JsonProperty("CheckInTime")]
|
||||
public string CheckInTime { get; set; }
|
||||
|
||||
[JsonProperty("CheckOutTime")]
|
||||
public string CheckOutTime { get; set; }
|
||||
|
||||
[JsonProperty("CreatedAt")]
|
||||
public DateTime CreatedAt { get; set; }
|
||||
|
||||
[JsonProperty("UpdatedAt")]
|
||||
public DateTime UpdatedAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 轉換為後端 API 使用的模型
|
||||
/// </summary>
|
||||
public static 報到系統客戶端.Models.SignUpItem ConvertToApiModel(LocalSignUpItem local)
|
||||
{
|
||||
if (local == null) return null;
|
||||
|
||||
return new 報到系統客戶端.Models.SignUpItem
|
||||
{
|
||||
ID = local.ID,
|
||||
CourseID = local.CourseID,
|
||||
Name = local.Name,
|
||||
Mobile = local.Mobile,
|
||||
QRCode = local.QRCode,
|
||||
SignUpType = local.SignUpType,
|
||||
Email = local.Email,
|
||||
LossJobTimes = local.LossJobTimes,
|
||||
Gender = local.Gender,
|
||||
AgreementStatus = local.AgreementStatus,
|
||||
CheckInTime = local.CheckInTime,
|
||||
CheckOutTime = local.CheckOutTime
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 從後端 API 模型轉換
|
||||
/// </summary>
|
||||
public static LocalSignUpItem ConvertFromApiModel(報到系統客戶端.Models.SignUpItem apiModel)
|
||||
{
|
||||
if (apiModel == null) return null;
|
||||
|
||||
return new LocalSignUpItem
|
||||
{
|
||||
ID = apiModel.ID,
|
||||
CourseID = apiModel.CourseID,
|
||||
SeqNo = apiModel.SeqNo,
|
||||
Name = apiModel.Name,
|
||||
Mobile = apiModel.Mobile,
|
||||
QRCode = apiModel.QRCode,
|
||||
SignUpType = apiModel.SignUpType,
|
||||
IDNumber = apiModel.IDNumber,
|
||||
IDType = apiModel.IDType,
|
||||
MealType = apiModel.MealType,
|
||||
Email = apiModel.Email,
|
||||
LossJobTimes = apiModel.LossJobTimes,
|
||||
Gender = apiModel.Gender,
|
||||
AgreementStatus = apiModel.AgreementStatus,
|
||||
CheckInTime = apiModel.CheckInTime,
|
||||
CheckOutTime = apiModel.CheckOutTime,
|
||||
CreatedAt = DateTime.Now,
|
||||
UpdatedAt = DateTime.Now
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,359 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using 報到系統客戶端.Data.Models;
|
||||
|
||||
namespace 報到系統客戶端.Data.Repositories
|
||||
{
|
||||
/// <summary>
|
||||
/// BPSN 本地資料庫操作類別
|
||||
/// 對應員工資料
|
||||
/// </summary>
|
||||
public class BPSNRepository
|
||||
{
|
||||
private readonly DatabaseService _dbService;
|
||||
|
||||
public BPSNRepository()
|
||||
{
|
||||
_dbService = DatabaseService.Instance;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 新增一筆 BPSN 資料
|
||||
/// </summary>
|
||||
public bool Insert(LocalBPSNItem item)
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
string sql = @"
|
||||
INSERT OR REPLACE INTO BPSN
|
||||
(BPENO, BPNME, BPAWD, Is系統管理群組, Is客戶管理群組, Is現場工作群組, Is查詢群組, CreatedAt, UpdatedAt)
|
||||
VALUES (@BPENO, @BPNME, @BPAWD, @Is系統管理群組, @Is客戶管理群組, @Is現場工作群組, @Is查詢群組, @CreatedAt, @UpdatedAt)
|
||||
";
|
||||
|
||||
using (SqliteCommand cmd = new SqliteCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@BPENO", item.BPENO ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@BPNME", item.BPNME ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@BPAWD", item.BPAWD ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@Is系統管理群組", item.Is系統管理群組 ? 1 : 0);
|
||||
cmd.Parameters.AddWithValue("@Is客戶管理群組", item.Is客戶管理群組 ? 1 : 0);
|
||||
cmd.Parameters.AddWithValue("@Is現場工作群組", item.Is現場工作群組 ? 1 : 0);
|
||||
cmd.Parameters.AddWithValue("@Is查詢群組", item.Is查詢群組 ? 1 : 0);
|
||||
cmd.Parameters.AddWithValue("@CreatedAt", DateTime.Now);
|
||||
cmd.Parameters.AddWithValue("@UpdatedAt", DateTime.Now);
|
||||
|
||||
return cmd.ExecuteNonQuery() > 0;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"新增 BPSN 資料失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 批量新增 BPSN 資料
|
||||
/// </summary>
|
||||
public void InsertBatch(List<LocalBPSNItem> items)
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
|
||||
using (SqliteTransaction transaction = conn.BeginTransaction())
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (LocalBPSNItem item in items)
|
||||
{
|
||||
string sql = @"
|
||||
INSERT OR REPLACE INTO BPSN
|
||||
(BPENO, BPNME, BPAWD, Is系統管理群組, Is客戶管理群組, Is現場工作群組, Is查詢群組, CreatedAt, UpdatedAt)
|
||||
VALUES (@BPENO, @BPNME, @BPAWD, @Is系統管理群組, @Is客戶管理群組, @Is現場工作群組, @Is查詢群組, @CreatedAt, @UpdatedAt)
|
||||
";
|
||||
|
||||
using (SqliteCommand cmd = new SqliteCommand(sql, conn))
|
||||
{
|
||||
cmd.Transaction = transaction;
|
||||
cmd.Parameters.AddWithValue("@BPENO", item.BPENO ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@BPNME", item.BPNME ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@BPAWD", item.BPAWD ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@Is系統管理群組", item.Is系統管理群組 ? 1 : 0);
|
||||
cmd.Parameters.AddWithValue("@Is客戶管理群組", item.Is客戶管理群組 ? 1 : 0);
|
||||
cmd.Parameters.AddWithValue("@Is現場工作群組", item.Is現場工作群組 ? 1 : 0);
|
||||
cmd.Parameters.AddWithValue("@Is查詢群組", item.Is查詢群組 ? 1 : 0);
|
||||
cmd.Parameters.AddWithValue("@CreatedAt", DateTime.Now);
|
||||
cmd.Parameters.AddWithValue("@UpdatedAt", DateTime.Now);
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
|
||||
transaction.Commit();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
transaction.Rollback();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"批量新增 BPSN 資料失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新一筆 BPSN 資料
|
||||
/// </summary>
|
||||
public bool Update(LocalBPSNItem item)
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
string sql = @"
|
||||
UPDATE BPSN SET
|
||||
BPNME = @BPNME,
|
||||
BPAWD = @BPAWD,
|
||||
Is系統管理群組 = @Is系統管理群組,
|
||||
Is客戶管理群組 = @Is客戶管理群組,
|
||||
Is現場工作群組 = @Is現場工作群組,
|
||||
Is查詢群組 = @Is查詢群組,
|
||||
UpdatedAt = @UpdatedAt
|
||||
WHERE BPENO = @BPENO
|
||||
";
|
||||
|
||||
using (SqliteCommand cmd = new SqliteCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@BPENO", item.BPENO ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@BPNME", item.BPNME ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@BPAWD", item.BPAWD ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@Is系統管理群組", item.Is系統管理群組 ? 1 : 0);
|
||||
cmd.Parameters.AddWithValue("@Is客戶管理群組", item.Is客戶管理群組 ? 1 : 0);
|
||||
cmd.Parameters.AddWithValue("@Is現場工作群組", item.Is現場工作群組 ? 1 : 0);
|
||||
cmd.Parameters.AddWithValue("@Is查詢群組", item.Is查詢群組 ? 1 : 0);
|
||||
cmd.Parameters.AddWithValue("@UpdatedAt", DateTime.Now);
|
||||
|
||||
return cmd.ExecuteNonQuery() > 0;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"更新 BPSN 資料失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 刪除一筆 BPSN 資料
|
||||
/// </summary>
|
||||
public bool Delete(string bpeno)
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
string sql = "DELETE FROM BPSN WHERE BPENO = @BPENO";
|
||||
|
||||
using (SqliteCommand cmd = new SqliteCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@BPENO", bpeno ?? (object)DBNull.Value);
|
||||
return cmd.ExecuteNonQuery() > 0;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"刪除 BPSN 資料失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查詢所有 BPSN 資料
|
||||
/// </summary>
|
||||
public List<LocalBPSNItem> GetAll()
|
||||
{
|
||||
return Query("SELECT * FROM BPSN ORDER BY BPENO ASC");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查詢單筆 BPSN 資料
|
||||
/// </summary>
|
||||
public LocalBPSNItem GetByBPENO(string bpeno)
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
string sql = "SELECT * FROM BPSN WHERE BPENO = @BPENO LIMIT 1";
|
||||
|
||||
using (SqliteCommand cmd = new SqliteCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@BPENO", bpeno ?? (object)DBNull.Value);
|
||||
|
||||
using (SqliteDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
return ReadBPSNItem(reader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"查詢 BPSN 資料失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 條件查詢 BPSN 資料(分頁)
|
||||
/// </summary>
|
||||
public List<LocalBPSNItem> GetByCondition(int pageIndex, int pageSize, string bpeno = "", string bpnme = "")
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
string sql = "SELECT * FROM BPSN WHERE 1=1";
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(bpeno))
|
||||
sql += " AND BPENO LIKE '%' || @BPENO || '%'";
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(bpnme))
|
||||
sql += " AND BPNME LIKE '%' || @BPNME || '%'";
|
||||
|
||||
sql += " ORDER BY BPENO ASC LIMIT @PageSize OFFSET @Offset";
|
||||
|
||||
List<LocalBPSNItem> result = new List<LocalBPSNItem>();
|
||||
|
||||
using (SqliteCommand cmd = new SqliteCommand(sql, conn))
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(bpeno))
|
||||
cmd.Parameters.AddWithValue("@BPENO", bpeno);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(bpnme))
|
||||
cmd.Parameters.AddWithValue("@BPNME", bpnme);
|
||||
|
||||
cmd.Parameters.AddWithValue("@PageSize", pageSize);
|
||||
cmd.Parameters.AddWithValue("@Offset", (pageIndex - 1) * pageSize);
|
||||
|
||||
using (SqliteDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
result.Add(ReadBPSNItem(reader));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"查詢 BPSN 資料失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查詢 BPSN 資料總數
|
||||
/// </summary>
|
||||
public int GetCount(string bpeno = "", string bpnme = "")
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
string sql = "SELECT COUNT(*) FROM BPSN WHERE 1=1";
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(bpeno))
|
||||
sql += " AND BPENO LIKE '%' || @BPENO || '%'";
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(bpnme))
|
||||
sql += " AND BPNME LIKE '%' || @BPNME || '%'";
|
||||
|
||||
using (SqliteCommand cmd = new SqliteCommand(sql, conn))
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(bpeno))
|
||||
cmd.Parameters.AddWithValue("@BPENO", bpeno);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(bpnme))
|
||||
cmd.Parameters.AddWithValue("@BPNME", bpnme);
|
||||
|
||||
return Convert.ToInt32(cmd.ExecuteScalar());
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"統計 BPSN 資料失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清除所有 BPSN 資料
|
||||
/// </summary>
|
||||
public void DeleteAll()
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
using (SqliteCommand cmd = new SqliteCommand("DELETE FROM BPSN", conn))
|
||||
{
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"清除 BPSN 資料失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 私用方法 - 執行查詢
|
||||
/// </summary>
|
||||
private List<LocalBPSNItem> Query(string sql)
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
List<LocalBPSNItem> result = new List<LocalBPSNItem>();
|
||||
|
||||
using (SqliteCommand cmd = new SqliteCommand(sql, conn))
|
||||
{
|
||||
using (SqliteDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
result.Add(ReadBPSNItem(reader));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"查詢 BPSN 失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 私用方法 - 讀取資料列
|
||||
/// </summary>
|
||||
private LocalBPSNItem ReadBPSNItem(SqliteDataReader reader)
|
||||
{
|
||||
return new LocalBPSNItem
|
||||
{
|
||||
BPENO = reader.IsDBNull(reader.GetOrdinal("BPENO")) ? null : reader.GetString(reader.GetOrdinal("BPENO")),
|
||||
BPNME = reader.IsDBNull(reader.GetOrdinal("BPNME")) ? null : reader.GetString(reader.GetOrdinal("BPNME")),
|
||||
BPAWD = reader.IsDBNull(reader.GetOrdinal("BPAWD")) ? null : reader.GetString(reader.GetOrdinal("BPAWD")),
|
||||
Is系統管理群組 = reader.GetInt32(reader.GetOrdinal("Is系統管理群組")) != 0,
|
||||
Is客戶管理群組 = reader.GetInt32(reader.GetOrdinal("Is客戶管理群組")) != 0,
|
||||
Is現場工作群組 = reader.GetInt32(reader.GetOrdinal("Is現場工作群組")) != 0,
|
||||
Is查詢群組 = reader.GetInt32(reader.GetOrdinal("Is查詢群組")) != 0,
|
||||
CreatedAt = reader.GetDateTime(reader.GetOrdinal("CreatedAt")),
|
||||
UpdatedAt = reader.GetDateTime(reader.GetOrdinal("UpdatedAt"))
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,560 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using 報到系統客戶端.Data.Models;
|
||||
|
||||
namespace 報到系統客戶端.Data.Repositories
|
||||
{
|
||||
/// <summary>
|
||||
/// CheckIn 本地資料庫操作類別
|
||||
/// 簽到簽退紀錄表
|
||||
/// </summary>
|
||||
public class CheckInRepository
|
||||
{
|
||||
private readonly DatabaseService _dbService;
|
||||
|
||||
public CheckInRepository()
|
||||
{
|
||||
_dbService = DatabaseService.Instance;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 新增一筆 CheckIn 資料
|
||||
/// </summary>
|
||||
public int Insert(LocalCheckInItem item)
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
string sql = @"
|
||||
INSERT INTO CheckIn
|
||||
(CourseID, Name, Mobile, SignUpType, IDNumber, IDType, MealType, Email, LossJobTimes, Gender, AgreementStatus, CheckInType, CheckInTime, UploadTime, CreatedAt, UpdatedAt)
|
||||
VALUES (@CourseID, @Name, @Mobile, @SignUpType, @IDNumber, @IDType, @MealType, @Email, @LossJobTimes, @Gender, @AgreementStatus,@CheckInType, @CheckInTime, @UploadTime, @CreatedAt, @UpdatedAt)
|
||||
";
|
||||
|
||||
using (SqliteCommand cmd = new SqliteCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@CourseID", item.CourseID);
|
||||
cmd.Parameters.AddWithValue("@Name", item.Name ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@Mobile", item.Mobile ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@SignUpType", item.SignUpType ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@IDNumber", item.IDNumber ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@IDType", item.IDType ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@MealType", item.MealType ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@Email", item.Email ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@LossJobTimes", item.LossJobTimes ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@Gender", item.Gender ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@AgreementStatus", item.AgreementStatus ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@CheckInType", item.CheckInType ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@CheckInTime", item.CheckInTime);
|
||||
cmd.Parameters.AddWithValue("@UploadTime", item.UploadTime ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@CreatedAt", DateTime.Now);
|
||||
cmd.Parameters.AddWithValue("@UpdatedAt", DateTime.Now);
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
// 取得新增資料的 ID
|
||||
using (SqliteCommand cmd = new SqliteCommand("SELECT last_insert_rowid()", conn))
|
||||
{
|
||||
return Convert.ToInt32(cmd.ExecuteScalar());
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"新增 CheckIn 資料失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 批量新增 CheckIn 資料
|
||||
/// </summary>
|
||||
public void InsertBatch(List<LocalCheckInItem> items)
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
|
||||
using (SqliteTransaction transaction = conn.BeginTransaction())
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (LocalCheckInItem item in items)
|
||||
{
|
||||
string sql = @"
|
||||
INSERT INTO CheckIn
|
||||
(CourseID, Name, Mobile, SignUpType, IDNumber, IDType, MealType, Email, LossJobTimes, Gender, AgreementStatus, CheckInType, CheckInTime, UploadTime, CreatedAt, UpdatedAt)
|
||||
VALUES (@CourseID, @Name, @Mobile, @SignUpType, @IDNumber, @IDType, @MealType, @Email, @LossJobTimes, @Gender, @AgreementStatus, @CheckInType, @CheckInTime, @UploadTime, @CreatedAt, @UpdatedAt)
|
||||
";
|
||||
|
||||
using (SqliteCommand cmd = new SqliteCommand(sql, conn))
|
||||
{
|
||||
cmd.Transaction = transaction;
|
||||
cmd.Parameters.AddWithValue("@CourseID", item.CourseID);
|
||||
cmd.Parameters.AddWithValue("@Name", item.Name ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@Mobile", item.Mobile ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@SignUpType", item.SignUpType ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@IDNumber", item.IDNumber ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@IDType", item.IDType ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@MealType", item.MealType ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@Email", item.Email ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@LossJobTimes", item.LossJobTimes ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@Gender", item.Gender ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@AgreementStatus", item.AgreementStatus ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@CheckInType", item.CheckInType ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@CheckInTime", item.CheckInTime);
|
||||
cmd.Parameters.AddWithValue("@UploadTime", item.UploadTime ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@CreatedAt", DateTime.Now);
|
||||
cmd.Parameters.AddWithValue("@UpdatedAt", DateTime.Now);
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
|
||||
transaction.Commit();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
transaction.Rollback();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"批量新增 CheckIn 資料失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新一筆 CheckIn 資料
|
||||
/// </summary>
|
||||
public bool Update(LocalCheckInItem item)
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
string sql = @"
|
||||
UPDATE CheckIn SET
|
||||
CourseID = @CourseID,
|
||||
Name = @Name,
|
||||
Mobile = @Mobile,
|
||||
SignUpType = @SignUpType,
|
||||
IDNumber = @IDNumber,
|
||||
IDType = @IDType,
|
||||
MealType = @MealType,
|
||||
Email = @Email,
|
||||
LossJobTimes = @LossJobTimes,
|
||||
Gender = @Gender,
|
||||
AgreementStatus = @AgreementStatus,
|
||||
CheckInType = @CheckInType,
|
||||
CheckInTime = @CheckInTime,
|
||||
UploadTime = @UploadTime,
|
||||
UpdatedAt = @UpdatedAt
|
||||
WHERE ID = @ID
|
||||
";
|
||||
|
||||
using (SqliteCommand cmd = new SqliteCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@ID", item.ID);
|
||||
cmd.Parameters.AddWithValue("@CourseID", item.CourseID);
|
||||
cmd.Parameters.AddWithValue("@Name", item.Name ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@Mobile", item.Mobile ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@SignUpType", item.SignUpType ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@IDNumber", item.IDNumber ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@IDType", item.IDType ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@MealType", item.MealType ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@Email", item.Email ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@LossJobTimes", item.LossJobTimes ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@Gender", item.Gender ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@AgreementStatus", item.AgreementStatus ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@CheckInType", item.CheckInType ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@CheckInTime", item.CheckInTime);
|
||||
cmd.Parameters.AddWithValue("@UploadTime", item.UploadTime ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@UpdatedAt", DateTime.Now);
|
||||
|
||||
return cmd.ExecuteNonQuery() > 0;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"更新 CheckIn 資料失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 刪除一筆 CheckIn 資料
|
||||
/// </summary>
|
||||
public bool Delete(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
string sql = "DELETE FROM CheckIn WHERE ID = @ID";
|
||||
|
||||
using (SqliteCommand cmd = new SqliteCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@ID", id);
|
||||
return cmd.ExecuteNonQuery() > 0;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"刪除 CheckIn 資料失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查詢所有 CheckIn 資料
|
||||
/// </summary>
|
||||
public List<LocalCheckInItem> GetAll()
|
||||
{
|
||||
return Query("SELECT * FROM CheckIn ORDER BY CheckInTime DESC");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查詢單筆 CheckIn 資料
|
||||
/// </summary>
|
||||
public LocalCheckInItem GetById(int id)
|
||||
{
|
||||
var result = Query($"SELECT * FROM CheckIn WHERE ID = {id}");
|
||||
return result.Count > 0 ? result[0] : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 按課程 ID 查詢簽到記錄
|
||||
/// </summary>
|
||||
public List<LocalCheckInItem> GetByCourseID(int courseID)
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
string sql = "SELECT * FROM CheckIn WHERE CourseID = @CourseID ORDER BY CheckInTime DESC";
|
||||
|
||||
List<LocalCheckInItem> result = new List<LocalCheckInItem>();
|
||||
|
||||
using (SqliteCommand cmd = new SqliteCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@CourseID", courseID);
|
||||
|
||||
using (SqliteDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
result.Add(ReadCheckInItem(reader));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"按課程 ID 查詢簽到記錄失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 按課程和姓名手機查詢簽到記錄
|
||||
/// </summary>
|
||||
public List<LocalCheckInItem> GetByCourseNameMobile(int courseID, string name, string mobile)
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
string sql = "SELECT * FROM CheckIn WHERE CourseID = @CourseID AND Name = @Name AND Mobile = @Mobile ORDER BY CheckInTime DESC";
|
||||
|
||||
List<LocalCheckInItem> result = new List<LocalCheckInItem>();
|
||||
|
||||
using (SqliteCommand cmd = new SqliteCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@CourseID", courseID);
|
||||
cmd.Parameters.AddWithValue("@Name", name ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@Mobile", mobile ?? (object)DBNull.Value);
|
||||
|
||||
using (SqliteDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
result.Add(ReadCheckInItem(reader));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"按課程和姓名手機查詢簽到記錄失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 條件查詢 CheckIn 資料(分頁)
|
||||
/// </summary>
|
||||
public List<LocalCheckInItem> GetByCondition(int pageIndex, int pageSize, int courseID = 0, string name = "", string mobile = "", string checkInType = "", DateTime? startDate = null, DateTime? endDate = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
string sql = "SELECT * FROM CheckIn WHERE 1=1";
|
||||
|
||||
if (courseID > 0)
|
||||
sql += " AND CourseID = @CourseID";
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(name))
|
||||
sql += " AND Name LIKE '%' || @Name || '%'";
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(mobile))
|
||||
sql += " AND Mobile LIKE '%' || @Mobile || '%'";
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(checkInType))
|
||||
sql += " AND CheckInType = @CheckInType";
|
||||
|
||||
if (startDate.HasValue && endDate.HasValue)
|
||||
sql += " AND CheckInTime >= @StartDate AND CheckInTime <= @EndDate";
|
||||
else if (startDate.HasValue)
|
||||
sql += " AND CheckInTime >= @StartDate";
|
||||
else if (endDate.HasValue)
|
||||
sql += " AND CheckInTime <= @EndDate";
|
||||
|
||||
sql += " ORDER BY CheckInTime DESC LIMIT @PageSize OFFSET @Offset";
|
||||
|
||||
List<LocalCheckInItem> result = new List<LocalCheckInItem>();
|
||||
|
||||
using (SqliteCommand cmd = new SqliteCommand(sql, conn))
|
||||
{
|
||||
if (courseID > 0)
|
||||
cmd.Parameters.AddWithValue("@CourseID", courseID);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(name))
|
||||
cmd.Parameters.AddWithValue("@Name", name);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(mobile))
|
||||
cmd.Parameters.AddWithValue("@Mobile", mobile);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(checkInType))
|
||||
cmd.Parameters.AddWithValue("@CheckInType", checkInType);
|
||||
|
||||
if (startDate.HasValue)
|
||||
cmd.Parameters.AddWithValue("@StartDate", startDate.Value);
|
||||
|
||||
if (endDate.HasValue)
|
||||
cmd.Parameters.AddWithValue("@EndDate", endDate.Value);
|
||||
|
||||
cmd.Parameters.AddWithValue("@PageSize", pageSize);
|
||||
cmd.Parameters.AddWithValue("@Offset", (pageIndex - 1) * pageSize);
|
||||
|
||||
using (SqliteDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
result.Add(ReadCheckInItem(reader));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"查詢 CheckIn 資料失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查詢 CheckIn 資料總數
|
||||
/// </summary>
|
||||
public int GetCount(int courseID = 0, string name = "", string mobile = "", string checkInType = "", DateTime? startDate = null, DateTime? endDate = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
string sql = "SELECT COUNT(*) FROM CheckIn WHERE 1=1";
|
||||
|
||||
if (courseID > 0)
|
||||
sql += " AND CourseID = @CourseID";
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(name))
|
||||
sql += " AND Name LIKE '%' || @Name || '%'";
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(mobile))
|
||||
sql += " AND Mobile LIKE '%' || @Mobile || '%'";
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(checkInType))
|
||||
sql += " AND CheckInType = @CheckInType";
|
||||
|
||||
if (startDate.HasValue && endDate.HasValue)
|
||||
sql += " AND CheckInTime >= @StartDate AND CheckInTime <= @EndDate";
|
||||
else if (startDate.HasValue)
|
||||
sql += " AND CheckInTime >= @StartDate";
|
||||
else if (endDate.HasValue)
|
||||
sql += " AND CheckInTime <= @EndDate";
|
||||
|
||||
using (SqliteCommand cmd = new SqliteCommand(sql, conn))
|
||||
{
|
||||
if (courseID > 0)
|
||||
cmd.Parameters.AddWithValue("@CourseID", courseID);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(name))
|
||||
cmd.Parameters.AddWithValue("@Name", name);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(mobile))
|
||||
cmd.Parameters.AddWithValue("@Mobile", mobile);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(checkInType))
|
||||
cmd.Parameters.AddWithValue("@CheckInType", checkInType);
|
||||
|
||||
if (startDate.HasValue)
|
||||
cmd.Parameters.AddWithValue("@StartDate", startDate.Value);
|
||||
|
||||
if (endDate.HasValue)
|
||||
cmd.Parameters.AddWithValue("@EndDate", endDate.Value);
|
||||
|
||||
return Convert.ToInt32(cmd.ExecuteScalar());
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"統計 CheckIn 資料失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清除所有 CheckIn 資料
|
||||
/// </summary>
|
||||
public void DeleteAll()
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
using (SqliteCommand cmd = new SqliteCommand("DELETE FROM CheckIn", conn))
|
||||
{
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"清除 CheckIn 資料失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清除所有 CheckIn 資料
|
||||
/// </summary>
|
||||
public void DeleteByCourseID(int courseID)
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
using (SqliteCommand cmd = new SqliteCommand("DELETE FROM CheckIn WHERE CourseID=@CourseID", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@CourseID", courseID);
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"清除 CheckIn 資料失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 私用方法 - 執行查詢
|
||||
/// </summary>
|
||||
private List<LocalCheckInItem> Query(string sql)
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
List<LocalCheckInItem> result = new List<LocalCheckInItem>();
|
||||
|
||||
using (SqliteCommand cmd = new SqliteCommand(sql, conn))
|
||||
{
|
||||
using (SqliteDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
result.Add(ReadCheckInItem(reader));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"查詢 CheckIn 失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 私用方法 - 讀取資料列
|
||||
/// </summary>
|
||||
private LocalCheckInItem ReadCheckInItem(SqliteDataReader reader)
|
||||
{
|
||||
return new LocalCheckInItem
|
||||
{
|
||||
ID = reader.GetInt32(reader.GetOrdinal("ID")),
|
||||
CourseID = reader.GetInt32(reader.GetOrdinal("CourseID")),
|
||||
Name = reader.IsDBNull(reader.GetOrdinal("Name")) ? null : reader.GetString(reader.GetOrdinal("Name")),
|
||||
Mobile = reader.IsDBNull(reader.GetOrdinal("Mobile")) ? null : reader.GetString(reader.GetOrdinal("Mobile")),
|
||||
SignUpType = reader.IsDBNull(reader.GetOrdinal("SignUpType")) ? null : reader.GetString(reader.GetOrdinal("SignUpType")),
|
||||
IDNumber = reader.IsDBNull(reader.GetOrdinal("IDNumber")) ? null : reader.GetString(reader.GetOrdinal("IDNumber")),
|
||||
IDType = reader.IsDBNull(reader.GetOrdinal("IDType")) ? null : reader.GetString(reader.GetOrdinal("IDType")),
|
||||
MealType = reader.IsDBNull(reader.GetOrdinal("MealType")) ? null : reader.GetString(reader.GetOrdinal("MealType")),
|
||||
Email = reader.IsDBNull(reader.GetOrdinal("Email")) ? null : reader.GetString(reader.GetOrdinal("Email")),
|
||||
AgreementStatus = reader.IsDBNull(reader.GetOrdinal("AgreementStatus")) ? null : reader.GetString(reader.GetOrdinal("AgreementStatus")),
|
||||
CheckInType = reader.IsDBNull(reader.GetOrdinal("CheckInType")) ? null : reader.GetString(reader.GetOrdinal("CheckInType")),
|
||||
CheckInTime = reader.IsDBNull(reader.GetOrdinal("CheckInTime")) ? null : reader.GetString(reader.GetOrdinal("CheckInTime")),
|
||||
UploadTime = reader.IsDBNull(reader.GetOrdinal("UploadTime")) ? (DateTime?)null : reader.GetDateTime(reader.GetOrdinal("UploadTime")),
|
||||
CreatedAt = reader.GetDateTime(reader.GetOrdinal("CreatedAt")),
|
||||
UpdatedAt = reader.GetDateTime(reader.GetOrdinal("UpdatedAt"))
|
||||
};
|
||||
}
|
||||
|
||||
public void UpdateUploadTime(string[] successIDs)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (successIDs == null || successIDs.Length == 0)
|
||||
return;
|
||||
|
||||
var conn = _dbService.GetConnection();
|
||||
|
||||
using (SqliteTransaction transaction = conn.BeginTransaction())
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (string id in successIDs)
|
||||
{
|
||||
string sql = "UPDATE CheckIn SET UploadTime = @UploadTime, UpdatedAt = @UpdatedAt WHERE ID = @ID";
|
||||
|
||||
using (SqliteCommand cmd = new SqliteCommand(sql, conn))
|
||||
{
|
||||
cmd.Transaction = transaction;
|
||||
cmd.Parameters.AddWithValue("@ID", id);
|
||||
cmd.Parameters.AddWithValue("@UploadTime", DateTime.Now);
|
||||
cmd.Parameters.AddWithValue("@UpdatedAt", DateTime.Now);
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
|
||||
transaction.Commit();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
transaction.Rollback();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"更新 CheckIn UploadTime 失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,321 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using 報到系統客戶端.Data;
|
||||
using 報到系統客戶端.Data.Models;
|
||||
|
||||
namespace 報到系統客戶端.Data.Repositories
|
||||
{
|
||||
/// <summary>
|
||||
/// Classes 本地資料庫操作類別
|
||||
/// </summary>
|
||||
public class ClassesRepository
|
||||
{
|
||||
private readonly DatabaseService _dbService;
|
||||
|
||||
public ClassesRepository()
|
||||
{
|
||||
_dbService = DatabaseService.Instance;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 新增一筆 Classes 資料
|
||||
/// </summary>
|
||||
public int Insert(LocalClassesItem item)
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
string sql = @"
|
||||
INSERT INTO Classes
|
||||
(ID, CourseCode, CourseName, CourseDate, CourseLocation, NotificationTemplate, AgreedTerms, StartTime, EndTime, CreatedAt, UpdatedAt)
|
||||
VALUES (@ID, @CourseCode, @CourseName, @CourseDate, @CourseLocation, @NotificationTemplate, @AgreedTerms, @StartTime, @EndTime, @CreatedAt, @UpdatedAt)
|
||||
";
|
||||
|
||||
using (SqliteCommand cmd = new SqliteCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@ID", item.ID);
|
||||
cmd.Parameters.AddWithValue("@CourseCode", item.CourseCode ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@CourseName", item.CourseName ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@CourseDate", item.CourseDate ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@CourseLocation", item.CourseLocation ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@NotificationTemplate", item.NotificationTemplate ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@AgreedTerms", item.AgreedTerms ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@StartTime", item.StartTime ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@EndTime", item.EndTime ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@CreatedAt", DateTime.Now);
|
||||
cmd.Parameters.AddWithValue("@UpdatedAt", DateTime.Now);
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
// 返回傳入的 ID
|
||||
return item.ID;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"新增 Classes 資料失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新一筆 Classes 資料
|
||||
/// </summary>
|
||||
public bool Update(LocalClassesItem item)
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
string sql = @"
|
||||
UPDATE Classes SET
|
||||
CourseCode = @CourseCode,
|
||||
CourseName = @CourseName,
|
||||
CourseDate = @CourseDate,
|
||||
CourseLocation = @CourseLocation,
|
||||
NotificationTemplate = @NotificationTemplate,
|
||||
AgreedTerms = @AgreedTerms,
|
||||
StartTime = @StartTime,
|
||||
EndTime = @EndTime,
|
||||
UpdatedAt = @UpdatedAt
|
||||
WHERE ID = @ID
|
||||
";
|
||||
|
||||
using (SqliteCommand cmd = new SqliteCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@ID", item.ID);
|
||||
cmd.Parameters.AddWithValue("@CourseCode", item.CourseCode ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@CourseName", item.CourseName ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@CourseDate", item.CourseDate ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@CourseLocation", item.CourseLocation ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@NotificationTemplate", item.NotificationTemplate ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@AgreedTerms", item.AgreedTerms ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@StartTime", item.StartTime ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@EndTime", item.EndTime ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@UpdatedAt", DateTime.Now);
|
||||
|
||||
return cmd.ExecuteNonQuery() > 0;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"更新 Classes 資料失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 刪除一筆 Classes 資料
|
||||
/// </summary>
|
||||
public bool Delete(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
string sql = "DELETE FROM Classes WHERE ID = @ID";
|
||||
|
||||
using (SqliteCommand cmd = new SqliteCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@ID", id);
|
||||
return cmd.ExecuteNonQuery() > 0;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"刪除 Classes 資料失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查詢所有 Classes 資料
|
||||
/// </summary>
|
||||
public List<LocalClassesItem> GetAll()
|
||||
{
|
||||
return Query("SELECT * FROM Classes ORDER BY ID");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查詢單筆 Classes 資料
|
||||
/// </summary>
|
||||
public LocalClassesItem GetById(int id)
|
||||
{
|
||||
var result = Query($"SELECT * FROM Classes WHERE ID = {id}");
|
||||
return result.Count > 0 ? result[0] : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 條件查詢 Classes 資料(分頁)
|
||||
/// </summary>
|
||||
public List<LocalClassesItem> GetByCondition(int pageIndex, int pageSize, string courseName = "", string courseCode = "", DateTime? startDate = null, DateTime? endDate = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
string sql = "SELECT * FROM Classes WHERE 1=1";
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(courseCode))
|
||||
sql += " AND CourseCode LIKE '%' || @CourseCode || '%'";
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(courseName))
|
||||
sql += " AND CourseName LIKE '%' || @CourseName || '%'";
|
||||
|
||||
if (startDate.HasValue && endDate.HasValue)
|
||||
sql += " AND CourseDate >= @StartDate AND CourseDate <= @EndDate";
|
||||
else if (startDate.HasValue)
|
||||
sql += " AND CourseDate >= @StartDate";
|
||||
else if (endDate.HasValue)
|
||||
sql += " AND CourseDate <= @EndDate";
|
||||
|
||||
sql += " ORDER BY CourseDate DESC LIMIT @PageSize OFFSET @Offset";
|
||||
|
||||
List<LocalClassesItem> result = new List<LocalClassesItem>();
|
||||
|
||||
using (SqliteCommand cmd = new SqliteCommand(sql, conn))
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(courseCode))
|
||||
cmd.Parameters.AddWithValue("@CourseCode", courseCode);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(courseName))
|
||||
cmd.Parameters.AddWithValue("@CourseName", courseName);
|
||||
|
||||
if (startDate.HasValue)
|
||||
cmd.Parameters.AddWithValue("@StartDate", startDate.Value);
|
||||
|
||||
if (endDate.HasValue)
|
||||
cmd.Parameters.AddWithValue("@EndDate", endDate.Value);
|
||||
|
||||
cmd.Parameters.AddWithValue("@PageSize", pageSize);
|
||||
cmd.Parameters.AddWithValue("@Offset", (pageIndex - 1) * pageSize);
|
||||
|
||||
using (SqliteDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
result.Add(ReadClassesItem(reader));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"查詢 Classes 資料失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查詢 Classes 資料總數
|
||||
/// </summary>
|
||||
public int GetCount(string courseName = "", string courseCode = "", DateTime? startDate = null, DateTime? endDate = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
string sql = "SELECT COUNT(*) FROM Classes WHERE 1=1";
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(courseCode))
|
||||
sql += " AND CourseCode LIKE '%' || @CourseCode || '%'";
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(courseName))
|
||||
sql += " AND CourseName LIKE '%' || @CourseName || '%'";
|
||||
|
||||
if (startDate.HasValue && endDate.HasValue)
|
||||
sql += " AND CourseDate >= @StartDate AND CourseDate <= @EndDate";
|
||||
else if (startDate.HasValue)
|
||||
sql += " AND CourseDate >= @StartDate";
|
||||
else if (endDate.HasValue)
|
||||
sql += " AND CourseDate <= @EndDate";
|
||||
|
||||
using (SqliteCommand cmd = new SqliteCommand(sql, conn))
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(courseCode))
|
||||
cmd.Parameters.AddWithValue("@CourseCode", courseCode);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(courseName))
|
||||
cmd.Parameters.AddWithValue("@CourseName", courseName);
|
||||
|
||||
if (startDate.HasValue)
|
||||
cmd.Parameters.AddWithValue("@StartDate", startDate.Value);
|
||||
|
||||
if (endDate.HasValue)
|
||||
cmd.Parameters.AddWithValue("@EndDate", endDate.Value);
|
||||
|
||||
return Convert.ToInt32(cmd.ExecuteScalar());
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"統計 Classes 資料失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清除所有 Classes 資料
|
||||
/// </summary>
|
||||
public void DeleteAll()
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
using (SqliteCommand cmd = new SqliteCommand("DELETE FROM Classes", conn))
|
||||
{
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"清除 Classes 資料失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 私用方法 - 執行查詢
|
||||
/// </summary>
|
||||
private List<LocalClassesItem> Query(string sql)
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
List<LocalClassesItem> result = new List<LocalClassesItem>();
|
||||
|
||||
using (SqliteCommand cmd = new SqliteCommand(sql, conn))
|
||||
{
|
||||
using (SqliteDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
result.Add(ReadClassesItem(reader));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"查詢 Classes 失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 私用方法 - 讀取資料列
|
||||
/// </summary>
|
||||
private LocalClassesItem ReadClassesItem(SqliteDataReader reader)
|
||||
{
|
||||
return new LocalClassesItem
|
||||
{
|
||||
ID = reader.GetInt32(reader.GetOrdinal("ID")),
|
||||
CourseCode = reader.IsDBNull(reader.GetOrdinal("CourseCode")) ? null : reader.GetString(reader.GetOrdinal("CourseCode")),
|
||||
CourseName = reader.IsDBNull(reader.GetOrdinal("CourseName")) ? null : reader.GetString(reader.GetOrdinal("CourseName")),
|
||||
CourseDate = reader.IsDBNull(reader.GetOrdinal("CourseDate")) ? null : reader.GetString(reader.GetOrdinal("CourseDate")),
|
||||
CourseLocation = reader.IsDBNull(reader.GetOrdinal("CourseLocation")) ? null : reader.GetString(reader.GetOrdinal("CourseLocation")),
|
||||
NotificationTemplate = reader.IsDBNull(reader.GetOrdinal("NotificationTemplate")) ? null : reader.GetString(reader.GetOrdinal("NotificationTemplate")),
|
||||
AgreedTerms = reader.IsDBNull(reader.GetOrdinal("AgreedTerms")) ? null : reader.GetString(reader.GetOrdinal("AgreedTerms")),
|
||||
StartTime = reader.IsDBNull(reader.GetOrdinal("StartTime")) ? null : reader.GetString(reader.GetOrdinal("StartTime")),
|
||||
EndTime = reader.IsDBNull(reader.GetOrdinal("EndTime")) ? null : reader.GetString(reader.GetOrdinal("EndTime")),
|
||||
CreatedAt = reader.GetDateTime(reader.GetOrdinal("CreatedAt")),
|
||||
UpdatedAt = reader.GetDateTime(reader.GetOrdinal("UpdatedAt"))
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,528 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using 報到系統客戶端.Data.Models;
|
||||
|
||||
namespace 報到系統客戶端.Data.Repositories
|
||||
{
|
||||
/// <summary>
|
||||
/// SignUps 本地資料庫操作類別
|
||||
/// </summary>
|
||||
public class SignUpsRepository
|
||||
{
|
||||
private readonly DatabaseService _dbService;
|
||||
|
||||
public SignUpsRepository()
|
||||
{
|
||||
_dbService = DatabaseService.Instance;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 新增一筆 SignUps 資料
|
||||
/// </summary>
|
||||
public int Insert(LocalSignUpItem item)
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
string sql = @"
|
||||
INSERT INTO SignUps
|
||||
(CourseID, SeqNo, Name, Mobile, QRCode, SignUpType, IDNumber, IDType, MealType, Email, LossJobTimes, Gender, AgreementStatus, CheckInTime, CheckOutTime, CreatedAt, UpdatedAt)
|
||||
VALUES (@CourseID, @SeqNo, @Name, @Mobile, @QRCode, @SignUpType, @IDNumber, @IDType, @MealType, @Email, @LossJobTimes, @Gender, @AgreementStatus, @CheckInTime, @CheckOutTime, @CreatedAt, @UpdatedAt)
|
||||
";
|
||||
|
||||
using (SqliteCommand cmd = new SqliteCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@CourseID", item.CourseID);
|
||||
cmd.Parameters.AddWithValue("@SeqNo", item.SeqNo);
|
||||
cmd.Parameters.AddWithValue("@Name", item.Name ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@Mobile", item.Mobile ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@QRCode", item.QRCode ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@SignUpType", item.SignUpType ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@IDNumber", item.IDNumber ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@IDType", item.IDType ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@MealType", item.MealType ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@Email", item.Email ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@LossJobTimes", item.LossJobTimes.HasValue ? (object)item.LossJobTimes.Value : DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@Gender", item.Gender ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@AgreementStatus", item.AgreementStatus ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@CheckInTime", item.CheckInTime ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@CheckOutTime", item.CheckOutTime ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@CreatedAt", DateTime.Now);
|
||||
cmd.Parameters.AddWithValue("@UpdatedAt", DateTime.Now);
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
// 取得新增資料的 ID
|
||||
using (SqliteCommand cmd = new SqliteCommand("SELECT last_insert_rowid()", conn))
|
||||
{
|
||||
return Convert.ToInt32(cmd.ExecuteScalar());
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"新增 SignUps 資料失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新一筆 SignUps 資料
|
||||
/// </summary>
|
||||
public bool Update(LocalSignUpItem item)
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
string sql = @"
|
||||
UPDATE SignUps SET
|
||||
CourseID = @CourseID,
|
||||
SeqNo = @SeqNo,
|
||||
Name = @Name,
|
||||
Mobile = @Mobile,
|
||||
QRCode = @QRCode,
|
||||
SignUpType = @SignUpType,
|
||||
IDNumber = @IDNumber,
|
||||
IDType = @IDType,
|
||||
MealType = @MealType,
|
||||
Email = @Email,
|
||||
LossJobTimes = @LossJobTimes,
|
||||
Gender = @Gender,
|
||||
AgreementStatus = @AgreementStatus,
|
||||
CheckInTime = @CheckInTime,
|
||||
CheckOutTime = @CheckOutTime,
|
||||
UpdatedAt = @UpdatedAt
|
||||
WHERE ID = @ID
|
||||
";
|
||||
|
||||
using (SqliteCommand cmd = new SqliteCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@ID", item.ID);
|
||||
cmd.Parameters.AddWithValue("@CourseID", item.CourseID);
|
||||
cmd.Parameters.AddWithValue("@SeqNo", item.SeqNo);
|
||||
cmd.Parameters.AddWithValue("@Name", item.Name ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@Mobile", item.Mobile ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@QRCode", item.QRCode ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@SignUpType", item.SignUpType ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@IDNumber", item.IDNumber ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@IDType", item.IDType ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@MealType", item.MealType ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@Email", item.Email ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@LossJobTimes", item.LossJobTimes.HasValue ? (object)item.LossJobTimes.Value : DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@Gender", item.Gender ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@AgreementStatus", item.AgreementStatus ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@CheckInTime", item.CheckInTime ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@CheckOutTime", item.CheckOutTime ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@UpdatedAt", DateTime.Now);
|
||||
|
||||
return cmd.ExecuteNonQuery() > 0;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"更新 SignUps 資料失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 刪除一筆 SignUps 資料
|
||||
/// </summary>
|
||||
public bool Delete(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
string sql = "DELETE FROM SignUps WHERE ID = @ID";
|
||||
|
||||
using (SqliteCommand cmd = new SqliteCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@ID", id);
|
||||
return cmd.ExecuteNonQuery() > 0;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"刪除 SignUps 資料失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查詢所有 SignUps 資料
|
||||
/// </summary>
|
||||
public List<LocalSignUpItem> GetAll()
|
||||
{
|
||||
return Query("SELECT * FROM SignUps ORDER BY CourseID DESC, ID ASC");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查詢單筆 SignUps 資料
|
||||
/// </summary>
|
||||
public LocalSignUpItem GetById(int id)
|
||||
{
|
||||
var result = Query($"SELECT * FROM SignUps WHERE ID = {id}");
|
||||
return result.Count > 0 ? result[0] : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 透過 QRCode 查詢
|
||||
/// </summary>
|
||||
public LocalSignUpItem GetByQRCode(string qrCode)
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
string sql = "SELECT * FROM SignUps WHERE QRCode = @QRCode LIMIT 1";
|
||||
|
||||
using (SqliteCommand cmd = new SqliteCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@QRCode", qrCode);
|
||||
|
||||
using (SqliteDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
return ReadSignUpItem(reader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"按 QRCode 查詢失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 按課程和姓名手機查詢
|
||||
/// </summary>
|
||||
public LocalSignUpItem GetByCourseNameMobile(int courseID, string name, string mobile)
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
string sql = "SELECT * FROM SignUps WHERE CourseID = @CourseID";
|
||||
|
||||
using (SqliteCommand cmd = new SqliteCommand())
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@CourseID", courseID);
|
||||
if (!string.IsNullOrEmpty(name))
|
||||
{
|
||||
sql += " AND Name = @Name";
|
||||
cmd.Parameters.AddWithValue("@Name", name);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(mobile))
|
||||
{
|
||||
sql += " AND Mobile = @Mobile";
|
||||
cmd.Parameters.AddWithValue("@Mobile", mobile);
|
||||
}
|
||||
sql += " LIMIT 1";
|
||||
|
||||
cmd.Connection = conn;
|
||||
cmd.CommandText = sql;
|
||||
|
||||
using (SqliteDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
return ReadSignUpItem(reader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"按課程和姓名手機查詢失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 條件查詢 SignUps 資料(分頁)
|
||||
/// </summary>
|
||||
public List<LocalSignUpItem> GetByCondition(int pageIndex, int pageSize, int courseID = 0, string name = "", string mobile = "")
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
string sql = "SELECT * FROM SignUps WHERE 1=1";
|
||||
|
||||
if (courseID > 0)
|
||||
sql += " AND CourseID = @CourseID";
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(name))
|
||||
sql += " AND Name LIKE '%' || @Name || '%'";
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(mobile))
|
||||
sql += " AND Mobile LIKE '%' || @Mobile || '%'";
|
||||
|
||||
sql += " ORDER BY CourseID DESC, ID ASC LIMIT @PageSize OFFSET @Offset";
|
||||
|
||||
List<LocalSignUpItem> result = new List<LocalSignUpItem>();
|
||||
|
||||
using (SqliteCommand cmd = new SqliteCommand(sql, conn))
|
||||
{
|
||||
if (courseID > 0)
|
||||
cmd.Parameters.AddWithValue("@CourseID", courseID);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(name))
|
||||
cmd.Parameters.AddWithValue("@Name", name);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(mobile))
|
||||
cmd.Parameters.AddWithValue("@Mobile", mobile);
|
||||
|
||||
cmd.Parameters.AddWithValue("@PageSize", pageSize);
|
||||
cmd.Parameters.AddWithValue("@Offset", (pageIndex - 1) * pageSize);
|
||||
|
||||
using (SqliteDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
result.Add(ReadSignUpItem(reader));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"查詢 SignUps 資料失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查詢 SignUps 資料總數
|
||||
/// </summary>
|
||||
public int GetCount(int courseID = 0, string name = "", string mobile = "")
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
string sql = "SELECT COUNT(*) FROM SignUps WHERE 1=1";
|
||||
|
||||
if (courseID > 0)
|
||||
sql += " AND CourseID = @CourseID";
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(name))
|
||||
sql += " AND Name LIKE '%' || @Name || '%'";
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(mobile))
|
||||
sql += " AND Mobile LIKE '%' || @Mobile || '%'";
|
||||
|
||||
using (SqliteCommand cmd = new SqliteCommand(sql, conn))
|
||||
{
|
||||
if (courseID > 0)
|
||||
cmd.Parameters.AddWithValue("@CourseID", courseID);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(name))
|
||||
cmd.Parameters.AddWithValue("@Name", name);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(mobile))
|
||||
cmd.Parameters.AddWithValue("@Mobile", mobile);
|
||||
|
||||
return Convert.ToInt32(cmd.ExecuteScalar());
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"統計 SignUps 資料失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 按課程 ID 查詢所有報名人員
|
||||
/// </summary>
|
||||
public List<LocalSignUpItem> GetByCourseID(int courseID)
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
string sql = "SELECT * FROM SignUps WHERE CourseID = @CourseID ORDER BY ID ASC";
|
||||
|
||||
List<LocalSignUpItem> result = new List<LocalSignUpItem>();
|
||||
|
||||
using (SqliteCommand cmd = new SqliteCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@CourseID", courseID);
|
||||
|
||||
using (SqliteDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
result.Add(ReadSignUpItem(reader));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"按課程 ID 查詢失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 按序號查詢單筆記錄
|
||||
/// </summary>
|
||||
public LocalSignUpItem GetBySeqNo(int seqNo)
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
string sql = "SELECT * FROM SignUps WHERE SeqNo = @SeqNo LIMIT 1";
|
||||
|
||||
using (SqliteCommand cmd = new SqliteCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@SeqNo", seqNo);
|
||||
|
||||
using (SqliteDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
return ReadSignUpItem(reader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"按序號查詢失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 按活動編號和序號查詢單筆記錄
|
||||
/// </summary>
|
||||
public LocalSignUpItem GetByCourseIDAndSeqNo(int courseID, int seqNo)
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
string sql = "SELECT * FROM SignUps WHERE CourseID = @CourseID AND SeqNo = @SeqNo LIMIT 1";
|
||||
|
||||
using (SqliteCommand cmd = new SqliteCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@CourseID", courseID);
|
||||
cmd.Parameters.AddWithValue("@SeqNo", seqNo);
|
||||
|
||||
using (SqliteDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
return ReadSignUpItem(reader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"按課程編號和序號查詢失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清除所有 SignUps 資料
|
||||
/// </summary>
|
||||
public void DeleteByCourseID(int courseID)
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
using (SqliteCommand cmd = new SqliteCommand("DELETE FROM SignUps WHERE CourseID = @CourseID", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@CourseID", courseID);
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"清除 SignUps 資料失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清除所有 SignUps 資料
|
||||
/// </summary>
|
||||
public void DeleteAll()
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
using (SqliteCommand cmd = new SqliteCommand("DELETE FROM SignUps", conn))
|
||||
{
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"清除 SignUps 資料失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 私用方法 - 執行查詢
|
||||
/// </summary>
|
||||
private List<LocalSignUpItem> Query(string sql)
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = _dbService.GetConnection();
|
||||
List<LocalSignUpItem> result = new List<LocalSignUpItem>();
|
||||
|
||||
using (SqliteCommand cmd = new SqliteCommand(sql, conn))
|
||||
{
|
||||
using (SqliteDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
result.Add(ReadSignUpItem(reader));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"查詢 SignUps 失敗:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 私用方法 - 讀取資料列
|
||||
/// </summary>
|
||||
private LocalSignUpItem ReadSignUpItem(SqliteDataReader reader)
|
||||
{
|
||||
return new LocalSignUpItem
|
||||
{
|
||||
ID = reader.GetInt32(reader.GetOrdinal("ID")),
|
||||
CourseID = reader.GetInt32(reader.GetOrdinal("CourseID")),
|
||||
SeqNo = reader.IsDBNull(reader.GetOrdinal("SeqNo")) ? 0 : reader.GetInt32(reader.GetOrdinal("SeqNo")),
|
||||
Name = reader.IsDBNull(reader.GetOrdinal("Name")) ? null : reader.GetString(reader.GetOrdinal("Name")),
|
||||
Mobile = reader.IsDBNull(reader.GetOrdinal("Mobile")) ? null : reader.GetString(reader.GetOrdinal("Mobile")),
|
||||
QRCode = reader.IsDBNull(reader.GetOrdinal("QRCode")) ? null : reader.GetString(reader.GetOrdinal("QRCode")),
|
||||
SignUpType = reader.IsDBNull(reader.GetOrdinal("SignUpType")) ? null : reader.GetString(reader.GetOrdinal("SignUpType")),
|
||||
IDNumber = reader.IsDBNull(reader.GetOrdinal("IDNumber")) ? null : reader.GetString(reader.GetOrdinal("IDNumber")),
|
||||
IDType = reader.IsDBNull(reader.GetOrdinal("IDType")) ? null : reader.GetString(reader.GetOrdinal("IDType")),
|
||||
MealType = reader.IsDBNull(reader.GetOrdinal("MealType")) ? null : reader.GetString(reader.GetOrdinal("MealType")),
|
||||
Email = reader.IsDBNull(reader.GetOrdinal("Email")) ? null : reader.GetString(reader.GetOrdinal("Email")),
|
||||
LossJobTimes = reader.IsDBNull(reader.GetOrdinal("LossJobTimes")) ? null : (int?)reader.GetInt32(reader.GetOrdinal("LossJobTimes")),
|
||||
Gender = reader.IsDBNull(reader.GetOrdinal("Gender")) ? null : reader.GetString(reader.GetOrdinal("Gender")),
|
||||
AgreementStatus = reader.IsDBNull(reader.GetOrdinal("AgreementStatus")) ? null : reader.GetString(reader.GetOrdinal("AgreementStatus")),
|
||||
CheckInTime = reader.IsDBNull(reader.GetOrdinal("CheckInTime")) ? null : reader.GetString(reader.GetOrdinal("CheckInTime")),
|
||||
CheckOutTime = reader.IsDBNull(reader.GetOrdinal("CheckOutTime")) ? null : reader.GetString(reader.GetOrdinal("CheckOutTime")),
|
||||
CreatedAt = reader.GetDateTime(reader.GetOrdinal("CreatedAt")),
|
||||
UpdatedAt = reader.GetDateTime(reader.GetOrdinal("UpdatedAt"))
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,345 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user