diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application.Contracts/Dtos/Assignment/AssignmentGetListOutputDto.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application.Contracts/Dtos/Assignment/AssignmentGetListOutputDto.cs index 08677acb..cdd7baf1 100644 --- a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application.Contracts/Dtos/Assignment/AssignmentGetListOutputDto.cs +++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application.Contracts/Dtos/Assignment/AssignmentGetListOutputDto.cs @@ -23,7 +23,10 @@ public class AssignmentGetListOutputDto:EntityDto /// 总共步骤数 /// public int TotalStepNumber { get; set; } - + /// + /// 任务类型 + /// + public AssignmentTypeEnum AssignmentType { get; set; } /// /// 任务需求类型 diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Extensions/AccessLogMiddleware.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Extensions/AccessLogMiddleware.cs index 373dcf7b..7aba4c48 100644 --- a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Extensions/AccessLogMiddleware.cs +++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Extensions/AccessLogMiddleware.cs @@ -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; /// /// 访问日志中间件 /// 并发最高,采用缓存,默认10分钟才会真正操作一次数据库 -/// /// 需考虑一致性问题,又不能上锁影响性能 /// public class AccessLogMiddleware : IMiddleware, ITransientDependency { - private readonly IDistributedCache _accessLogCache; - private readonly ISqlSugarRepository _repository; + /// + /// 缓存前缀 + /// + private string CacheKeyPrefix => LazyServiceProvider.LazyGetRequiredService>() + .Value.KeyPrefix; - public AccessLogMiddleware(IDistributedCache accessLogCache, - ISqlSugarRepository repository) + /// + /// 使用懒加载防止报错 + /// + private IRedisClient RedisClient => LazyServiceProvider.LazyGetRequiredService(); + + /// + /// 属性注入 + /// + public IAbpLazyServiceProvider LazyServiceProvider { get; set; } + + private bool EnableRedisCache { - _accessLogCache = accessLogCache; - _repository = repository; + get + { + var redisEnabled = LazyServiceProvider.LazyGetRequiredService()["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); - } - - /// - /// 获取今天的统计 - /// - /// - private async Task 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; } } \ No newline at end of file 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 new file mode 100644 index 00000000..53659519 --- /dev/null +++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Jobs/AccessLogStoreJob.cs @@ -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 _repository; + + /// + /// 缓存前缀 + /// + private string CacheKeyPrefix => LazyServiceProvider.LazyGetRequiredService>() + .Value.KeyPrefix; + + /// + /// 使用懒加载防止报错 + /// + private IRedisClient RedisClient => LazyServiceProvider.LazyGetRequiredService(); + + /// + /// 属性注入 + /// + public IAbpLazyServiceProvider LazyServiceProvider { get; set; } + + private bool EnableRedisCache + { + get + { + var redisEnabled = LazyServiceProvider.LazyGetRequiredService()["Redis:IsEnabled"]; + return redisEnabled.IsNullOrEmpty() || bool.Parse(redisEnabled); + } + } + + public AccessLogStoreJob(ISqlSugarRepository repository) + { + _repository = repository; + JobDetail = JobBuilder.Create().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($"{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(); + + + } + } +} \ No newline at end of file diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Services/AssignmentService.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Services/AssignmentService.cs index 4b427fc9..456fdfea 100644 --- a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Services/AssignmentService.cs +++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Services/AssignmentService.cs @@ -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((x, define) => x.AssignmentDefineId==define.Id) diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain.Shared/Enums/AssignmentStateEnum.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain.Shared/Enums/AssignmentStateEnum.cs index 8cd23d90..05418cde 100644 --- a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain.Shared/Enums/AssignmentStateEnum.cs +++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain.Shared/Enums/AssignmentStateEnum.cs @@ -15,5 +15,10 @@ public enum AssignmentStateEnum /// /// 已过期 /// - Expired + Expired, + + /// + /// 已结束 + /// + End } \ No newline at end of file diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Entities/Assignment/AssignmentAggregateRoot.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Entities/Assignment/AssignmentAggregateRoot.cs index efdf1dab..5e8a6dc9 100644 --- a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Entities/Assignment/AssignmentAggregateRoot.cs +++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Entities/Assignment/AssignmentAggregateRoot.cs @@ -52,7 +52,7 @@ public class AssignmentAggregateRoot : AggregateRoot, IHasCreationTime, IO /// 任务需求类型 /// 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, 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, 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; } } \ No newline at end of file diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/EventHandlers/AssignmentEventHandler.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/EventHandlers/AssignmentEventHandler.cs index 9aaa45b4..b9c6d4af 100644 --- a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/EventHandlers/AssignmentEventHandler.cs +++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/EventHandlers/AssignmentEventHandler.cs @@ -68,10 +68,14 @@ public class AssignmentEventHandler : ILocalEventHandler, 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; + } } }); } diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/AssignmentManager.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/AssignmentManager.cs index 5b8a8a47..4ee4ad64 100644 --- a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/AssignmentManager.cs +++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/AssignmentManager.cs @@ -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 diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/AssignmentProviders/TimerAbstractProvider.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/AssignmentProviders/TimerAbstractProvider.cs index 527d659b..8a286fa9 100644 --- a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/AssignmentProviders/TimerAbstractProvider.cs +++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/AssignmentProviders/TimerAbstractProvider.cs @@ -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(); diff --git a/Yi.Bbs.Vue3/src/views/assignment/Index.vue b/Yi.Bbs.Vue3/src/views/assignment/Index.vue index b003a3e9..277e9f49 100644 --- a/Yi.Bbs.Vue3/src/views/assignment/Index.vue +++ b/Yi.Bbs.Vue3/src/views/assignment/Index.vue @@ -2,6 +2,7 @@ import {getAssignmentList, getCanReceiveAssignment, acceptAssignment, receiveAssignment} from '@/apis/assignmentApi' import {onMounted, reactive, ref} from "vue"; import AssignmentCard from "./components/AssignmentCard.vue" + const canReceiveAssignmentList = ref([]); const assignmentList = ref([]); @@ -14,7 +15,6 @@ const currentTableSelect = ref("canAccept"); //切换tab const changeClickTable = async (tabName) => { - console.log(tabName,"tabName") switch (tabName) { case "canAccept": const {data: canReceiveAssignmentListData} = await getCanReceiveAssignment(); @@ -47,11 +47,20 @@ const refreshData = async () => { //接收任务 const onClickAcceptAssignment = async (item) => { await acceptAssignment(item.id); + ElMessage({ + type: 'success', + message: '接受任务成功', + }); await refreshData(); } -const onClickReceiveAssignment = async (id) => { - await receiveAssignment(id); +//领取奖励 +const onClickReceiveAssignment = async (item) => { + await receiveAssignment(item.id); + ElMessage({ + type: 'success', + message: '任务奖励领取成功', + }); await refreshData(); } @@ -74,21 +83,32 @@ const changeTab = async (state) => { - -
- -
-
{{ item }} - +
+
+ +
+ + + +
+
+
+ +
+