feat: support template load by serial and department
Batched template queries and department-based employee selection.main
parent
6bb23a93ab
commit
b9f2216207
|
|
@ -69,6 +69,7 @@ namespace HanvonF710XAttendanceService
|
||||||
|
|
||||||
using (var cmd = new MySqlCommand(query, connection))
|
using (var cmd = new MySqlCommand(query, connection))
|
||||||
{
|
{
|
||||||
|
cmd.CommandTimeout = 300;
|
||||||
for (int i = 0; i < chunk.Length; i++)
|
for (int i = 0; i < chunk.Length; i++)
|
||||||
{
|
{
|
||||||
cmd.Parameters.AddWithValue(parameterNames[i], chunk[i]);
|
cmd.Parameters.AddWithValue(parameterNames[i], chunk[i]);
|
||||||
|
|
@ -178,6 +179,89 @@ namespace HanvonF710XAttendanceService
|
||||||
return result.ToList();
|
return result.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Active template serial numbers for employees in the given departments (HRMS employees table).
|
||||||
|
/// When department lookup is unavailable, returns an empty list and the caller should fall back.
|
||||||
|
/// </summary>
|
||||||
|
public List<string> GetActiveSerialNumbersByDepartmentIds(
|
||||||
|
MySqlConnection connection,
|
||||||
|
IReadOnlyList<string> departmentIds,
|
||||||
|
IReadOnlyList<string> allowedMachineIds)
|
||||||
|
{
|
||||||
|
var result = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
if (departmentIds == null || departmentIds.Count == 0)
|
||||||
|
{
|
||||||
|
return new List<string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
var machineIds = (allowedMachineIds ?? Array.Empty<string>())
|
||||||
|
.Where(id => !string.IsNullOrWhiteSpace(id))
|
||||||
|
.Select(id => id.Trim())
|
||||||
|
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
const int chunkSize = 80;
|
||||||
|
for (int offset = 0; offset < departmentIds.Count; offset += chunkSize)
|
||||||
|
{
|
||||||
|
var deptChunk = departmentIds.Skip(offset).Take(chunkSize).ToArray();
|
||||||
|
var deptParamNames = new List<string>(deptChunk.Length);
|
||||||
|
for (int i = 0; i < deptChunk.Length; i++)
|
||||||
|
{
|
||||||
|
deptParamNames.Add("@Dept" + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
string deptInClause = string.Join(",", deptParamNames);
|
||||||
|
string machineJoin = "";
|
||||||
|
string machineFilter = "";
|
||||||
|
if (machineIds.Count > 0)
|
||||||
|
{
|
||||||
|
var machineParamNames = new List<string>(machineIds.Count);
|
||||||
|
for (int i = 0; i < machineIds.Count; i++)
|
||||||
|
{
|
||||||
|
machineParamNames.Add("@Mid" + i);
|
||||||
|
}
|
||||||
|
machineJoin = " INNER JOIN hrms.attendance_machine_user u ON u.serial_number = t.serial_no AND u.is_deleted = 0 ";
|
||||||
|
machineFilter = " AND u.machine_id IN (" + string.Join(",", machineParamNames) + ") ";
|
||||||
|
}
|
||||||
|
|
||||||
|
string query =
|
||||||
|
"SELECT DISTINCT t.serial_no " +
|
||||||
|
"FROM hrms.attendance_machine_face_templates t " +
|
||||||
|
"INNER JOIN hrms.employee e ON CAST(e.emp_id AS CHAR) = t.serial_no " +
|
||||||
|
machineJoin +
|
||||||
|
"WHERE t.is_active = 1 AND e.department_id IN (" + deptInClause + ")" +
|
||||||
|
machineFilter;
|
||||||
|
|
||||||
|
using (var cmd = new MySqlCommand(query, connection))
|
||||||
|
{
|
||||||
|
cmd.CommandTimeout = 120;
|
||||||
|
for (int i = 0; i < deptChunk.Length; i++)
|
||||||
|
{
|
||||||
|
cmd.Parameters.AddWithValue(deptParamNames[i], deptChunk[i]);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < machineIds.Count; i++)
|
||||||
|
{
|
||||||
|
cmd.Parameters.AddWithValue("@Mid" + i, machineIds[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
using (var reader = cmd.ExecuteReader())
|
||||||
|
{
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
if (reader.IsDBNull(0)) continue;
|
||||||
|
var s = reader.GetString(0);
|
||||||
|
if (!string.IsNullOrWhiteSpace(s))
|
||||||
|
{
|
||||||
|
result.Add(s.Trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Active templates for employees registered on a specific Nedo machine.
|
/// Active templates for employees registered on a specific Nedo machine.
|
||||||
/// Registration-based target selection: attendance_machine_user (is_deleted=0) drives which employees are allowed.
|
/// Registration-based target selection: attendance_machine_user (is_deleted=0) drives which employees are allowed.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue