299 lines
13 KiB
C#
299 lines
13 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using MySql.Data.MySqlClient;
|
|
|
|
namespace HikvisionAttendanceService.Data;
|
|
|
|
internal sealed class MySqlAttendanceMachineRepository : IAttendanceMachineRepository
|
|
{
|
|
private readonly IHrmsDbConnectionFactory _factory;
|
|
public MySqlAttendanceMachineRepository(IHrmsDbConnectionFactory factory) { _factory = factory; }
|
|
|
|
public List<AttendanceMachineRow> GetActiveMachines(string? machineTypeFilter, out string error)
|
|
{
|
|
error = "";
|
|
var rows = new List<AttendanceMachineRow>();
|
|
if (!_factory.TryBuildConnectionString(out var cs, out error))
|
|
return rows;
|
|
try
|
|
{
|
|
using var conn = new MySqlConnection(cs);
|
|
conn.Open();
|
|
string sql = "SELECT machine_id,machine_ip,port_number,machine_name,site_id,machine_status,machine_type,status,last_sync_date,total_users " +
|
|
"FROM attendance_machine WHERE (machine_status='active' OR machine_status='1' OR machine_status=1)";
|
|
if (!string.IsNullOrWhiteSpace(machineTypeFilter))
|
|
sql += " AND machine_type=@machineType";
|
|
using var cmd = new MySqlCommand(sql, conn);
|
|
if (!string.IsNullOrWhiteSpace(machineTypeFilter))
|
|
cmd.Parameters.AddWithValue("@machineType", machineTypeFilter);
|
|
using var rd = cmd.ExecuteReader();
|
|
while (rd.Read())
|
|
{
|
|
rows.Add(new AttendanceMachineRow
|
|
{
|
|
MachineId = rd["machine_id"]?.ToString() ?? "",
|
|
MachineIp = rd["machine_ip"]?.ToString() ?? "",
|
|
PortNumber = rd["port_number"] == DBNull.Value ? 8000 : Convert.ToInt32(rd["port_number"]),
|
|
MachineName = rd["machine_name"]?.ToString() ?? "",
|
|
SiteId = rd["site_id"] == DBNull.Value ? (int?)null : Convert.ToInt32(rd["site_id"]),
|
|
MachineStatus = rd["machine_status"]?.ToString() ?? "",
|
|
MachineType = rd["machine_type"]?.ToString() ?? "",
|
|
Status = rd["status"]?.ToString() ?? "",
|
|
LastSyncDate = rd["last_sync_date"] == DBNull.Value ? (DateTime?)null : Convert.ToDateTime(rd["last_sync_date"]),
|
|
TotalUsers = rd["total_users"] == DBNull.Value ? 0 : Convert.ToInt32(rd["total_users"])
|
|
});
|
|
}
|
|
}
|
|
catch (Exception ex) { error = ex.Message; }
|
|
return rows;
|
|
}
|
|
|
|
public void UpdateMachineSyncState(string machineIp, string status, DateTime? lastSyncDate, int? totalUsers, out string error)
|
|
{
|
|
error = "";
|
|
if (!_factory.TryBuildConnectionString(out var cs, out error))
|
|
return;
|
|
try
|
|
{
|
|
using var conn = new MySqlConnection(cs);
|
|
conn.Open();
|
|
using var cmd = new MySqlCommand(
|
|
"UPDATE attendance_machine SET status=@status,last_sync_date=COALESCE(@last_sync_date,last_sync_date),total_users=COALESCE(@total_users,total_users) WHERE machine_ip=@machine_ip",
|
|
conn);
|
|
cmd.Parameters.AddWithValue("@status", status ?? "");
|
|
cmd.Parameters.AddWithValue("@last_sync_date", (object?)lastSyncDate ?? DBNull.Value);
|
|
cmd.Parameters.AddWithValue("@total_users", (object?)totalUsers ?? DBNull.Value);
|
|
cmd.Parameters.AddWithValue("@machine_ip", machineIp ?? "");
|
|
cmd.ExecuteNonQuery();
|
|
}
|
|
catch (Exception ex) { error = ex.Message; }
|
|
}
|
|
|
|
public bool TryGetMachineLastSyncDate(string machineIp, out DateTime? lastSyncDate, out string error)
|
|
{
|
|
lastSyncDate = null;
|
|
error = "";
|
|
if (!_factory.TryBuildConnectionString(out var cs, out error))
|
|
return false;
|
|
try
|
|
{
|
|
using var conn = new MySqlConnection(cs);
|
|
conn.Open();
|
|
using var cmd = new MySqlCommand(
|
|
"SELECT last_sync_date FROM attendance_machine WHERE machine_ip=@machine_ip LIMIT 1",
|
|
conn);
|
|
cmd.Parameters.AddWithValue("@machine_ip", machineIp ?? "");
|
|
var obj = cmd.ExecuteScalar();
|
|
if (obj == null || obj == DBNull.Value)
|
|
return true;
|
|
lastSyncDate = Convert.ToDateTime(obj);
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
error = ex.Message;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public bool UpdateMachineLastSyncDate(string machineIp, DateTime lastSyncDate, out string error)
|
|
{
|
|
error = "";
|
|
if (!_factory.TryBuildConnectionString(out var cs, out error))
|
|
return false;
|
|
try
|
|
{
|
|
using var conn = new MySqlConnection(cs);
|
|
conn.Open();
|
|
using var cmd = new MySqlCommand(
|
|
"UPDATE attendance_machine SET last_sync_date=@last_sync_date WHERE machine_ip=@machine_ip",
|
|
conn);
|
|
cmd.Parameters.AddWithValue("@last_sync_date", lastSyncDate);
|
|
cmd.Parameters.AddWithValue("@machine_ip", machineIp ?? "");
|
|
cmd.ExecuteNonQuery();
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
error = ex.Message;
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
internal sealed class MySqlAttendanceLogRepository : IAttendanceLogRepository
|
|
{
|
|
private readonly IHrmsDbConnectionFactory _factory;
|
|
public MySqlAttendanceLogRepository(IHrmsDbConnectionFactory factory) { _factory = factory; }
|
|
|
|
public bool UpsertAttendance(string acNo, DateTime checkTime, int processed, string machineId, int inOutTypeId, string machineIp, DateTime dateOnly, out string error)
|
|
{
|
|
error = "";
|
|
if (!_factory.TryBuildConnectionString(out var cs, out error))
|
|
return false;
|
|
try
|
|
{
|
|
using var conn = new MySqlConnection(cs);
|
|
conn.Open();
|
|
using var cmd = new MySqlCommand(
|
|
"REPLACE INTO attendance_log (ac_no,checktime,processed,machine_id,in_out_type_id,machine_ip,date) " +
|
|
"VALUES (@ac_no,@checktime,@processed,@machine_id,@in_out_type_id,@machine_ip,@date)",
|
|
conn);
|
|
cmd.Parameters.AddWithValue("@ac_no", acNo ?? "");
|
|
cmd.Parameters.AddWithValue("@checktime", checkTime);
|
|
cmd.Parameters.AddWithValue("@processed", processed);
|
|
cmd.Parameters.AddWithValue("@machine_id", machineId ?? "");
|
|
cmd.Parameters.AddWithValue("@in_out_type_id", inOutTypeId);
|
|
cmd.Parameters.AddWithValue("@machine_ip", machineIp ?? "");
|
|
cmd.Parameters.AddWithValue("@date", dateOnly.Date);
|
|
cmd.ExecuteNonQuery();
|
|
return true;
|
|
}
|
|
catch (Exception ex) { error = ex.Message; return false; }
|
|
}
|
|
}
|
|
|
|
internal sealed class MySqlAttendanceMachineUserRepository : IAttendanceMachineUserRepository
|
|
{
|
|
private readonly IHrmsDbConnectionFactory _factory;
|
|
public MySqlAttendanceMachineUserRepository(IHrmsDbConnectionFactory factory) { _factory = factory; }
|
|
|
|
public List<AttendanceMachineUserRow> GetActiveUsersByMachine(string machineId, out string error) =>
|
|
QueryUsers(machineId, false, out error);
|
|
|
|
public List<AttendanceMachineUserRow> GetPendingDeletionUsersByMachine(string machineId, out string error) =>
|
|
QueryUsers(machineId, true, out error);
|
|
|
|
private List<AttendanceMachineUserRow> QueryUsers(string machineId, bool deletionRequested, out string error)
|
|
{
|
|
error = "";
|
|
var rows = new List<AttendanceMachineUserRow>();
|
|
if (!_factory.TryBuildConnectionString(out var cs, out error))
|
|
return rows;
|
|
try
|
|
{
|
|
using var conn = new MySqlConnection(cs);
|
|
conn.Open();
|
|
using var cmd = new MySqlCommand(
|
|
"SELECT machine_id,serial_number,employee_name,is_deleted,is_deletion_requested FROM attendance_machine_user " +
|
|
"WHERE machine_id=@machine_id AND is_deleted=0 AND is_deletion_requested=@is_deletion_requested",
|
|
conn);
|
|
cmd.Parameters.AddWithValue("@machine_id", machineId ?? "");
|
|
cmd.Parameters.AddWithValue("@is_deletion_requested", deletionRequested ? 1 : 0);
|
|
using var rd = cmd.ExecuteReader();
|
|
while (rd.Read())
|
|
{
|
|
rows.Add(new AttendanceMachineUserRow
|
|
{
|
|
MachineId = rd["machine_id"]?.ToString() ?? "",
|
|
SerialNumber = rd["serial_number"]?.ToString() ?? "",
|
|
EmployeeName = rd["employee_name"]?.ToString() ?? "",
|
|
IsDeleted = Convert.ToInt32(rd["is_deleted"]) != 0,
|
|
IsDeletionRequested = Convert.ToInt32(rd["is_deletion_requested"]) != 0
|
|
});
|
|
}
|
|
}
|
|
catch (Exception ex) { error = ex.Message; }
|
|
return rows;
|
|
}
|
|
|
|
public bool UpsertMachineUser(string machineId, string serialNumber, string employeeName, out string error)
|
|
{
|
|
error = "";
|
|
if (!_factory.TryBuildConnectionString(out var cs, out error))
|
|
return false;
|
|
try
|
|
{
|
|
using var conn = new MySqlConnection(cs);
|
|
conn.Open();
|
|
using var cmd = new MySqlCommand(
|
|
"REPLACE INTO attendance_machine_user (machine_id,serial_number,employee_name,is_deleted,is_deletion_requested,updated_at) " +
|
|
"VALUES (@machine_id,@serial_number,@employee_name,0,0,NOW())", conn);
|
|
cmd.Parameters.AddWithValue("@machine_id", machineId ?? "");
|
|
cmd.Parameters.AddWithValue("@serial_number", serialNumber ?? "");
|
|
cmd.Parameters.AddWithValue("@employee_name", employeeName ?? "");
|
|
cmd.ExecuteNonQuery();
|
|
return true;
|
|
}
|
|
catch (Exception ex) { error = ex.Message; return false; }
|
|
}
|
|
|
|
public bool MarkDeleted(string machineId, string serialNumber, string updatedBy, out string error)
|
|
{
|
|
error = "";
|
|
if (!_factory.TryBuildConnectionString(out var cs, out error))
|
|
return false;
|
|
try
|
|
{
|
|
using var conn = new MySqlConnection(cs);
|
|
conn.Open();
|
|
using var cmd = new MySqlCommand(
|
|
"UPDATE attendance_machine_user SET is_deleted=1,is_deletion_requested=0,updated_by=@updated_by,updated_at=NOW() " +
|
|
"WHERE machine_id=@machine_id AND serial_number=@serial_number", conn);
|
|
cmd.Parameters.AddWithValue("@updated_by", updatedBy ?? "hikvision-service");
|
|
cmd.Parameters.AddWithValue("@machine_id", machineId ?? "");
|
|
cmd.Parameters.AddWithValue("@serial_number", serialNumber ?? "");
|
|
cmd.ExecuteNonQuery();
|
|
return true;
|
|
}
|
|
catch (Exception ex) { error = ex.Message; return false; }
|
|
}
|
|
}
|
|
|
|
internal sealed class MySqlAttendanceMachineFaceTemplateRepository : IAttendanceMachineFaceTemplateRepository
|
|
{
|
|
private readonly IHrmsDbConnectionFactory _factory;
|
|
public MySqlAttendanceMachineFaceTemplateRepository(IHrmsDbConnectionFactory factory) { _factory = factory; }
|
|
|
|
public bool UpsertFaceTemplate(string serialNo, byte[] template, DateTime createdDate, bool isActive, out string error)
|
|
{
|
|
error = "";
|
|
if (!_factory.TryBuildConnectionString(out var cs, out error))
|
|
return false;
|
|
try
|
|
{
|
|
using var conn = new MySqlConnection(cs);
|
|
conn.Open();
|
|
using var cmd = new MySqlCommand(
|
|
"REPLACE INTO attendance_machine_face_templates (serial_no,template,created_date,is_active) " +
|
|
"VALUES (@serial_no,@template,@created_date,@is_active)", conn);
|
|
cmd.Parameters.AddWithValue("@serial_no", serialNo ?? "");
|
|
cmd.Parameters.Add("@template", MySqlDbType.Blob).Value = (object?)template ?? Array.Empty<byte>();
|
|
cmd.Parameters.AddWithValue("@created_date", createdDate);
|
|
cmd.Parameters.AddWithValue("@is_active", isActive ? 1 : 0);
|
|
cmd.ExecuteNonQuery();
|
|
return true;
|
|
}
|
|
catch (Exception ex) { error = ex.Message; return false; }
|
|
}
|
|
|
|
public bool TryGetActiveFaceTemplateBySerial(string serialNo, out AttendanceMachineFaceTemplateRow? row, out string error)
|
|
{
|
|
row = null;
|
|
error = "";
|
|
if (!_factory.TryBuildConnectionString(out var cs, out error))
|
|
return false;
|
|
try
|
|
{
|
|
using var conn = new MySqlConnection(cs);
|
|
conn.Open();
|
|
using var cmd = new MySqlCommand(
|
|
"SELECT serial_no,template,created_date,is_active FROM attendance_machine_face_templates " +
|
|
"WHERE serial_no=@serial_no AND is_active=1 ORDER BY created_date DESC LIMIT 1", conn);
|
|
cmd.Parameters.AddWithValue("@serial_no", serialNo ?? "");
|
|
using var rd = cmd.ExecuteReader();
|
|
if (!rd.Read())
|
|
return false;
|
|
row = new AttendanceMachineFaceTemplateRow
|
|
{
|
|
SerialNo = rd["serial_no"]?.ToString() ?? "",
|
|
Template = rd["template"] == DBNull.Value ? Array.Empty<byte>() : (byte[])rd["template"],
|
|
CreatedDate = rd["created_date"] == DBNull.Value ? DateTime.MinValue : Convert.ToDateTime(rd["created_date"]),
|
|
IsActive = rd["is_active"] != DBNull.Value && Convert.ToInt32(rd["is_active"]) != 0
|
|
};
|
|
return true;
|
|
}
|
|
catch (Exception ex) { error = ex.Message; return false; }
|
|
}
|
|
}
|