using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Haoliang.Data; using Haoliang.Data.Entities; using Haoliang.Models.System; using Haoliang.Data.Repositories; namespace Haoliang.Data.Repositories { public interface IScheduledTaskRepository : IRepository { Task> GetActiveTasksAsync(); Task> GetTasksByStatusAsync(Haoliang.Models.System.TaskStatus status); Task GetLastExecutionResultAsync(string taskId); Task> GetTasksByCronExpressionAsync(string cronExpression); Task> GetOverdueTasksAsync(); Task ExecuteTaskAsync(string taskId); Task GetNextScheduledTaskAsync(); Task GetExecutionSummaryAsync(DateTime date); Task> GetExecutionHistoryAsync(string taskId, int count = 10); } public class ScheduledTaskRepository : Repository, IScheduledTaskRepository { private readonly CNCDbContext _context; public ScheduledTaskRepository(CNCDbContext context) : base(context) { _context = context; } public async Task> GetActiveTasksAsync() { return await _context.ScheduledTasks .Where(t => t.IsActive && t.TaskStatus != Haoliang.Models.System.TaskStatus.Disabled) .OrderBy(t => t.NextRunTime) .ToListAsync(); } public async Task> GetTasksByStatusAsync(Haoliang.Models.System.TaskStatus status) { return await _context.ScheduledTasks .Where(t => t.TaskStatus == status) .OrderBy(t => t.CreatedAt) .ToListAsync(); } public async Task GetLastExecutionResultAsync(string taskId) { return await _context.TaskExecutionResults .Where(r => r.TaskId == taskId) .OrderByDescending(r => r.ExecutionTime) .FirstOrDefaultAsync(); } public async Task> GetTasksByCronExpressionAsync(string cronExpression) { return await _context.ScheduledTasks .Where(t => t.CronExpression == cronExpression && t.IsActive) .OrderBy(t => t.TaskName) .ToListAsync(); } public async Task> GetOverdueTasksAsync() { var now = DateTime.Now; return await _context.ScheduledTasks .Where(t => t.IsActive && t.NextRunTime <= now && t.TaskStatus != Haoliang.Models.System.TaskStatus.Running) .OrderBy(t => t.NextRunTime) .ToListAsync(); } public async Task ExecuteTaskAsync(string taskId) { var task = await _context.ScheduledTasks.Where(t => t.TaskId == taskId).FirstOrDefaultAsync(); if (task == null || !task.IsActive) { return false; } task.TaskStatus = Haoliang.Models.System.TaskStatus.Running; task.LastRunAt = DateTime.Now; await SaveAsync(); // Create execution result var result = new TaskExecutionResult { TaskId = taskId, ExecutionTime = DateTime.Now, Status = Haoliang.Models.System.TaskStatus.Running, ErrorMessage = null }; _context.TaskExecutionResults.Add(result); await SaveAsync(); return true; } public async Task GetNextScheduledTaskAsync() { var now = DateTime.Now; return await _context.ScheduledTasks .Where(t => t.IsActive && t.NextRunTime <= now && t.TaskStatus != Haoliang.Models.System.TaskStatus.Running) .OrderBy(t => t.NextRunTime) .FirstOrDefaultAsync(); } public async Task 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 == Haoliang.Models.System.TaskStatus.Completed), FailedExecutions = executionResults.Count(r => r.Status == Haoliang.Models.System.TaskStatus.Failed), RunningExecutions = executionResults.Count(r => r.Status == Haoliang.Models.System.TaskStatus.Running), ExecutionDetails = executionResults .GroupBy(r => r.TaskId) .ToDictionary(g => g.Key, g => new TaskExecutionDetail { TaskName = g.Key ?? "", TotalExecutions = g.Count(), SuccessfulExecutions = g.Count(r => r.Status == Haoliang.Models.System.TaskStatus.Completed), FailedExecutions = g.Count(r => r.Status == Haoliang.Models.System.TaskStatus.Failed), AverageExecutionTime = g.Average(r => r.ExecutionDurationMs?.TotalMilliseconds ?? 0) }) }; return summary; } public async Task> GetExecutionHistoryAsync(string taskId, int count = 10) { return await _context.TaskExecutionResults .Where(r => r.TaskId == taskId) .OrderByDescending(r => r.ExecutionTime) .Take(count) .ToListAsync(); } } }