From b75a8cb60d69321cabaabc1505581f8ac56a0553 Mon Sep 17 00:00:00 2001 From: chenchun Date: Fri, 15 Nov 2024 16:45:01 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=85=A8=E9=87=8Fquarzt=E5=88=B0hangfi?= =?UTF-8?q?re=E4=BB=BB=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Jobs/AccessLogCacheJob.cs | 24 +- .../Jobs/AccessLogStoreJob.cs | 23 +- .../Jobs/AssignmentExpireTimeOutJob.cs | 22 +- .../Jobs/InterestRecordsJob.cs | 21 +- .../Services/BbsUserInfoService.cs | 10 +- .../Services/Forum/CommentService.cs | 5 + .../Jobs/BackupDataBaseJob.cs | 15 +- .../Services/Monitor/TaskService.cs | 220 ---------- .../Yi.Framework.Rbac.Application.csproj | 4 +- .../YiFrameworkRbacApplicationModule.cs | 5 +- .../Yi.Abp.Application/Jobs/DemoResetJob.cs | 19 +- .../src/Yi.Abp.Application/Jobs/TestJob.cs | 21 +- Yi.Abp.Net8/src/Yi.Abp.Web/Yi.Abp.Web.csproj | 1 + Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs | 408 ++++++++++-------- .../YiHangfireConventionalRegistrar.cs | 20 + .../YiFrameworkRbacTestModule.cs | 12 +- 16 files changed, 348 insertions(+), 482 deletions(-) delete mode 100644 Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/Monitor/TaskService.cs create mode 100644 Yi.Abp.Net8/src/Yi.Abp.Web/YiHangfireConventionalRegistrar.cs diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Jobs/AccessLogCacheJob.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Jobs/AccessLogCacheJob.cs index 8f936574..63b3b4d0 100644 --- a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Jobs/AccessLogCacheJob.cs +++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Jobs/AccessLogCacheJob.cs @@ -1,8 +1,8 @@ using FreeRedis; +using Hangfire; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Options; -using Quartz; -using Volo.Abp.BackgroundWorkers.Quartz; +using Volo.Abp.BackgroundWorkers.Hangfire; using Volo.Abp.Caching; using Volo.Abp.DependencyInjection; using Volo.Abp.Domain.Entities; @@ -15,23 +15,27 @@ using Yi.Framework.SqlSugarCore.Abstractions; namespace Yi.Framework.Bbs.Application.Jobs; -public class AccessLogCacheJob : QuartzBackgroundWorkerBase +public class AccessLogCacheJob : HangfireBackgroundWorkerBase { private readonly ILocalEventBus _localEventBus; public AccessLogCacheJob(ILocalEventBus localEventBus) { _localEventBus = localEventBus; - JobDetail = JobBuilder.Create().WithIdentity(nameof(AccessLogCacheJob)) - .Build(); + RecurringJobId = "访问日志写入缓存"; + //每10秒执行一次,将本地缓存转入redis,防止丢数据 + CronExpression = "*/10 * * * * *"; + // + // JobDetail = JobBuilder.Create().WithIdentity(nameof(AccessLogCacheJob)) + // .Build(); //每10秒执行一次,将本地缓存转入redis,防止丢数据 - Trigger = TriggerBuilder.Create().WithIdentity(nameof(AccessLogCacheJob)) - .WithSimpleSchedule((schedule) => { schedule.WithInterval(TimeSpan.FromSeconds(10)).RepeatForever();; }) - .Build(); + // Trigger = TriggerBuilder.Create().WithIdentity(nameof(AccessLogCacheJob)) + // .WithSimpleSchedule((schedule) => { schedule.WithInterval(TimeSpan.FromSeconds(10)).RepeatForever();; }) + // .Build(); } - - public override async Task Execute(IJobExecutionContext context) + + public override async Task DoWorkAsync(CancellationToken cancellationToken = new CancellationToken()) { await _localEventBus.PublishAsync(new AccessLogResetArgs()); } diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Jobs/AccessLogStoreJob.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Jobs/AccessLogStoreJob.cs index 66cc24d5..8fb30491 100644 --- a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Jobs/AccessLogStoreJob.cs +++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Jobs/AccessLogStoreJob.cs @@ -1,11 +1,9 @@ using FreeRedis; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Options; -using Quartz; -using Volo.Abp.BackgroundWorkers.Quartz; +using Volo.Abp.BackgroundWorkers.Hangfire; using Volo.Abp.Caching; using Volo.Abp.DependencyInjection; -using Volo.Abp.Domain.Entities; using Yi.Framework.Bbs.Domain.Entities; using Yi.Framework.Bbs.Domain.Shared.Caches; using Yi.Framework.Bbs.Domain.Shared.Enums; @@ -13,7 +11,7 @@ using Yi.Framework.SqlSugarCore.Abstractions; namespace Yi.Framework.Bbs.Application.Jobs; -public class AccessLogStoreJob : QuartzBackgroundWorkerBase +public class AccessLogStoreJob : HangfireBackgroundWorkerBase { private readonly ISqlSugarRepository _repository; @@ -45,18 +43,23 @@ public class AccessLogStoreJob : QuartzBackgroundWorkerBase public AccessLogStoreJob(ISqlSugarRepository repository) { _repository = repository; - JobDetail = JobBuilder.Create().WithIdentity(nameof(AccessLogStoreJob)) - .Build(); + + RecurringJobId = "访问日志写入数据库"; //每分钟执行一次 - Trigger = TriggerBuilder.Create().WithIdentity(nameof(AccessLogStoreJob)) - .WithCronSchedule("0 * * * * ?") - .Build(); + CronExpression = "0 * * * * ?"; + // JobDetail = JobBuilder.Create().WithIdentity(nameof(AccessLogStoreJob)) + // .Build(); + // //每分钟执行一次 + // Trigger = TriggerBuilder.Create().WithIdentity(nameof(AccessLogStoreJob)) + // .WithCronSchedule("0 * * * * ?") + // .Build(); } + - public override async Task Execute(IJobExecutionContext context) + public override async Task DoWorkAsync(CancellationToken cancellationToken = new CancellationToken()) { if (EnableRedisCache) { diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Jobs/AssignmentExpireTimeOutJob.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Jobs/AssignmentExpireTimeOutJob.cs index 937fb689..1238c979 100644 --- a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Jobs/AssignmentExpireTimeOutJob.cs +++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Jobs/AssignmentExpireTimeOutJob.cs @@ -1,5 +1,4 @@ -using Quartz; -using Volo.Abp.BackgroundWorkers.Quartz; +using Volo.Abp.BackgroundWorkers.Hangfire; using Yi.Framework.Bbs.Domain.Managers; namespace Yi.Framework.Bbs.Application.Jobs; @@ -7,20 +6,25 @@ namespace Yi.Framework.Bbs.Application.Jobs; /// /// 每日任务job /// -public class AssignmentExpireTimeOutJob : QuartzBackgroundWorkerBase +public class AssignmentExpireTimeOutJob : HangfireBackgroundWorkerBase { private readonly AssignmentManager _assignmentManager; public AssignmentExpireTimeOutJob(AssignmentManager assignmentManager) { _assignmentManager = assignmentManager; - JobDetail = JobBuilder.Create().WithIdentity(nameof(AssignmentExpireTimeOutJob)).Build(); - //每个小时整点执行一次 - Trigger = TriggerBuilder.Create().WithIdentity(nameof(AssignmentExpireTimeOutJob)).WithCronSchedule("0 0 * * * ?") - .Build(); + + RecurringJobId = "每日任务系统超时检测"; + //每分钟执行一次 + CronExpression = "0 * * * * ?"; + // + // JobDetail = JobBuilder.Create().WithIdentity(nameof(AssignmentExpireTimeOutJob)).Build(); + // //每个小时整点执行一次 + // Trigger = TriggerBuilder.Create().WithIdentity(nameof(AssignmentExpireTimeOutJob)).WithCronSchedule("0 0 * * * ?") + // .Build(); } - - public override async Task Execute(IJobExecutionContext context) + + public override async Task DoWorkAsync(CancellationToken cancellationToken = new CancellationToken()) { await _assignmentManager.ExpireTimeoutAsync(); } diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Jobs/InterestRecordsJob.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Jobs/InterestRecordsJob.cs index 80837a9e..85bfafdd 100644 --- a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Jobs/InterestRecordsJob.cs +++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Jobs/InterestRecordsJob.cs @@ -1,20 +1,24 @@ -using Quartz; -using Volo.Abp.BackgroundWorkers.Quartz; +using Volo.Abp.BackgroundWorkers.Hangfire; using Yi.Framework.Bbs.Domain.Managers; namespace Yi.Framework.Bbs.Application.Jobs { - public class InterestRecordsJob : QuartzBackgroundWorkerBase + public class InterestRecordsJob : HangfireBackgroundWorkerBase { private BankManager _bankManager; public InterestRecordsJob(BankManager bankManager) { _bankManager = bankManager; - JobDetail = JobBuilder.Create().WithIdentity(nameof(InterestRecordsJob)).Build(); - + + RecurringJobId = "银行利息积分刷新"; //每个小时整点执行一次 - - Trigger = TriggerBuilder.Create().WithIdentity(nameof(InterestRecordsJob)).WithCronSchedule("0 0 * * * ?").Build(); + CronExpression = "0 0 * * * ?"; + + // JobDetail = JobBuilder.Create().WithIdentity(nameof(InterestRecordsJob)).Build(); + // + // //每个小时整点执行一次 + // + // Trigger = TriggerBuilder.Create().WithIdentity(nameof(InterestRecordsJob)).WithCronSchedule("0 0 * * * ?").Build(); //测试 // Trigger = TriggerBuilder.Create().WithIdentity(nameof(InterestRecordsJob)) @@ -23,7 +27,8 @@ namespace Yi.Framework.Bbs.Application.Jobs // .RepeatForever()) //.Build(); } - public override async Task Execute(IJobExecutionContext context) + + public override async Task DoWorkAsync(CancellationToken cancellationToken = new CancellationToken()) { //创建一个记录,莫得了 await _bankManager.GetCurrentInterestRate(); diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Services/BbsUserInfoService.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Services/BbsUserInfoService.cs index 0e93ced2..91c0c739 100644 --- a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Services/BbsUserInfoService.cs +++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Services/BbsUserInfoService.cs @@ -27,13 +27,19 @@ namespace Yi.Framework.Bbs.Application.Services var userEntity = await _bbsUserManager._userRepository.GetFirstAsync(x => x.UserName == userNameOrUserId); if (userEntity == null) { - throw new Volo.Abp.UserFriendlyException("该用户不存在"); + throw new UserFriendlyException("该用户不存在"); } userId= userEntity.Id; } var output =await _bbsUserManager.GetBbsUserInfoAsync(userId); - + + //不是自己 + if (CurrentUser.Id != output.Id) + { + output.Phone = null; + output.Email=null; + } return output!; } } diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Services/Forum/CommentService.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Services/Forum/CommentService.cs index 52db5120..b8926f13 100644 --- a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Services/Forum/CommentService.cs +++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Services/Forum/CommentService.cs @@ -136,6 +136,11 @@ namespace Yi.Framework.Bbs.Application.Services.Forum [Authorize] public override async Task CreateAsync(CommentCreateInputVo input) { + if (input.Content.Length<=6) + { + throw new UserFriendlyException("评论长度至少大于6"); + } + var discuess = await _discussRepository.GetFirstAsync(x => x.Id == input.DiscussId); if (discuess is null) { diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Jobs/BackupDataBaseJob.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Jobs/BackupDataBaseJob.cs index 7db58b06..88398f87 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Jobs/BackupDataBaseJob.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Jobs/BackupDataBaseJob.cs @@ -6,16 +6,14 @@ using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; -using Quartz; -using Quartz.Logging; -using Volo.Abp.BackgroundWorkers.Quartz; +using Volo.Abp.BackgroundWorkers.Hangfire; using Volo.Abp.Domain.Repositories; using Yi.Framework.Rbac.Domain.Shared.Options; using Yi.Framework.SqlSugarCore.Abstractions; namespace Yi.Framework.Rbac.Application.Jobs { - public class BackupDataBaseJob : QuartzBackgroundWorkerBase + public class BackupDataBaseJob: HangfireBackgroundWorkerBase { private ISqlSugarDbContext _dbContext; private IOptions _options; @@ -24,13 +22,12 @@ namespace Yi.Framework.Rbac.Application.Jobs _options = options; _dbContext = dbContext; - JobDetail = JobBuilder.Create().WithIdentity(nameof(BackupDataBaseJob)).Build(); - + + RecurringJobId = "数据库备份"; //每天00点与24点进行备份 - Trigger = TriggerBuilder.Create().WithIdentity(nameof(BackupDataBaseJob)).WithCronSchedule("0 0 0,12 * * ? ").Build(); - //Trigger = TriggerBuilder.Create().WithIdentity(nameof(BackupDataBaseJob)).WithSimpleSchedule(x=>x.WithIntervalInSeconds(10)).Build(); + CronExpression = "0 0 0,12 * * ? "; } - public override Task Execute(IJobExecutionContext context) + public override Task DoWorkAsync(CancellationToken cancellationToken = new CancellationToken()) { if (_options.Value.EnableDataBaseBackup) { diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/Monitor/TaskService.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/Monitor/TaskService.cs deleted file mode 100644 index ab857fb6..00000000 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/Monitor/TaskService.cs +++ /dev/null @@ -1,220 +0,0 @@ -using System.Reflection; -using Mapster; -using Microsoft.AspNetCore.Mvc; -using Quartz; -using Quartz.Impl.Matchers; -using Volo.Abp; -using Volo.Abp.Application.Dtos; -using Volo.Abp.Application.Services; -using Volo.Abp.Timing; -using Yi.Framework.Rbac.Application.Contracts.Dtos.Task; -using Yi.Framework.Rbac.Application.Contracts.IServices; -using Yi.Framework.Rbac.Domain.Shared.Enums; - -namespace Yi.Framework.Rbac.Application.Services.Monitor -{ - public class TaskService : ApplicationService, ITaskService - { - private readonly ISchedulerFactory _schedulerFactory; - private readonly IClock _clock; - public TaskService(ISchedulerFactory schedulerFactory, IClock clock) - { - _clock = clock; - _schedulerFactory = schedulerFactory; - } - - - /// - /// 单查job - /// - /// - /// - [HttpGet("task/{jobId}")] - public async Task GetAsync([FromRoute] string jobId) - { - var scheduler = await _schedulerFactory.GetScheduler(); - - var jobDetail = await scheduler.GetJobDetail(new JobKey(jobId)); - var trigger = (await scheduler.GetTriggersOfJob(new JobKey(jobId))).First(); - //状态 - var state = await scheduler.GetTriggerState(trigger.Key); - - - var output = new TaskGetOutput - { - JobId = jobDetail.Key.Name, - GroupName = jobDetail.Key.Group, - JobType = jobDetail.JobType.Name, - Properties = Newtonsoft.Json.JsonConvert.SerializeObject(jobDetail.JobDataMap), - Concurrent = !jobDetail.ConcurrentExecutionDisallowed, - Description = jobDetail.Description, - LastRunTime = _clock.Normalize(trigger.GetPreviousFireTimeUtc()?.DateTime ?? DateTime.MinValue), - NextRunTime = _clock.Normalize(trigger.GetNextFireTimeUtc()?.DateTime ?? DateTime.MinValue), - AssemblyName = jobDetail.JobType.Assembly.GetName().Name, - Status = state.ToString() - }; - - if (trigger is ISimpleTrigger simple) - { - output.TriggerArgs = Math.Round(simple.RepeatInterval.TotalMinutes, 2).ToString() + "分钟"; - output.Type = JobTypeEnum.Millisecond; - output.Millisecond = simple.RepeatInterval.TotalMilliseconds; - } - else if (trigger is ICronTrigger cron) - { - output.TriggerArgs = cron.CronExpressionString!; - output.Type = JobTypeEnum.Cron; - output.Cron = cron.CronExpressionString; - } - return output; - } - - /// - /// 多查job - /// - /// - public async Task> GetListAsync([FromQuery] TaskGetListInput input) - { - var items = new List(); - - var scheduler = await _schedulerFactory.GetScheduler(); - - var groups = await scheduler.GetJobGroupNames(); - - foreach (var groupName in groups) - { - foreach (var jobKey in await scheduler.GetJobKeys(GroupMatcher.GroupEquals(groupName))) - { - string jobName = jobKey.Name; - string jobGroup = jobKey.Group; - var triggers = (await scheduler.GetTriggersOfJob(jobKey)).First(); - items.Add(await GetAsync(jobName)); - } - } - - - var output = items.Skip((input.SkipCount - 1) * input.MaxResultCount).Take(input.MaxResultCount) - .OrderByDescending(x => x.LastRunTime) - .ToList(); - return new PagedResultDto(items.Count(), output.Adapt>()); - } - - /// - /// 创建job - /// - /// - /// - public async Task CreateAsync(TaskCreateInput input) - { - var scheduler = await _schedulerFactory.GetScheduler(); - - //设置启动时执行一次,然后最大只执行一次 - - - //jobBuilder - var jobClassType = Assembly.Load(input.AssemblyName).GetTypes().Where(x => x.Name == input.JobType).FirstOrDefault(); - - if (jobClassType is null) - { - throw new UserFriendlyException($"程序集:{input.AssemblyName},{input.JobType} 不存在"); - } - - var jobBuilder = JobBuilder.Create(jobClassType).WithIdentity(new JobKey(input.JobId, input.GroupName)) - .WithDescription(input.Description); - if (!input.Concurrent) - { - jobBuilder.DisallowConcurrentExecution(); - } - - //triggerBuilder - TriggerBuilder triggerBuilder = null; - switch (input.Type) - { - case JobTypeEnum.Cron: - triggerBuilder = - TriggerBuilder.Create() - .WithCronSchedule(input.Cron); - - - - - break; - case JobTypeEnum.Millisecond: - triggerBuilder = - TriggerBuilder.Create().StartNow() - .WithSimpleSchedule(x => x - .WithInterval(TimeSpan.FromMilliseconds(input.Millisecond ?? 10000)) - .RepeatForever() - ); - break; - } - - //作业计划,单个jobBuilder与多个triggerBuilder组合 - await scheduler.ScheduleJob(jobBuilder.Build(), triggerBuilder.Build()); - } - - /// - /// 移除job - /// - /// - /// - public async Task DeleteAsync(IEnumerable id) - { - var scheduler = await _schedulerFactory.GetScheduler(); - await scheduler.DeleteJobs(id.Select(x => new JobKey(x)).ToList()); - } - - /// - /// 暂停job - /// - /// - /// - [HttpPut] - public async Task PauseAsync(string jobId) - { - var scheduler = await _schedulerFactory.GetScheduler(); - await scheduler.PauseJob(new JobKey(jobId)); - } - - /// - /// 开始job - /// - /// - /// - [HttpPut] - public async Task StartAsync(string jobId) - { - var scheduler = await _schedulerFactory.GetScheduler(); - await scheduler.ResumeJob(new JobKey(jobId)); - } - - /// - /// 更新job - /// - /// - /// - /// - public async Task UpdateAsync(string id, TaskUpdateInput input) - { - await DeleteAsync(new List() { id }); - await CreateAsync(input.Adapt()); - } - - [HttpPost("task/run-once/{id}")] - public async Task RunOnceAsync([FromRoute] string id) - { - var scheduler = await _schedulerFactory.GetScheduler(); - var jobDetail = await scheduler.GetJobDetail(new JobKey(id)); - - var jobBuilder = JobBuilder.Create(jobDetail.JobType).WithIdentity(new JobKey(Guid.NewGuid().ToString())); - //设置启动时执行一次,然后最大只执行一次 - var trigger = TriggerBuilder.Create().WithIdentity(Guid.NewGuid().ToString()).StartNow() - .WithSimpleSchedule(x => x - .WithIntervalInHours(1) - .WithRepeatCount(1)) - .Build(); - - await scheduler.ScheduleJob(jobBuilder.Build(), trigger); - } - } -} diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Yi.Framework.Rbac.Application.csproj b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Yi.Framework.Rbac.Application.csproj index b9536345..d7fcf3c9 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Yi.Framework.Rbac.Application.csproj +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Yi.Framework.Rbac.Application.csproj @@ -10,7 +10,9 @@ - + + + diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/YiFrameworkRbacApplicationModule.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/YiFrameworkRbacApplicationModule.cs index 13d07949..0a5f1a59 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/YiFrameworkRbacApplicationModule.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/YiFrameworkRbacApplicationModule.cs @@ -2,7 +2,7 @@ using Microsoft.Extensions.DependencyInjection; using Volo.Abp; using Volo.Abp.BackgroundWorkers; -using Volo.Abp.BackgroundWorkers.Quartz; +using Volo.Abp.BackgroundWorkers.Hangfire; using Volo.Abp.Modularity; using Yi.Framework.Ddd.Application; using Yi.Framework.Rbac.Application.Contracts; @@ -17,7 +17,7 @@ namespace Yi.Framework.Rbac.Application typeof(YiFrameworkDddApplicationModule), - typeof(AbpBackgroundWorkersQuartzModule) + typeof(AbpBackgroundWorkersHangfireModule) )] public class YiFrameworkRbacApplicationModule : AbpModule { @@ -28,7 +28,6 @@ namespace Yi.Framework.Rbac.Application service.AddCaptcha(options => { options.CaptchaType = CaptchaType.ARITHMETIC; - }); } diff --git a/Yi.Abp.Net8/src/Yi.Abp.Application/Jobs/DemoResetJob.cs b/Yi.Abp.Net8/src/Yi.Abp.Application/Jobs/DemoResetJob.cs index a91e7c5e..86c60a08 100644 --- a/Yi.Abp.Net8/src/Yi.Abp.Application/Jobs/DemoResetJob.cs +++ b/Yi.Abp.Net8/src/Yi.Abp.Application/Jobs/DemoResetJob.cs @@ -1,15 +1,13 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; -using Quartz; -using Quartz.Logging; -using Volo.Abp.BackgroundWorkers.Quartz; +using Volo.Abp.BackgroundWorkers.Hangfire; using Volo.Abp.Data; using Yi.Framework.Rbac.Domain.Entities; using Yi.Framework.SqlSugarCore.Abstractions; namespace Yi.Abp.Application.Jobs { - public class DemoResetJob : QuartzBackgroundWorkerBase + public class DemoResetJob : HangfireBackgroundWorkerBase { private ISqlSugarDbContext _dbContext; private ILogger _logger => LoggerFactory.CreateLogger(); @@ -18,15 +16,15 @@ namespace Yi.Abp.Application.Jobs public DemoResetJob(ISqlSugarDbContext dbContext, IDataSeeder dataSeeder, IConfiguration configuration) { _dbContext = dbContext; - JobDetail = JobBuilder.Create().WithIdentity(nameof(DemoResetJob)).Build(); - - //每天01点与13点,演示环境进行重置 - Trigger = TriggerBuilder.Create().WithIdentity(nameof(DemoResetJob)).WithCronSchedule("0 0 1,13 * * ? ").Build(); - // Trigger = TriggerBuilder.Create().WithIdentity(nameof(DemoResetJob)).WithSimpleSchedule(x=>x.WithIntervalInSeconds(10)).Build(); + RecurringJobId = "重置demo环境"; + //每天1点和13点进行重置demo环境 + CronExpression = "0 0 1,13 * * ?"; + _dataSeeder = dataSeeder; _configuration = configuration; } - public override async Task Execute(IJobExecutionContext context) + + public override async Task DoWorkAsync(CancellationToken cancellationToken = new CancellationToken()) { //开启演示环境重置功能 if (_configuration.GetSection("EnableDemoReset").Get()) @@ -50,7 +48,6 @@ namespace Yi.Abp.Application.Jobs } - } } } diff --git a/Yi.Abp.Net8/src/Yi.Abp.Application/Jobs/TestJob.cs b/Yi.Abp.Net8/src/Yi.Abp.Application/Jobs/TestJob.cs index e0b68065..9c098146 100644 --- a/Yi.Abp.Net8/src/Yi.Abp.Application/Jobs/TestJob.cs +++ b/Yi.Abp.Net8/src/Yi.Abp.Application/Jobs/TestJob.cs @@ -1,6 +1,6 @@ -using Quartz; +using Hangfire; using SqlSugar; -using Volo.Abp.BackgroundWorkers.Quartz; +using Volo.Abp.BackgroundWorkers.Hangfire; using Volo.Abp.Domain.Repositories; using Volo.Abp.Uow; using Yi.Framework.Rbac.Domain.Entities; @@ -11,26 +11,21 @@ namespace Yi.Abp.Application.Jobs /// /// 定时任务 /// - public class TestJob : QuartzBackgroundWorkerBase + public class TestJob : HangfireBackgroundWorkerBase { private ISqlSugarRepository _repository; public TestJob(ISqlSugarRepository repository) { _repository = repository; - JobDetail = JobBuilder.Create().WithIdentity(nameof(TestJob)).Build(); - Trigger = TriggerBuilder.Create().WithIdentity(nameof(TestJob)).StartNow() - .WithSimpleSchedule(x => x - .WithIntervalInSeconds(1000 * 60) - .RepeatForever()) - .Build(); + RecurringJobId = "测试"; + //每天一次 + CronExpression = Cron.Daily(); } - public override async Task Execute(IJobExecutionContext context) + public override Task DoWorkAsync(CancellationToken cancellationToken = new CancellationToken()) { //定时任务,非常简单 Console.WriteLine("你好,世界"); - // var eneities= await _repository.GetListAsync(); - //var entities= await _sqlSugarClient.Queryable().ToListAsync(); - //await Console.Out.WriteLineAsync(entities.Count().ToString()); + return Task.CompletedTask; } } } diff --git a/Yi.Abp.Net8/src/Yi.Abp.Web/Yi.Abp.Web.csproj b/Yi.Abp.Net8/src/Yi.Abp.Web/Yi.Abp.Web.csproj index f50d8a24..4dbd1dd6 100644 --- a/Yi.Abp.Net8/src/Yi.Abp.Web/Yi.Abp.Web.csproj +++ b/Yi.Abp.Net8/src/Yi.Abp.Web/Yi.Abp.Web.csproj @@ -8,6 +8,7 @@ + diff --git a/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs b/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs index 8228608d..e5116649 100644 --- a/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs +++ b/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs @@ -3,6 +3,9 @@ using System.Text; using System.Text.Json.Serialization; using System.Text.Json.Serialization.Metadata; using System.Threading.RateLimiting; +using Hangfire; +using Hangfire.Dashboard; +using Hangfire.Redis.StackExchange; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Cors; using Microsoft.AspNetCore.Mvc; @@ -12,6 +15,8 @@ using Microsoft.Extensions.Options; using Microsoft.IdentityModel.Tokens; using Microsoft.OpenApi.Models; using Newtonsoft.Json.Converters; +using StackExchange.Redis; +using Volo.Abp.AspNetCore.Auditing; using Volo.Abp.AspNetCore.Authentication.JwtBearer; using Volo.Abp.AspNetCore.ExceptionHandling; using Volo.Abp.AspNetCore.MultiTenancy; @@ -21,7 +26,11 @@ using Volo.Abp.AspNetCore.Mvc.ExceptionHandling; using Volo.Abp.AspNetCore.Serilog; using Volo.Abp.Auditing; using Volo.Abp.Autofac; +using Volo.Abp.BackgroundJobs.Hangfire; +using Volo.Abp.BackgroundWorkers; +using Volo.Abp.BackgroundWorkers.Hangfire; using Volo.Abp.Caching; +using Volo.Abp.Hangfire; using Volo.Abp.Json; using Volo.Abp.Json.SystemTextJson; using Volo.Abp.MultiTenancy; @@ -57,6 +66,8 @@ namespace Yi.Abp.Web typeof(AbpSwashbuckleModule), typeof(AbpAspNetCoreSerilogModule), typeof(AbpAuditingModule), + typeof(AbpBackgroundWorkersHangfireModule), + typeof(AbpBackgroundJobsHangfireModule), typeof(AbpAspNetCoreAuthenticationJwtBearerModule), typeof(YiFrameworkAspNetCoreModule), typeof(YiFrameworkAspNetCoreAuthenticationOAuthModule) @@ -70,217 +81,241 @@ namespace Yi.Abp.Web var configuration = context.Services.GetConfiguration(); var host = context.Services.GetHostingEnvironment(); var service = context.Services; + //请求日志 Configure(optios => { //默认关闭,开启会有大量的审计日志 optios.IsEnabled = true; - //审计日志过滤器,符合条件的才记录 - optios.AlwaysLogSelectors.Add(x => Task.FromResult(x.Url is null?true:!x.Url.StartsWith("/api/app/file/"))); }); - - //采用furion格式的规范化api,默认不开启,使用abp优雅的方式 - //你没看错。。。 - //service.AddFurionUnifyResultApi(); - - //配置错误处理显示详情 - Configure(options => { options.SendExceptionsDetailsToClients = true; }); - - //动态Api - Configure(options => + //忽略审计日志路径 + Configure(options => { - options.ConventionalControllers.Create(typeof(YiAbpApplicationModule).Assembly, - options => options.RemoteServiceName = "default"); - options.ConventionalControllers.Create(typeof(YiFrameworkRbacApplicationModule).Assembly, - options => options.RemoteServiceName = "rbac"); - options.ConventionalControllers.Create(typeof(YiFrameworkBbsApplicationModule).Assembly, - options => options.RemoteServiceName = "bbs"); - options.ConventionalControllers.Create(typeof(YiFrameworkChatHubApplicationModule).Assembly, - options => options.RemoteServiceName = "chat-hub"); - options.ConventionalControllers.Create(typeof(YiFrameworkTenantManagementApplicationModule).Assembly, - options => options.RemoteServiceName = "tenant-management"); - options.ConventionalControllers.Create(typeof(YiFrameworkCodeGenApplicationModule).Assembly, - options => options.RemoteServiceName = "code-gen"); - - //统一前缀 - options.ConventionalControllers.ConventionalControllerSettings.ForEach(x => x.RootPath = "api/app"); + options.IgnoredUrls.Add("/api/app/file/"); + options.IgnoredUrls.Add("/hangfire"); }); - - //【NewtonsoftJson严重问题!!!!!逆天】设置api格式,留给后人铭记 - // service.AddControllers().AddNewtonsoftJson(options => - // { - // options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss"; - // options.SerializerSettings.Converters.Add(new StringEnumConverter()); - // }); - //请使用微软的,注意abp date又包了一层,采用DefaultJsonTypeInfoResolver统一覆盖 - Configure(options => - { - options.JsonSerializerOptions.TypeInfoResolver = new DefaultJsonTypeInfoResolver(); - options.JsonSerializerOptions.Converters.Add(new DatetimeJsonConverter()); - options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()); - }); + //采用furion格式的规范化api,默认不开启,使用abp优雅的方式 + //你没看错。。。 + //service.AddFurionUnifyResultApi(); - //设置缓存不要过期,默认滑动20分钟 - Configure(cacheOptions => - { - cacheOptions.GlobalCacheEntryOptions.SlidingExpiration = null; - //缓存key前缀 - cacheOptions.KeyPrefix = "Yi:"; - }); + //配置错误处理显示详情 + Configure(options => { options.SendExceptionsDetailsToClients = true; }); - - Configure(options => { options.AutoValidate = false; }); - - //Swagger - context.Services.AddYiSwaggerGen(options => - { - options.SwaggerDoc("default", - new OpenApiInfo { Title = "Yi.Framework.Abp", Version = "v1", Description = "集大成者" }); - }); - - //跨域 - context.Services.AddCors(options => - { - options.AddPolicy(DefaultCorsPolicyName, builder => + //动态Api + Configure(options => { - builder - .WithOrigins( - configuration["App:CorsOrigins"]! - .Split(";", StringSplitOptions.RemoveEmptyEntries) - .Select(o => o.RemovePostFix("/")) - .ToArray() - ) - .WithAbpExposedHeaders() - .SetIsOriginAllowedToAllowWildcardSubdomains() - .AllowAnyHeader() - .AllowAnyMethod() - .AllowCredentials(); + options.ConventionalControllers.Create(typeof(YiAbpApplicationModule).Assembly, + options => options.RemoteServiceName = "default"); + options.ConventionalControllers.Create(typeof(YiFrameworkRbacApplicationModule).Assembly, + options => options.RemoteServiceName = "rbac"); + options.ConventionalControllers.Create(typeof(YiFrameworkBbsApplicationModule).Assembly, + options => options.RemoteServiceName = "bbs"); + options.ConventionalControllers.Create(typeof(YiFrameworkChatHubApplicationModule).Assembly, + options => options.RemoteServiceName = "chat-hub"); + options.ConventionalControllers.Create( + typeof(YiFrameworkTenantManagementApplicationModule).Assembly, + options => options.RemoteServiceName = "tenant-management"); + options.ConventionalControllers.Create(typeof(YiFrameworkCodeGenApplicationModule).Assembly, + options => options.RemoteServiceName = "code-gen"); + + //统一前缀 + options.ConventionalControllers.ConventionalControllerSettings.ForEach(x => x.RootPath = "api/app"); }); - }); - //配置多租户 - Configure(options => - { - //基于cookie jwt不好用,有坑 - options.TenantResolvers.Clear(); - options.TenantResolvers.Add(new HeaderTenantResolveContributor()); - //options.TenantResolvers.Add(new HeaderTenantResolveContributor()); - //options.TenantResolvers.Add(new CookieTenantResolveContributor()); + //【NewtonsoftJson严重问题!!!!!逆天】设置api格式,留给后人铭记 + // service.AddControllers().AddNewtonsoftJson(options => + // { + // options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss"; + // options.SerializerSettings.Converters.Add(new StringEnumConverter()); + // }); - //options.TenantResolvers.RemoveAll(x => x.Name == CookieTenantResolveContributor.ContributorName); - }); - - //速率限制 - //每60秒限制100个请求,滑块添加,分6段 - service.AddRateLimiter(_ => - { - _.RejectionStatusCode = StatusCodes.Status429TooManyRequests; - _.OnRejected = (context, _) => + //请使用微软的,注意abp date又包了一层,采用DefaultJsonTypeInfoResolver统一覆盖 + Configure(options => { - if (context.Lease.TryGetMetadata(MetadataName.RetryAfter, out var retryAfter)) - { - context.HttpContext.Response.Headers.RetryAfter = - ((int)retryAfter.TotalSeconds).ToString(NumberFormatInfo.InvariantInfo); - } + options.JsonSerializerOptions.TypeInfoResolver = new DefaultJsonTypeInfoResolver(); + options.JsonSerializerOptions.Converters.Add(new DatetimeJsonConverter()); + options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()); + }); - context.HttpContext.Response.StatusCode = StatusCodes.Status429TooManyRequests; - context.HttpContext.Response.WriteAsync("Too many requests. Please try again later."); - - return new ValueTask(); - }; - - //全局使用,链式表达式 - _.GlobalLimiter = PartitionedRateLimiter.CreateChained( - PartitionedRateLimiter.Create(httpContext => - { - var userAgent = httpContext.Request.Headers.UserAgent.ToString(); - - return RateLimitPartition.GetSlidingWindowLimiter - (userAgent, _ => - new SlidingWindowRateLimiterOptions - { - PermitLimit = 1000, - Window = TimeSpan.FromSeconds(60), - SegmentsPerWindow = 6, - QueueProcessingOrder = QueueProcessingOrder.OldestFirst - }); - })); - }); - - - //jwt鉴权 - var jwtOptions = configuration.GetSection(nameof(JwtOptions)).Get(); - var refreshJwtOptions = configuration.GetSection(nameof(RefreshJwtOptions)).Get(); - - context.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) - .AddJwtBearer(options => + //设置缓存不要过期,默认滑动20分钟 + Configure(cacheOptions => { - options.TokenValidationParameters = new TokenValidationParameters + cacheOptions.GlobalCacheEntryOptions.SlidingExpiration = null; + //缓存key前缀 + cacheOptions.KeyPrefix = "Yi:"; + }); + + + Configure(options => { options.AutoValidate = false; }); + + //Swagger + context.Services.AddYiSwaggerGen(options => + { + options.SwaggerDoc("default", + new OpenApiInfo { Title = "Yi.Framework.Abp", Version = "v1", Description = "集大成者" }); + }); + + //跨域 + context.Services.AddCors(options => + { + options.AddPolicy(DefaultCorsPolicyName, builder => { - ClockSkew = TimeSpan.Zero, - ValidateIssuerSigningKey = true, - ValidIssuer = jwtOptions.Issuer, - ValidAudience = jwtOptions.Audience, - IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtOptions.SecurityKey)) - }; - options.Events = new JwtBearerEvents - { - OnMessageReceived = context => + builder + .WithOrigins( + configuration["App:CorsOrigins"]! + .Split(";", StringSplitOptions.RemoveEmptyEntries) + .Select(o => o.RemovePostFix("/")) + .ToArray() + ) + .WithAbpExposedHeaders() + .SetIsOriginAllowedToAllowWildcardSubdomains() + .AllowAnyHeader() + .AllowAnyMethod() + .AllowCredentials(); + }); + }); + + //配置多租户 + Configure(options => + { + //基于cookie jwt不好用,有坑 + options.TenantResolvers.Clear(); + options.TenantResolvers.Add(new HeaderTenantResolveContributor()); + //options.TenantResolvers.Add(new HeaderTenantResolveContributor()); + //options.TenantResolvers.Add(new CookieTenantResolveContributor()); + //options.TenantResolvers.RemoveAll(x => x.Name == CookieTenantResolveContributor.ContributorName); + }); + + //配置Hangfire定时任务存储 + var redisConfiguration = configuration["Redis:Configuration"]; + context.Services.AddHangfire(config => + { + config.UseRedisStorage( + ConnectionMultiplexer.Connect(redisConfiguration), + new RedisStorageOptions() { - var accessToken = context.Request.Query["access_token"]; - if (!string.IsNullOrEmpty(accessToken)) - { - context.Token = accessToken; - } + InvisibilityTimeout = TimeSpan.FromHours(1), //JOB允许执行1小时 + Prefix = "Yi:HangfireJob:" + }).WithJobExpirationTimeout(TimeSpan.FromHours(1)); + }); - return Task.CompletedTask; + //速率限制 + //每60秒限制100个请求,滑块添加,分6段 + service.AddRateLimiter(_ => + { + _.RejectionStatusCode = StatusCodes.Status429TooManyRequests; + _.OnRejected = (context, _) => + { + if (context.Lease.TryGetMetadata(MetadataName.RetryAfter, out var retryAfter)) + { + context.HttpContext.Response.Headers.RetryAfter = + ((int)retryAfter.TotalSeconds).ToString(NumberFormatInfo.InvariantInfo); } + + context.HttpContext.Response.StatusCode = StatusCodes.Status429TooManyRequests; + context.HttpContext.Response.WriteAsync("Too many requests. Please try again later."); + + return new ValueTask(); }; - }) - .AddJwtBearer(TokenTypeConst.Refresh, options => - { - options.TokenValidationParameters = new TokenValidationParameters - { - ClockSkew = TimeSpan.Zero, - ValidateIssuerSigningKey = true, - ValidIssuer = refreshJwtOptions.Issuer, - ValidAudience = refreshJwtOptions.Audience, - IssuerSigningKey = - new SymmetricSecurityKey(Encoding.UTF8.GetBytes(refreshJwtOptions.SecurityKey)) - }; - options.Events = new JwtBearerEvents - { - OnMessageReceived = context => + + //全局使用,链式表达式 + _.GlobalLimiter = PartitionedRateLimiter.CreateChained( + PartitionedRateLimiter.Create(httpContext => { - var refresh_token = context.Request.Headers["refresh_token"]; - if (!string.IsNullOrEmpty(refresh_token)) + var userAgent = httpContext.Request.Headers.UserAgent.ToString(); + + return RateLimitPartition.GetSlidingWindowLimiter + (userAgent, _ => + new SlidingWindowRateLimiterOptions + { + PermitLimit = 1000, + Window = TimeSpan.FromSeconds(60), + SegmentsPerWindow = 6, + QueueProcessingOrder = QueueProcessingOrder.OldestFirst + }); + })); + }); + + + //jwt鉴权 + var jwtOptions = configuration.GetSection(nameof(JwtOptions)).Get(); + var refreshJwtOptions = configuration.GetSection(nameof(RefreshJwtOptions)).Get(); + + context.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) + .AddJwtBearer(options => + { + options.TokenValidationParameters = new TokenValidationParameters + { + ClockSkew = TimeSpan.Zero, + ValidateIssuerSigningKey = true, + ValidIssuer = jwtOptions.Issuer, + ValidAudience = jwtOptions.Audience, + IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtOptions.SecurityKey)) + }; + options.Events = new JwtBearerEvents + { + OnMessageReceived = context => { - context.Token = refresh_token; + var accessToken = context.Request.Query["access_token"]; + if (!string.IsNullOrEmpty(accessToken)) + { + context.Token = accessToken; + } + return Task.CompletedTask; } - - var refreshToken = context.Request.Query["refresh_token"]; - if (!string.IsNullOrEmpty(refreshToken)) + }; + }) + .AddJwtBearer(TokenTypeConst.Refresh, options => + { + options.TokenValidationParameters = new TokenValidationParameters + { + ClockSkew = TimeSpan.Zero, + ValidateIssuerSigningKey = true, + ValidIssuer = refreshJwtOptions.Issuer, + ValidAudience = refreshJwtOptions.Audience, + IssuerSigningKey = + new SymmetricSecurityKey(Encoding.UTF8.GetBytes(refreshJwtOptions.SecurityKey)) + }; + options.Events = new JwtBearerEvents + { + OnMessageReceived = context => { - context.Token = refreshToken; + var refresh_token = context.Request.Headers["refresh_token"]; + if (!string.IsNullOrEmpty(refresh_token)) + { + context.Token = refresh_token; + return Task.CompletedTask; + } + + var refreshToken = context.Request.Query["refresh_token"]; + if (!string.IsNullOrEmpty(refreshToken)) + { + context.Token = refreshToken; + } + + return Task.CompletedTask; } + }; + }) + .AddQQ(options => { configuration.GetSection("OAuth:QQ").Bind(options); }) + .AddGitee(options => { configuration.GetSection("OAuth:Gitee").Bind(options); }); - return Task.CompletedTask; - } - }; - }) - .AddQQ(options => { configuration.GetSection("OAuth:QQ").Bind(options); }) - .AddGitee(options => { configuration.GetSection("OAuth:Gitee").Bind(options); }); + //授权 + context.Services.AddAuthorization(); - //授权 - context.Services.AddAuthorization(); + + + return Task.CompletedTask; + } - return Task.CompletedTask; + public override void PreConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddConventionalRegistrar(new YiHangfireConventionalRegistrar()); } - - public override Task OnApplicationInitializationAsync(ApplicationInitializationContext context) + public override async Task OnApplicationInitializationAsync(ApplicationInitializationContext context) { var service = context.ServiceProvider; var env = context.GetEnvironment(); @@ -335,10 +370,25 @@ namespace Yi.Abp.Web //日志记录 app.UseAbpSerilogEnrichers(); + + //定时任务自动注入,Abp默认只有在Quartz才实现 + var backgroundWorkerManager = context.ServiceProvider.GetRequiredService(); + var works = context.ServiceProvider.GetServices(); + + foreach (var work in works) + { + await backgroundWorkerManager.AddAsync(work); + } + + + //Hangfire定时任务面板,可配置授权 + app.UseAbpHangfireDashboard("/hangfire", options => + { + // options.AsyncAuthorization = new[] { new AbpHangfireAuthorizationFilter() }; + }); + //终节点 app.UseConfiguredEndpoints(); - - return Task.CompletedTask; } } } \ No newline at end of file diff --git a/Yi.Abp.Net8/src/Yi.Abp.Web/YiHangfireConventionalRegistrar.cs b/Yi.Abp.Net8/src/Yi.Abp.Web/YiHangfireConventionalRegistrar.cs new file mode 100644 index 00000000..3a1582a2 --- /dev/null +++ b/Yi.Abp.Net8/src/Yi.Abp.Web/YiHangfireConventionalRegistrar.cs @@ -0,0 +1,20 @@ +using Volo.Abp.BackgroundWorkers.Hangfire; +using Volo.Abp.DependencyInjection; + +namespace Yi.Abp.Web; + +public class YiHangfireConventionalRegistrar : DefaultConventionalRegistrar +{ + protected override bool IsConventionalRegistrationDisabled(Type type) + { + return !typeof(IHangfireBackgroundWorker).IsAssignableFrom(type) || base.IsConventionalRegistrationDisabled(type); + } + + protected override List GetExposedServiceTypes(Type type) + { + return new List() + { + typeof(IHangfireBackgroundWorker) + }; + } +} diff --git a/Yi.Abp.Net8/test/Yi.Framework.Rbac.Test/YiFrameworkRbacTestModule.cs b/Yi.Abp.Net8/test/Yi.Framework.Rbac.Test/YiFrameworkRbacTestModule.cs index 956492f6..40353e03 100644 --- a/Yi.Abp.Net8/test/Yi.Framework.Rbac.Test/YiFrameworkRbacTestModule.cs +++ b/Yi.Abp.Net8/test/Yi.Framework.Rbac.Test/YiFrameworkRbacTestModule.cs @@ -2,8 +2,6 @@ using Volo.Abp.Auditing; using Volo.Abp.Autofac; using Volo.Abp.BackgroundWorkers; -using Volo.Abp.BackgroundWorkers.Quartz; -using Volo.Abp.Domain.Repositories; using Yi.Framework.Rbac.Application; using Yi.Framework.Rbac.Domain.Entities; using Yi.Framework.Rbac.Domain.Managers; @@ -24,10 +22,11 @@ namespace Yi.Framework.Rbac.Test { public override void ConfigureServices(ServiceConfigurationContext context) { - Configure(options => - { - options.IsAutoRegisterEnabled = false; - }); + + // Configure(options => + // { + // options.IsAutoRegisterEnabled = false; + // }); Configure (options => { options.IsEnabled = false; //禁用作业执行 @@ -35,7 +34,6 @@ namespace Yi.Framework.Rbac.Test Configure(options => { options.Url = $"DataSource=yi-rbac-test-{DateTime.Now.ToString("yyyyMMdd_HHmmss")}.db"; - }); }