using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Haoliang.Models.DataCollection; using Haoliang.Data; using Haoliang.Data.Repositories; using Haoliang.Data.Entities; namespace Haoliang.Data.Repositories { public interface ICollectionTaskRepository : IRepository { Task> GetPendingTasksAsync(); Task> GetRunningTasksAsync(); Task> GetTasksByDeviceIdAsync(int deviceId); Task> GetFailedTasksAsync(int retryCount = 3); Task GetNextPendingTaskAsync(); Task MarkTaskCompletedAsync(int taskId, bool isSuccess, string errorMessage = null); Task MarkTaskRunningAsync(int taskId); Task CountPendingTasksAsync(); Task CountFailedTasksAsync(); Task GetTaskSuccessRateAsync(int hours = 24); } public class CollectionTaskRepository : Repository, ICollectionTaskRepository { private readonly CNCDbContext _context; public CollectionTaskRepository(CNCDbContext context) : base(context) { _context = context; } public async Task> GetPendingTasksAsync() { return await _context.CollectionTasks .Where(ct => ct.Status == "Pending") .OrderBy(ct => ct.ScheduledTime) .ToListAsync(); } public async Task> GetRunningTasksAsync() { return await _context.CollectionTasks .Where(ct => ct.Status == "Running") .OrderBy(ct => ct.StartTime) .ToListAsync(); } public async Task> GetTasksByDeviceIdAsync(int deviceId) { return await _context.CollectionTasks .Where(ct => ct.DeviceId == deviceId) .OrderByDescending(ct => ct.ScheduledTime) .ToListAsync(); } public async Task> GetFailedTasksAsync(int retryCount = 3) { return await _context.CollectionTasks .Where(ct => ct.Status == "Failed" && ct.RetryCount >= retryCount) .OrderByDescending(ct => ct.ScheduledTime) .ToListAsync(); } public async Task GetNextPendingTaskAsync() { return await _context.CollectionTasks .Where(ct => ct.Status == "Pending" && ct.ScheduledTime <= DateTime.Now) .OrderBy(ct => ct.ScheduledTime) .FirstOrDefaultAsync(); } public async Task MarkTaskCompletedAsync(int taskId, bool isSuccess, string errorMessage = null) { var task = await GetByIdAsync(taskId); if (task != null) { task.Status = isSuccess ? "Completed" : "Failed"; task.EndTime = DateTime.Now; task.IsSuccess = isSuccess; if (!isSuccess) { task.ErrorMessage = errorMessage; task.RetryCount++; } Update(task); await SaveAsync(); return true; } return false; } public async Task MarkTaskRunningAsync(int taskId) { var task = await GetByIdAsync(taskId); if (task != null) { task.Status = "Running"; task.StartTime = DateTime.Now; Update(task); await SaveAsync(); return true; } return false; } public async Task CountPendingTasksAsync() { return await _context.CollectionTasks .CountAsync(ct => ct.Status == "Pending"); } public async Task CountFailedTasksAsync() { return await _context.CollectionTasks .CountAsync(ct => ct.Status == "Failed"); } public async Task GetTaskSuccessRateAsync(int hours = 24) { var startTime = DateTime.Now.AddHours(-hours); var tasks = await _context.CollectionTasks .Where(ct => ct.ScheduledTime >= startTime) .ToListAsync(); if (tasks.Any()) { var successCount = tasks.Count(ct => ct.IsSuccess); return (decimal)successCount / tasks.Count * 100; } return 0; } } public interface ICollectionResultRepository : IRepository { Task> GetResultsByDeviceIdAsync(int deviceId); Task> GetResultsByDateRangeAsync(DateTime startDate, DateTime endDate); Task> GetFailedResultsAsync(int deviceId = 0); Task GetLatestResultAsync(int deviceId); Task CountResultsAsync(int deviceId = 0); Task CountFailedResultsAsync(int deviceId = 0); Task GetAverageResponseTimeAsync(int deviceId = 0); Task GetTotalDataSizeAsync(int deviceId = 0); Task DeleteOldResultsAsync(int keepDays = 30); } public class CollectionResultRepository : Repository, ICollectionResultRepository { private readonly CNCDbContext _context; public CollectionResultRepository(CNCDbContext context) : base(context) { _context = context; } public async Task> GetResultsByDeviceIdAsync(int deviceId) { return await _context.CollectionResults .Where(cr => cr.DeviceId == deviceId) .OrderByDescending(cr => cr.CollectionTime) .ToListAsync(); } public async Task> GetResultsByDateRangeAsync(DateTime startDate, DateTime endDate) { return await _context.CollectionResults .Where(cr => cr.CollectionTime >= startDate && cr.CollectionTime <= endDate) .OrderByDescending(cr => cr.CollectionTime) .ToListAsync(); } public async Task> GetFailedResultsAsync(int deviceId = 0) { var query = _context.CollectionResults.Where(cr => !cr.IsSuccess); if (deviceId > 0) { query = query.Where(cr => cr.DeviceId == deviceId); } return await query .OrderByDescending(cr => cr.CollectionTime) .ToListAsync(); } public async Task GetLatestResultAsync(int deviceId) { return await _context.CollectionResults .Where(cr => cr.DeviceId == deviceId) .OrderByDescending(cr => cr.CollectionTime) .FirstOrDefaultAsync(); } public async Task CountResultsAsync(int deviceId = 0) { var query = _context.CollectionResults.AsQueryable(); if (deviceId > 0) { query = query.Where(cr => cr.DeviceId == deviceId); } return await query.CountAsync(); } public async Task CountFailedResultsAsync(int deviceId = 0) { var query = _context.CollectionResults.Where(cr => !cr.IsSuccess); if (deviceId > 0) { query = query.Where(cr => cr.DeviceId == deviceId); } return await query.CountAsync(); } public async Task GetAverageResponseTimeAsync(int deviceId = 0) { var query = _context.CollectionResults.Where(cr => cr.IsSuccess); if (deviceId > 0) { query = query.Where(cr => cr.DeviceId == deviceId); } var results = await query.ToListAsync(); if (results.Any()) { return (decimal)results.Average(cr => cr.ResponseTime); } return 0; } public async Task GetTotalDataSizeAsync(int deviceId = 0) { var query = _context.CollectionResults.Where(cr => cr.IsSuccess); if (deviceId > 0) { query = query.Where(cr => cr.DeviceId == deviceId); } var results = await query.ToListAsync(); return results.Sum(cr => cr.DataSize ?? 0); } public async Task DeleteOldResultsAsync(int keepDays = 30) { var cutoffDate = DateTime.Now.AddDays(-keepDays); var oldResults = await _context.CollectionResults .Where(cr => cr.CollectionTime < cutoffDate) .ToListAsync(); if (oldResults.Any()) { RemoveRange(oldResults); await SaveAsync(); return true; } return false; } } public interface ICollectionLogRepository : IRepository { Task> GetLogsByLevelAsync(LogLevel logLevel); Task> GetLogsByDeviceIdAsync(int deviceId); Task> GetLogsByDateRangeAsync(DateTime startDate, DateTime endDate); Task> GetErrorLogsAsync(); Task CountLogsByLevelAsync(LogLevel logLevel); Task DeleteOldLogsAsync(int keepDays = 90); } public class CollectionLogRepository : Repository, ICollectionLogRepository { private readonly CNCDbContext _context; public CollectionLogRepository(CNCDbContext context) : base(context) { _context = context; } public async Task> GetLogsByLevelAsync(LogLevel logLevel) { return await _context.CollectionLogs .Where(cl => cl.LogLevel == logLevel) .OrderByDescending(cl => cl.LogTime) .ToListAsync(); } public async Task> GetLogsByDeviceIdAsync(int deviceId) { return await _context.CollectionLogs .Where(cl => cl.DeviceId == deviceId) .OrderByDescending(cl => cl.LogTime) .ToListAsync(); } public async Task> GetLogsByDateRangeAsync(DateTime startDate, DateTime endDate) { return await _context.CollectionLogs .Where(cl => cl.LogTime >= startDate && cl.LogTime <= endDate) .OrderByDescending(cl => cl.LogTime) .ToListAsync(); } public async Task> GetErrorLogsAsync() { return await _context.CollectionLogs .Where(cl => cl.LogLevel == LogLevel.Error || cl.LogLevel == LogLevel.Critical) .OrderByDescending(cl => cl.LogTime) .ToListAsync(); } public async Task CountLogsByLevelAsync(LogLevel logLevel) { return await _context.CollectionLogs .CountAsync(cl => cl.LogLevel == logLevel); } public async Task DeleteOldLogsAsync(int keepDays = 90) { var cutoffDate = DateTime.Now.AddDays(-keepDays); var oldLogs = await _context.CollectionLogs .Where(cl => cl.LogTime < cutoffDate) .ToListAsync(); if (oldLogs.Any()) { RemoveRange(oldLogs); await SaveAsync(); return true; } return false; } } }