diff --git a/Src/Dlhis.ScheduledTask/BaseJob.cs b/Src/Dlhis.ScheduledTask/BaseJob.cs index 6fdd5974..f3d84a5c 100644 --- a/Src/Dlhis.ScheduledTask/BaseJob.cs +++ b/Src/Dlhis.ScheduledTask/BaseJob.cs @@ -21,34 +21,32 @@ public abstract class BaseJob : IJob public async Task TodoAsync() { - using (var scope = _serviceProvider.CreateScope()) + using var scope = _serviceProvider.CreateScope(); + var recurringJob = this.GetType().GetCustomAttribute()!; + var key = recurringJob.UniqueJobKey; + var name = recurringJob.Name; + + Logger = scope.ServiceProvider.GetService>(); + DbContext = scope.ServiceProvider.GetService(); + + try { - var recurringJob = this.GetType().GetCustomAttribute()!; - var key = recurringJob.UniqueJobKey; - var name = recurringJob.Name; - - Logger = scope.ServiceProvider.GetService>(); - DbContext = scope.ServiceProvider.GetService(); - - try + var redisCache = scope.ServiceProvider.GetService(); + await using var handler = await redisCache.LockAsync($"Scheduled:{key}"); + if (handler.Acquired) { - var redisCache = scope.ServiceProvider.GetService(); - await using var handler = await redisCache.LockAsync($"Scheduled:{key}"); - if (handler.Acquired) - { - Logger.LogDebug("[{name}]开始执行...", name); - await DbContext.IgnoreAsync(async () => { await RunAsync(scope.ServiceProvider); }); - } - } - catch (Exception ex) - { - Logger.LogError(ex, "[{name}]执行失败:{message} {stacktrace}", name, ex.Message, ex.StackTrace); - } - finally - { - Logger.LogDebug("[{name}]执行结束...", name); + Logger.LogDebug("[{name}]开始执行...", name); + await DbContext.IgnoreAsync(async () => { await RunAsync(scope.ServiceProvider); }); } } + catch (Exception ex) + { + Logger.LogError(ex, "[{name}]执行失败:{message} {stacktrace}", name, ex.Message, ex.StackTrace); + } + finally + { + Logger.LogDebug("[{name}]执行结束...", name); + } } protected abstract Task RunAsync(IServiceProvider serviceProvider); diff --git a/Src/Dlhis.ScheduledTask/DeviceUploadLog/Controllers/DeviceUploadLogsController.cs b/Src/Dlhis.ScheduledTask/DeviceUploadLog/Controllers/DeviceUploadLogsController.cs index 8baa8d58..d4f9fc9c 100644 --- a/Src/Dlhis.ScheduledTask/DeviceUploadLog/Controllers/DeviceUploadLogsController.cs +++ b/Src/Dlhis.ScheduledTask/DeviceUploadLog/Controllers/DeviceUploadLogsController.cs @@ -75,14 +75,6 @@ public class DeviceUploadLogsController : ControllerBase await _deviceUploadLogService.QiaoqiaoGaoshiqingAsync(request); } - [AllowAnonymous] - [HttpPost("testMigration")] - [IgnoreTenant] - [Transactional] - public async Task Test() - { - await _deviceUploadLogService.Test(); - } /// /// 获取设备记录读取的配置 @@ -115,4 +107,6 @@ public class DeviceUploadLogsController : ControllerBase { await _deviceUploadLogService.ManuallySetTimeInfoAsync(request.DeviceNo, request.Start, request.End); } + + } \ No newline at end of file diff --git a/Src/Dlhis.ScheduledTask/Jobs/ArchiveDeviceUploadLogJob.cs b/Src/Dlhis.ScheduledTask/Jobs/ArchiveDeviceUploadLogJob.cs index 9a441628..3a690fa6 100644 --- a/Src/Dlhis.ScheduledTask/Jobs/ArchiveDeviceUploadLogJob.cs +++ b/Src/Dlhis.ScheduledTask/Jobs/ArchiveDeviceUploadLogJob.cs @@ -4,57 +4,68 @@ using Dlhis.ScheduledTask.Attributes; namespace Dlhis.ScheduledTask.Jobs; /// -/// 归档设备通行记录 +/// 归档设备通行记录的定时任务作业 /// [RecurringJob(nameof(ArchiveDeviceUploadLogJob), "0 0 3 * * ? ", Name = "归档设备通行记录")] public class ArchiveDeviceUploadLogJob : BaseJob { + /// + /// 构造函数,注入服务提供者。 + /// + /// 服务提供者 public ArchiveDeviceUploadLogJob(IServiceProvider serviceProvider) : base(serviceProvider) { } + /// + /// 执行归档任务的主方法。 + /// 查询60天前的数据,分批归档到指定表,并从主表删除,操作包含事务控制。 + /// + /// 服务提供者 + /// 异步任务 protected override async Task RunAsync(IServiceProvider serviceProvider) { - //设置60天前的数据需要归档 + // 设置60天前的数据需要归档 var before60Days = DateTime.Today.AddDays(-60).AddSeconds(1); - //每次查询500条数据 + // 每次查询500条数据 const int limit = 500; - //归档表 + // 归档表 const string tableName = "deviceuploadlog_20250107"; - //正序获取数据 - var data = await DbContext.Queryable() - .Where(x => x.RaiseDateTime < before60Days) - .OrderBy(x => x.Id) - .ToPageListAsync(1, limit); - + /* + 分批查询并归档60天前的设备通行记录数据。 + 每次最多处理500条数据,先从主表删除,再插入到归档表,整个过程在事务中完成。 + 若查询到的数据量等于分页上限,则继续处理下一批,直到数据处理完毕。 + */ + List data; do { + data = await DbContext.Queryable() + .Where(x => x.RaiseDateTime < before60Days) + .OrderBy(x => x.Id) + .ToPageListAsync(1, limit); + + // ReSharper disable once InvertIf if (data.Any()) { await DbContext.Client.Ado.BeginTranAsync(); try { - //删除数据 await DbContext.DeleteReallyAsync(data); foreach (var item in data) { item.Id = 0; } - //插入到归档表 await DbContext.Client.Insertable(data).AS(tableName).ExecuteCommandAsync(); await DbContext.Client.Ado.CommitTranAsync(); } - catch (Exception) + catch //忽略异常,确保99.99%情况下异常不会触发!!! { await DbContext.Client.Ado.RollbackTranAsync(); } await Task.Delay(200); - - //再次获取数据 - data = await DbContext.Queryable().Where(x => x.RaiseDateTime < before60Days).OrderBy(x => x.Id).ToPageListAsync(1, limit); } } while (data.Count == limit); } diff --git a/Src/Dlhis.ScheduledTask/Jobs/CancelDuplicationTaskJob.cs b/Src/Dlhis.ScheduledTask/Jobs/CancelDuplicationTaskJob.cs deleted file mode 100644 index 93b83db4..00000000 --- a/Src/Dlhis.ScheduledTask/Jobs/CancelDuplicationTaskJob.cs +++ /dev/null @@ -1,138 +0,0 @@ -//using Dlhis.Entity.Device.Entities; -//using Dlhis.Entity.Device.Enums; -//using Kurisu.AspNetCore.Utils.Extensions; -//using Kurisu.Scheduled; -//using Kurisu.Scheduled.Attributes; -//using SqlSugar; -//using System.Linq.Expressions; - -//namespace Dlhis.ScheduledTask.Jobs; - -///// -///// 处理重复下发任务 -///// -//[RecurringJob(nameof(CancelDuplicationTaskJob), "0/15 * * * * ?", Name = "处理重复下发任务")] -//public class CancelDuplicationTaskJob : BaseJob -//{ -// public CancelDuplicationTaskJob(IServiceProvider serviceProvider) : base(serviceProvider) -// { -// } - -// public override async Task RunAsync(IServiceProvider serviceProvider) -// { -// //人员下发任务相关 -// var taskTypes = new List() { DeviceTaskEnumType.Add, DeviceTaskEnumType.Delete, DeviceTaskEnumType.Update }; - -// var deviceTasks = await DbContext.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 = LinqExpressionExtensions.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 DbContext.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 DbContext.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); -// } -// } -// } -// } - -// class IdVersion -// { -// public long Id { get; set; } -// public int Version { get; set; } -// } -//} - diff --git a/Src/Dlhis.ScheduledTask/Jobs/CreateBirthdayTicketJob.cs b/Src/Dlhis.ScheduledTask/Jobs/CreateBirthdayTicketJob.cs index 75058d75..acf5d064 100644 --- a/Src/Dlhis.ScheduledTask/Jobs/CreateBirthdayTicketJob.cs +++ b/Src/Dlhis.ScheduledTask/Jobs/CreateBirthdayTicketJob.cs @@ -1,22 +1,22 @@ -using Dlhis.Canteen.Api; -using Dlhis.Entity.Canteen.Enums; -using Dlhis.ScheduledTask.Attributes; - -namespace Dlhis.ScheduledTask.Jobs; - -/// -/// -/// -[RecurringJob(nameof(CreateBirthdayTicketJob), "0 0 1 * * ?", Name = "生日券发放")] -public class CreateBirthdayTicketJob : BaseJob -{ - public CreateBirthdayTicketJob(IServiceProvider serviceProvider) : base(serviceProvider) - { - } - - /// - protected override async Task RunAsync(IServiceProvider serviceProvider) - { - await serviceProvider.GetService().CreateAsync(TicketEnumType.Birthday.ToString()); - } -} \ No newline at end of file +// using Dlhis.Canteen.Api; +// using Dlhis.Entity.Canteen.Enums; +// using Dlhis.ScheduledTask.Attributes; +// +// namespace Dlhis.ScheduledTask.Jobs; +// +// /// +// /// +// /// +// [RecurringJob(nameof(CreateBirthdayTicketJob), "0 0 1 * * ?", Name = "生日券发放")] +// public class CreateBirthdayTicketJob : BaseJob +// { +// public CreateBirthdayTicketJob(IServiceProvider serviceProvider) : base(serviceProvider) +// { +// } +// +// /// +// protected override async Task RunAsync(IServiceProvider serviceProvider) +// { +// await serviceProvider.GetService().CreateAsync(TicketEnumType.Birthday.ToString()); +// } +// } \ No newline at end of file diff --git a/Src/Dlhis.ScheduledTask/Jobs/DeleteApiLogTaskJob.cs b/Src/Dlhis.ScheduledTask/Jobs/DeleteApiLogTaskJob.cs deleted file mode 100644 index 094e3954..00000000 --- a/Src/Dlhis.ScheduledTask/Jobs/DeleteApiLogTaskJob.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Dlhis.Entity.Common.Entities; -using Dlhis.ScheduledTask.Attributes; - -namespace Dlhis.ScheduledTask.Jobs; - -/// -/// 删除过期日志 -/// -[RecurringJob(nameof(DeleteApiLogTaskJob), "0 0 0 */6 * ?", Name = "删除过期日志")] -public class DeleteApiLogTaskJob : BaseJob -{ - public DeleteApiLogTaskJob(IServiceProvider serviceProvider) : base(serviceProvider) - { - } - - protected override async Task RunAsync(IServiceProvider serviceProvider) - { - var before = DateTime.Now.Date.AddDays(-60); - await DbContext.ChangeDb("log").Client.Deleteable().Where(x => x._ts <= before).ExecuteCommandAsync(); - } -} - - diff --git a/Src/Dlhis.ScheduledTask/Jobs/SyncOrganizationJob.cs b/Src/Dlhis.ScheduledTask/Jobs/SyncOrganizationJob.cs index 48bf832f..3896edd1 100644 --- a/Src/Dlhis.ScheduledTask/Jobs/SyncOrganizationJob.cs +++ b/Src/Dlhis.ScheduledTask/Jobs/SyncOrganizationJob.cs @@ -8,7 +8,7 @@ namespace Dlhis.ScheduledTask.Jobs; /// /// SAP组织架构数据同步 /// -[RecurringJob(nameof(SyncOrganizationJob), "0 0/30 * * * ?", Name = "SAP组织架构数据同步")] +[RecurringJob(nameof(SyncOrganizationJob), "0 0 0/1 * * ? ", Name = "SAP组织架构数据同步")] public class SyncOrganizationJob : BaseJob { private readonly ISyncApi _syncApi; diff --git a/Src/Dlhis.ScheduledTask/Jobs/SyncPersonJob.cs b/Src/Dlhis.ScheduledTask/Jobs/SyncPersonJob.cs index ddb88339..8987d412 100644 --- a/Src/Dlhis.ScheduledTask/Jobs/SyncPersonJob.cs +++ b/Src/Dlhis.ScheduledTask/Jobs/SyncPersonJob.cs @@ -2,14 +2,13 @@ using Dlhis.Entity.Basic.Entity; using Dlhis.ScheduledTask.Attributes; using Hangfire; -using Kurisu.AspNetCore.Utils.Extensions; namespace Dlhis.ScheduledTask.Jobs; /// /// SAP人员信息同步(按人事范围拆分) /// -[RecurringJob(nameof(SyncPersonJob), "0 0 3,12,18 * * ?", Name = "SAP人员信息同步")] +[RecurringJob(nameof(SyncPersonJob), "0 0 3,14 * * ?", Name = "SAP人员信息同步")] public class SyncPersonJob : BaseJob { public SyncPersonJob(IServiceProvider serviceProvider) : base(serviceProvider) diff --git a/Src/Dlhis.ScheduledTask/Packs/JobPack.cs b/Src/Dlhis.ScheduledTask/Packs/JobPack.cs index c95386dd..66d0652e 100644 --- a/Src/Dlhis.ScheduledTask/Packs/JobPack.cs +++ b/Src/Dlhis.ScheduledTask/Packs/JobPack.cs @@ -51,7 +51,7 @@ public class JobPack : BaseAppPack (jobs.Select(job => job.GetCustomAttribute()!.UniqueJobKey).Distinct().Count() != jobs.Count).ThrowIfTrue("任务key重复"); // 记录发现的任务数量 - logger.LogDebug("一共获取{count}个调度任务", jobs.Count); + logger.LogInformation("一共获取{count}个调度任务", jobs.Count); // 遍历每个发现的任务并进行调度 foreach (var job in jobs)