using Dlhis.Entity.Device.Entities; using Dlhis.Entity.Device.Enums; using Kurisu.AspNetCore.Utils.Extensions; using Kurisu.Core.DataAccess.Entity; using Kurisu.SqlSugar.Services; using SqlSugar; using System.Linq.Expressions; namespace Dlhis.ScheduledTask.CommonJobs; public class CancelDuplicationTaskJob { private readonly IServiceProvider _serviceProvider; private readonly ILogger _logger; public CancelDuplicationTaskJob(IServiceProvider serviceProvider, ILogger logger) { _serviceProvider = serviceProvider; _logger = logger; } public async Task RunAsync() { _logger.LogInformation("抵消任务开始处理"); using (var scope = _serviceProvider.CreateScope()) { var optionService = scope.ServiceProvider.GetService(); var db = scope.ServiceProvider.GetService(); db.Client.QueryFilter.ClearAndBackup(); optionService.IgnoreTenant = true; try { //人员下发任务相关 var taskTypes = new List() { DeviceTaskEnumType.Add, DeviceTaskEnumType.Delete, DeviceTaskEnumType.Update }; var deviceTasks = await db.Queryable() .Where(x => x.Status == DeviceTaskStatusEnumType.Wait)//没有被获取 .Where(x => taskTypes.Contains(x.Type)) .OrderBy(x => x.CreateTime, OrderByType.Desc) .ToListAsync(); var groupData = deviceTasks.GroupBy(x => new { x.TenantId, x.UserNo, x.DeviceUniqueNo }); foreach (var deviceTaskPack in groupData) { var uniqueInfo = deviceTaskPack.Key; var data = deviceTaskPack.ToList(); foreach (var item in data) { try { Expression> where = LinqExpressionExtension.False(); var ignoreData = new List(); //最新一条更新人员信息 if (item.Type == DeviceTaskEnumType.Update && item.Status == DeviceTaskStatusEnumType.Wait) { //获取过往的更新人员任务 ignoreData = data.Where(x => x.Type == DeviceTaskEnumType.Update) .Where(x => x.Status == DeviceTaskStatusEnumType.Wait) .Where(x => x.Id != item.Id) .Where(x => item.CreateTime > x.CreateTime) .Select(x => new IdVersion { Id = x.Id, Version = x.Version }).ToList(); } //最新一条删除人员信息 else if (item.Type == DeviceTaskEnumType.Delete && item.Status == DeviceTaskStatusEnumType.Wait) { //存在成功下发的任务,此处可以直接把其他任务取消 if (await db.Queryable().Where(x => x.UserNo == item.UserNo) .Where(x => x.DeviceUniqueNo == item.DeviceUniqueNo) .Where(x => x.TenantId == item.TenantId).Where(x => x.Status == DeviceTaskStatusEnumType.Success).AnyAsync()) { ignoreData.AddRange(data.Where(x => x.Type == DeviceTaskEnumType.Add || x.Type == DeviceTaskEnumType.Delete || x.Type == DeviceTaskEnumType.Update) .Where(x => x.Status == DeviceTaskStatusEnumType.Wait) .Where(x => x.Id != item.Id) .Where(x => item.CreateTime > x.CreateTime) .Select(x => new IdVersion { Id = x.Id, Version = x.Version }) ); } else { var currentIds = new List { item.Id }; var beforeTask = data.Where(x => x.Type == DeviceTaskEnumType.Add || x.Type == DeviceTaskEnumType.Update) .Where(x => !currentIds.Contains(x.Id)) .Where(x => x.Status == DeviceTaskStatusEnumType.Wait) .Where(x => item.CreateTime > x.CreateTime) .FirstOrDefault(); //逻辑正确,最终beforeTask.type == DeviceTaskEnumType.Add while (beforeTask != null && beforeTask.Type == DeviceTaskEnumType.Update) { ignoreData.Add(new IdVersion() { Id = beforeTask.Id, Version = beforeTask.Version }); currentIds.Add(beforeTask.Id); beforeTask = data.Where(x => x.Type == DeviceTaskEnumType.Add || x.Type == DeviceTaskEnumType.Update) .Where(x => !currentIds.Contains(x.Id)) .Where(x => x.Status == DeviceTaskStatusEnumType.Wait) .Where(x => item.CreateTime > x.CreateTime) .FirstOrDefault(); } if (beforeTask != null) { ignoreData.Add(new IdVersion() { Id = beforeTask.Id, Version = beforeTask.Version }); ignoreData.Add(new IdVersion() { Id = item.Id, Version = item.Version }); } } } if (ignoreData.Any()) { ignoreData.ForEach(p => { where = where.Or(x => x.Id == p.Id && x.Version == p.Version && x.Status == DeviceTaskStatusEnumType.Wait); }); await db.Updateable() .SetColumns(x => x.Version == x.Version + 1) .SetColumns(x => x.Status == DeviceTaskStatusEnumType.Cancel) .SetColumns(x => x.CancellationId == item.Id) .SetColumns(x => x.ModifiedTime == DateTime.Now) .Where(where) .ExecuteCommandAsync(); data.ForEach(x => { if (ignoreData.Any(p => p.Id == x.Id)) x.Status = DeviceTaskStatusEnumType.Cancel; }); } } catch (Exception ex) { _logger.LogError(ex, "抵消处理异常:{message}", ex.Message); } } } } catch (Exception ex) { _logger.LogError(ex, "抵消处理异常:{message}", ex.Message); } finally { db.Client.QueryFilter.Restore(); optionService.IgnoreTenant = false; } } _logger.LogInformation("抵消任务处理完成"); } class IdVersion { public long Id { get; set; } public int Version { get; set; } } }