feat:完善任务界面
This commit is contained in:
@@ -23,7 +23,10 @@ public class AssignmentGetListOutputDto:EntityDto<Guid>
|
||||
/// 总共步骤数
|
||||
/// </summary>
|
||||
public int TotalStepNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 任务类型
|
||||
/// </summary>
|
||||
public AssignmentTypeEnum AssignmentType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 任务需求类型
|
||||
|
||||
@@ -1,109 +1,51 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using FreeRedis;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Volo.Abp.Caching;
|
||||
using Volo.Abp.DependencyInjection;
|
||||
using Yi.Framework.Bbs.Domain.Entities;
|
||||
using Yi.Framework.Bbs.Domain.Shared.Caches;
|
||||
using Yi.Framework.Bbs.Domain.Shared.Enums;
|
||||
using Yi.Framework.SqlSugarCore.Abstractions;
|
||||
|
||||
namespace Yi.Framework.Bbs.Application.Extensions;
|
||||
|
||||
/// <summary>
|
||||
/// 访问日志中间件
|
||||
/// 并发最高,采用缓存,默认10分钟才会真正操作一次数据库
|
||||
///
|
||||
/// 需考虑一致性问题,又不能上锁影响性能
|
||||
/// </summary>
|
||||
public class AccessLogMiddleware : IMiddleware, ITransientDependency
|
||||
{
|
||||
private readonly IDistributedCache<AccessLogCacheItem> _accessLogCache;
|
||||
private readonly ISqlSugarRepository<AccessLogAggregateRoot> _repository;
|
||||
/// <summary>
|
||||
/// 缓存前缀
|
||||
/// </summary>
|
||||
private string CacheKeyPrefix => LazyServiceProvider.LazyGetRequiredService<IOptions<AbpDistributedCacheOptions>>()
|
||||
.Value.KeyPrefix;
|
||||
|
||||
public AccessLogMiddleware(IDistributedCache<AccessLogCacheItem> accessLogCache,
|
||||
ISqlSugarRepository<AccessLogAggregateRoot> repository)
|
||||
/// <summary>
|
||||
/// 使用懒加载防止报错
|
||||
/// </summary>
|
||||
private IRedisClient RedisClient => LazyServiceProvider.LazyGetRequiredService<IRedisClient>();
|
||||
|
||||
/// <summary>
|
||||
/// 属性注入
|
||||
/// </summary>
|
||||
public IAbpLazyServiceProvider LazyServiceProvider { get; set; }
|
||||
|
||||
private bool EnableRedisCache
|
||||
{
|
||||
_accessLogCache = accessLogCache;
|
||||
_repository = repository;
|
||||
get
|
||||
{
|
||||
var redisEnabled = LazyServiceProvider.LazyGetRequiredService<IConfiguration>()["Redis:IsEnabled"];
|
||||
return redisEnabled.IsNullOrEmpty() || bool.Parse(redisEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
|
||||
{
|
||||
await next(context);
|
||||
|
||||
//获取缓存
|
||||
var cache = await _accessLogCache.GetAsync(AccessLogCacheConst.Key);
|
||||
|
||||
//当前缓存需赋的值
|
||||
long currentNumber = 1;
|
||||
//最后插入的时间
|
||||
DateTime lastInsertTime = DateTime.Now;
|
||||
//cahce是空,创建缓存,当前数量从数据库中获取
|
||||
//不等于空,如果大于当前天,插入数据库(间隔超过10分钟,也插入)
|
||||
|
||||
//获取当前访问数量
|
||||
//没有缓存
|
||||
if (cache is null)
|
||||
if (EnableRedisCache)
|
||||
{
|
||||
//获取数据库今天最后最后一条数据
|
||||
var currentDayEntity = await GetDateAccessLogEntityAsync();
|
||||
|
||||
//数据库有数据,以数据库数据为准+1
|
||||
if (currentDayEntity is not null)
|
||||
{
|
||||
currentNumber = currentDayEntity.Number + 1;
|
||||
}
|
||||
//数据库没有数据,就是默认的1,重新开始
|
||||
await RedisClient.IncrByAsync($"{CacheKeyPrefix}:{AccessLogCacheConst.Key}:{DateTime.Now.Date}", 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
//有缓存,根据根据缓存的值来
|
||||
currentNumber = cache.Number + 1;
|
||||
lastInsertTime = cache.LastInsertTime;
|
||||
|
||||
//数据库持久化
|
||||
//缓存的日期大于当天的日期,插入到数据库,同时缓存变成0,重新开始统计
|
||||
if (cache.LastModificationTime.Date > DateTime.Today)
|
||||
{
|
||||
await _repository.InsertAsync(new AccessLogAggregateRoot()
|
||||
{ AccessLogType = AccessLogTypeEnum.Request, Number = currentNumber });
|
||||
currentNumber = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cache.LastInsertTime <= DateTime.Now - TimeSpan.FromMinutes(10))
|
||||
{
|
||||
//这里还需要判断数据库是否有值,不能之间更新
|
||||
|
||||
//缓存的时间大于当前数据库时间10分钟之后,更新(减少数据库交互,10分钟才更新一次)
|
||||
var currentDayEntity = await GetDateAccessLogEntityAsync();
|
||||
if (currentDayEntity is null)
|
||||
{
|
||||
await _repository.InsertAsync(new AccessLogAggregateRoot()
|
||||
{ AccessLogType = AccessLogTypeEnum.Request, Number = currentNumber });
|
||||
}
|
||||
await _repository.UpdateAsync(currentDayEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//覆盖缓存
|
||||
var newCache = new AccessLogCacheItem(currentNumber) { LastInsertTime = lastInsertTime };
|
||||
await _accessLogCache.SetAsync(AccessLogCacheConst.Key, newCache);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取今天的统计
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private async Task<AccessLogAggregateRoot?> GetDateAccessLogEntityAsync()
|
||||
{
|
||||
//获取数据库今天最后最后一条数据
|
||||
var currentDayEntity = await _repository._DbQueryable
|
||||
.Where(x => x.AccessLogType == AccessLogTypeEnum.Request)
|
||||
.Where(x => x.CreationTime == DateTime.Today)
|
||||
.OrderByDescending(x => x.CreationTime)
|
||||
.FirstAsync();
|
||||
return currentDayEntity;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
using FreeRedis;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Quartz;
|
||||
using Volo.Abp.BackgroundWorkers.Quartz;
|
||||
using Volo.Abp.Caching;
|
||||
using Volo.Abp.DependencyInjection;
|
||||
using Yi.Framework.Bbs.Domain.Entities;
|
||||
using Yi.Framework.Bbs.Domain.Shared.Caches;
|
||||
using Yi.Framework.Bbs.Domain.Shared.Enums;
|
||||
using Yi.Framework.SqlSugarCore.Abstractions;
|
||||
|
||||
namespace Yi.Framework.Bbs.Application.Jobs;
|
||||
|
||||
public class AccessLogStoreJob : QuartzBackgroundWorkerBase
|
||||
{
|
||||
private readonly ISqlSugarRepository<AccessLogAggregateRoot> _repository;
|
||||
|
||||
/// <summary>
|
||||
/// 缓存前缀
|
||||
/// </summary>
|
||||
private string CacheKeyPrefix => LazyServiceProvider.LazyGetRequiredService<IOptions<AbpDistributedCacheOptions>>()
|
||||
.Value.KeyPrefix;
|
||||
|
||||
/// <summary>
|
||||
/// 使用懒加载防止报错
|
||||
/// </summary>
|
||||
private IRedisClient RedisClient => LazyServiceProvider.LazyGetRequiredService<IRedisClient>();
|
||||
|
||||
/// <summary>
|
||||
/// 属性注入
|
||||
/// </summary>
|
||||
public IAbpLazyServiceProvider LazyServiceProvider { get; set; }
|
||||
|
||||
private bool EnableRedisCache
|
||||
{
|
||||
get
|
||||
{
|
||||
var redisEnabled = LazyServiceProvider.LazyGetRequiredService<IConfiguration>()["Redis:IsEnabled"];
|
||||
return redisEnabled.IsNullOrEmpty() || bool.Parse(redisEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
public AccessLogStoreJob(ISqlSugarRepository<AccessLogAggregateRoot> repository)
|
||||
{
|
||||
_repository = repository;
|
||||
JobDetail = JobBuilder.Create<AccessLogStoreJob>().WithIdentity(nameof(AccessLogStoreJob))
|
||||
.Build();
|
||||
//每分钟执行一次
|
||||
Trigger = TriggerBuilder.Create().WithIdentity(nameof(AccessLogStoreJob))
|
||||
.WithCronSchedule("* * * * *")
|
||||
.Build();
|
||||
}
|
||||
|
||||
public override async Task Execute(IJobExecutionContext context)
|
||||
{
|
||||
if (EnableRedisCache)
|
||||
{
|
||||
//当天的访问量
|
||||
var number =
|
||||
await RedisClient.GetAsync<long>($"{CacheKeyPrefix}:{AccessLogCacheConst.Key}:{DateTime.Now.Date}");
|
||||
|
||||
|
||||
var entity = await _repository._DbQueryable.Where(x => x.AccessLogType == AccessLogTypeEnum.Request)
|
||||
.Where(x => x.CreationTime.Date == DateTime.Today)
|
||||
.FirstAsync();
|
||||
// _repository._Db.Storageable(list2).ExecuteCommandAsync();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -64,9 +64,10 @@ public class AssignmentService : ApplicationService
|
||||
var output = await _assignmentManager._assignmentRepository._DbQueryable
|
||||
.Where(x => x.UserId == CurrentUser.GetId())
|
||||
.WhereIF(input.AssignmentQueryState == AssignmentQueryStateEnum.Progress,
|
||||
x => x.AssignmentState == AssignmentStateEnum.Progress)
|
||||
x => x.AssignmentState == AssignmentStateEnum.Progress||
|
||||
x.AssignmentState == AssignmentStateEnum.Completed)
|
||||
.WhereIF(input.AssignmentQueryState == AssignmentQueryStateEnum.End,
|
||||
x => x.AssignmentState == AssignmentStateEnum.Completed ||
|
||||
x => x.AssignmentState == AssignmentStateEnum.End ||
|
||||
x.AssignmentState == AssignmentStateEnum.Expired)
|
||||
.OrderBy(x=>x.CreationTime)
|
||||
.LeftJoin<AssignmentDefineAggregateRoot>((x, define) => x.AssignmentDefineId==define.Id)
|
||||
|
||||
@@ -15,5 +15,10 @@ public enum AssignmentStateEnum
|
||||
/// <summary>
|
||||
/// 已过期
|
||||
/// </summary>
|
||||
Expired
|
||||
Expired,
|
||||
|
||||
/// <summary>
|
||||
/// 已结束
|
||||
/// </summary>
|
||||
End
|
||||
}
|
||||
@@ -52,7 +52,7 @@ public class AssignmentAggregateRoot : AggregateRoot<Guid>, IHasCreationTime, IO
|
||||
/// 任务需求类型
|
||||
/// </summary>
|
||||
public AssignmentRequirementTypeEnum AssignmentRequirementType{ get; set; }
|
||||
public DateTime? CompleteTime { get; set; }
|
||||
public DateTime? EndTime { get; set; }
|
||||
|
||||
|
||||
public DateTime CreationTime { get; set; }
|
||||
@@ -62,7 +62,7 @@ public class AssignmentAggregateRoot : AggregateRoot<Guid>, IHasCreationTime, IO
|
||||
|
||||
public bool IsAllowCompleted()
|
||||
{
|
||||
return AssignmentState == AssignmentStateEnum.Progress && this.CurrentStepNumber == this.TotalStepNumber;
|
||||
return AssignmentState == AssignmentStateEnum.Completed && this.CurrentStepNumber == this.TotalStepNumber;
|
||||
}
|
||||
|
||||
public bool TrySetExpire()
|
||||
@@ -76,10 +76,10 @@ public class AssignmentAggregateRoot : AggregateRoot<Guid>, IHasCreationTime, IO
|
||||
return true;
|
||||
}
|
||||
|
||||
public void SetComplete()
|
||||
public void SetEnd()
|
||||
{
|
||||
this.AssignmentState = AssignmentStateEnum.Completed;
|
||||
this.CompleteTime=DateTime.Now;
|
||||
this.AssignmentState = AssignmentStateEnum.End;
|
||||
this.EndTime=DateTime.Now;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -68,10 +68,14 @@ public class AssignmentEventHandler : ILocalEventHandler<AssignmentEventArgs>, I
|
||||
{
|
||||
currentAssignmentList.ForEach(x =>
|
||||
{
|
||||
if (x.AssignmentRequirementType == AssignmentRequirementTypeEnum.Agree &&
|
||||
if (x.AssignmentRequirementType == requirementType &&
|
||||
x.CurrentStepNumber < x.TotalStepNumber)
|
||||
{
|
||||
x.CurrentStepNumber += 1;
|
||||
if (x.CurrentStepNumber==x.TotalStepNumber)
|
||||
{
|
||||
x.AssignmentState = AssignmentStateEnum.Completed;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ public class AssignmentManager : DomainService
|
||||
new MoneyChangeEventArgs { UserId = assignment.UserId, Number = assignment.RewardsMoneyNumber }, false);
|
||||
|
||||
//设置已完成,并领取奖励,钱钱
|
||||
assignment.SetComplete();
|
||||
assignment.SetEnd();
|
||||
await _assignmentRepository.UpdateAsync(assignment);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -24,10 +24,11 @@ public abstract class TimerProvider : IAssignmentProvider
|
||||
//2: 存在已完成,但是完成时间是过期的
|
||||
var assignmentFilterIds = context.CurrentUserAssignments
|
||||
.Where(x =>
|
||||
//正在进行的,要去掉
|
||||
//正在进行的,已经完成,要去掉
|
||||
x.AssignmentState == AssignmentStateEnum.Progress||
|
||||
//已完成,但是还没过期,要去掉
|
||||
(x.AssignmentState == AssignmentStateEnum.Completed&&!AssignmentType.IsExpire(x.CompleteTime!.Value)))
|
||||
x.AssignmentState==AssignmentStateEnum.Completed||
|
||||
//已结束,但是还没过期,要去掉
|
||||
(x.AssignmentState == AssignmentStateEnum.End&&!AssignmentType.IsExpire(x.EndTime!.Value)))
|
||||
.Select(x => x.AssignmentDefineId)
|
||||
.ToList();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user