using System.Collections.ObjectModel; using System.Text.Json; using BetterGenshinImpact.Model; using BetterGenshinImpact.ViewModel; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using Microsoft.Extensions.Logging; using System.IO; using System.Windows; using System.Linq; using System; using BetterGenshinImpact.ViewModel.Pages.Component; using BetterGenshinImpact.Service; using System.Threading.Tasks; using System.Collections.Specialized; using GongSolutions.Wpf.DragDrop; using BetterGenshinImpact.View.Windows; using BetterGenshinImpact.ViewModel.Windows; using Microsoft.Extensions.DependencyInjection; namespace BetterGenshinImpact.ViewModel.Pages; /// /// 任务列表页面ViewModel /// public partial class GearTaskListPageViewModel : ViewModel { private readonly ILogger _logger; private readonly GearTaskStorageService _storageService; /// /// 任务定义列表(左侧) /// [ObservableProperty] private ObservableCollection _taskDefinitions = new(); /// /// 当前选中的任务定义 /// [ObservableProperty] private GearTaskDefinitionViewModel? _selectedTaskDefinition; /// /// 当前任务树根节点(右侧) /// [ObservableProperty] private GearTaskViewModel _currentTaskTreeRoot = new(); /// /// 当前选中的任务节点 /// [ObservableProperty] private GearTaskViewModel? _selectedTaskNode; /// /// 可用的任务类型 /// public ObservableCollection AvailableTaskTypes { get; } = new() { "采集任务", "战斗任务", "传送任务", "交互任务", "等待任务", "脚本任务", "条件任务", "循环任务", "组合任务" }; public GearTaskListPageViewModel(ILogger logger, GearTaskStorageService storageService) { _logger = logger; _storageService = storageService; InitializeData(); // 监听集合变化,实现自动保存 TaskDefinitions.CollectionChanged += OnTaskDefinitionsChanged; // 监听当前任务树根节点的子集合变化,用于拖拽后自动保存 CurrentTaskTreeRoot.Children.CollectionChanged += OnCurrentTaskTreeChanged; } /// /// 任务定义集合变化时的处理 /// private async void OnTaskDefinitionsChanged(object? sender, NotifyCollectionChangedEventArgs e) { // 当集合发生变化时,可以在这里处理自动保存等逻辑 // 例如:保存到配置文件等 } /// /// 当前任务树集合变化时的处理(用于拖拽后自动保存) /// private async void OnCurrentTaskTreeChanged(object? sender, NotifyCollectionChangedEventArgs e) { if (SelectedTaskDefinition != null) { try { SelectedTaskDefinition.ModifiedTime = DateTime.Now; await _storageService.SaveTaskDefinitionAsync(SelectedTaskDefinition); _logger.LogInformation("任务树根级别结构变化,已自动保存任务定义 '{TaskName}'", SelectedTaskDefinition.Name); } catch (Exception ex) { _logger.LogError(ex, "自动保存任务定义 {TaskName} 时发生错误", SelectedTaskDefinition.Name); } } } /// /// 初始化数据 /// private async void InitializeData() { try { // 从 JSON 文件加载任务定义 var loadedTasks = await _storageService.LoadAllTaskDefinitionsAsync(); // 按order字段排序 var sortedTasks = loadedTasks.OrderBy(t => t.Order).ToList(); foreach (var task in sortedTasks) { TaskDefinitions.Add(task); // 为每个任务定义设置属性变化监听 SetupTaskDefinitionPropertyChanged(task); } // 如果没有加载到任何任务,创建一个示例任务 if (TaskDefinitions.Count == 0) { await CreateSampleTaskAsync(); } } catch (Exception ex) { _logger.LogError(ex, "初始化任务数据时发生错误"); // 发生错误时创建示例任务 await CreateSampleTaskAsync(); } } /// /// 创建示例任务 /// private async Task CreateSampleTaskAsync() { var sampleTask = new GearTaskDefinitionViewModel("示例任务组", "这是一个示例任务组"); if (sampleTask.RootTask != null) { sampleTask.RootTask.AddChild(new GearTaskViewModel("采集任务1") { TaskType = "采集任务", Description = "采集莲花" }); sampleTask.RootTask.AddChild(new GearTaskViewModel("战斗任务1") { TaskType = "战斗任务", Description = "击败史莱姆" }); var subGroup = new GearTaskViewModel("子任务组", true); subGroup.AddChild(new GearTaskViewModel("传送任务1") { TaskType = "传送任务", Description = "传送到蒙德" }); subGroup.AddChild(new GearTaskViewModel("交互任务1") { TaskType = "交互任务", Description = "与NPC对话" }); sampleTask.RootTask.AddChild(subGroup); } TaskDefinitions.Add(sampleTask); SetupTaskDefinitionPropertyChanged(sampleTask); // 保存示例任务到文件 await _storageService.SaveTaskDefinitionAsync(sampleTask); } /// /// 选中任务定义时的处理 /// partial void OnSelectedTaskDefinitionChanged(GearTaskDefinitionViewModel? value) { // 清除之前选中项的状态 foreach (var task in TaskDefinitions) { task.IsSelected = false; } // 设置当前选中项 if (value != null) { value.IsSelected = true; } // 先解除之前的事件绑定 CurrentTaskTreeRoot.Children.CollectionChanged -= OnCurrentTaskTreeChanged; // 设置当前任务树根节点 if (value?.RootTask != null) { CurrentTaskTreeRoot = value.RootTask; } else { CurrentTaskTreeRoot = new GearTaskViewModel(); } // 重新绑定事件 CurrentTaskTreeRoot.Children.CollectionChanged += OnCurrentTaskTreeChanged; } /// /// 选择任务定义命令 /// [RelayCommand] private void SelectTaskDefinition(GearTaskDefinitionViewModel? taskDefinition) { SelectedTaskDefinition = taskDefinition; } /// /// 添加新的任务定义 /// [RelayCommand] private async Task AddTaskDefinition() { var editViewModel = App.GetService(); if (editViewModel == null) return; editViewModel.Name = $"新任务组{TaskDefinitions.Count + 1}"; editViewModel.Description = ""; var editWindow = App.GetService(); if (editWindow == null) return; editWindow.ViewModel.Name = editViewModel.Name; editWindow.ViewModel.Description = editViewModel.Description; editWindow.Owner = Application.Current.MainWindow; if (editWindow.ShowDialog() == true) { var newTask = new GearTaskDefinitionViewModel(editWindow.ViewModel.Name, editWindow.ViewModel.Description); // 设置新任务的order为当前最大值+1 newTask.Order = TaskDefinitions.Count > 0 ? TaskDefinitions.Max(t => t.Order) + 1 : 0; TaskDefinitions.Add(newTask); SetupTaskDefinitionPropertyChanged(newTask); SelectedTaskDefinition = newTask; // 自动保存到文件 await _storageService.SaveTaskDefinitionAsync(newTask); } } /// /// 删除任务定义 /// [RelayCommand] private async Task DeleteTaskDefinition(GearTaskDefinitionViewModel? taskDefinition) { if (taskDefinition == null) return; var result = MessageBox.Show($"确定要删除任务定义 '{taskDefinition.Name}' 吗?", "确认删除", MessageBoxButton.YesNo, MessageBoxImage.Question); if (result == MessageBoxResult.Yes) { var taskName = taskDefinition.Name; TaskDefinitions.Remove(taskDefinition); if (SelectedTaskDefinition == taskDefinition) { SelectedTaskDefinition = TaskDefinitions.FirstOrDefault(); } // 删除对应的 JSON 文件 await _storageService.DeleteTaskDefinitionAsync(taskName); } } /// /// 编辑选中的任务定义 /// [RelayCommand] private async Task EditSelectedTaskDefinition() { if (SelectedTaskDefinition == null) return; var editViewModel = App.GetService(); if (editViewModel == null) return; editViewModel.Name = SelectedTaskDefinition.Name; editViewModel.Description = SelectedTaskDefinition.Description; var editWindow = App.GetService(); if (editWindow == null) return; editWindow.ViewModel.Name = editViewModel.Name; editWindow.ViewModel.Description = editViewModel.Description; editWindow.Owner = Application.Current.MainWindow; if (editWindow.ShowDialog() == true) { SelectedTaskDefinition.Name = editWindow.ViewModel.Name; SelectedTaskDefinition.Description = editWindow.ViewModel.Description; SelectedTaskDefinition.ModifiedTime = DateTime.Now; // 自动保存到文件 await _storageService.SaveTaskDefinitionAsync(SelectedTaskDefinition); _logger.LogInformation("编辑了任务定义: {Name}", SelectedTaskDefinition.Name); } } /// /// 删除选中的任务定义 /// [RelayCommand] private async Task DeleteSelectedTaskDefinition() { if (SelectedTaskDefinition == null) return; await DeleteTaskDefinition(SelectedTaskDefinition); } /// /// 重命名任务定义 /// [RelayCommand] private async Task RenameTaskDefinition(GearTaskDefinitionViewModel? taskDefinition) { if (taskDefinition == null) return; // 这里可以弹出重命名对话框,暂时简单处理 var newName = "新名称"; // 简化处理,实际应该弹出输入框 if (!string.IsNullOrWhiteSpace(newName) && newName != taskDefinition.Name) { var oldName = taskDefinition.Name; taskDefinition.Name = newName; taskDefinition.ModifiedTime = DateTime.Now; if (taskDefinition.RootTask != null) { taskDefinition.RootTask.Name = newName; } // 重命名对应的 JSON 文件 await _storageService.RenameTaskDefinitionAsync(oldName, newName); } } /// /// 添加任务节点 /// [RelayCommand] private async Task AddTaskNode(string? taskType = null) { if (SelectedTaskDefinition?.RootTask == null) return; var newTask = new GearTaskViewModel($"新任务 {DateTime.Now:HHmmss}") { TaskType = taskType ?? AvailableTaskTypes.First(), Description = "新创建的任务" }; // 如果有选中的节点,则在选中节点下新增 // 如果未选择节点,则在根节点下直接新增 var targetParent = SelectedTaskNode ?? SelectedTaskDefinition.RootTask; targetParent.AddChild(newTask); // 展开父节点 targetParent.IsExpanded = true; SelectedTaskDefinition.ModifiedTime = DateTime.Now; // 自动保存到文件 await _storageService.SaveTaskDefinitionAsync(SelectedTaskDefinition); } /// /// 添加任务组 /// [RelayCommand] private async Task AddTaskGroup() { if (SelectedTaskDefinition?.RootTask == null) return; var newGroup = new GearTaskViewModel($"新任务组 {DateTime.Now:HHmmss}", true) { Description = "新创建的任务组" }; // 如果有选中的节点,则在选中节点下新增 // 如果未选择节点,则在根节点下直接新增 var targetParent = SelectedTaskNode ?? SelectedTaskDefinition.RootTask; targetParent.AddChild(newGroup); // 展开父节点 targetParent.IsExpanded = true; SelectedTaskDefinition.ModifiedTime = DateTime.Now; // 自动保存到文件 await _storageService.SaveTaskDefinitionAsync(SelectedTaskDefinition); } /// /// 删除任务节点 /// [RelayCommand] private async Task DeleteTaskNode(GearTaskViewModel? taskNode) { if (taskNode == null || SelectedTaskDefinition?.RootTask == null) return; var result = MessageBox.Show($"确定要删除任务 '{taskNode.Name}' 吗?", "确认删除", MessageBoxButton.YesNo, MessageBoxImage.Question); if (result == MessageBoxResult.Yes) { RemoveTaskFromTree(SelectedTaskDefinition.RootTask, taskNode); SelectedTaskDefinition.ModifiedTime = DateTime.Now; // 自动保存到文件 await _storageService.SaveTaskDefinitionAsync(SelectedTaskDefinition); } } /// /// 从树中移除任务节点 /// private bool RemoveTaskFromTree(GearTaskViewModel parent, GearTaskViewModel target) { if (parent.Children.Contains(target)) { parent.RemoveChild(target); return true; } foreach (var child in parent.Children) { if (RemoveTaskFromTree(child, target)) { return true; } } return false; } /// /// 从JSON文件重新加载所有任务定义(内部使用) /// private async Task LoadFromJsonInternal() { try { TaskDefinitions.Clear(); var loadedTasks = await _storageService.LoadAllTaskDefinitionsAsync(); foreach (var task in loadedTasks) { TaskDefinitions.Add(task); SetupTaskDefinitionPropertyChanged(task); } _logger.LogInformation("从JSON文件重新加载了 {Count} 个任务定义", loadedTasks.Count); } catch (Exception ex) { _logger.LogError(ex, "从JSON文件加载任务定义时发生错误"); } } /// /// 为任务定义设置属性变化监听器,实现自动保存 /// private void SetupTaskDefinitionPropertyChanged(GearTaskDefinitionViewModel taskDefinition) { taskDefinition.PropertyChanged += async (sender, e) => { if (sender is GearTaskDefinitionViewModel task) { try { await _storageService.SaveTaskDefinitionAsync(task); } catch (Exception ex) { _logger.LogError(ex, "自动保存任务定义 {TaskName} 时发生错误", task.Name); } } }; // 为根任务及其所有子任务设置监听器 if (taskDefinition.RootTask != null) { SetupTaskPropertyChangeListener(taskDefinition.RootTask, taskDefinition); } } /// /// 递归为任务及其子任务设置属性变化监听器 /// private void SetupTaskPropertyChangeListener(GearTaskViewModel task, GearTaskDefinitionViewModel parentDefinition) { task.PropertyChanged += async (sender, e) => { try { parentDefinition.ModifiedTime = DateTime.Now; await _storageService.SaveTaskDefinitionAsync(parentDefinition); } catch (Exception ex) { _logger.LogError(ex, "自动保存任务定义 {TaskName} 时发生错误", parentDefinition.Name); } }; // 为子任务设置监听器 foreach (var child in task.Children) { SetupTaskPropertyChangeListener(child, parentDefinition); } // 监听子任务集合变化 task.Children.CollectionChanged += async (sender, e) => { if (e.NewItems != null) { foreach (GearTaskViewModel newTask in e.NewItems) { SetupTaskPropertyChangeListener(newTask, parentDefinition); } } // 任何集合变化都触发保存(包括拖拽重排序) try { parentDefinition.ModifiedTime = DateTime.Now; await _storageService.SaveTaskDefinitionAsync(parentDefinition); _logger.LogInformation("任务树结构变化,已自动保存任务定义 '{TaskName}'", parentDefinition.Name); } catch (Exception ex) { _logger.LogError(ex, "自动保存任务定义 {TaskName} 时发生错误", parentDefinition.Name); } }; } /// /// 刷新当前任务树显示 /// }