using BetterGenshinImpact.Model.Gear; using BetterGenshinImpact.ViewModel.Pages.Component; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; using BetterGenshinImpact.Core.Config; namespace BetterGenshinImpact.Service; /// /// 齿轮任务存储服务,负责任务定义的 JSON 持久化 /// public class GearTaskStorageService { private readonly ILogger _logger; private readonly string _taskStoragePath; private readonly JsonSerializerSettings _jsonSettings; public GearTaskStorageService(ILogger logger) { _logger = logger; _taskStoragePath = Path.Combine(Global.Absolute("User"), "task_v2", "list"); // 确保目录存在 Directory.CreateDirectory(_taskStoragePath); // 配置 JSON 序列化设置 _jsonSettings = new JsonSerializerSettings { Formatting = Formatting.Indented, DateFormatString = "yyyy-MM-dd HH:mm:ss", NullValueHandling = NullValueHandling.Ignore }; } /// /// 保存任务定义到 JSON 文件 /// /// 任务定义 /// public async Task SaveTaskDefinitionAsync(GearTaskDefinitionViewModel taskDefinition) { try { var data = ConvertToData(taskDefinition); var fileName = GetSafeFileName(taskDefinition.Name) + ".json"; var filePath = Path.Combine(_taskStoragePath, fileName); var json = JsonConvert.SerializeObject(data, _jsonSettings); await File.WriteAllTextAsync(filePath, json); _logger.LogInformation("任务定义 '{TaskName}' 已保存到 {FilePath}", taskDefinition.Name, filePath); } catch (Exception ex) { _logger.LogError(ex, "保存任务定义 '{TaskName}' 时发生错误", taskDefinition.Name); throw; } } /// /// 从 JSON 文件加载任务定义 /// /// 文件名(不含扩展名) /// public async Task LoadTaskDefinitionAsync(string fileName) { try { var filePath = Path.Combine(_taskStoragePath, fileName + ".json"); if (!File.Exists(filePath)) { _logger.LogWarning("任务定义文件不存在: {FilePath}", filePath); return null; } var json = await File.ReadAllTextAsync(filePath); var data = JsonConvert.DeserializeObject(json, _jsonSettings); if (data == null) { _logger.LogWarning("无法反序列化任务定义文件: {FilePath}", filePath); return null; } var viewModel = ConvertToViewModel(data); _logger.LogInformation("任务定义 '{TaskName}' 已从 {FilePath} 加载", data.Name, filePath); return viewModel; } catch (Exception ex) { _logger.LogError(ex, "加载任务定义文件 '{FileName}' 时发生错误", fileName); throw; } } /// /// 加载所有任务定义 /// /// public async Task> LoadAllTaskDefinitionsAsync() { var taskDefinitions = new List(); try { var jsonFiles = Directory.GetFiles(_taskStoragePath, "*.json"); foreach (var filePath in jsonFiles) { try { var json = await File.ReadAllTextAsync(filePath); var data = JsonConvert.DeserializeObject(json, _jsonSettings); if (data != null) { var viewModel = ConvertToViewModel(data); taskDefinitions.Add(viewModel); } } catch (Exception ex) { _logger.LogError(ex, "加载任务定义文件 '{FilePath}' 时发生错误", filePath); } } _logger.LogInformation("已加载 {Count} 个任务定义", taskDefinitions.Count); } catch (Exception ex) { _logger.LogError(ex, "加载任务定义列表时发生错误"); } return taskDefinitions; } /// /// 删除任务定义文件 /// /// 任务名称 /// public async Task DeleteTaskDefinitionAsync(string taskName) { try { var fileName = GetSafeFileName(taskName) + ".json"; var filePath = Path.Combine(_taskStoragePath, fileName); if (File.Exists(filePath)) { await Task.Run(() => File.Delete(filePath)); _logger.LogInformation("任务定义文件已删除: {FilePath}", filePath); } else { _logger.LogWarning("要删除的任务定义文件不存在: {FilePath}", filePath); } } catch (Exception ex) { _logger.LogError(ex, "删除任务定义 '{TaskName}' 时发生错误", taskName); throw; } } /// /// 将 ViewModel 转换为数据模型 /// /// 视图模型 /// private GearTaskDefinitionData ConvertToData(GearTaskDefinitionViewModel viewModel) { return new GearTaskDefinitionData { Name = viewModel.Name, Description = viewModel.Description, CreatedTime = viewModel.CreatedTime, ModifiedTime = viewModel.ModifiedTime, Order = viewModel.Order, RootTask = viewModel.RootTask != null ? ConvertTaskToData(viewModel.RootTask) : null }; } /// /// 将任务 ViewModel 转换为数据模型 /// /// 任务视图模型 /// private GearTaskData ConvertTaskToData(GearTaskViewModel viewModel) { var children = viewModel.Children.Select(ConvertTaskToData).ToList(); return new GearTaskData { Name = viewModel.Name, Path = viewModel.Path, TaskType = viewModel.TaskType, IsEnabled = viewModel.IsEnabled, // 当 Children 存在值的情况下,IsDirectory 必定为 true IsDirectory = children.Count > 0 || viewModel.IsDirectory, IsExpanded = viewModel.IsExpanded, Parameters = viewModel.Parameters, CreatedTime = viewModel.CreatedTime, ModifiedTime = viewModel.ModifiedTime, Priority = viewModel.Priority, Children = children }; } /// /// 将数据模型转换为 ViewModel /// /// 数据模型 /// private GearTaskDefinitionViewModel ConvertToViewModel(GearTaskDefinitionData data) { var viewModel = new GearTaskDefinitionViewModel { Name = data.Name, Description = data.Description, CreatedTime = data.CreatedTime, ModifiedTime = data.ModifiedTime, Order = data.Order, RootTask = data.RootTask != null ? ConvertTaskToViewModel(data.RootTask) : null }; return viewModel; } /// /// 将任务数据模型转换为 ViewModel /// /// 任务数据模型 /// private GearTaskViewModel ConvertTaskToViewModel(GearTaskData data) { var viewModel = new GearTaskViewModel { Name = data.Name, Path = data.Path, TaskType = data.TaskType, IsEnabled = data.IsEnabled, IsDirectory = data.IsDirectory, IsExpanded = data.IsExpanded, Parameters = data.Parameters, CreatedTime = data.CreatedTime, ModifiedTime = data.ModifiedTime, Priority = data.Priority, }; // 递归转换子任务 foreach (var childData in data.Children) { viewModel.Children.Add(ConvertTaskToViewModel(childData)); } return viewModel; } /// /// 获取安全的文件名(移除非法字符) /// /// 原始名称 /// private string GetSafeFileName(string name) { var invalidChars = Path.GetInvalidFileNameChars(); var safeName = string.Join("_", name.Split(invalidChars, StringSplitOptions.RemoveEmptyEntries)); return string.IsNullOrWhiteSpace(safeName) ? "unnamed_task" : safeName; } }