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;
}
}
///
/// 重命名任务定义文件
///
/// 旧名称
/// 新名称
///
public async Task RenameTaskDefinitionAsync(string oldName, string newName)
{
try
{
var oldFileName = GetSafeFileName(oldName) + ".json";
var newFileName = GetSafeFileName(newName) + ".json";
var oldFilePath = Path.Combine(_taskStoragePath, oldFileName);
var newFilePath = Path.Combine(_taskStoragePath, newFileName);
if (File.Exists(oldFilePath))
{
await Task.Run(() => File.Move(oldFilePath, newFilePath));
_logger.LogInformation("任务定义文件已重命名: {OldPath} -> {NewPath}", oldFilePath, newFilePath);
}
else
{
_logger.LogWarning("要重命名的任务定义文件不存在: {FilePath}", oldFilePath);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "重命名任务定义 '{OldName}' -> '{NewName}' 时发生错误", oldName, newName);
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,
Description = viewModel.Description,
TaskType = viewModel.TaskType,
IsEnabled = viewModel.IsEnabled,
// 当 Children 存在值的情况下,IsDirectory 必定为 true
IsDirectory = children.Count > 0 || viewModel.IsDirectory,
Parameters = viewModel.Parameters,
CreatedTime = viewModel.CreatedTime,
ModifiedTime = viewModel.ModifiedTime,
Priority = viewModel.Priority,
Tags = viewModel.Tags,
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,
Description = data.Description,
TaskType = data.TaskType,
IsEnabled = data.IsEnabled,
IsDirectory = data.IsDirectory,
Parameters = data.Parameters,
CreatedTime = data.CreatedTime,
ModifiedTime = data.ModifiedTime,
Priority = data.Priority,
Tags = data.Tags
};
// 递归转换子任务
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;
}
}