diff --git a/YD_YiLu/Services/Impl/DeviceSyncService.cs b/YD_YiLu/Services/Impl/DeviceSyncService.cs index b1c2647..687cddf 100644 --- a/YD_YiLu/Services/Impl/DeviceSyncService.cs +++ b/YD_YiLu/Services/Impl/DeviceSyncService.cs @@ -161,19 +161,41 @@ namespace YD_YiLu.Api.Services.Impl return result; // 👉 2. 批量查已存在的 TrainSerial(防重复) - var trainSerials = list.Select(x => x.TrainSerial).ToList(); + var normalizedItems = list + .Where(x => x != null + && !string.IsNullOrWhiteSpace(x.DeviceSerial) + && !string.IsNullOrWhiteSpace(x.UserSerial)) + .Select(x => + { + var trainSerial = NormalizeTrainSerial(x.TrainSerial, x); + var videoSerial = NormalizeSerial(x.VideoSerial, trainSerial); + return new + { + Item = x, + TrainSerial = trainSerial, + VideoSerial = videoSerial + }; + }) + .ToList(); + + if (!normalizedItems.Any()) + return result; + + var trainSerials = normalizedItems.Select(x => x.TrainSerial).Distinct().ToList(); var existSerials = await _context.YL_Train .Where(x => trainSerials.Contains(x.TrainSerial)) .Select(x => x.TrainSerial) .ToListAsync(); + var seenSerials = new HashSet(existSerials, StringComparer.OrdinalIgnoreCase); var newEntities = new List(); - foreach (var item in list) + foreach (var normalized in normalizedItems) { + var item = normalized.Item; // 👉 3. 唯一校验(跳过已存在) - if (existSerials.Contains(item.TrainSerial)) + if (!seenSerials.Add(normalized.TrainSerial)) continue; var entity = new YL_Train @@ -182,8 +204,8 @@ namespace YD_YiLu.Api.Services.Impl DeviceType = item.DeviceType, UserSerial = item.UserSerial, - TrainSerial = item.TrainSerial, - VideoSerial = item.VideoSerial, + TrainSerial = normalized.TrainSerial, + VideoSerial = normalized.VideoSerial, TrainExam = item.TrainExam, QuizId = item.QuizId, @@ -876,6 +898,38 @@ namespace YD_YiLu.Api.Services.Impl return dto; } + private static string NormalizeTrainSerial(string serial, DeviceSyncTrainPushRequestDto item) + { + if (!string.IsNullOrWhiteSpace(serial)) + return NormalizeSerial(serial, "AUTO-" + MD5Helper.MD5Encrypt32(serial)); + + var seed = string.Join("|", new[] + { + item.DeviceSerial, + item.UserSerial, + item.CourseId.ToString(), + item.TrainExam.ToString(), + item.StartTime, + item.EndTime, + item.Duration.ToString(), + item.StandardCounts.ToString(), + item.UnStandardCounts.ToString(), + item.Distance?.ToString() ?? "", + item.TimeKeeping?.ToString() ?? "" + }); + + return "AUTO-" + MD5Helper.MD5Encrypt32(seed); + } + + private static string NormalizeSerial(string serial, string fallback) + { + var value = string.IsNullOrWhiteSpace(serial) ? fallback : serial.Trim(); + if (value.Length <= 64) + return value; + + return "AUTO-" + MD5Helper.MD5Encrypt32(value); + } + private static (DateTime? start, DateTime? end) GetDateRange(int dateType, string queryStart, string queryEnd) { var now = DateTime.Now;