Commit d6db8bbe by liulongfei

任务支持

parent f33e1d02
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace VIZ.Package.Domain
{
/// <summary>
/// 包装任务状态
/// </summary>
public enum PackageTaskStatus
{
/// <summary>
/// 停止
/// </summary>
Stop,
/// <summary>
/// 执行
/// </summary>
Runing,
/// <summary>
/// 错误
/// </summary>
Error
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace VIZ.Package.Domain
{
/// <summary>
/// 包装任务接口
/// </summary>
public interface IPackageTaskInterface
{
/// <summary>
/// 预览更新
/// </summary>
/// <param name="task">任务</param>
void PreviewUpdate(PackageTaskModel task);
/// <summary>
/// 上版更新
/// </summary>
/// <param name="task">任务</param>
void TakeUpdate(PackageTaskModel task);
/// <summary>
/// 销毁
/// </summary>
/// <param name="task">任务</param>
void Dispose(PackageTaskModel task);
}
}
......@@ -21,6 +21,11 @@ namespace VIZ.Package.Domain
this.View = view;
}
/// <summary>
/// 全局任务ID统计
/// </summary>
private static int ALL_ID = 1;
#region View -- 插件视图
private IPluginView view;
......@@ -38,14 +43,14 @@ namespace VIZ.Package.Domain
#region ID -- 编号
private int id;
private int id = ALL_ID++;
/// <summary>
/// 编号
/// </summary>
public int ID
{
get { return id; }
set { id = value; this.RaisePropertyChanged(nameof(ID)); }
private set { id = value; }
}
#endregion
......@@ -78,30 +83,44 @@ namespace VIZ.Package.Domain
#endregion
#region IsEnabled -- 是否启用
#region IsPreviewEnabled -- 预览是否启用
private bool isPreviewEnabled;
/// <summary>
/// 预览是否启用
/// </summary>
public bool IsPreviewEnabled
{
get { return isPreviewEnabled; }
set { isPreviewEnabled = value; this.RaisePropertyChanged(nameof(IsPreviewEnabled)); }
}
#endregion
#region IsTakeEnabled -- 上版是否启用
private bool isEnabled;
private bool isTakeEnabled;
/// <summary>
/// 是否启用
/// 上版是否启用
/// </summary>
public bool IsEnabled
public bool IsTakeEnabled
{
get { return isEnabled; }
set { isEnabled = value; this.RaisePropertyChanged(nameof(IsEnabled)); }
get { return isTakeEnabled; }
set { isTakeEnabled = value; this.RaisePropertyChanged(nameof(IsTakeEnabled)); }
}
#endregion
#region Status -- 状态
#region IsRunning -- 是否正在运行
private PackageTaskStatus status;
private bool isRunning;
/// <summary>
/// 状态
/// 是否正在运行
/// </summary>
public PackageTaskStatus Status
public bool IsRunning
{
get { return status; }
set { status = value; this.RaisePropertyChanged(nameof(Status)); }
get { return isRunning; }
set { isRunning = value; this.RaisePropertyChanged(nameof(IsRunning)); }
}
#endregion
......@@ -120,6 +139,20 @@ namespace VIZ.Package.Domain
#endregion
#region Interval -- 触发间隔(单位:秒)
private double interval = 5;
/// <summary>
/// 触发间隔(单位:秒)
/// </summary>
public double Interval
{
get { return interval; }
set { interval = value; this.RaisePropertyChanged(nameof(Interval)); }
}
#endregion
#region PreviewUpdateTime -- 预览更新时间
private DateTime? previewUpdateTime;
......@@ -149,9 +182,14 @@ namespace VIZ.Package.Domain
#endregion
/// <summary>
/// 包装任务接口
/// 计时器信息
/// </summary>
public IPackageTaskInterface PackageTaskInterface { get; set; }
public TimerInfo TimerInfo { get; set; }
/// <summary>
/// 是否可以执行
/// </summary>
public bool CanExecute { get; set; } = true;
/// <summary>
/// 预览更新行为
......@@ -164,37 +202,12 @@ namespace VIZ.Package.Domain
public Action<ConnModel> TakeUpdateAction { get; set; }
/// <summary>
/// 预览更新
/// </summary>
public void PreviewUpdate()
{
if (!this.IsEnabled || this.PreviewUpdateAction == null)
return;
this.PackageTaskInterface?.PreviewUpdate(this);
this.PreviewUpdateTime = DateTime.Now;
}
/// <summary>
/// 上版更新
/// </summary>
public void TakeUpdate()
{
if (!this.IsEnabled || this.TakeUpdateAction == null)
return;
this.PackageTaskInterface?.TakeUpdate(this);
this.TakeUpdateTime = DateTime.Now;
}
/// <summary>
/// 销毁
/// </summary>
public void Dispose()
{
this.PackageTaskInterface?.Dispose(this);
this.PreviewUpdateAction = null;
this.TakeUpdateAction = null;
}
}
}
......@@ -111,5 +111,9 @@ namespace VIZ.Package.Domain
#endregion
/// <summary>
/// 空插件
/// </summary>
public static PluginInfo NONE { get; } = new PluginInfo();
}
}
......@@ -77,10 +77,8 @@
<Compile Include="Core\GridColumnDefinition.cs" />
<Compile Include="Enum\ConnGroupStatus.cs" />
<Compile Include="Enum\ModulePluginIds.cs" />
<Compile Include="Enum\PackageTaskStatus.cs" />
<Compile Include="Enum\ViewServiceKeys.cs" />
<Compile Include="Info\VizTreeNodeInfo.cs" />
<Compile Include="Interface\Task\IPackageTaskInterface.cs" />
<Compile Include="Message\Application\ApplicationClosedMessage.cs" />
<Compile Include="Message\Application\ApplicationClosingMessage.cs" />
<Compile Include="Message\Conn\ConnChangedMessage.cs" />
......
......@@ -152,6 +152,9 @@
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="icon" Property="Background" Value="#AA4E4BDE"></Setter>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.4"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
......
......@@ -219,5 +219,17 @@
<Resource Include="Icons\add_32x32.png" />
<Resource Include="Icons\delete_32x32.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Icons\status_error_32x32.png" />
<Resource Include="Icons\status_pause_32x32.png" />
<Resource Include="Icons\status_runing_32x32.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Icons\message_32x32.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Icons\icon_pause_32x32.png" />
<Resource Include="Icons\icon_play_32x32.png" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
\ No newline at end of file
......@@ -210,6 +210,13 @@ namespace VIZ.Package.Module
{
// 模板上版等操作使用默认分组
ConnGroupModel group = ApplicationDomainEx.ConnGroups.FirstOrDefault(p => p.IsDefault);
// 如果没有默认分组,那么采用第一个可用分组
if (group == null)
{
group = ApplicationDomainEx.ConnGroups.FirstOrDefault(p => p.IsEnabled);
}
// 如果没有分组可用,那么不处理
if (group == null)
return;
......
......@@ -123,17 +123,19 @@ namespace VIZ.Package.Module
private void Loaded()
{
// 模板插件集合
this.TemplatePlugins = ApplicationDomainEx.PluginInfos.Where(
p => !string.IsNullOrWhiteSpace(p.Group) &&
p.Group != ApplicationConstants.APPLICATION_GROUP_NAME &&
p.Group == ApplicationDomainEx.VizConfig.PluginGroup &&
p.PluginType == PluginType.Page).ToList();
var list = ApplicationDomainEx.PluginInfos.Where(
p => !string.IsNullOrWhiteSpace(p.Group) &&
p.Group != ApplicationConstants.APPLICATION_GROUP_NAME &&
p.Group == ApplicationDomainEx.VizConfig.PluginGroup &&
p.PluginType == PluginType.Page).ToList();
list.Insert(0, PluginInfo.NONE);
this.TemplatePlugins = list;
// 选择默认模板
PluginMapping mapping = ApplicationDomainEx.PluginMappingConfig?.Mappings?.FirstOrDefault(p => p.Scene == this.Scene);
if (mapping != null)
{
this.SelectedTemplatePlugin = this.TemplatePlugins.FirstOrDefault(p => p.ID == mapping.PluginID);
this.SelectedTemplatePlugin = this.TemplatePlugins.FirstOrDefault(p => p != PluginInfo.NONE && p.ID == mapping.PluginID);
}
}
......
......@@ -219,6 +219,9 @@ namespace VIZ.Package.Module
{
foreach (PluginNavigationConfig config in this.ItemsSource)
{
if (config.View == null)
continue;
config.View.TryGetTarget(out object target);
if (target == null)
continue;
......
......@@ -15,45 +15,103 @@
xmlns:local="clr-namespace:VIZ.Package.Module"
xmlns:domain="clr-namespace:VIZ.Package.Domain;assembly=VIZ.Package.Domain"
d:DataContext="{d:DesignInstance Type=local:PackageTaskViewModel}"
mc:Ignorable="d"
mc:Ignorable="d" x:Name="uc"
d:DesignHeight="45" d:DesignWidth="800">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/VIZ.Package.Module.Resource;component/Style/IconButton/IconButton_Default.xaml"></ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
<fcore:Bool2ImageSourceConverter x:Key="Bool2ImageSourceConverter"
TrueResult="/VIZ.Package.Module.Resource;component/Icons/status_runing_32x32.png"
FalseResult="/VIZ.Package.Module.Resource;component/Icons/status_pause_32x32.png"
NullResult="/VIZ.Package.Module.Resource;component/Icons/status_pause_32x32.png"></fcore:Bool2ImageSourceConverter>
<fcore:Bool2BoolConverter x:Key="Bool2BoolConverter"></fcore:Bool2BoolConverter>
<fcore:StringNotNull2VisibilityConverter x:Key="StringNotNull2VisibilityConverter"></fcore:StringNotNull2VisibilityConverter>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<dxg:GridControl ItemsSource="{Binding Path=ItemsSource}" ShowBorder="False">
<dxg:GridControl.Columns>
<dxg:GridColumn Header="编号" FieldName="ID" ReadOnly="True" AllowSorting="False" AllowColumnFiltering="False"></dxg:GridColumn>
<dxg:GridColumn Header="编号" FieldName="ID" ReadOnly="True" AllowSorting="False" AllowColumnFiltering="False"
AllowResizing="False" Width="80"></dxg:GridColumn>
<dxg:GridColumn Header="状态" FieldName="Status" ReadOnly="True" AllowSorting="False" AllowColumnFiltering="False"
AllowResizing="False" Width="80">
<dxg:GridColumn.CellTemplate>
<DataTemplate>
<Image Width="20" Height="20" Margin="0,3,0,3" HorizontalAlignment="Center" VerticalAlignment="Center"
Source="{Binding Path=Row.IsRunning,Converter={StaticResource Bool2ImageSourceConverter}}"></Image>
</DataTemplate>
</dxg:GridColumn.CellTemplate>
</dxg:GridColumn>
<dxg:GridColumn Header="名称" FieldName="Name" ReadOnly="True" AllowSorting="False" AllowColumnFiltering="False"></dxg:GridColumn>
<dxg:GridColumn Header="备注" FieldName="Remark" AllowSorting="False" AllowColumnFiltering="False">
<dxg:GridColumn.EditSettings>
<dxe:TextEditSettings AcceptsReturn="False"></dxe:TextEditSettings>
</dxg:GridColumn.EditSettings>
</dxg:GridColumn>
<dxg:GridColumn Header="状态" FieldName="Status" ReadOnly="True" AllowSorting="False" AllowColumnFiltering="False"></dxg:GridColumn>
<dxg:GridColumn Header="预览更新时间" ReadOnly="True">
<dxg:GridColumn Header="预览更新时间" ReadOnly="True"
AllowResizing="False" Width="100">
<dxg:GridColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Row.PreviewUpdateTime,StringFormat=yyyy-MM-dd hh:mm:ss}"
<TextBlock Text="{Binding Path=Row.PreviewUpdateTime,StringFormat=hh:mm:ss}"
VerticalAlignment="Center"></TextBlock>
</DataTemplate>
</dxg:GridColumn.CellTemplate>
</dxg:GridColumn>
<dxg:GridColumn Header="更新时间" ReadOnly="True">
<dxg:GridColumn Header="版子更新时间" ReadOnly="True"
AllowResizing="False" Width="100">
<dxg:GridColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Row.TakeUpdateTime,StringFormat=yyyy-MM-dd hh:mm:ss}"
<TextBlock Text="{Binding Path=Row.TakeUpdateTime,StringFormat=hh:mm:ss}"
VerticalAlignment="Center"></TextBlock>
</DataTemplate>
</dxg:GridColumn.CellTemplate>
</dxg:GridColumn>
<dxg:GridColumn Header="是否启用" FieldName="IsEnabled" AllowSorting="False" AllowColumnFiltering="False">
<dxg:GridColumn Header="更新预览" FieldName="IsPreviewEnabled" AllowSorting="False" AllowColumnFiltering="False"
AllowResizing="False" Width="80">
<dxg:GridColumn.EditSettings>
<dxe:CheckEditSettings HorizontalContentAlignment="Left"></dxe:CheckEditSettings>
<dxe:CheckEditSettings></dxe:CheckEditSettings>
</dxg:GridColumn.EditSettings>
</dxg:GridColumn>
<dxg:GridColumn Header="更新版子" FieldName="IsTakeEnabled" AllowSorting="False" AllowColumnFiltering="False"
AllowResizing="False" Width="80">
<dxg:GridColumn.EditSettings>
<dxe:CheckEditSettings></dxe:CheckEditSettings>
</dxg:GridColumn.EditSettings>
</dxg:GridColumn>
<dxg:GridColumn Header="任务信息" FieldName="Status" ReadOnly="True" AllowSorting="False" AllowColumnFiltering="False"
AllowResizing="False" Width="80">
<dxg:GridColumn.CellTemplate>
<DataTemplate>
<Image Width="20" Height="20" Margin="0,3,0,3" HorizontalAlignment="Center" VerticalAlignment="Center"
Source="/VIZ.Package.Module.Resource;component/Icons/message_32x32.png"
ToolTip="{Binding Path=Row.ErrorMessage}"
Visibility="{Binding Path=Row.ErrorMessage,Converter={StaticResource StringNotNull2VisibilityConverter}}"></Image>
</DataTemplate>
</dxg:GridColumn.CellTemplate>
</dxg:GridColumn>
<dxg:GridColumn AllowSorting="False" AllowColumnFiltering="False"
AllowResizing="False" Width="100">
<dxg:GridColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<fcommon:IconButton Style="{StaticResource IconButton_Menu_Mask}"
Icon="/VIZ.Package.Module.Resource;component/Icons/icon_play_32x32.png"
IsEnabled="{Binding Path=Row.IsRunning,Converter={StaticResource Bool2BoolConverter}}"
Command="{Binding ElementName=uc,Path=DataContext.StartCommand}"
CommandParameter="{Binding Row}"></fcommon:IconButton>
<fcommon:IconButton Style="{StaticResource IconButton_Menu_Mask}" Margin="10,0,0,0"
Icon="/VIZ.Package.Module.Resource;component/Icons/icon_pause_32x32.png"
IsEnabled="{Binding Path=Row.IsRunning}"
Command="{Binding ElementName=uc,Path=DataContext.StopCommand}"
CommandParameter="{Binding Row}"></fcommon:IconButton>
</StackPanel>
</DataTemplate>
</dxg:GridColumn.CellTemplate>
</dxg:GridColumn>
</dxg:GridControl.Columns>
<dxg:GridControl.View>
<dxg:TableView IsColumnMenuEnabled="False"
......
......@@ -17,7 +17,7 @@ namespace VIZ.Package.Module
/// <summary>
/// 包装任务视图模型
/// </summary>
public class PackageTaskViewModel : ViewModelBase, IPackageTaskService, IPackageTaskInterface
public class PackageTaskViewModel : ViewModelBase, IPackageTaskService
{
/// <summary>
/// 日志
......@@ -38,7 +38,8 @@ namespace VIZ.Package.Module
/// </summary>
private void InitCommand()
{
this.StartCommand = new VCommand<PackageTaskModel>(this.Start);
this.StopCommand = new VCommand<PackageTaskModel>(this.Stop);
}
// ==============================================================
......@@ -77,6 +78,41 @@ namespace VIZ.Package.Module
// Command
// ==============================================================
#region StartCommand -- 开始命令
/// <summary>
/// 开始命令
/// </summary>
public VCommand<PackageTaskModel> StartCommand { get; set; }
/// <summary>
/// 开始
/// </summary>
/// <param name="task">任务</param>
private void Start(PackageTaskModel task)
{
task.IsRunning = true;
}
#endregion
#region StopCommand -- 停止命令
/// <summary>
/// 停止命令
/// </summary>
public VCommand<PackageTaskModel> StopCommand { get; set; }
/// <summary>
/// 停止
/// </summary>
/// <param name="task">任务</param>
private void Stop(PackageTaskModel task)
{
task.IsRunning = false;
}
#endregion
// ==============================================================
// Public Function
......@@ -93,9 +129,75 @@ namespace VIZ.Package.Module
if (this.ItemsSource.Contains(task))
return;
task.PackageTaskInterface = this;
this.ItemsSource.Add(task);
string key = $"PackageTask_{task.ID}";
task.TimerInfo = ApplicationDomainEx.TimerManager.Register(key, task.Interval, () =>
{
// 任务没有在运行状态 || 任务不可以执行
if (!task.IsRunning || !task.CanExecute)
return;
// 上预览
if (task.IsPreviewEnabled && ApplicationDomainEx.PreviewConn != null && ApplicationDomainEx.PreviewConn.IsConnected)
{
try
{
task.PreviewUpdateAction(ApplicationDomainEx.PreviewConn);
WPFHelper.Invoke(() =>
{
task.PreviewUpdateTime = DateTime.Now;
});
}
catch (Exception ex)
{
log.Error(ex);
WPFHelper.Invoke(() =>
{
task.ErrorMessage = ex.Message;
});
}
}
// 上版
if (task.IsTakeEnabled)
{
IPluginService pluginService = ApplicationDomainEx.ServiceManager.GetService<IPluginService>(ViewServiceKeys.PLUGIN_SERVICE);
if (pluginService == null)
return;
PageModel page = pluginService.GetPageModelFromView(task.View);
if (page == null)
return;
ConnGroupModel group = ApplicationDomainEx.ConnGroups.FirstOrDefault(p => p.GroupID == page.ConnGroupID);
if (group == null)
return;
foreach (var item in group.Items)
{
if (!item.IsEnabled || !item.IsConnected)
continue;
try
{
task.TakeUpdateAction(item);
WPFHelper.Invoke(() =>
{
task.TakeUpdateTime = DateTime.Now;
});
}
catch (Exception ex)
{
log.Error(ex);
WPFHelper.Invoke(() =>
{
task.ErrorMessage = ex.Message;
});
}
}
}
});
}
}
......@@ -109,70 +211,14 @@ namespace VIZ.Package.Module
{
if (this.ItemsSource.Contains(task))
{
task.IsEnabled = false;
string key = $"PackageTask_{task.ID}";
ApplicationDomainEx.TimerManager.UnRegister(key);
this.ItemsSource.Remove(task);
}
}
}
/// <summary>
/// 预览更新
/// </summary>
/// <param name="task">任务</param>
public void PreviewUpdate(PackageTaskModel task)
{
try
{
task.PreviewUpdateAction(ApplicationDomainEx.PreviewConn);
}
catch (Exception ex)
{
log.Error(ex);
}
}
/// <summary>
/// 上版更新
/// </summary>
/// <param name="task">任务</param>
public void TakeUpdate(PackageTaskModel task)
{
IPluginService pluginService = ApplicationDomainEx.ServiceManager.GetService<IPluginService>(ViewServiceKeys.PLUGIN_SERVICE);
if (pluginService == null)
return;
PageModel page = pluginService.GetPageModelFromView(task.View);
if (page == null)
return;
ConnGroupModel group = ApplicationDomainEx.ConnGroups.FirstOrDefault(p => p.GroupID == page.ConnGroupID);
if (group == null)
return;
foreach (var item in group.Items)
{
if (!item.IsEnabled || !item.IsConnected)
continue;
try
{
task.TakeUpdateAction(item);
}
catch (Exception ex)
{
log.Error(ex);
task.TimerInfo?.Dispose();
}
}
}
/// <summary>
/// 销毁
/// </summary>
/// <param name="task">任务</param>
public void Dispose(PackageTaskModel task)
{
this.Cancel(task);
}
}
}
\ No newline at end of file
......@@ -7,6 +7,7 @@
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Button Width="240" Height="60" Click="Button_Click" Content="包装任务触发"></Button>
<TextBlock Text="测试插件" VerticalAlignment="Center" HorizontalAlignment="Center"
Foreground="Red" FontSize="36"></TextBlock>
</Grid>
</UserControl>
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
......@@ -40,6 +41,10 @@ namespace VIZ.Package.TestPlugin
return;
this.task = new PackageTaskModel(this);
this.task.IsPreviewEnabled = true;
this.task.IsTakeEnabled = true;
this.task.IsRunning = true;
this.task.ErrorMessage = "this is a try.";
this.task.PreviewUpdateAction = this.OnPreviewUpdate;
this.task.TakeUpdateAction = this.OnTakeUpdate;
......@@ -52,12 +57,12 @@ namespace VIZ.Package.TestPlugin
private void OnPreviewUpdate(ConnModel conn)
{
Debug.WriteLine($"PreviewUpdate");
}
private void OnTakeUpdate(ConnModel conn)
{
Debug.WriteLine($"TakeUpdate");
}
/// <summary>
......@@ -114,10 +119,5 @@ namespace VIZ.Package.TestPlugin
/// </summary>
public void Dispose()
{ }
private void Button_Click(object sender, RoutedEventArgs e)
{
this.task?.PreviewUpdate();
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment