using System; using System.Collections.Generic; using System.Data; using Microsoft.Data.Sqlite; using 報到系統客戶端.Data.Models; namespace 報到系統客戶端.Data.Repositories { /// /// CheckIn 本地資料庫操作類別 /// 簽到簽退紀錄表 /// public class CheckInRepository { private readonly DatabaseService _dbService; public CheckInRepository() { _dbService = DatabaseService.Instance; } /// /// 新增一筆 CheckIn 資料 /// 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); } } /// /// 批量新增 CheckIn 資料 /// public void InsertBatch(List 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); } } /// /// 更新一筆 CheckIn 資料 /// 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); } } /// /// 刪除一筆 CheckIn 資料 /// 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); } } /// /// 查詢所有 CheckIn 資料 /// public List GetAll() { return Query("SELECT * FROM CheckIn ORDER BY CheckInTime DESC"); } /// /// 查詢單筆 CheckIn 資料 /// public LocalCheckInItem GetById(int id) { var result = Query($"SELECT * FROM CheckIn WHERE ID = {id}"); return result.Count > 0 ? result[0] : null; } /// /// 按課程 ID 查詢簽到記錄 /// public List GetByCourseID(int courseID) { try { var conn = _dbService.GetConnection(); string sql = "SELECT * FROM CheckIn WHERE CourseID = @CourseID ORDER BY CheckInTime DESC"; List result = new List(); 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); } } /// /// 按課程和姓名手機查詢簽到記錄 /// public List 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 result = new List(); 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); } } /// /// 條件查詢 CheckIn 資料(分頁) /// public List 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 result = new List(); 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); } } /// /// 查詢 CheckIn 資料總數 /// 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); } } /// /// 清除所有 CheckIn 資料 /// 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); } } /// /// 清除所有 CheckIn 資料 /// 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); } } /// /// 私用方法 - 執行查詢 /// private List Query(string sql) { try { var conn = _dbService.GetConnection(); List result = new List(); 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); } } /// /// 私用方法 - 讀取資料列 /// 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); } } } }