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))
|
||||
{
|
||||
cmd.CommandTimeout = 300;
|
||||
for (int i = 0; i < chunk.Length; i++)
|
||||
{
|
||||
cmd.Parameters.AddWithValue(parameterNames[i], chunk[i]);
|
||||
|
|
@ -178,6 +179,89 @@ namespace HanvonF710XAttendanceService
|
|||
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>
|
||||
/// 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.
|
||||
|
|
|
|||
Loading…
Reference in New Issue