修复课表

This commit is contained in:
2026-07-28 20:08:12 +08:00 Unverified
parent 2dae303cf1
commit 865378dbdf
3 changed files with 42 additions and 2 deletions
@@ -275,8 +275,8 @@ public sealed class AttendanceController(
.Where(x => .Where(x =>
x.IsSuccessful && x.IsSuccessful &&
x.CreatedAt >= now.AddHours(-24) && x.CreatedAt >= now.AddHours(-24) &&
x.DeviceIdentifierHash != null && x.DeviceIdentifierHash != null)
deviceHashes.Contains(x.DeviceIdentifierHash)) .WhereIn(deviceHashes, x => x.DeviceIdentifierHash!)
.GroupBy(x => x.DeviceIdentifierHash!) .GroupBy(x => x.DeviceIdentifierHash!)
.Select(x => new .Select(x => new
{ {
@@ -302,6 +302,21 @@ public sealed class AttendanceControllerTests
Assert.Contains( Assert.Contains(
"SharedDevice", "SharedDevice",
sharedDeviceAttempt.RiskFlags ?? string.Empty); sharedDeviceAttempt.RiskFlags ?? string.Empty);
var sheetDetailResult = await controller.GetSheet(
qrSheet.Id,
CancellationToken.None);
var sheetDetailOk = Assert.IsType<OkObjectResult>(sheetDetailResult);
var sheetDetail = sheetDetailOk.Value!.GetType()
.GetProperty("Sheet")!
.GetValue(sheetDetailOk.Value)!;
var riskSummary = sheetDetail.GetType()
.GetProperty("RiskSummary")!
.GetValue(sheetDetail)!;
Assert.Equal(
2,
riskSummary.GetType()
.GetProperty("SharedDeviceStudentCount")!
.GetValue(riskSummary));
var locationRecord = new AttendanceRecord var locationRecord = new AttendanceRecord
{ {
@@ -108,6 +108,31 @@ public sealed class MySqlMigrationTests
Assert.Contains(ids[1].ToString(), sql, StringComparison.OrdinalIgnoreCase); Assert.Contains(ids[1].ToString(), sql, StringComparison.OrdinalIgnoreCase);
} }
[Fact]
public void MySql_attendance_device_hash_query_uses_provider_safe_predicates()
{
using var db = new AppDbContext(CreateMySqlOptions());
var deviceHashes = new[] { "device-hash-one", "device-hash-two" };
var sql = db.AttendanceCheckInAttempts
.Where(x =>
x.IsSuccessful &&
x.CreatedAt >= DateTime.UtcNow.AddHours(-24) &&
x.DeviceIdentifierHash != null)
.WhereIn(deviceHashes, x => x.DeviceIdentifierHash!)
.GroupBy(x => x.DeviceIdentifierHash!)
.Select(x => new
{
DeviceIdentifierHash = x.Key,
StudentCount = x.Select(a => a.StudentId).Distinct().Count()
})
.ToQueryString();
Assert.Contains(" IN (", sql, StringComparison.OrdinalIgnoreCase);
Assert.Contains(deviceHashes[0], sql, StringComparison.Ordinal);
Assert.Contains(deviceHashes[1], sql, StringComparison.Ordinal);
}
[Fact] [Fact]
public void MySql_invigilator_candidate_query_is_translatable_without_uuid_ordering() public void MySql_invigilator_candidate_query_is_translatable_without_uuid_ordering()
{ {