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.

216 lines
8.6 KiB
C#

using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Haoliang.Models.DataCollection;
using Haoliang.Data.Repositories;
namespace Haoliang.Data.Repositories
{
public interface ICollectionResultRepository : IRepository<CollectionResult>
{
Task<IEnumerable<CollectionResult>> GetByDeviceAsync(int deviceId);
Task<IEnumerable<CollectionResult>> GetByDateRangeAsync(int deviceId, DateTime startDate, DateTime endDate);
Task<CollectionStatistics> GetStatisticsAsync(DateTime date);
Task<CollectionHealth> GetHealthAsync();
Task ArchiveResultsAsync(int daysToKeep = 30);
Task<IEnumerable<CollectionResult>> GetSuccessfulResultsAsync(int deviceId, DateTime date);
Task<IEnumerable<CollectionResult>> GetFailedResultsAsync(int deviceId, DateTime date);
Task<AverageResponseTime> GetAverageResponseTimeAsync(int deviceId, DateTime date);
Task<int> GetSuccessRateAsync(int deviceId, DateTime date);
}
public class CollectionResultRepository : Repository<CollectionResult>, ICollectionResultRepository
{
private readonly CNCDbContext _context;
public CollectionResultRepository(CNCDbContext context) : base(context)
{
_context = context;
}
public async Task<IEnumerable<CollectionResult>> GetByDeviceAsync(int deviceId)
{
return await _context.CollectionResults
.Where(r => r.DeviceId == deviceId)
.OrderByDescending(r => r.CollectionTime)
.ToListAsync();
}
public async Task<IEnumerable<CollectionResult>> GetByDateRangeAsync(int deviceId, DateTime startDate, DateTime endDate)
{
return await _context.CollectionResults
.Where(r => r.DeviceId == deviceId &&
r.CollectionTime >= startDate &&
r.CollectionTime <= endDate)
.OrderByDescending(r => r.CollectionTime)
.ToListAsync();
}
public async Task<CollectionStatistics> GetStatisticsAsync(DateTime date)
{
var startOfDay = date.Date;
var endOfDay = startOfDay.AddDays(1);
var results = await _context.CollectionResults
.Where(r => r.CollectionTime >= startOfDay &&
r.CollectionTime <= endOfDay)
.ToListAsync();
var stats = new CollectionStatistics
{
Date = date,
TotalAttempts = results.Count(),
SuccessCount = results.Count(r => r.IsSuccess),
FailedCount = results.Count(r => !r.IsSuccess),
SuccessRate = results.Any() ? (decimal)results.Count(r => r.IsSuccess) / results.Count() * 100 : 0,
DeviceCount = results.Select(r => r.DeviceId).Distinct().Count(),
OnlineDeviceCount = await _context.Devices.CountAsync(d => d.IsOnline),
TotalDataSize = results.Sum(r => r.DataSize ?? 0)
};
if (stats.SuccessCount > 0)
{
var successfulResults = results.Where(r => r.IsSuccess).ToList();
stats.AverageResponseTime = TimeSpan.FromTicks(
(long)successfulResults.Average(r => r.ResponseTime ?? 0));
}
return stats;
}
public async Task<CollectionHealth> GetHealthAsync()
{
var stats = await GetStatisticsAsync(DateTime.Now);
var onlineDeviceCount = await _context.Devices.CountAsync(d => d.IsOnline);
var availableDeviceCount = await _context.Devices.CountAsync(d => d.IsAvailable);
var activeTasks = await _context.CollectionTasks
.CountAsync(t => t.Status == "Running");
var failedTasks = await _context.CollectionTasks
.CountAsync(t => t.Status == "Failed");
var lastSuccessful = await _context.CollectionResults
.Where(r => r.IsSuccess)
.OrderByDescending(r => r.CollectionTime)
.FirstOrDefault();
var lastFailed = await _context.CollectionResults
.Where(r => !r.IsSuccess)
.OrderByDescending(r => r.CollectionTime)
.FirstOrDefault();
return new CollectionHealth
{
CheckTime = DateTime.Now,
TotalDevices = onlineDeviceCount,
OnlineDevices = availableDeviceCount,
ActiveCollectionTasks = activeTasks,
FailedTasks = failedTasks,
SuccessRate = stats.SuccessRate,
AverageResponseTime = stats.AverageResponseTime,
TotalCollectedData = stats.TotalDataSize,
LastSuccessfulCollection = lastSuccessful?.CollectionTime ?? DateTime.MinValue,
LastFailedCollection = lastFailed?.CollectionTime ?? DateTime.MinValue
};
}
public async Task ArchiveResultsAsync(int daysToKeep = 30)
{
var cutoffDate = DateTime.Now.AddDays(-daysToKeep);
var resultsToArchive = await _context.CollectionResults
.Where(r => r.CollectionTime < cutoffDate)
.ToListAsync();
if (resultsToArchive.Any())
{
// In a real implementation, you would move these to an archive table
_context.CollectionResults.RemoveRange(resultsToArchive);
await SaveAsync();
}
}
public async Task<IEnumerable<CollectionResult>> GetSuccessfulResultsAsync(int deviceId, DateTime date)
{
var startOfDay = date.Date;
var endOfDay = startOfDay.AddDays(1);
return await _context.CollectionResults
.Where(r => r.DeviceId == deviceId &&
r.CollectionTime >= startOfDay &&
r.CollectionTime <= endOfDay &&
r.IsSuccess)
.OrderByDescending(r => r.CollectionTime)
.ToListAsync();
}
public async Task<IEnumerable<CollectionResult>> GetFailedResultsAsync(int deviceId, DateTime date)
{
var startOfDay = date.Date;
var endOfDay = startOfDay.AddDays(1);
return await _context.CollectionResults
.Where(r => r.DeviceId == deviceId &&
r.CollectionTime >= startOfDay &&
r.CollectionTime <= endOfDay &&
!r.IsSuccess)
.OrderByDescending(r => r.CollectionTime)
.ToListAsync();
}
public async Task<AverageResponseTime> GetAverageResponseTimeAsync(int deviceId, DateTime date)
{
var startOfDay = date.Date;
var endOfDay = startOfDay.AddDays(1);
var successfulResults = await _context.CollectionResults
.Where(r => r.DeviceId == deviceId &&
r.CollectionTime >= startOfDay &&
r.CollectionTime <= endOfDay &&
r.IsSuccess)
.ToListAsync();
if (successfulResults.Any())
{
var averageTicks = (long)successfulResults.Average(r => r.ResponseTime ?? 0);
return new AverageResponseTime
{
DeviceId = deviceId,
Date = date,
AverageTime = TimeSpan.FromTicks(averageTicks),
SampleCount = successfulResults.Count
};
}
return new AverageResponseTime
{
DeviceId = deviceId,
Date = date,
AverageTime = TimeSpan.Zero,
SampleCount = 0
};
}
public async Task<int> GetSuccessRateAsync(int deviceId, DateTime date)
{
var startOfDay = date.Date;
var endOfDay = startOfDay.AddDays(1);
var results = await _context.CollectionResults
.Where(r => r.DeviceId == deviceId &&
r.CollectionTime >= startOfDay &&
r.CollectionTime <= endOfDay)
.ToListAsync();
if (results.Any())
{
var successCount = results.Count(r => r.IsSuccess);
return (int)(decimal)successCount / results.Count() * 100;
}
return 0;
}
}
}