Merge branch 'refs/heads/abp' into digital-collectibles

# Conflicts:
#	Yi.Abp.Net8/Yi.Abp.sln
#	Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Jobs/AccessLogCacheJob.cs
#	Yi.Abp.Net8/src/Yi.Abp.Application/Jobs/DemoResetJob.cs
#	Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs
This commit is contained in:
橙子
2024-11-15 20:16:23 +08:00
21 changed files with 422 additions and 459 deletions

View File

@@ -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<AccessLogCacheJob>().WithIdentity(nameof(AccessLogCacheJob))
.Build();
RecurringJobId = "访问日志写入缓存";
//每10秒执行一次将本地缓存转入redis防止丢数据
CronExpression = "*/10 * * * * *";
//
// JobDetail = JobBuilder.Create<AccessLogCacheJob>().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());
}

View File

@@ -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<AccessLogAggregateRoot> _repository;
@@ -45,18 +43,23 @@ public class AccessLogStoreJob : QuartzBackgroundWorkerBase
public AccessLogStoreJob(ISqlSugarRepository<AccessLogAggregateRoot> repository)
{
_repository = repository;
JobDetail = JobBuilder.Create<AccessLogStoreJob>().WithIdentity(nameof(AccessLogStoreJob))
.Build();
RecurringJobId = "访问日志写入数据库";
//每分钟执行一次
Trigger = TriggerBuilder.Create().WithIdentity(nameof(AccessLogStoreJob))
.WithCronSchedule("0 * * * * ?")
.Build();
CronExpression = "0 * * * * ?";
// JobDetail = JobBuilder.Create<AccessLogStoreJob>().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)
{

View File

@@ -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;
/// <summary>
/// 每日任务job
/// </summary>
public class AssignmentExpireTimeOutJob : QuartzBackgroundWorkerBase
public class AssignmentExpireTimeOutJob : HangfireBackgroundWorkerBase
{
private readonly AssignmentManager _assignmentManager;
public AssignmentExpireTimeOutJob(AssignmentManager assignmentManager)
{
_assignmentManager = assignmentManager;
JobDetail = JobBuilder.Create<AssignmentExpireTimeOutJob>().WithIdentity(nameof(AssignmentExpireTimeOutJob)).Build();
//每个小时整点执行一次
Trigger = TriggerBuilder.Create().WithIdentity(nameof(AssignmentExpireTimeOutJob)).WithCronSchedule("0 0 * * * ?")
.Build();
RecurringJobId = "每日任务系统超时检测";
//每分钟执行一次
CronExpression = "0 * * * * ?";
//
// JobDetail = JobBuilder.Create<AssignmentExpireTimeOutJob>().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();
}

View File

@@ -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<InterestRecordsJob>().WithIdentity(nameof(InterestRecordsJob)).Build();
RecurringJobId = "银行利息积分刷新";
//每个小时整点执行一次
Trigger = TriggerBuilder.Create().WithIdentity(nameof(InterestRecordsJob)).WithCronSchedule("0 0 * * * ?").Build();
CronExpression = "0 0 * * * ?";
// JobDetail = JobBuilder.Create<InterestRecordsJob>().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();

View File

@@ -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!;
}
}

View File

@@ -136,6 +136,11 @@ namespace Yi.Framework.Bbs.Application.Services.Forum
[Authorize]
public override async Task<CommentGetOutputDto> 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)
{

View File

@@ -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<RbacOptions> _options;
@@ -24,13 +22,12 @@ namespace Yi.Framework.Rbac.Application.Jobs
_options = options;
_dbContext = dbContext;
JobDetail = JobBuilder.Create<BackupDataBaseJob>().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)
{

View File

@@ -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;
}
/// <summary>
/// 单查job
/// </summary>
/// <param name="jobId"></param>
/// <returns></returns>
[HttpGet("task/{jobId}")]
public async Task<TaskGetOutput> 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;
}
/// <summary>
/// 多查job
/// </summary>
/// <returns></returns>
public async Task<PagedResultDto<TaskGetListOutput>> GetListAsync([FromQuery] TaskGetListInput input)
{
var items = new List<TaskGetOutput>();
var scheduler = await _schedulerFactory.GetScheduler();
var groups = await scheduler.GetJobGroupNames();
foreach (var groupName in groups)
{
foreach (var jobKey in await scheduler.GetJobKeys(GroupMatcher<JobKey>.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<TaskGetListOutput>(items.Count(), output.Adapt<List<TaskGetListOutput>>());
}
/// <summary>
/// 创建job
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
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());
}
/// <summary>
/// 移除job
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task DeleteAsync(IEnumerable<string> id)
{
var scheduler = await _schedulerFactory.GetScheduler();
await scheduler.DeleteJobs(id.Select(x => new JobKey(x)).ToList());
}
/// <summary>
/// 暂停job
/// </summary>
/// <param name="jobId"></param>
/// <returns></returns>
[HttpPut]
public async Task PauseAsync(string jobId)
{
var scheduler = await _schedulerFactory.GetScheduler();
await scheduler.PauseJob(new JobKey(jobId));
}
/// <summary>
/// 开始job
/// </summary>
/// <param name="jobId"></param>
/// <returns></returns>
[HttpPut]
public async Task StartAsync(string jobId)
{
var scheduler = await _schedulerFactory.GetScheduler();
await scheduler.ResumeJob(new JobKey(jobId));
}
/// <summary>
/// 更新job
/// </summary>
/// <param name="id"></param>
/// <param name="input"></param>
/// <returns></returns>
public async Task UpdateAsync(string id, TaskUpdateInput input)
{
await DeleteAsync(new List<string>() { id });
await CreateAsync(input.Adapt<TaskCreateInput>());
}
[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);
}
}
}

View File

@@ -10,13 +10,15 @@
<ItemGroup>
<PackageReference Include="Lazy.Captcha.Core" Version="2.0.7" />
<PackageReference Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="2.88.7" />
<PackageReference Include="Volo.Abp.BackgroundWorkers.Quartz" Version="$(AbpVersion)" />
<PackageReference Include="Volo.Abp.BackgroundJobs.Hangfire" Version="$(AbpVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\framework\Yi.Framework.Ddd.Application\Yi.Framework.Ddd.Application.csproj" />
<ProjectReference Include="..\Yi.Framework.Rbac.Application.Contracts\Yi.Framework.Rbac.Application.Contracts.csproj" />
<ProjectReference Include="..\Yi.Framework.Rbac.Domain\Yi.Framework.Rbac.Domain.csproj" />
<ProjectReference Include="..\..\..\framework\Yi.Framework.BackgroundWorkers.Hangfire\Yi.Framework.BackgroundWorkers.Hangfire.csproj" />
</ItemGroup>
</Project>

View File

@@ -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;
@@ -16,8 +16,7 @@ namespace Yi.Framework.Rbac.Application
typeof(YiFrameworkRbacDomainModule),
typeof(YiFrameworkDddApplicationModule),
typeof(AbpBackgroundWorkersQuartzModule)
typeof(YiFrameworkDddApplicationModule)
)]
public class YiFrameworkRbacApplicationModule : AbpModule
{
@@ -28,7 +27,6 @@ namespace Yi.Framework.Rbac.Application
service.AddCaptcha(options =>
{
options.CaptchaType = CaptchaType.ARITHMETIC;
});
}