using System; using System.Collections.Generic; using System.Threading.Tasks; using Haoliang.Models.System; namespace Haoliang.Core.Services { public interface ISystemConfigService { Task GetConfigAsync(string configKey); Task> GetAllConfigsAsync(); Task SetConfigAsync(string configKey, string configValue); Task DeleteConfigAsync(string configKey); Task ConfigExistsAsync(string configKey); Task> GetConfigsByCategoryAsync(string category); Task ValidateConfigAsync(SystemConfig config); Task RefreshConfigCacheAsync(); Task GetConfigValueAsync(string configKey, T defaultValue = default); } public interface ILoggingService { Task LogAsync(LogLevel logLevel, string message, Exception exception = null, Dictionary properties = null); Task LogErrorAsync(string message, Exception exception = null, Dictionary properties = null); Task LogWarningAsync(string message, Dictionary properties = null); Task LogInfoAsync(string message, Dictionary properties = null); Task LogDebugAsync(string message, Dictionary properties = null); Task LogTraceAsync(string message, Dictionary properties = null); Task> GetLogsAsync(LogLevel? logLevel = null, DateTime? startDate = null, DateTime? endDate = null, string category = null); Task> GetErrorLogsAsync(DateTime? startDate = null, DateTime? endDate = null); Task GetLogCountAsync(LogLevel? logLevel = null, DateTime? startDate = null, DateTime? endDate = null); Task ArchiveLogsAsync(int daysToKeep = 30); Task ClearLogsAsync(); } public interface ISchedulerService { Task StartSchedulerAsync(); Task StopSchedulerAsync(); Task ScheduleTaskAsync(ScheduledTask task); Task RemoveTaskAsync(string taskId); Task> GetAllScheduledTasksAsync(); Task GetTaskByIdAsync(string taskId); Task ExecuteTaskAsync(string taskId); Task GetTaskExecutionResultAsync(string taskId); Task IsTaskRunningAsync(string taskId); Task ScheduleRecurringTaskAsync(string taskName, Action taskAction, TimeSpan interval); } public interface ICachingService { Task GetAsync(string key); Task SetAsync(string key, T value, TimeSpan? expiration = null); Task RemoveAsync(string key); Task ExistsAsync(string key); Task ClearAsync(); Task GetOrCreateAsync(string key, Func> factory, TimeSpan? expiration = null); Task> GetAllKeysAsync(); Task RefreshAsync(string key); } public class SystemConfigManager : ISystemConfigService { private readonly ISystemConfigRepository _configRepository; private readonly ICachingService _cachingService; public SystemConfigManager( ISystemConfigRepository configRepository, ICachingService cachingService) { _configRepository = configRepository; _cachingService = cachingService; } public async Task GetConfigAsync(string configKey) { // 先从缓存获取 var cachedConfig = await _cachingService.GetAsync($"config_{configKey}"); if (cachedConfig != null) { return cachedConfig; } // 缓存未命中,从数据库获取 var config = await _configRepository.GetByKeyAsync(configKey); if (config != null) { // 存入缓存 await _cachingService.SetAsync($"config_{configKey}", config, TimeSpan.FromMinutes(30)); } return config; } public async Task> GetAllConfigsAsync() { var configs = await _configRepository.GetAllAsync(); var configDict = new Dictionary(); foreach (var config in configs) { configDict[config.ConfigKey] = config.ConfigValue; } return configDict; } public async Task SetConfigAsync(string configKey, string configValue) { // 验证配置 var config = new SystemConfig { ConfigKey = configKey, ConfigValue = configValue, Category = "General", LastUpdated = DateTime.Now }; var validationErrors = await ValidateConfigAsync(config); if (validationErrors.Count > 0) { throw new InvalidOperationException($"Config validation failed: {string.Join(", ", validationErrors)}"); } // 检查配置是否已存在 var existingConfig = await _configRepository.GetByKeyAsync(configKey); if (existingConfig != null) { config.ConfigId = existingConfig.ConfigId; config.CreateTime = existingConfig.CreateTime; } config.LastUpdated = DateTime.Now; var updatedConfig = await _configRepository.UpsertAsync(config); // 更新缓存 await _cachingService.SetAsync($"config_{configKey}", updatedConfig, TimeSpan.FromMinutes(30)); await _cachingService.RemoveAsync("all_configs"); return updatedConfig; } public async Task DeleteConfigAsync(string configKey) { var result = await _configRepository.DeleteByKeyAsync(configKey); if (result) { // 清除缓存 await _cachingService.RemoveAsync($"config_{configKey}"); await _cachingService.RemoveAsync("all_configs"); } return result; } public async Task ConfigExistsAsync(string configKey) { // 先检查缓存 var existsInCache = await _cachingService.ExistsAsync($"config_{configKey}"); if (existsInCache) { return true; } return await _configRepository.KeyExistsAsync(configKey); } public async Task> GetConfigsByCategoryAsync(string category) { return await _configRepository.GetByCategoryAsync(category); } public async Task ValidateConfigAsync(SystemConfig config) { var errors = new List(); // 验证配置键 if (string.IsNullOrWhiteSpace(config.ConfigKey)) { errors.Add("Config key cannot be empty"); } // 验证配置值 if (config.ConfigValue == null) { errors.Add("Config value cannot be null"); } // 根据不同的配置键进行特定验证 switch (config.ConfigKey) { case "Database.ConnectionString": if (!IsValidConnectionString(config.ConfigValue)) { errors.Add("Invalid database connection string"); } break; case "Logging.Level": if (!IsValidLogLevel(config.ConfigValue)) { errors.Add("Invalid log level"); } break; case "Collection.Interval": if (!IsValidInterval(config.ConfigValue)) { errors.Add("Invalid collection interval"); } break; case "Security.JwtSecret": if (string.IsNullOrWhiteSpace(config.ConfigValue) || config.ConfigValue.Length < 16) { errors.Add("JWT secret must be at least 16 characters long"); } break; } return errors.Count == 0; } public async Task RefreshConfigCacheAsync() { // 清除所有配置缓存 await _cachingService.RemoveAsync("all_configs"); // 重新加载常用配置 var commonKeys = new[] { "Database.ConnectionString", "Logging.Level", "Collection.Interval" }; foreach (var key in commonKeys) { await GetConfigAsync(key); } } public async Task GetConfigValueAsync(string configKey, T defaultValue = default) { var config = await GetConfigAsync(configKey); if (config == null) { return defaultValue; } try { return (T)Convert.ChangeType(config.ConfigValue, typeof(T)); } catch { return defaultValue; } } private bool IsValidConnectionString(string connectionString) { // 简单的连接字符串验证 return !string.IsNullOrWhiteSpace(connectionString) && (connectionString.Contains("Server=") || connectionString.Contains("Host=")); } private bool IsValidLogLevel(string logLevel) { var validLevels = new[] { "Trace", "Debug", "Information", "Warning", "Error", "Critical", "None" }; return Array.Exists(validLevels, level => level.Equals(logLevel, StringComparison.OrdinalIgnoreCase)); } private bool IsValidInterval(string interval) { if (int.TryParse(interval, out int seconds)) { return seconds >= 5 && seconds <= 3600; // 5秒到1小时 } return false; } } public class LoggingManager : ILoggingService { private readonly ILogRepository _logRepository; private readonly ICachingService _cachingService; public LoggingManager( ILogRepository logRepository, ICachingService cachingService) { _logRepository = logRepository; _cachingService = cachingService; } public async Task LogAsync(LogLevel logLevel, string message, Exception exception = null, Dictionary properties = null) { var logEntry = new LogEntry { LogLevel = logLevel, Message = message, ExceptionMessage = exception?.Message, StackTrace = exception?.StackTrace, Properties = properties, Timestamp = DateTime.Now, Category = "General" }; // 异步保存到数据库 await _logRepository.AddAsync(logEntry); // 控制台输出(开发环境) if (IsDevelopmentEnvironment()) { Console.WriteLine($"[{logLevel}] {message}"); if (exception != null) { Console.WriteLine(exception.ToString()); } } } public async Task LogErrorAsync(string message, Exception exception = null, Dictionary properties = null) { await LogAsync(LogLevel.Error, message, exception, properties); } public async Task LogWarningAsync(string message, Dictionary properties = null) { await LogAsync(LogLevel.Warning, message, null, properties); } public async Task LogInfoAsync(string message, Dictionary properties = null) { await LogAsync(LogLevel.Information, message, null, properties); } public async Task LogDebugAsync(string message, Dictionary properties = null) { await LogAsync(LogLevel.Debug, message, null, properties); } public async Task LogTraceAsync(string message, Dictionary properties = null) { await LogAsync(LogLevel.Trace, message, null, properties); } public async Task> GetLogsAsync(LogLevel? logLevel = null, DateTime? startDate = null, DateTime? endDate = null, string category = null) { return await _logRepository.GetLogsAsync(logLevel, startDate, endDate, category); } public async Task> GetErrorLogsAsync(DateTime? startDate = null, DateTime? endDate = null) { return await _logRepository.GetLogsAsync(LogLevel.Error, startDate, endDate, null); } public async Task GetLogCountAsync(LogLevel? logLevel = null, DateTime? startDate = null, DateTime? endDate = null) { return await _logRepository.GetLogCountAsync(logLevel, startDate, endDate); } public async Task ArchiveLogsAsync(int daysToKeep = 30) { var cutoffDate = DateTime.Now.AddDays(-daysToKeep); await _logRepository.ArchiveLogsAsync(cutoffDate); } public async Task ClearLogsAsync() { await _logRepository.ClearLogsAsync(); } private bool IsDevelopmentEnvironment() { // 简单判断是否为开发环境 return Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development"; } } }