using System; using System.Collections.Generic; using System.Threading.Tasks; using Haoliang.Models.DataCollection; using Haoliang.Models.Device; using Haoliang.Models.System; using Haoliang.Models.User; using Haoliang.Models.Template; using Haoliang.Models.Production; using Haoliang.Data.Repositories; namespace Haoliang.Core.Services { // 完整的仓储接口定义(确保所有服务都能编译) public interface IAlarmRepository : IRepository { Task> GetByDeviceIdAsync(int deviceId); Task> GetByAlarmTypeAsync(AlarmType type); Task> GetByStatusAsync(AlarmStatus status); Task> GetByDateRangeAsync(DateTime startDate, DateTime endDate); Task GetAlarmStatisticsAsync(DateTime date); Task> GetBySeverityAsync(AlarmSeverity severity); Task> GetByDeviceAndDateRangeAsync(int deviceId, DateTime startDate, DateTime endDate); } public interface ISystemConfigRepository : IRepository { Task GetByKeyAsync(string configKey); Task DeleteByKeyAsync(string configKey); Task KeyExistsAsync(string configKey); Task> GetByCategoryAsync(string category); SystemConfig UpsertAsync(SystemConfig config); } public interface ILogRepository : IRepository { Task> GetLogsAsync(LogLevel? logLevel = null, DateTime? startDate = null, DateTime? endDate = null, string category = null); Task GetLogCountAsync(LogLevel? logLevel = null, DateTime? startDate = null, DateTime? endDate = null); Task ArchiveLogsAsync(DateTime cutoffDate); Task ClearLogsAsync(); } public interface IScheduledTaskRepository : IRepository { Task> GetActiveTasksAsync(); Task> GetTasksByStatusAsync(TaskStatus status); Task GetLastExecutionResultAsync(string taskId); } public interface IProgramProductionSummaryRepository : IRepository { Task GetByDeviceAndDateAsync(int deviceId, DateTime date); Task> GetByDateAsync(DateTime date); Task> GetByDeviceAsync(int deviceId); } public interface IUserRepository : IRepository { Task GetByUsernameAsync(string username); Task GetByEmailAsync(string email); Task IsUsernameExistsAsync(string username); Task IsEmailExistsAsync(string email); Task> GetByRoleAsync(string roleName); Task> GetByDepartmentAsync(string department); } // 增强的仓储接口 public interface IDeviceRepository : IRepository { Task> GetOnlineDevicesAsync(); Task> GetOfflineDevicesAsync(); Task GetByDeviceCodeAsync(string deviceCode); Task IsDeviceOnlineAsync(int deviceId); Task> GetByTemplateAsync(int templateId); Task UpdateDeviceStatusAsync(int deviceId, DeviceStatus status); Task GetDeviceStatisticsAsync(int deviceId); } public interface ITemplateRepository : IRepository { Task> GetByBrandAsync(string brandName); Task> GetActiveTemplatesAsync(); Task IsTemplateInUseAsync(int templateId); Task GetByNameAsync(string templateName); } public interface IProductionRepository : IRepository { Task GetByDeviceAndDateAsync(int deviceId, DateTime date); Task> GetByDateRangeAsync(int deviceId, DateTime startDate, DateTime endDate); Task GetStatisticsAsync(int deviceId, DateTime date); Task GetSummaryAsync(DateTime date); Task HasProductionDataAsync(int deviceId, DateTime date); Task ArchiveProductionDataAsync(int daysToKeep = 90); } public interface ICollectionTaskRepository : IRepository { Task> GetPendingTasksAsync(); Task> GetFailedTasksAsync(); Task GetByDeviceAsync(int deviceId); Task MarkTaskCompletedAsync(int taskId, bool isSuccess, string result); } public interface ICollectionResultRepository : IRepository { Task> GetByDeviceAsync(int deviceId); Task> GetByDateRangeAsync(int deviceId, DateTime startDate, DateTime endDate); Task GetStatisticsAsync(DateTime date); Task GetHealthAsync(); Task ArchiveResultsAsync(int daysToKeep = 30); } public interface ICollectionLogRepository : IRepository { Task> GetByDeviceAsync(int deviceId); Task> GetByLogLevelAsync(LogLevel logLevel); Task GetErrorCountAsync(int deviceId); Task ArchiveLogsAsync(int daysToKeep = 30); Task ClearLogsAsync(); } public interface IProductionSummaryRepository : IRepository { Task GetByDateAsync(DateTime date); Task> GetByDateRangeAsync(DateTime startDate, DateTime endDate); Task GetByDeviceAndDateAsync(int deviceId, DateTime date); Task GetTodaySummaryAsync(); } // 背景任务管理器 public class BackgroundTaskManager : ISchedulerService { private readonly IScheduledTaskRepository _taskRepository; private readonly IProductionService _productionService; private readonly ILoggingService _loggingService; private readonly ConcurrentDictionary _runningTasks = new(); private readonly ConcurrentDictionary _taskStatus = new(); private System.Threading.Timer _schedulerTimer; public BackgroundTaskManager( IScheduledTaskRepository taskRepository, IProductionService productionService, ILoggingService loggingService) { _taskRepository = taskRepository; _productionService = productionService; _loggingService = loggingService; } public async Task StartSchedulerAsync() { _schedulerTimer = new System.Threading.Timer( async _ => await CheckAndExecuteTasksAsync(), null, TimeSpan.Zero, TimeSpan.FromMinutes(1)); await _loggingService.LogInfoAsync("Background task scheduler started"); } public async Task StopSchedulerAsync() { _schedulerTimer?.Dispose(); _schedulerTimer = null; foreach (var task in _runningTasks.Values) { if (!task.IsCompleted) { await Task.WhenAny(task, Task.Delay(TimeSpan.FromSeconds(5))); } } await _loggingService.LogInfoAsync("Background task scheduler stopped"); } public async Task ScheduleTaskAsync(ScheduledTask task) { task.TaskStatus = TaskStatus.Pending; task.CreatedAt = DateTime.Now; task.LastRunAt = null; await _taskRepository.AddAsync(task); await _loggingService.LogInfoAsync($"Task {task.TaskName} scheduled"); } public async Task RemoveTaskAsync(string taskId) { var task = await _taskRepository.GetByIdAsync(taskId); if (task == null) { return false; } // 如果任务正在运行,等待完成 if (_runningTasks.ContainsKey(taskId)) { var runningTask = _runningTasks[taskId]; await Task.WhenAny(runningTask, Task.Delay(TimeSpan.FromSeconds(5))); } return await _taskRepository.DeleteAsync(taskId); } public async Task> GetAllScheduledTasksAsync() { return await _taskRepository.GetAllAsync(); } public async Task GetTaskByIdAsync(string taskId) { return await _taskRepository.GetByIdAsync(taskId); } public async Task ExecuteTaskAsync(string taskId) { if (_runningTasks.ContainsKey(taskId)) { await _loggingService.LogWarningAsync($"Task {taskId} is already running"); return; } var task = await _taskRepository.GetByIdAsync(taskId); if (task == null) { await _loggingService.LogErrorAsync($"Task {taskId} not found"); return; } var taskExecution = Task.Run(async () => { try { _taskStatus[taskId] = true; task.TaskStatus = TaskStatus.Running; task.LastRunAt = DateTime.Now; await _taskRepository.UpdateAsync(task); await _loggingService.LogInfoAsync($"Executing task: {task.TaskName}"); // 执行任务逻辑 switch (task.TaskName) { case "ProductionCalculation": await _productionService.CalculateAllProductionAsync(); break; case "DataCollection": // 数据采集逻辑 break; case "LogArchival": await _loggingService.ArchiveLogsAsync(30); break; case "DataCleanup": // 数据清理逻辑 break; default: await _loggingService.LogWarningAsync($"Unknown task type: {task.TaskName}"); break; } task.TaskStatus = TaskStatus.Completed; task.CompletedAt = DateTime.Now; await _taskRepository.UpdateAsync(task); await _loggingService.LogInfoAsync($"Task {task.TaskName} completed successfully"); } catch (Exception ex) { task.TaskStatus = TaskStatus.Failed; task.ErrorMessage = ex.Message; task.CompletedAt = DateTime.Now; await _taskRepository.UpdateAsync(task); await _loggingService.LogErrorAsync($"Task {task.TaskName} failed: {ex.Message}", ex); } finally { _runningTasks.TryRemove(taskId, out _); _taskStatus.TryRemove(taskId, out _); } }); _runningTasks[taskId] = taskExecution; } public async Task GetTaskExecutionResultAsync(string taskId) { return await _taskRepository.GetLastExecutionResultAsync(taskId); } public async Task IsTaskRunningAsync(string taskId) { return _runningTasks.ContainsKey(taskId) && _taskStatus.ContainsKey(taskId) && _taskStatus[taskId]; } public async Task ScheduleRecurringTaskAsync(string taskName, Action taskAction, TimeSpan interval) { var task = new ScheduledTask { TaskId = Guid.NewGuid().ToString(), TaskName = taskName, CronExpression = $"*/{interval.TotalMinutes} * * * *", TaskStatus = TaskStatus.Pending, IsActive = true, CreatedAt = DateTime.Now, Description = $"Recurring task: {taskName}" }; await ScheduleTaskAsync(task); return task.TaskId; } private async Task CheckAndExecuteTasksAsync() { var pendingTasks = await _taskRepository.GetActiveTasksAsync(); var now = DateTime.Now; foreach (var task in pendingTasks) { if (await ShouldExecuteTaskAsync(task, now)) { await ExecuteTaskAsync(task.TaskId); } } } private async Task ShouldExecuteTaskAsync(ScheduledTask task, DateTime now) { if (task.TaskStatus == TaskStatus.Running || !task.IsActive) { return false; } // 简单的时间检查(实际应该使用CRON表达式解析器) if (task.LastRunAt == null) { return true; } var timeSinceLastRun = now - task.LastRunAt.Value; return timeSinceLastRun.TotalMinutes >= 1; // 每分钟执行一次 } } // 缓存服务实现 public class CacheManager : ICachingService { private readonly ConcurrentDictionary _cache = new(); private readonly System.Threading.Timer _cleanupTimer; public CacheManager() { _cleanupTimer = new System.ThreadingTimer( _ => CleanupExpiredItems(), null, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5)); } public async Task GetAsync(string key) { if (_cache.TryGetValue(key, out var item)) { if (item.ExpirationTime > DateTime.Now) { return (T)item.Value; } _cache.TryRemove(key, out _); } return default; } public async Task SetAsync(string key, T value, TimeSpan? expiration = null) { var item = new CacheItem { Value = value, ExpirationTime = DateTime.Now + (expiration ?? TimeSpan.FromMinutes(30)) }; _cache[key] = item; } public async Task RemoveAsync(string key) { return _cache.TryRemove(key, out _); } public async Task ExistsAsync(string key) { if (_cache.TryGetValue(key, out var item)) { if (item.ExpirationTime > DateTime.Now) { return true; } _cache.TryRemove(key, out _); } return false; } public async Task ClearAsync() { _cache.Clear(); } public async Task GetOrCreateAsync(string key, Func> factory, TimeSpan? expiration = null) { var value = await GetAsync(key); if (value == null) { value = await factory(); await SetAsync(key, value, expiration); } return value; } public async Task> GetAllKeysAsync() { return _cache.Keys; } public async Task RefreshAsync(string key) { if (_cache.TryGetValue(key, out var item)) { item.ExpirationTime = DateTime.Now + TimeSpan.FromMinutes(30); return true; } return false; } private void CleanupExpiredItems() { var now = DateTime.Now; var expiredKeys = _cache .Where(kvp => kvp.Value.ExpirationTime <= now) .Select(kvp => kvp.Key) .ToList(); foreach (var key in expiredKeys) { _cache.TryRemove(key, out _); } } private class CacheItem { public object Value { get; set; } public DateTime ExpirationTime { get; set; } } } // 简化的JWT认证中间件 public class JwtAuthMiddleware : IWebSocketAuthMiddleware { private readonly IAuthService _authService; private readonly ConcurrentDictionary _connectionUsers = new(); public JwtAuthMiddleware(IAuthService authService) { _authService = authService; } public async Task AuthenticateAsync(string connectionId, string token) { try { var isValid = await _authService.ValidateTokenAsync(token); if (isValid) { var claims = await _authService.GetUserClaimsAsync(int.Parse(token)); _connectionUsers[connectionId] = claims.UserId.ToString(); } } catch (Exception ex) { // 认证失败 } } public async Task GetUserIdAsync(string connectionId) { _connectionUsers.TryGetValue(connectionId, out var userId); return userId; } public async Task GetConnectionIdAsync(string userId) { foreach (var kvp in _connectionUsers) { if (kvp.Value == userId) { return kvp.Key; } } return null; } public async Task IsAuthenticatedAsync(string connectionId) { return _connectionUsers.ContainsKey(connectionId); } public async Task HasPermissionAsync(string connectionId, string permission) { var userId = await GetUserIdAsync(connectionId); if (string.IsNullOrEmpty(userId)) { return false; } // 这里应该检查用户权限 return true; // 简化实现 } } }