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
new file mode 100644
index 00000000..937fb689
--- /dev/null
+++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Jobs/AssignmentExpireTimeOutJob.cs
@@ -0,0 +1,27 @@
+using Quartz;
+using Volo.Abp.BackgroundWorkers.Quartz;
+using Yi.Framework.Bbs.Domain.Managers;
+
+namespace Yi.Framework.Bbs.Application.Jobs;
+
+///
+/// 每日任务job
+///
+public class AssignmentExpireTimeOutJob : QuartzBackgroundWorkerBase
+{
+ 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();
+ }
+
+ public override async Task Execute(IJobExecutionContext context)
+ {
+ await _assignmentManager.ExpireTimeoutAsync();
+ }
+}
\ No newline at end of file
diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain.Shared/Enums/AssignmentTypeEnum.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain.Shared/Enums/AssignmentTypeEnum.cs
index d0665771..84e00060 100644
--- a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain.Shared/Enums/AssignmentTypeEnum.cs
+++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain.Shared/Enums/AssignmentTypeEnum.cs
@@ -6,14 +6,60 @@ public enum AssignmentTypeEnum
/// 新手任务
///
Novice,
-
+
///
/// 每日任务
///
Daily,
-
+
///
/// 每周任务
///
Weekly
+}
+
+public static class AssignmentTypeExtension
+{
+ public static DateTime? GetExpireTime(this AssignmentTypeEnum assignmentType)
+ {
+ switch (assignmentType)
+ {
+ case AssignmentTypeEnum.Novice:
+ return null;
+ case AssignmentTypeEnum.Daily:
+ return DateTime.Now.Date.AddDays(1);
+ case AssignmentTypeEnum.Weekly:
+ DateTime today = DateTime.Now; // 获取当前日期和时间
+ int daysUntilNextMonday = ((int)DayOfWeek.Monday - (int)today.DayOfWeek + 7) % 7 + 7;
+ DateTime nextMonday = today.AddDays(daysUntilNextMonday).Date; // 添加天数并将时间设为 0 点
+ return nextMonday;
+ default:
+ throw new ArgumentOutOfRangeException(nameof(assignmentType), assignmentType, null);
+ }
+ }
+
+ public static bool IsExpire(this AssignmentTypeEnum assignmentType,DateTime time)
+ {
+ switch (assignmentType)
+ {
+ case AssignmentTypeEnum.Novice:
+ return false;
+ case AssignmentTypeEnum.Daily:
+ //昨天之前发的,算过期
+ return time.Date < DateTime.Now.Date;
+ case AssignmentTypeEnum.Weekly:
+ // 获取当前日期
+ DateTime now = DateTime.Now;
+ // 计算本周一的日期
+ int daysToSubtract = (int)now.DayOfWeek - (int)DayOfWeek.Monday;
+ if (daysToSubtract < 0) daysToSubtract += 7; // 如果今天是周日,则需要调整
+ DateTime startOfWeek = now.AddDays(-daysToSubtract).Date;
+ // 获取本周一的凌晨 00:00
+ DateTime mondayMidnight = startOfWeek; // .Date 默认为 00:00
+ //本周一之前发的
+ return time, IHasCreationTime, IO
///
public Guid UserId { get; set; }
- ///
- /// 总共步骤数
- ///
- public int TotalStepNumber { get; set; }
-
///
/// 当前步骤数
///
public int CurrentStepNumber { get; set; }
+ ///
+ /// 总共步骤数
+ ///
+ public int TotalStepNumber { get; set; }
///
/// 任务状态
///
public AssignmentStateEnum AssignmentState { get; set; }
-
+ ///
+ /// 任务奖励的钱钱数量
+ ///
+ public decimal RewardsMoneyNumber { get; set; }
///
/// 任务过期时间
///
public DateTime? ExpireTime { get; set; }
+
+ public DateTime? CompleteTime { get; set; }
+
public DateTime CreationTime { get; }
public int OrderNum { get; set; }
public DateTime? LastModificationTime { get; }
+
+
+ public bool IsAllowCompleted()
+ {
+ return AssignmentState == AssignmentStateEnum.Progress && this.CurrentStepNumber == this.TotalStepNumber;
+ }
+
+ public bool TrySetExpire()
+ {
+ if (ExpireTime<=DateTime.Now)
+ {
+ AssignmentState = AssignmentStateEnum.Expired;
+ return false;
+ }
+
+ return true;
+ }
}
\ No newline at end of file
diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Entities/Assignment/AssignmentDefineAggregateRoot.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Entities/Assignment/AssignmentDefineAggregateRoot.cs
index 5573e76a..72d44e8d 100644
--- a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Entities/Assignment/AssignmentDefineAggregateRoot.cs
+++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Entities/Assignment/AssignmentDefineAggregateRoot.cs
@@ -31,7 +31,11 @@ public class AssignmentDefineAggregateRoot: AggregateRoot, IHasCreationTim
///
public AssignmentTypeEnum AssignmentType{ get; set; }
-
+ ///
+ /// 总共步骤数
+ ///
+ public int TotalStepNumber { get; set; }
+
///
/// 前置任务id
///
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 e37d92a8..8ab3e89c 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
@@ -1,5 +1,12 @@
-using Volo.Abp.Domain.Services;
+using SqlSugar;
+using Volo.Abp.Domain.Services;
+using Volo.Abp.EventBus.Local;
+using Volo.Abp.Users;
using Yi.Framework.Bbs.Domain.Entities.Assignment;
+using Yi.Framework.Bbs.Domain.Managers.AssignmentProviders;
+using Yi.Framework.Bbs.Domain.Shared.Enums;
+using Yi.Framework.Bbs.Domain.Shared.Etos;
+using Yi.Framework.SqlSugarCore.Abstractions;
namespace Yi.Framework.Bbs.Domain.Managers;
@@ -8,36 +15,125 @@ namespace Yi.Framework.Bbs.Domain.Managers;
///
public class AssignmentManager : DomainService
{
+ private readonly IEnumerable _assignmentProviders;
+ private readonly ISqlSugarRepository _assignmentRepository;
+ private readonly ISqlSugarRepository _assignmentDefineRepository;
+ private readonly ILocalEventBus _localEventBus;
+
+ public AssignmentManager(IEnumerable assignmentProviders,
+ ISqlSugarRepository assignmentRepository,
+ ISqlSugarRepository assignmentDefineRepository, ILocalEventBus localEventBus)
+ {
+ this._assignmentProviders = assignmentProviders;
+ _assignmentRepository = assignmentRepository;
+ _assignmentDefineRepository = assignmentDefineRepository;
+ _localEventBus = localEventBus;
+ }
+
///
/// 接受任务
///
/// 领取用户
/// 任务定义id
///
- public Task AcceptAsync(Guid userId, Guid asignmentDefineId)
+ public async Task AcceptAsync(Guid userId, Guid asignmentDefineId)
{
- throw new NotImplementedException();
+ var canReceiveList = await GetCanReceiveListAsync(userId);
+
+ //如果要接收的任务id在可领取的任务列表中,就可以接收任务
+ if (canReceiveList.Select(x => x.Id).Contains(asignmentDefineId))
+ {
+ var assignmentDefine = await _assignmentDefineRepository.GetByIdAsync(asignmentDefineId);
+
+ var entity = new AssignmentAggregateRoot();
+ entity.AssignmentDefineId = asignmentDefineId;
+ entity.UserId = userId;
+ entity.AssignmentState = AssignmentStateEnum.Progress;
+ entity.CurrentStepNumber = 0;
+ entity.TotalStepNumber = assignmentDefine.TotalStepNumber;
+ entity.RewardsMoneyNumber = assignmentDefine.RewardsMoneyNumber;
+ entity.ExpireTime = assignmentDefine.AssignmentType.GetExpireTime();
+ await _assignmentRepository.InsertAsync(entity);
+ }
}
-
+
///
/// 领取任务奖励
///
/// 任务id
///
///
- public Task ReceiveRewardsAsync(Guid asignmentId)
+ public async Task ReceiveRewardsAsync(Guid asignmentId)
{
- throw new NotImplementedException();
+ var assignment = await _assignmentRepository.GetByIdAsync(asignmentId);
+ if (assignment.IsAllowCompleted())
+ {
+ //设置已完成,并领取奖励,钱钱
+ assignment.AssignmentState = AssignmentStateEnum.Completed;
+ //加钱加钱
+ await _localEventBus.PublishAsync(
+ new MoneyChangeEventArgs { UserId = assignment.UserId, Number = assignment.RewardsMoneyNumber }, false);
+ }
}
-
-
+
+
///
/// 根据用户id获取能够领取的任务列表
///
/// 用户id
///
- public Task> GetCanReceiveListAsync(Guid userId)
+ public async Task> GetCanReceiveListAsync(Guid userId)
{
+ var context = await GetAssignmentContext(userId);
+ var output = new List();
+ foreach (var assignmentProvider in _assignmentProviders)
+ {
+ output.AddRange(await assignmentProvider.GetCanReceiveListAsync(context));
+ }
+
+ output.DistinctBy(x => x.Id);
throw new NotImplementedException();
}
+
+
+ ///
+ /// 获取任务的上下文
+ ///
+ ///
+ ///
+ private async Task GetAssignmentContext(Guid userId)
+ {
+ var allAssignmentDefine = await _assignmentDefineRepository.GetListAsync();
+
+ var currentUserAssignment = await _assignmentRepository.GetListAsync(x => x.UserId == userId);
+
+ var context = new AssignmentContext(userId, allAssignmentDefine, currentUserAssignment);
+ return context;
+ }
+
+
+ ///
+ /// 过期超时的任务,定时任务去处理即可
+ ///
+ public async Task ExpireTimeoutAsync()
+ {
+ var progressEntities = await _assignmentRepository._DbQueryable
+ .Where(x => x.AssignmentState == AssignmentStateEnum.Progress)
+ .ToListAsync();
+
+ var needUpdateEntities = new List();
+ foreach (var progressEntity in progressEntities)
+ {
+ if (progressEntity.TrySetExpire())
+ {
+ needUpdateEntities.Add(progressEntity);
+ }
+ }
+
+ if (needUpdateEntities.Any())
+ {
+ await _assignmentRepository._Db.Updateable(needUpdateEntities).ExecuteCommandAsync();
+ }
+
+ }
}
\ No newline at end of file
diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/AssignmentProviders/AssignmentContext.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/AssignmentProviders/AssignmentContext.cs
index 4f1f6048..5ed79e80 100644
--- a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/AssignmentProviders/AssignmentContext.cs
+++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/AssignmentProviders/AssignmentContext.cs
@@ -4,6 +4,13 @@ namespace Yi.Framework.Bbs.Domain.Managers.AssignmentProviders;
public class AssignmentContext
{
+ public AssignmentContext( Guid currentUserId,List allAssignmentDefine, List currentUserAssignments)
+ {
+ AllAssignmentDefine = allAssignmentDefine;
+ CurrentUserAssignments = currentUserAssignments;
+ CurrentUserId = currentUserId;
+ }
+
///
/// 全部的任务定义
///
@@ -17,5 +24,5 @@ public class AssignmentContext
///
/// 当前用户id
///
- public Guid CurrentUserId { get; set; }
+ public Guid CurrentUserId { get; }
}
\ No newline at end of file
diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/AssignmentProviders/IAssignmentProvider.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/AssignmentProviders/IAssignmentProvider.cs
index 9f718414..0cffaff7 100644
--- a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/AssignmentProviders/IAssignmentProvider.cs
+++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/AssignmentProviders/IAssignmentProvider.cs
@@ -14,11 +14,4 @@ public interface IAssignmentProvider : ITransientDependency
///
///
Task> GetCanReceiveListAsync(AssignmentContext context);
-
- ///
- /// 校验是否能够被领取,该方法还需工厂进行代理执行一次
- ///
- ///
- ///
- Task VerifyCanAcceptAsync(AssignmentContext context);
}
\ No newline at end of file
diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/AssignmentProviders/Impl/DailyProvider.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/AssignmentProviders/Impl/DailyProvider.cs
index 56ce0057..a51477a3 100644
--- a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/AssignmentProviders/Impl/DailyProvider.cs
+++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/AssignmentProviders/Impl/DailyProvider.cs
@@ -1,9 +1,11 @@
-namespace Yi.Framework.Bbs.Domain.Managers.AssignmentProviders;
+using Yi.Framework.Bbs.Domain.Shared.Enums;
+
+namespace Yi.Framework.Bbs.Domain.Managers.AssignmentProviders;
///
/// 每日任务提供者
///
public class DailyProvider : TimerProvider
{
- protected override TimeSpan TimeCycle => TimeSpan.FromDays(1);
+ protected override AssignmentTypeEnum AssignmentType => AssignmentTypeEnum.Daily;
}
\ No newline at end of file
diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/AssignmentProviders/Impl/NoviceProvider.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/AssignmentProviders/Impl/NoviceProvider.cs
index 24f2062c..d4ff0a02 100644
--- a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/AssignmentProviders/Impl/NoviceProvider.cs
+++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/AssignmentProviders/Impl/NoviceProvider.cs
@@ -9,11 +9,7 @@ public class NoviceProvider : IAssignmentProvider
{
public Task> GetCanReceiveListAsync(AssignmentContext context)
{
- throw new NotImplementedException();
- }
-
- public Task VerifyCanAcceptAsync(AssignmentContext context)
- {
+ //新手任务是要有前置依赖关系的,链表类型依赖
throw new NotImplementedException();
}
}
\ No newline at end of file
diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/AssignmentProviders/Impl/WeeklyProvider.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/AssignmentProviders/Impl/WeeklyProvider.cs
index 4a39e7a7..52d264d8 100644
--- a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/AssignmentProviders/Impl/WeeklyProvider.cs
+++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/AssignmentProviders/Impl/WeeklyProvider.cs
@@ -1,9 +1,11 @@
-namespace Yi.Framework.Bbs.Domain.Managers.AssignmentProviders;
+using Yi.Framework.Bbs.Domain.Shared.Enums;
+
+namespace Yi.Framework.Bbs.Domain.Managers.AssignmentProviders;
///
/// 每周任务提供者
///
public class WeeklyProvider : TimerProvider
{
- protected override TimeSpan TimeCycle => TimeSpan.FromDays(7);
+ protected override AssignmentTypeEnum AssignmentType => AssignmentTypeEnum.Weekly;
}
\ No newline at end of file
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 a22a8637..527d659b 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
@@ -1,24 +1,41 @@
-using Yi.Framework.Bbs.Domain.Entities.Assignment;
+using SqlSugar;
+using Yi.Framework.Bbs.Domain.Entities.Assignment;
+using Yi.Framework.Bbs.Domain.Shared.Enums;
namespace Yi.Framework.Bbs.Domain.Managers.AssignmentProviders;
///
-/// 定时任务提供者
+/// 循环任务提供者
///
public abstract class TimerProvider : IAssignmentProvider
{
///
- /// 时间周期
+ /// 任务类型
///
- protected abstract TimeSpan TimeCycle { get; }
+ protected abstract AssignmentTypeEnum AssignmentType { get; }
public Task> GetCanReceiveListAsync(AssignmentContext context)
{
- throw new NotImplementedException();
- }
+ //先获取到对应任务定义列表
+ var assignmentDefines = context.AllAssignmentDefine.Where(x => x.AssignmentType == AssignmentType).ToList();
- public Task VerifyCanAcceptAsync(AssignmentContext context)
- {
- throw new NotImplementedException();
+ //满足以下1个条件
+ //1:没有正在运行的
+ //2: 存在已完成,但是完成时间是过期的
+ var assignmentFilterIds = context.CurrentUserAssignments
+ .Where(x =>
+ //正在进行的,要去掉
+ x.AssignmentState == AssignmentStateEnum.Progress||
+ //已完成,但是还没过期,要去掉
+ (x.AssignmentState == AssignmentStateEnum.Completed&&!AssignmentType.IsExpire(x.CompleteTime!.Value)))
+ .Select(x => x.AssignmentDefineId)
+ .ToList();
+
+
+
+ //出去不可接收的任务,就是可接收任务
+ var output = assignmentDefines.Where(x => !assignmentFilterIds.Contains(x.Id)).ToList();
+ return Task.FromResult(output);
}
+
}
\ No newline at end of file