You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
154 lines
5.8 KiB
C#
154 lines
5.8 KiB
C#
using Microsoft.EntityFrameworkCore;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using Haoliang.Models.System;
|
|
using Haoliang.Data.Repositories;
|
|
|
|
namespace Haoliang.Data.Repositories
|
|
{
|
|
public interface IScheduledTaskRepository : IRepository<ScheduledTask>
|
|
{
|
|
Task<IEnumerable<ScheduledTask>> GetActiveTasksAsync();
|
|
Task<IEnumerable<ScheduledTask>> GetTasksByStatusAsync(TaskStatus status);
|
|
Task<TaskExecutionResult> GetLastExecutionResultAsync(string taskId);
|
|
Task<IEnumerable<ScheduledTask>> GetTasksByCronExpressionAsync(string cronExpression);
|
|
Task<IEnumerable<ScheduledTask>> GetOverdueTasksAsync();
|
|
Task<bool> ExecuteTaskAsync(string taskId);
|
|
Task<ScheduledTask> GetNextScheduledTaskAsync();
|
|
Task<TaskExecutionSummary> GetExecutionSummaryAsync(DateTime date);
|
|
Task<IEnumerable<TaskExecutionResult>> GetExecutionHistoryAsync(string taskId, int count = 10);
|
|
}
|
|
|
|
public class ScheduledTaskRepository : Repository<ScheduledTask>, IScheduledTaskRepository
|
|
{
|
|
private readonly CNCDbContext _context;
|
|
|
|
public ScheduledTaskRepository(CNCDbContext context) : base(context)
|
|
{
|
|
_context = context;
|
|
}
|
|
|
|
public async Task<IEnumerable<ScheduledTask>> GetActiveTasksAsync()
|
|
{
|
|
return await _context.ScheduledTasks
|
|
.Where(t => t.IsActive && t.TaskStatus != TaskStatus.Disabled)
|
|
.OrderBy(t => t.NextRunTime)
|
|
.ToListAsync();
|
|
}
|
|
|
|
public async Task<IEnumerable<ScheduledTask>> GetTasksByStatusAsync(TaskStatus status)
|
|
{
|
|
return await _context.ScheduledTasks
|
|
.Where(t => t.TaskStatus == status)
|
|
.OrderBy(t => t.CreatedAt)
|
|
.ToListAsync();
|
|
}
|
|
|
|
public async Task<TaskExecutionResult> GetLastExecutionResultAsync(string taskId)
|
|
{
|
|
return await _context.TaskExecutionResults
|
|
.Where(r => r.TaskId == taskId)
|
|
.OrderByDescending(r => r.ExecutionTime)
|
|
.FirstOrDefaultAsync();
|
|
}
|
|
|
|
public async Task<IEnumerable<ScheduledTask>> GetTasksByCronExpressionAsync(string cronExpression)
|
|
{
|
|
return await _context.ScheduledTasks
|
|
.Where(t => t.CronExpression == cronExpression && t.IsActive)
|
|
.OrderBy(t => t.TaskName)
|
|
.ToListAsync();
|
|
}
|
|
|
|
public async Task<IEnumerable<ScheduledTask>> GetOverdueTasksAsync()
|
|
{
|
|
var now = DateTime.Now;
|
|
return await _context.ScheduledTasks
|
|
.Where(t => t.IsActive &&
|
|
t.NextRunTime <= now &&
|
|
t.TaskStatus != TaskStatus.Running)
|
|
.OrderBy(t => t.NextRunTime)
|
|
.ToListAsync();
|
|
}
|
|
|
|
public async Task<bool> ExecuteTaskAsync(string taskId)
|
|
{
|
|
var task = await GetByIdAsync(taskId);
|
|
if (task == null || !task.IsActive)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
task.TaskStatus = TaskStatus.Running;
|
|
task.LastRunAt = DateTime.Now;
|
|
await SaveAsync();
|
|
|
|
// Create execution result
|
|
var result = new TaskExecutionResult
|
|
{
|
|
TaskId = taskId,
|
|
ExecutionTime = DateTime.Now,
|
|
Status = TaskStatus.Running,
|
|
ErrorMessage = null
|
|
};
|
|
|
|
_context.TaskExecutionResults.Add(result);
|
|
await SaveAsync();
|
|
|
|
return true;
|
|
}
|
|
|
|
public async Task<ScheduledTask> GetNextScheduledTaskAsync()
|
|
{
|
|
var now = DateTime.Now;
|
|
return await _context.ScheduledTasks
|
|
.Where(t => t.IsActive &&
|
|
t.NextRunTime <= now &&
|
|
t.TaskStatus != TaskStatus.Running)
|
|
.OrderBy(t => t.NextRunTime)
|
|
.FirstOrDefaultAsync();
|
|
}
|
|
|
|
public async Task<TaskExecutionSummary> GetExecutionSummaryAsync(DateTime date)
|
|
{
|
|
var startOfDay = date.Date;
|
|
var endOfDay = startOfDay.AddDays(1);
|
|
|
|
var executionResults = await _context.TaskExecutionResults
|
|
.Where(r => r.ExecutionTime >= startOfDay && r.ExecutionTime <= endOfDay)
|
|
.ToListAsync();
|
|
|
|
var summary = new TaskExecutionSummary
|
|
{
|
|
Date = date,
|
|
TotalExecutions = executionResults.Count,
|
|
SuccessfulExecutions = executionResults.Count(r => r.Status == TaskStatus.Completed),
|
|
FailedExecutions = executionResults.Count(r => r.Status == TaskStatus.Failed),
|
|
RunningExecutions = executionResults.Count(r => r.Status == TaskStatus.Running),
|
|
ExecutionDetails = executionResults
|
|
.GroupBy(r => r.TaskId)
|
|
.ToDictionary(g => g.Key, g => new TaskExecutionDetail
|
|
{
|
|
TaskName = g.FirstOrDefault()?.ScheduledTask?.TaskName ?? "",
|
|
TotalExecutions = g.Count(),
|
|
SuccessfulExecutions = g.Count(r => r.Status == TaskStatus.Completed),
|
|
FailedExecutions = g.Count(r => r.Status == TaskStatus.Failed),
|
|
AverageExecutionTime = g.Average(r => r.ExecutionDurationMs)
|
|
})
|
|
};
|
|
|
|
return summary;
|
|
}
|
|
|
|
public async Task<IEnumerable<TaskExecutionResult>> GetExecutionHistoryAsync(string taskId, int count = 10)
|
|
{
|
|
return await _context.TaskExecutionResults
|
|
.Where(r => r.TaskId == taskId)
|
|
.OrderByDescending(r => r.ExecutionTime)
|
|
.Take(count)
|
|
.ToListAsync();
|
|
}
|
|
}
|
|
} |