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#

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();
}
}
}