任务计划类优化改进;修复活动任务没有正确记录领取奖励的用户

This commit is contained in:
milimoe 2025-12-25 19:38:12 +08:00
parent 11afb4dc95
commit b9fbed9c68
Signed by: milimoe
GPG Key ID: 9554D37E4B8991D0
5 changed files with 120 additions and 59 deletions

View File

@ -1,4 +1,5 @@
using Milimoe.FunGame.Core.Library.Constant; using Milimoe.FunGame.Core.Interface.Base;
using Milimoe.FunGame.Core.Library.Constant;
using Milimoe.FunGame.Core.Model; using Milimoe.FunGame.Core.Model;
namespace Milimoe.FunGame.Core.Api.Utility namespace Milimoe.FunGame.Core.Api.Utility
@ -80,78 +81,75 @@ namespace Milimoe.FunGame.Core.Api.Utility
} }
/// <summary> /// <summary>
/// 获取任务计划上一次执行时间 /// 获取任务计划
/// </summary> /// </summary>
/// <param name="name"></param> /// <param name="name"></param>
/// <param name="recurring"></param> /// <param name="recurring"></param>
/// <returns></returns> /// <returns></returns>
public DateTime GetLastTime(string name, bool recurring = false) public IScheduledTask? GetTask(string name, bool recurring = false)
{
if (!recurring)
{
if (_tasks.FirstOrDefault(t => t.Name == name) is ScheduledTask task && task.LastRun.HasValue)
{
return task.LastRun.Value;
}
else if (_recurringTasks.FirstOrDefault(t => t.Name == name) is RecurringTask recurringTask && recurringTask.LastRun.HasValue)
{
return recurringTask.LastRun.Value;
}
}
else if (_recurringTasks.FirstOrDefault(t => t.Name == name) is RecurringTask recurringTask && recurringTask.LastRun.HasValue)
{
return recurringTask.LastRun.Value;
}
return DateTime.MinValue;
}
/// <summary>
/// 获取任务计划下一次执行时间
/// </summary>
/// <param name="name"></param>
/// <param name="recurring"></param>
/// <returns></returns>
public DateTime GetNextTime(string name, bool recurring = false)
{ {
if (!recurring) if (!recurring)
{ {
if (_tasks.FirstOrDefault(t => t.Name == name) is ScheduledTask task) if (_tasks.FirstOrDefault(t => t.Name == name) is ScheduledTask task)
{ {
DateTime today = DateTime.Today.Add(task.TimeOfDay); return task;
return task.IsTodayRun ? today.AddDays(1) : today;
} }
else if (_recurringTasks.FirstOrDefault(t => t.Name == name) is RecurringTask recurringTask) else if (_recurringTasks.FirstOrDefault(t => t.Name == name) is RecurringTask recurringTask)
{ {
return recurringTask.NextRun; return recurringTask;
} }
} }
else if (_recurringTasks.FirstOrDefault(t => t.Name == name) is RecurringTask recurringTask) else if (_recurringTasks.FirstOrDefault(t => t.Name == name) is RecurringTask recurringTask)
{ {
return recurringTask.NextRun; return recurringTask;
} }
return DateTime.MaxValue; return null;
} }
/// <summary>
/// 获取任务计划上一次执行时间
/// </summary>
/// <param name="task"></param>
/// <returns></returns>
public static DateTime GetLastTime(IScheduledTask task) => task.LastRun.HasValue ? task.LastRun.Value : DateTime.MinValue;
/// <summary>
/// 获取任务计划下一次执行时间
/// </summary>
/// <param name="task"></param>
/// <returns></returns>
public static DateTime GetNextTime(IScheduledTask task) => task.NextRun;
/// <summary>
/// 格式化任务计划执行信息
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public string GetRunTimeInfo(string name) public string GetRunTimeInfo(string name)
{ {
DateTime last = GetLastTime(name); string msg;
DateTime next = GetNextTime(name); IScheduledTask? task = GetTask(name);
string msg = ""; if (task is null)
if (last != DateTime.MinValue)
{ {
msg += $"上次运行时间:{last.ToString(General.GeneralDateTimeFormat)}\r\n"; msg = $"任务计划 {name} 不存在!";
}
if (next != DateTime.MaxValue)
{
msg += $"下次运行时间:{next.ToString(General.GeneralDateTimeFormat)}\r\n";
}
if (msg != "")
{
msg = $"任务计划:{name}\r\n{msg}";
} }
else else
{ {
msg = $"任务计划 {name} 不存在!"; msg = $"任务计划:{name}\r\n";
DateTime last = GetLastTime(task);
DateTime next = GetNextTime(task);
if (last != DateTime.MinValue)
{
msg += $"上次执行时间:{last.ToString(General.GeneralDateTimeFormat)}\r\n";
}
if (next != DateTime.MaxValue)
{
msg += $"下次执行时间:{next.ToString(General.GeneralDateTimeFormat)}\r\n";
}
if (task.ExecutedTimeSpan.TotalSeconds > 0)
{
msg += $"任务执行时长:{task.ExecutedTimeSpan.TotalSeconds:0.###} 秒\r\n";
}
} }
return msg.Trim(); return msg.Trim();
} }
@ -168,6 +166,7 @@ namespace Milimoe.FunGame.Core.Api.Utility
{ {
if (!task.IsTodayRun) if (!task.IsTodayRun)
{ {
now = DateTime.Now;
if (now.TimeOfDay >= task.TimeOfDay && now.TimeOfDay < task.TimeOfDay.Add(TimeSpan.FromSeconds(10))) if (now.TimeOfDay >= task.TimeOfDay && now.TimeOfDay < task.TimeOfDay.Add(TimeSpan.FromSeconds(10)))
{ {
task.LastRun = now; task.LastRun = now;
@ -176,6 +175,7 @@ namespace Milimoe.FunGame.Core.Api.Utility
try try
{ {
task.Action(); task.Action();
task.ExecutedTimeSpan = DateTime.Now - now;
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -190,6 +190,7 @@ namespace Milimoe.FunGame.Core.Api.Utility
foreach (RecurringTask recurringTask in _recurringTasks) foreach (RecurringTask recurringTask in _recurringTasks)
{ {
now = DateTime.Now;
if (now >= recurringTask.NextRun) if (now >= recurringTask.NextRun)
{ {
recurringTask.LastRun = now; recurringTask.LastRun = now;
@ -199,6 +200,7 @@ namespace Milimoe.FunGame.Core.Api.Utility
try try
{ {
recurringTask.Action(); recurringTask.Action();
recurringTask.ExecutedTimeSpan = DateTime.Now - now;
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@ -130,7 +130,7 @@ namespace Milimoe.FunGame.Core.Entity
return false; return false;
} }
public bool RegisterAwardedUser(long userId, long questId) => Quests.FirstOrDefault(q => q.Id == questId && q.Status == QuestState.Completed) is Quest quest && RegisterAwardedUser(userId, quest); public bool RegisterAwardedUser(long userId, long questId) => Quests.FirstOrDefault(q => q.Id == questId) is Quest quest && RegisterAwardedUser(userId, quest);
public bool HasUserAwarded(long userId, Quest quest) public bool HasUserAwarded(long userId, Quest quest)
{ {

View File

@ -0,0 +1,40 @@
namespace Milimoe.FunGame.Core.Interface.Base
{
public interface IScheduledTask
{
/// <summary>
/// 任务名称
/// </summary>
public string Name { get; }
/// <summary>
/// 任务执行逻辑
/// </summary>
public Action Action { get; }
/// <summary>
/// 记录上一次执行时间
/// </summary>
public DateTime? LastRun { get; }
/// <summary>
/// 记录下一次执行时间
/// </summary>
public DateTime NextRun { get; }
/// <summary>
/// 任务执行时长
/// </summary>
public TimeSpan ExecutedTimeSpan { get; }
/// <summary>
/// 最后一次执行时发生的错误
/// </summary>
public Exception? Error { get; }
/// <summary>
/// 捕获异常后,触发的回调函数
/// </summary>
public Action<Exception>? ErrorHandler { get; }
}
}

View File

@ -1,6 +1,8 @@
namespace Milimoe.FunGame.Core.Model using Milimoe.FunGame.Core.Interface.Base;
namespace Milimoe.FunGame.Core.Model
{ {
public class RecurringTask(string name, TimeSpan interval, Action action, Action<Exception>? error = null) public class RecurringTask(string name, TimeSpan interval, Action action, Action<Exception>? error = null) : IScheduledTask
{ {
/// <summary> /// <summary>
/// 任务名称 /// 任务名称
@ -18,17 +20,22 @@
public Action Action { get; set; } = action; public Action Action { get; set; } = action;
/// <summary> /// <summary>
/// 记录上一次行时间 /// 记录上一次行时间
/// </summary> /// </summary>
public DateTime? LastRun { get; set; } = null; public DateTime? LastRun { get; set; } = null;
/// <summary> /// <summary>
/// 记录下一次行时间 /// 记录下一次行时间
/// </summary> /// </summary>
public DateTime NextRun { get; set; } = DateTime.MaxValue; public DateTime NextRun { get; set; } = DateTime.MaxValue;
/// <summary> /// <summary>
/// 最后一次运行时发生的错误 /// 任务执行时长
/// </summary>
public TimeSpan ExecutedTimeSpan { get; set; } = new();
/// <summary>
/// 最后一次执行时发生的错误
/// </summary> /// </summary>
public Exception? Error { get; set; } public Exception? Error { get; set; }

View File

@ -1,6 +1,8 @@
namespace Milimoe.FunGame.Core.Model using Milimoe.FunGame.Core.Interface.Base;
namespace Milimoe.FunGame.Core.Model
{ {
public class ScheduledTask(string name, TimeSpan timeSpan, Action action, Action<Exception>? error = null) public class ScheduledTask(string name, TimeSpan timeSpan, Action action, Action<Exception>? error = null) : IScheduledTask
{ {
/// <summary> /// <summary>
/// 任务名称 /// 任务名称
@ -18,17 +20,27 @@
public Action Action { get; set; } = action; public Action Action { get; set; } = action;
/// <summary> /// <summary>
/// 记录上一次行时间 /// 记录上一次行时间
/// </summary> /// </summary>
public DateTime? LastRun { get; set; } = null; public DateTime? LastRun { get; set; } = null;
/// <summary> /// <summary>
/// 当天是否已经运行 /// 记录下一次执行时间
/// </summary>
public DateTime NextRun => IsTodayRun ? DateTime.Today.AddDays(1).Add(TimeOfDay) : DateTime.Today.Add(TimeOfDay);
/// <summary>
/// 当天是否已经执行
/// </summary> /// </summary>
public bool IsTodayRun => LastRun.HasValue && LastRun.Value.Date == DateTime.Today; public bool IsTodayRun => LastRun.HasValue && LastRun.Value.Date == DateTime.Today;
/// <summary> /// <summary>
/// 最后一次运行时发生的错误 /// 任务执行时长
/// </summary>
public TimeSpan ExecutedTimeSpan { get; set; } = new();
/// <summary>
/// 最后一次执行时发生的错误
/// </summary> /// </summary>
public Exception? Error { get; set; } public Exception? Error { get; set; }