bag
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Quartz;
|
||||
using YhCore.Entity;
|
||||
using YhCore.Repository;
|
||||
|
||||
namespace YhCore.Tasks.Jobs
|
||||
{
|
||||
/// <summary>
|
||||
/// 审计日志清理 Job(对应 Java scheduler/SysOperationLogCleanupTask)。
|
||||
/// 定时删除 30 天前的系统审计日志(sys_operation_log 表)。
|
||||
/// </summary>
|
||||
public class CleanupLogJob : IJob
|
||||
{
|
||||
private const int BatchSize = 1000;
|
||||
|
||||
public async Task Execute(IJobExecutionContext context)
|
||||
{
|
||||
var services = (IServiceProvider)context.Scheduler.Context.Get("services");
|
||||
using var scope = services.CreateScope();
|
||||
var provider = scope.ServiceProvider;
|
||||
|
||||
var logger = provider.GetRequiredService<ILogger<CleanupLogJob>>();
|
||||
var repo = provider.GetRequiredService<IRepository<SysOperationLog>>();
|
||||
|
||||
var cutoff = DateTime.Now.AddDays(-30);
|
||||
logger.LogInformation("审计日志清理开始:删除 {Cutoff:yyyy-MM-dd HH:mm:ss} 之前的数据", cutoff);
|
||||
|
||||
try
|
||||
{
|
||||
var oldList = await repo.FindAsync(l => l.CreateTime < cutoff);
|
||||
if (oldList.Count == 0)
|
||||
{
|
||||
logger.LogInformation("审计日志清理完成:无 30 天前的数据");
|
||||
return;
|
||||
}
|
||||
|
||||
logger.LogInformation("审计日志清理:待删除 {Count} 条,分块提交(每批 {Batch} 条)", oldList.Count, BatchSize);
|
||||
|
||||
var removed = 0;
|
||||
foreach (var batch in Chunk(oldList, BatchSize))
|
||||
{
|
||||
foreach (var item in batch)
|
||||
{
|
||||
await repo.RemoveAsync(item);
|
||||
}
|
||||
removed += await repo.SaveChangesAsync();
|
||||
}
|
||||
|
||||
logger.LogInformation("审计日志清理完成:共删除 {Count} 条", removed);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 缺表/数据库异常时记录错误日志,不让 Job 崩溃(Quartz 连续失败会标记 Job 错误状态)
|
||||
logger.LogError(ex, "审计日志清理失败:{Message}", ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>将列表分块(net5.0 无 Enumerable.Chunk,自行实现)</summary>
|
||||
private static IEnumerable<List<T>> Chunk<T>(List<T> source, int size)
|
||||
{
|
||||
for (var i = 0; i < source.Count; i += size)
|
||||
{
|
||||
yield return source.GetRange(i, Math.Min(size, source.Count - i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Quartz;
|
||||
using YhCore.Tasks.Jobs;
|
||||
|
||||
namespace YhCore.Tasks
|
||||
{
|
||||
/// <summary>
|
||||
/// Quartz 调度宿主(对应 Java scheduler 包由 Spring 管理的调度器)。
|
||||
/// 承载框架内置 Job 模板;业务 Job 在 InitJobs 中追加注册。
|
||||
/// </summary>
|
||||
public class QuartzHostedService : IHostedService
|
||||
{
|
||||
private const string ServiceProviderKey = "services";
|
||||
|
||||
private readonly ISchedulerFactory _schedulerFactory;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private IScheduler _scheduler;
|
||||
|
||||
public QuartzHostedService(ISchedulerFactory schedulerFactory, IServiceProvider serviceProvider)
|
||||
{
|
||||
_schedulerFactory = schedulerFactory;
|
||||
_serviceProvider = serviceProvider;
|
||||
}
|
||||
|
||||
public async Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
_scheduler = await _schedulerFactory.GetScheduler(cancellationToken);
|
||||
_scheduler.Context.Put(ServiceProviderKey, _serviceProvider); // Job 经此取 DI 服务
|
||||
|
||||
await InitJobs();
|
||||
|
||||
await _scheduler.Start(cancellationToken);
|
||||
}
|
||||
|
||||
public async Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
if (_scheduler != null)
|
||||
{
|
||||
await _scheduler.Shutdown(waitForJobsToComplete: true, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task InitJobs()
|
||||
{
|
||||
// ============ 定时任务注册 ============
|
||||
|
||||
// 1. 审计日志清理(对应 Java SysOperationLogCleanupTask:每日凌晨 3:30 删除 30 天前 sys_operation_log 数据)
|
||||
await ScheduleJobAsync<CleanupLogJob>("cleanup-log-job", "0 30 3 * * ?");
|
||||
|
||||
// 2. 其他业务 Job 在此追加注册(示例:每 10 分钟执行一次)
|
||||
// await ScheduleJobAsync<TJob>("job-name", "0 */10 * * * ?");
|
||||
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>注册一个 Cron 定时任务</summary>
|
||||
protected async Task ScheduleJobAsync<TJob>(string jobName, string cronExpression) where TJob : IJob
|
||||
{
|
||||
var job = JobBuilder.Create<TJob>()
|
||||
.WithIdentity(jobName)
|
||||
.Build();
|
||||
|
||||
var trigger = TriggerBuilder.Create()
|
||||
.WithIdentity(jobName + "-trigger")
|
||||
.WithCronSchedule(cronExpression)
|
||||
.Build();
|
||||
|
||||
await _scheduler.ScheduleJob(job, trigger);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Quartz;
|
||||
using Quartz.Impl;
|
||||
|
||||
namespace YhCore.Tasks
|
||||
{
|
||||
/// <summary>
|
||||
/// 任务调度注册扩展:Quartz 调度器工厂 + 宿主服务(对应 Java scheduler 自动装配)。
|
||||
/// </summary>
|
||||
public static class QuartzServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection AddQuartzHosted(this IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<ISchedulerFactory, StdSchedulerFactory>();
|
||||
services.AddHostedService<QuartzHostedService>();
|
||||
return services;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<RootNamespace>YhCore.Task</RootNamespace>
|
||||
<AssemblyName>YhCore.Task</AssemblyName>
|
||||
<LangVersion>9.0</LangVersion>
|
||||
<Nullable>disable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- 任务调度:对应 Java Quartz / scheduler 包 -->
|
||||
<PackageReference Include="Quartz" Version="3.3.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\YhCore.Common\YhCore.Common.csproj" />
|
||||
<ProjectReference Include="..\YhCore.Entity\YhCore.Entity.csproj" />
|
||||
<ProjectReference Include="..\YhCore.Repository\YhCore.Repository.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
Reference in New Issue
Block a user