mirror of
https://github.com/babalae/better-genshin-impact.git
synced 2026-05-21 09:45:48 +08:00
任务列表初始化
This commit is contained in:
@@ -110,6 +110,7 @@ public partial class App : Application
|
||||
// services.AddView<PathingConfigView, PathingConfigViewModel>();
|
||||
services.AddView<KeyBindingsSettingsPage, KeyBindingsSettingsPageViewModel>();
|
||||
services.AddView<SchedulerPage, SchedulerViewModel>();
|
||||
services.AddView<GearTaskListPage, GearTaskListPageViewModel>();
|
||||
|
||||
|
||||
// 一条龙 ViewModels
|
||||
|
||||
@@ -16,7 +16,7 @@ public class GearTaskRefence
|
||||
public bool Enabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// GearTask 的文件路径
|
||||
/// GearTaskViewModel 的文件路径
|
||||
/// </summary>
|
||||
public string GearTaskFilePath { get; set; } = string.Empty;
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
|
||||
xmlns:viewModel="clr-namespace:BetterGenshinImpact.ViewModel"
|
||||
Title="更好的原神"
|
||||
Width="900"
|
||||
Height="600"
|
||||
Width="1050"
|
||||
Height="700"
|
||||
d:Background="#D2D2D2"
|
||||
d:DataContext="{d:DesignInstance Type=viewModel:MainWindowViewModel}"
|
||||
ui:Design.Background="{DynamicResource ApplicationBackgroundBrush}"
|
||||
@@ -79,6 +79,7 @@
|
||||
</ui:NavigationViewItem.Icon>
|
||||
</ui:NavigationViewItem>
|
||||
|
||||
|
||||
<!--<ui:NavigationViewItemSeparator />-->
|
||||
|
||||
<ui:NavigationViewItem Content="一条龙"
|
||||
@@ -94,7 +95,13 @@
|
||||
<ui:SymbolIcon Symbol="Bot24" />
|
||||
</ui:NavigationViewItem.Icon>
|
||||
<ui:NavigationViewItem.MenuItems>
|
||||
|
||||
<ui:NavigationViewItem Content="任务列表"
|
||||
NavigationCacheMode="Enabled"
|
||||
TargetPageType="{x:Type pages:GearTaskListPage}">
|
||||
<ui:NavigationViewItem.Icon>
|
||||
<ui:SymbolIcon Symbol="TaskListLtr24" />
|
||||
</ui:NavigationViewItem.Icon>
|
||||
</ui:NavigationViewItem>
|
||||
<!--<ui:NavigationViewItemSeparator />-->
|
||||
<!-- ConvertRange20 -->
|
||||
<ui:NavigationViewItem Content="调度器"
|
||||
|
||||
290
BetterGenshinImpact/View/Pages/GearTaskListPage.xaml
Normal file
290
BetterGenshinImpact/View/Pages/GearTaskListPage.xaml
Normal file
@@ -0,0 +1,290 @@
|
||||
<UserControl x:Class="BetterGenshinImpact.View.Pages.GearTaskListPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:pages="clr-namespace:BetterGenshinImpact.ViewModel.Pages"
|
||||
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
|
||||
xmlns:component="clr-namespace:BetterGenshinImpact.ViewModel.Pages.Component"
|
||||
d:DataContext="{d:DesignInstance Type=pages:GearTaskListPageViewModel}"
|
||||
d:DesignHeight="850"
|
||||
d:DesignWidth="1200"
|
||||
ui:Design.Background="{DynamicResource ApplicationBackgroundBrush}"
|
||||
ui:Design.Foreground="{DynamicResource TextFillColorPrimaryBrush}"
|
||||
FontFamily="{StaticResource TextThemeFontFamily}"
|
||||
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<UserControl.Resources>
|
||||
<!-- 任务定义项模板 -->
|
||||
<DataTemplate x:Key="TaskDefinitionItemTemplate" DataType="{x:Type component:GearTaskDefinitionViewModel}">
|
||||
<Border Background="{DynamicResource CardBackground}"
|
||||
BorderBrush="{DynamicResource CardBorderBrush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="4"
|
||||
Margin="2"
|
||||
Padding="8">
|
||||
<Border.Style>
|
||||
<Style TargetType="Border">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsSelected}" Value="True">
|
||||
<Setter Property="Background" Value="{DynamicResource AccentFillColorDefaultBrush}" />
|
||||
<Setter Property="BorderBrush" Value="{DynamicResource AccentFillColorDefaultBrush}" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Style>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<ui:TextBlock Grid.Row="0"
|
||||
FontWeight="SemiBold"
|
||||
Text="{Binding Name}"
|
||||
TextTrimming="CharacterEllipsis" />
|
||||
|
||||
<ui:TextBlock Grid.Row="1"
|
||||
Margin="0,4,0,0"
|
||||
FontSize="12"
|
||||
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
|
||||
Text="{Binding Description}"
|
||||
TextTrimming="CharacterEllipsis"
|
||||
TextWrapping="Wrap"
|
||||
MaxHeight="40" />
|
||||
|
||||
<StackPanel Grid.Row="2"
|
||||
Margin="0,4,0,0"
|
||||
Orientation="Horizontal">
|
||||
<ui:TextBlock FontSize="10"
|
||||
Foreground="{DynamicResource TextFillColorTertiaryBrush}"
|
||||
Text="{Binding ModifiedTime, StringFormat='修改: {0:MM-dd HH:mm}'}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- 右键菜单 -->
|
||||
<ContextMenu x:Key="TaskNodeContextMenu">
|
||||
<MenuItem Header="添加采集任务" Command="{Binding DataContext.AddTaskNodeCommand, RelativeSource={RelativeSource AncestorType=UserControl}}" CommandParameter="采集任务">
|
||||
<MenuItem.Icon>
|
||||
<ui:SymbolIcon Symbol="Add24" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem Header="添加战斗任务" Command="{Binding DataContext.AddTaskNodeCommand, RelativeSource={RelativeSource AncestorType=UserControl}}" CommandParameter="战斗任务">
|
||||
<MenuItem.Icon>
|
||||
<ui:SymbolIcon Symbol="Add24" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem Header="添加传送任务" Command="{Binding DataContext.AddTaskNodeCommand, RelativeSource={RelativeSource AncestorType=UserControl}}" CommandParameter="传送任务">
|
||||
<MenuItem.Icon>
|
||||
<ui:SymbolIcon Symbol="Add24" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem Header="添加交互任务" Command="{Binding DataContext.AddTaskNodeCommand, RelativeSource={RelativeSource AncestorType=UserControl}}" CommandParameter="交互任务">
|
||||
<MenuItem.Icon>
|
||||
<ui:SymbolIcon Symbol="Add24" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<Separator />
|
||||
<MenuItem Header="添加任务组" Command="{Binding DataContext.AddTaskGroupCommand, RelativeSource={RelativeSource AncestorType=UserControl}}">
|
||||
<MenuItem.Icon>
|
||||
<ui:SymbolIcon Symbol="Folder24" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<Separator />
|
||||
<MenuItem Header="删除" Command="{Binding DataContext.DeleteTaskNodeCommand, RelativeSource={RelativeSource AncestorType=UserControl}}" CommandParameter="{Binding}">
|
||||
<MenuItem.Icon>
|
||||
<ui:SymbolIcon Symbol="Delete24" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
</ContextMenu>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid Margin="16">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="300" />
|
||||
<ColumnDefinition Width="8" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- 左侧:任务定义列表 -->
|
||||
<Grid Grid.Column="0">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<ui:TextBlock Grid.Row="0"
|
||||
Margin="0,0,0,8"
|
||||
FontSize="16"
|
||||
FontWeight="SemiBold"
|
||||
Text="任务定义列表" />
|
||||
|
||||
<!-- 左侧工具栏 -->
|
||||
<StackPanel Grid.Row="1"
|
||||
Margin="0,0,0,8"
|
||||
Orientation="Horizontal">
|
||||
<ui:Button Command="{Binding AddTaskDefinitionCommand}"
|
||||
Content="新建"
|
||||
Icon="{ui:SymbolIcon Add24}"
|
||||
Margin="0,0,4,0" />
|
||||
<ui:Button Command="{Binding SaveToJsonCommand}"
|
||||
Content="保存"
|
||||
Icon="{ui:SymbolIcon Save24}"
|
||||
Margin="0,0,4,0" />
|
||||
<ui:Button Command="{Binding LoadFromJsonCommand}"
|
||||
Content="加载"
|
||||
Icon="{ui:SymbolIcon Open24}" />
|
||||
</StackPanel>
|
||||
|
||||
<!-- 任务定义列表 -->
|
||||
<ui:Border Grid.Row="2"
|
||||
Background="{DynamicResource CardBackground}"
|
||||
BorderBrush="{DynamicResource CardBorderBrush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="{DynamicResource ControlCornerRadius}">
|
||||
<ListBox ItemsSource="{Binding TaskDefinitions}"
|
||||
SelectedItem="{Binding SelectedTaskDefinition}"
|
||||
ItemTemplate="{StaticResource TaskDefinitionItemTemplate}"
|
||||
Background="Transparent"
|
||||
BorderThickness="0"
|
||||
Padding="4">
|
||||
<ListBox.ItemContainerStyle>
|
||||
<Style TargetType="ListBoxItem">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||
<Setter Property="Padding" Value="0" />
|
||||
<Setter Property="Margin" Value="0" />
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="BorderThickness" Value="0" />
|
||||
<EventSetter Event="MouseDoubleClick" Handler="TaskDefinitionItem_MouseDoubleClick" />
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsSelected" Value="True">
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</ListBox.ItemContainerStyle>
|
||||
<b:Interaction.Triggers>
|
||||
<b:EventTrigger EventName="SelectionChanged">
|
||||
<b:InvokeCommandAction Command="{Binding SelectTaskDefinitionCommand}" CommandParameter="{Binding SelectedItem, RelativeSource={RelativeSource AncestorType=ListBox}}" />
|
||||
</b:EventTrigger>
|
||||
</b:Interaction.Triggers>
|
||||
</ListBox>
|
||||
</ui:Border>
|
||||
</Grid>
|
||||
|
||||
<!-- 分隔线 -->
|
||||
<GridSplitter Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
Background="{DynamicResource CardBorderBrush}" />
|
||||
|
||||
<!-- 右侧:任务详情 -->
|
||||
<Grid Grid.Column="2">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<ui:TextBlock Grid.Row="0"
|
||||
Margin="0,0,0,8"
|
||||
FontSize="16"
|
||||
FontWeight="SemiBold"
|
||||
Text="{Binding SelectedTaskDefinition.Name, StringFormat='任务详情 - {0}', FallbackValue='任务详情'}" />
|
||||
|
||||
<!-- 右侧工具栏 -->
|
||||
<StackPanel Grid.Row="1"
|
||||
Margin="0,0,0,8"
|
||||
Orientation="Horizontal">
|
||||
<ui:Button Command="{Binding AddTaskNodeCommand}"
|
||||
Content="添加任务"
|
||||
Icon="{ui:SymbolIcon Add24}"
|
||||
Margin="0,0,4,0" />
|
||||
<ui:Button Command="{Binding AddTaskGroupCommand}"
|
||||
Content="添加组"
|
||||
Icon="{ui:SymbolIcon Folder24}"
|
||||
Margin="0,0,4,0" />
|
||||
<ComboBox ItemsSource="{Binding AvailableTaskTypes}"
|
||||
SelectedIndex="0"
|
||||
Width="120"
|
||||
Margin="8,0,0,0" />
|
||||
</StackPanel>
|
||||
|
||||
<!-- 任务树 -->
|
||||
<ui:Border Grid.Row="2"
|
||||
Background="{DynamicResource CardBackground}"
|
||||
BorderBrush="{DynamicResource CardBorderBrush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="{DynamicResource ControlCornerRadius}">
|
||||
<Grid Margin="4">
|
||||
<ui:Grid ColumnDefinitions="*,120,80,100" Visibility="Hidden">
|
||||
<Grid x:Name="TreeColumnName" Grid.Column="0" />
|
||||
<Grid x:Name="TreeColumnType" Grid.Column="1" />
|
||||
<Grid x:Name="TreeColumnEnabled" Grid.Column="2" />
|
||||
<Grid x:Name="TreeColumnActions" Grid.Column="3" />
|
||||
</ui:Grid>
|
||||
|
||||
<ui:TreeListView BorderThickness="0"
|
||||
ItemsSource="{Binding CurrentTaskTree}"
|
||||
SelectedItem="{Binding SelectedTaskNode}">
|
||||
<ui:TreeListView.Columns>
|
||||
<GridViewColumnCollection>
|
||||
<ui:GridViewColumn Width="{Binding ActualWidth, ElementName=TreeColumnName}" Header="任务名称">
|
||||
<ui:GridViewColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<ui:TreeRowExpander Content="{Binding Name}">
|
||||
<ui:TreeRowExpander.ContextMenu>
|
||||
<StaticResource ResourceKey="TaskNodeContextMenu" />
|
||||
</ui:TreeRowExpander.ContextMenu>
|
||||
</ui:TreeRowExpander>
|
||||
</DataTemplate>
|
||||
</ui:GridViewColumn.CellTemplate>
|
||||
</ui:GridViewColumn>
|
||||
<ui:GridViewColumn Width="{Binding ActualWidth, ElementName=TreeColumnType}" Header="任务类型">
|
||||
<ui:GridViewColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<ui:TextBlock Text="{Binding TaskType}"
|
||||
VerticalAlignment="Center"
|
||||
Visibility="{Binding IsDirectory, Converter={StaticResource BooleanToVisibilityRevertConverter}}" />
|
||||
</DataTemplate>
|
||||
</ui:GridViewColumn.CellTemplate>
|
||||
</ui:GridViewColumn>
|
||||
<ui:GridViewColumn Width="{Binding ActualWidth, ElementName=TreeColumnEnabled}" Header="启用">
|
||||
<ui:GridViewColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<CheckBox IsChecked="{Binding IsEnabled}"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center" />
|
||||
</DataTemplate>
|
||||
</ui:GridViewColumn.CellTemplate>
|
||||
</ui:GridViewColumn>
|
||||
<ui:GridViewColumn Width="{Binding ActualWidth, ElementName=TreeColumnActions}" Header="操作">
|
||||
<ui:GridViewColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
|
||||
<ui:Button Command="{Binding DataContext.DeleteTaskNodeCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
CommandParameter="{Binding}"
|
||||
Icon="{ui:SymbolIcon Delete24}"
|
||||
Appearance="Transparent"
|
||||
Padding="4"
|
||||
ToolTip="删除" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ui:GridViewColumn.CellTemplate>
|
||||
</ui:GridViewColumn>
|
||||
</GridViewColumnCollection>
|
||||
</ui:TreeListView.Columns>
|
||||
<ui:TreeListView.ItemTemplate>
|
||||
<HierarchicalDataTemplate ItemsSource="{Binding Children}" />
|
||||
</ui:TreeListView.ItemTemplate>
|
||||
</ui:TreeListView>
|
||||
</Grid>
|
||||
</ui:Border>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
33
BetterGenshinImpact/View/Pages/GearTaskListPage.xaml.cs
Normal file
33
BetterGenshinImpact/View/Pages/GearTaskListPage.xaml.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using BetterGenshinImpact.ViewModel.Pages;
|
||||
using BetterGenshinImpact.ViewModel.Pages.Component;
|
||||
|
||||
namespace BetterGenshinImpact.View.Pages;
|
||||
|
||||
/// <summary>
|
||||
/// GearTaskListPage.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class GearTaskListPage : UserControl
|
||||
{
|
||||
private GearTaskListPageViewModel ViewModel { get; }
|
||||
|
||||
public GearTaskListPage(GearTaskListPageViewModel viewModel)
|
||||
{
|
||||
DataContext = ViewModel = viewModel;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 任务定义项双击事件
|
||||
/// </summary>
|
||||
private void TaskDefinitionItem_MouseDoubleClick(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (sender is ListBoxItem item && item.DataContext is GearTaskDefinitionViewModel taskDefinition)
|
||||
{
|
||||
// 双击重命名
|
||||
ViewModel.RenameTaskDefinitionCommand.Execute(taskDefinition);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace BetterGenshinImpact.ViewModel.Pages.Component;
|
||||
|
||||
/// <summary>
|
||||
/// 任务定义模型,用于左侧列表显示
|
||||
/// </summary>
|
||||
public partial class GearTaskDefinitionViewModel : ObservableObject
|
||||
{
|
||||
[ObservableProperty]
|
||||
private string _name = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _description = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isSelected = false;
|
||||
|
||||
[ObservableProperty]
|
||||
private DateTime _createdTime = DateTime.Now;
|
||||
|
||||
[ObservableProperty]
|
||||
private DateTime _modifiedTime = DateTime.Now;
|
||||
|
||||
/// <summary>
|
||||
/// 任务根节点
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private GearTaskViewModel? _rootTask;
|
||||
|
||||
public GearTaskDefinitionViewModel()
|
||||
{
|
||||
}
|
||||
|
||||
public GearTaskDefinitionViewModel(string name, string description = "")
|
||||
{
|
||||
Name = name;
|
||||
Description = description;
|
||||
RootTask = new GearTaskViewModel(name, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取任务总数(包括所有子任务)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public int GetTotalTaskCount()
|
||||
{
|
||||
if (RootTask == null) return 0;
|
||||
return 1 + Enumerable.Count<GearTaskViewModel>(RootTask.GetAllChildren());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取启用的任务数量
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public int GetEnabledTaskCount()
|
||||
{
|
||||
if (RootTask == null) return 0;
|
||||
var count = RootTask.IsEnabled ? 1 : 0;
|
||||
count += Enumerable.Count<GearTaskViewModel>(RootTask.GetAllChildren(), t => t.IsEnabled);
|
||||
return count;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace BetterGenshinImpact.ViewModel.Pages.Component;
|
||||
|
||||
/// <summary>
|
||||
/// 齿轮任务模型,支持无限树嵌套层级
|
||||
/// </summary>
|
||||
public partial class GearTaskViewModel : ObservableObject
|
||||
{
|
||||
[ObservableProperty]
|
||||
private string _name = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _description = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _taskType = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isEnabled = true;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isDirectory = false;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isExpanded = false;
|
||||
|
||||
[ObservableProperty]
|
||||
private ObservableCollection<GearTaskViewModel> _children = new();
|
||||
|
||||
/// <summary>
|
||||
/// 任务参数,存储为JSON字符串
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private string _parameters = "{}";
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public DateTime CreatedTime { get; set; } = DateTime.Now;
|
||||
|
||||
/// <summary>
|
||||
/// 修改时间
|
||||
/// </summary>
|
||||
public DateTime ModifiedTime { get; set; } = DateTime.Now;
|
||||
|
||||
/// <summary>
|
||||
/// 任务优先级
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private int _priority = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 任务标签
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private string _tags = string.Empty;
|
||||
|
||||
public GearTaskViewModel()
|
||||
{
|
||||
}
|
||||
|
||||
public GearTaskViewModel(string name, bool isDirectory = false)
|
||||
{
|
||||
Name = name;
|
||||
IsDirectory = isDirectory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加子任务
|
||||
/// </summary>
|
||||
/// <param name="child"></param>
|
||||
public void AddChild(GearTaskViewModel child)
|
||||
{
|
||||
Children.Add(child);
|
||||
IsDirectory = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 移除子任务
|
||||
/// </summary>
|
||||
/// <param name="child"></param>
|
||||
public void RemoveChild(GearTaskViewModel child)
|
||||
{
|
||||
Children.Remove(child);
|
||||
if (Children.Count == 0)
|
||||
{
|
||||
IsDirectory = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有子任务(递归)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<GearTaskViewModel> GetAllChildren()
|
||||
{
|
||||
foreach (var child in Children)
|
||||
{
|
||||
yield return child;
|
||||
foreach (var grandChild in child.GetAllChildren())
|
||||
{
|
||||
yield return grandChild;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 克隆任务
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public GearTaskViewModel Clone()
|
||||
{
|
||||
var clone = new GearTaskViewModel
|
||||
{
|
||||
Name = Name,
|
||||
Description = Description,
|
||||
TaskType = TaskType,
|
||||
IsEnabled = IsEnabled,
|
||||
IsDirectory = IsDirectory,
|
||||
Parameters = Parameters,
|
||||
Priority = Priority,
|
||||
Tags = Tags,
|
||||
CreatedTime = CreatedTime,
|
||||
ModifiedTime = DateTime.Now
|
||||
};
|
||||
|
||||
foreach (var child in Children)
|
||||
{
|
||||
clone.Children.Add(child.Clone());
|
||||
}
|
||||
|
||||
return clone;
|
||||
}
|
||||
}
|
||||
311
BetterGenshinImpact/ViewModel/Pages/GearTaskListPageViewModel.cs
Normal file
311
BetterGenshinImpact/ViewModel/Pages/GearTaskListPageViewModel.cs
Normal file
@@ -0,0 +1,311 @@
|
||||
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;
|
||||
|
||||
namespace BetterGenshinImpact.ViewModel.Pages;
|
||||
|
||||
/// <summary>
|
||||
/// 任务列表页面ViewModel
|
||||
/// </summary>
|
||||
public partial class GearTaskListPageViewModel : ViewModel
|
||||
{
|
||||
private readonly ILogger<GearTaskListPageViewModel> _logger;
|
||||
|
||||
/// <summary>
|
||||
/// 任务定义列表(左侧)
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private ObservableCollection<GearTaskDefinitionViewModel> _taskDefinitions = new();
|
||||
|
||||
/// <summary>
|
||||
/// 当前选中的任务定义
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private GearTaskDefinitionViewModel? _selectedTaskDefinition;
|
||||
|
||||
/// <summary>
|
||||
/// 当前任务树(右侧)
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private ObservableCollection<GearTaskViewModel> _currentTaskTree = new();
|
||||
|
||||
/// <summary>
|
||||
/// 当前选中的任务节点
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private GearTaskViewModel? _selectedTaskNode;
|
||||
|
||||
/// <summary>
|
||||
/// 可用的任务类型
|
||||
/// </summary>
|
||||
public ObservableCollection<string> AvailableTaskTypes { get; } = new()
|
||||
{
|
||||
"采集任务",
|
||||
"战斗任务",
|
||||
"传送任务",
|
||||
"交互任务",
|
||||
"等待任务",
|
||||
"脚本任务",
|
||||
"条件任务",
|
||||
"循环任务",
|
||||
"组合任务"
|
||||
};
|
||||
|
||||
public GearTaskListPageViewModel(ILogger<GearTaskListPageViewModel> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
InitializeData();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化数据
|
||||
/// </summary>
|
||||
private void InitializeData()
|
||||
{
|
||||
// 创建示例数据
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 选中任务定义时的处理
|
||||
/// </summary>
|
||||
partial void OnSelectedTaskDefinitionChanged(GearTaskDefinitionViewModel? value)
|
||||
{
|
||||
// 清除之前选中项的状态
|
||||
foreach (var task in TaskDefinitions)
|
||||
{
|
||||
task.IsSelected = false;
|
||||
}
|
||||
|
||||
// 设置当前选中项
|
||||
if (value != null)
|
||||
{
|
||||
value.IsSelected = true;
|
||||
}
|
||||
|
||||
CurrentTaskTree.Clear();
|
||||
if (value?.RootTask != null)
|
||||
{
|
||||
CurrentTaskTree.Add(value.RootTask);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 选择任务定义命令
|
||||
/// </summary>
|
||||
[RelayCommand]
|
||||
private void SelectTaskDefinition(GearTaskDefinitionViewModel? taskDefinition)
|
||||
{
|
||||
SelectedTaskDefinition = taskDefinition;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加新的任务定义
|
||||
/// </summary>
|
||||
[RelayCommand]
|
||||
private void AddTaskDefinition()
|
||||
{
|
||||
var newTask = new GearTaskDefinitionViewModel($"新任务组 {TaskDefinitions.Count + 1}", "新创建的任务组");
|
||||
TaskDefinitions.Add(newTask);
|
||||
SelectedTaskDefinition = newTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除任务定义
|
||||
/// </summary>
|
||||
[RelayCommand]
|
||||
private void DeleteTaskDefinition(GearTaskDefinitionViewModel? taskDefinition)
|
||||
{
|
||||
if (taskDefinition == null) return;
|
||||
|
||||
var result = MessageBox.Show($"确定要删除任务定义 '{taskDefinition.Name}' 吗?", "确认删除",
|
||||
MessageBoxButton.YesNo, MessageBoxImage.Question);
|
||||
|
||||
if (result == MessageBoxResult.Yes)
|
||||
{
|
||||
TaskDefinitions.Remove(taskDefinition);
|
||||
if (SelectedTaskDefinition == taskDefinition)
|
||||
{
|
||||
SelectedTaskDefinition = TaskDefinitions.FirstOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重命名任务定义
|
||||
/// </summary>
|
||||
[RelayCommand]
|
||||
private void RenameTaskDefinition(GearTaskDefinitionViewModel? taskDefinition)
|
||||
{
|
||||
if (taskDefinition == null) return;
|
||||
|
||||
// 这里可以弹出重命名对话框,暂时简单处理
|
||||
var newName = "新名称"; // 简化处理,实际应该弹出输入框
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(newName))
|
||||
{
|
||||
taskDefinition.Name = newName;
|
||||
taskDefinition.ModifiedTime = DateTime.Now;
|
||||
if (taskDefinition.RootTask != null)
|
||||
{
|
||||
taskDefinition.RootTask.Name = newName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加任务节点
|
||||
/// </summary>
|
||||
[RelayCommand]
|
||||
private void AddTaskNode(string? taskType = null)
|
||||
{
|
||||
if (SelectedTaskDefinition?.RootTask == null) return;
|
||||
|
||||
var newTask = new GearTaskViewModel($"新任务 {DateTime.Now:HHmmss}")
|
||||
{
|
||||
TaskType = taskType ?? AvailableTaskTypes.First(),
|
||||
Description = "新创建的任务"
|
||||
};
|
||||
|
||||
if (SelectedTaskNode != null)
|
||||
{
|
||||
SelectedTaskNode.AddChild(newTask);
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectedTaskDefinition.RootTask.AddChild(newTask);
|
||||
}
|
||||
|
||||
SelectedTaskDefinition.ModifiedTime = DateTime.Now;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加任务组
|
||||
/// </summary>
|
||||
[RelayCommand]
|
||||
private void AddTaskGroup()
|
||||
{
|
||||
if (SelectedTaskDefinition?.RootTask == null) return;
|
||||
|
||||
var newGroup = new GearTaskViewModel($"新任务组 {DateTime.Now:HHmmss}", true)
|
||||
{
|
||||
Description = "新创建的任务组"
|
||||
};
|
||||
|
||||
if (SelectedTaskNode != null)
|
||||
{
|
||||
SelectedTaskNode.AddChild(newGroup);
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectedTaskDefinition.RootTask.AddChild(newGroup);
|
||||
}
|
||||
|
||||
SelectedTaskDefinition.ModifiedTime = DateTime.Now;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除任务节点
|
||||
/// </summary>
|
||||
[RelayCommand]
|
||||
private void 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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从树中移除任务节点
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存到JSON(预留功能)
|
||||
/// </summary>
|
||||
[RelayCommand]
|
||||
private void SaveToJson()
|
||||
{
|
||||
try
|
||||
{
|
||||
var json = JsonSerializer.Serialize(TaskDefinitions, new JsonSerializerOptions
|
||||
{
|
||||
WriteIndented = true,
|
||||
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
||||
});
|
||||
|
||||
// 这里可以保存到配置文件
|
||||
_logger.LogInformation("任务定义已序列化为JSON: {Json}", json);
|
||||
MessageBox.Show("保存成功!", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "保存任务定义到JSON时发生错误");
|
||||
MessageBox.Show($"保存失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从JSON加载(预留功能)
|
||||
/// </summary>
|
||||
[RelayCommand]
|
||||
private void LoadFromJson()
|
||||
{
|
||||
try
|
||||
{
|
||||
// 这里可以从配置文件加载
|
||||
_logger.LogInformation("从JSON加载任务定义功能待实现");
|
||||
MessageBox.Show("加载功能待实现!", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "从JSON加载任务定义时发生错误");
|
||||
MessageBox.Show($"加载失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user