This commit is contained in:
wanghu
2026-09-02 10:23:24 +08:00
parent 5a414b14d2
commit ce436cbb32
117 changed files with 13768 additions and 0 deletions
+71
View File
@@ -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));
}
}
}
}
+75
View File
@@ -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;
}
}
}
+25
View File
@@ -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>