diff --git a/ADP/ADP.csproj b/ADP/ADP.csproj
index 876b4b7..6c43360 100644
--- a/ADP/ADP.csproj
+++ b/ADP/ADP.csproj
@@ -8,6 +8,10 @@
true
+
+
+
+
diff --git a/ADP/App.xaml.cs b/ADP/App.xaml.cs
index 06f0652..0e19940 100644
--- a/ADP/App.xaml.cs
+++ b/ADP/App.xaml.cs
@@ -20,6 +20,9 @@ using UIShare;
using System;
using DeviceCommand.Device;
using DeviceCommand.Base;
+using AutoMapper;
+using Microsoft.Extensions.Logging.Abstractions;
+using ADP.Profiles;
namespace ADP
{
@@ -68,6 +71,22 @@ namespace ADP
RegionManager.SetRegionManager(Application.Current.MainWindow, re);
login.Show();
}
+ protected override void RegisterRequiredTypes(IContainerRegistry containerRegistry)
+ {
+ base.RegisterRequiredTypes(containerRegistry);
+ //注册全局变量
+ containerRegistry.RegisterScoped();
+ containerRegistry.RegisterScoped();
+ containerRegistry.RegisterScoped();
+ containerRegistry.RegisterScoped();
+ containerRegistry.RegisterSingleton();
+ //注册AutoMapper
+ var config = new MapperConfiguration(
+ cfg => cfg.AddProfile(),
+ NullLoggerFactory.Instance
+ );
+ containerRegistry.RegisterSingleton(() => config.CreateMapper());
+ }
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
//注册弹窗
@@ -75,12 +94,8 @@ namespace ADP
// 注册通知管理器
INotificationManager NotificationManager = new NotificationManager();
containerRegistry.RegisterInstance(NotificationManager);
- //注册全局变量
- containerRegistry.RegisterScoped();
- containerRegistry.RegisterScoped();
- containerRegistry.RegisterScoped();
- containerRegistry.RegisterScoped();
- containerRegistry.RegisterSingleton();
+ // 注册仓储
+ containerRegistry.RegisterScoped(typeof(SqlSugarRepository<>));
}
//指定模块加载方式(需要手动将模块生成的dll放入Modules文件夹中)
protected override IModuleCatalog CreateModuleCatalog()
diff --git a/ADP/Profiles/AutoMapperProfile.cs b/ADP/Profiles/AutoMapperProfile.cs
new file mode 100644
index 0000000..c197626
--- /dev/null
+++ b/ADP/Profiles/AutoMapperProfile.cs
@@ -0,0 +1,64 @@
+using AutoMapper;
+using Model.Models;
+using System;
+using UIShare.UIViewModel;
+
+namespace ADP.Profiles
+{
+ ///
+ /// UIShare.UIViewModel ↔ Model.Models 双向映射配置。
+ ///
+ public class AutoMapperProfile : Profile
+ {
+ public AutoMapperProfile()
+ {
+ // ===== Parameter =====
+ // ParameterModel.Type(System.Type) ↔ Parameter.TypeName(string)
+ // ParameterModel.Category(enum) ↔ Parameter.Category(string)
+ CreateMap()
+ .ForMember(dest => dest.TypeName,
+ opt => opt.MapFrom(src => src.Type != null ? src.Type.AssemblyQualifiedName : null))
+ .ForMember(dest => dest.Category,
+ opt => opt.MapFrom(src => src.Category.ToString()));
+
+ CreateMap()
+ .ForMember(dest => dest.Type,
+ opt => opt.MapFrom(src => string.IsNullOrEmpty(src.TypeName)
+ ? typeof(string)
+ : (Type.GetType(src.TypeName) ?? typeof(string))))
+ .ForMember(dest => dest.Category,
+ opt => opt.MapFrom(src => ParseCategory(src.Category)));
+
+ // ===== Step =====
+ CreateMap().ReverseMap();
+
+ // ===== Program =====
+ CreateMap().ReverseMap();
+
+ // ===== Method =====
+ CreateMap().ReverseMap();
+
+ // ===== DeviceInfo =====
+ CreateMap().ReverseMap();
+
+ // ===== CanMessageShow =====
+ CreateMap().ReverseMap();
+
+
+ // ===== InstructionNode =====
+ CreateMap().ReverseMap();
+
+ // ===== SubProgramItem =====
+ CreateMap().ReverseMap();
+ }
+
+ private static ParameterVM.ParameterCategory ParseCategory(string? category)
+ {
+ if (string.IsNullOrEmpty(category))
+ return ParameterVM.ParameterCategory.Temp;
+ return Enum.TryParse(category, true, out var result)
+ ? result
+ : ParameterVM.ParameterCategory.Temp;
+ }
+ }
+}
diff --git a/ADP/ViewModels/ShellViewModel.cs b/ADP/ViewModels/ShellViewModel.cs
index c028ba2..7792b69 100644
--- a/ADP/ViewModels/ShellViewModel.cs
+++ b/ADP/ViewModels/ShellViewModel.cs
@@ -530,8 +530,8 @@ namespace ADP.ViewModels
// 读取 JSON 文件
string json = File.ReadAllText(filePath);
- // 反序列化为 ProgramModel
- var program = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
+ // 反序列化为 ProgramVM
+ var program = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
if (program == null)
{
@@ -621,12 +621,12 @@ namespace ADP.ViewModels
LoggerHelper.SuccessWithNotify($"工位 [{runningScope}] 程序保存成功!");
}
- // 💡 辅助方法:建议将你的通用序列化落盘代码调整为接收 ProgramModel 参数,提高复用性
- private void SaveProgramToFile(string filePath, ProgramModel programModel)
+ // 💡 辅助方法:建议将你的通用序列化落盘代码调整为接收 ProgramVM 参数,提高复用性
+ private void SaveProgramToFile(string filePath, ProgramVM ProgramVM)
{
try
{
- string json = Newtonsoft.Json.JsonConvert.SerializeObject(programModel, Newtonsoft.Json.Formatting.Indented);
+ string json = Newtonsoft.Json.JsonConvert.SerializeObject(ProgramVM, Newtonsoft.Json.Formatting.Indented);
File.WriteAllText(filePath, json);
}
catch (Exception ex)
diff --git a/MainModule/ViewModels/AutomatedTestingViewModel.cs b/MainModule/ViewModels/AutomatedTestingViewModel.cs
index ae7343c..3392937 100644
--- a/MainModule/ViewModels/AutomatedTestingViewModel.cs
+++ b/MainModule/ViewModels/AutomatedTestingViewModel.cs
@@ -133,8 +133,8 @@ namespace MainModule.ViewModels
// 读取 JSON 文件
string json = File.ReadAllText(filePath);
- // 反序列化为 ProgramModel
- var program = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
+ // 反序列化为 ProgramVM
+ var program = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
if (program == null)
{
diff --git a/Model/Models/CanMessageShow.cs b/Model/Models/CanMessageShow.cs
new file mode 100644
index 0000000..8fa34dd
--- /dev/null
+++ b/Model/Models/CanMessageShow.cs
@@ -0,0 +1,24 @@
+namespace Model.Models
+{
+ ///
+ /// CAN 报文展示纯数据类(对应 UIShare.UIViewModel.CanMessageShowModel)
+ ///
+ public class CanMessageShow
+ {
+ public byte 通道 { get; set; }
+
+ public int 报文ID { get; set; }
+
+ public ulong 时间戳 { get; set; }
+
+ public byte 长度 { get; set; }
+
+ public bool FD { get; set; }
+
+ public bool IsTx { get; set; }
+
+ public byte[] Bytes { get; set; } = new byte[64];
+
+ public string? 报文 { get; set; }
+ }
+}
diff --git a/Model/Models/DeviceInfo.cs b/Model/Models/DeviceInfo.cs
new file mode 100644
index 0000000..7e2c415
--- /dev/null
+++ b/Model/Models/DeviceInfo.cs
@@ -0,0 +1,18 @@
+namespace Model.Models
+{
+ ///
+ /// 设备信息纯数据类(对应 UIShare.UIViewModel.DeviceInfoModel)
+ ///
+ public class DeviceInfo
+ {
+ public string? DeviceName { get; set; }
+
+ public string? DeviceType { get; set; }
+
+ public string? Remark { get; set; }
+
+ public bool IsEnabled { get; set; }
+
+ public bool IsConnected { get; set; }
+ }
+}
diff --git a/Model/Models/InstructionNode.cs b/Model/Models/InstructionNode.cs
new file mode 100644
index 0000000..bd46445
--- /dev/null
+++ b/Model/Models/InstructionNode.cs
@@ -0,0 +1,16 @@
+using System.Collections.Generic;
+
+namespace Model.Models
+{
+ ///
+ /// 指令节点纯数据类(对应 UIShare.UIViewModel.InstructionNode)
+ ///
+ public class InstructionNode
+ {
+ public string? Name { get; set; }
+
+ public IList Children { get; set; } = new List();
+
+ public object? Tag { get; set; }
+ }
+}
diff --git a/Model/Models/Method.cs b/Model/Models/Method.cs
new file mode 100644
index 0000000..350cbc3
--- /dev/null
+++ b/Model/Models/Method.cs
@@ -0,0 +1,16 @@
+using System.Collections.Generic;
+
+namespace Model.Models
+{
+ ///
+ /// 方法纯数据类(对应 UIShare.UIViewModel.MethodModel)
+ ///
+ public class Method
+ {
+ public string? Name { get; set; }
+
+ public string? FullName { get; set; }
+
+ public IList Parameters { get; set; } = new List();
+ }
+}
diff --git a/Model/Models/Parameter.cs b/Model/Models/Parameter.cs
new file mode 100644
index 0000000..d8b0aa5
--- /dev/null
+++ b/Model/Models/Parameter.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+
+namespace Model.Models
+{
+ ///
+ /// 参数纯数据类(对应 UIShare.UIViewModel.ParameterModel)
+ ///
+ public class Parameter
+ {
+ public Guid ID { get; set; } = Guid.NewGuid();
+
+ public bool IsVisible { get; set; } = true;
+
+ public string? Name { get; set; }
+
+ ///
+ /// 类型全名(对应 ParameterModel.Type 的 FullName)
+ ///
+ public string? TypeName { get; set; }
+
+ ///
+ /// 参数类别(Input / Output / Temp)
+ ///
+ public string? Category { get; set; }
+
+ public bool IsGlobal { get; set; }
+
+ public object? Value { get; set; }
+
+ public object? LowerLimit { get; set; }
+
+ public object? UpperLimit { get; set; }
+
+ public bool Result { get; set; } = true;
+
+ public bool IsUseVar { get; set; }
+
+ public bool IsSave { get; set; }
+
+ public string? VariableName { get; set; }
+
+ public Guid? VariableID { get; set; }
+ }
+}
diff --git a/Model/Models/Program.cs b/Model/Models/Program.cs
new file mode 100644
index 0000000..5aef8a4
--- /dev/null
+++ b/Model/Models/Program.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+
+namespace Model.Models
+{
+ ///
+ /// 程序纯数据类(对应 UIShare.UIViewModel.ProgramModel)
+ ///
+ public class Program
+ {
+ public Guid ID { get; set; } = Guid.NewGuid();
+
+ public IList StepCollection { get; set; } = new List();
+
+ public IList ErrorStepCollection { get; set; } = new List();
+
+ public IList Parameters { get; set; } = new List();
+ }
+}
diff --git a/Model/Models/Step.cs b/Model/Models/Step.cs
new file mode 100644
index 0000000..812ef6a
--- /dev/null
+++ b/Model/Models/Step.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+
+namespace Model.Models
+{
+ ///
+ /// 步骤纯数据类(对应 UIShare.UIViewModel.StepModel)
+ ///
+ public class Step
+ {
+ public Guid ID { get; set; } = Guid.NewGuid();
+
+ public bool IsUsed { get; set; } = true;
+
+ public int Index { get; set; }
+
+ public string? Name { get; set; }
+
+ public string? StepType { get; set; }
+
+ public Method? Method { get; set; }
+
+ public Program? SubProgram { get; set; }
+
+ public int? LoopCount { get; set; }
+
+ public int? CurrentLoopCount { get; set; }
+
+ public Guid? LoopStartStepId { get; set; }
+
+ public int Result { get; set; } = -1;
+
+ public int? RunTime { get; set; }
+
+ public string? OKExpression { get; set; }
+
+ public string GotoSettingString { get; set; } = "";
+
+ public Guid? OKGotoStepID { get; set; }
+
+ public Guid? NGGotoStepID { get; set; }
+
+ public string? Description { get; set; }
+ }
+}
diff --git a/Model/Models/SubProgramItem.cs b/Model/Models/SubProgramItem.cs
new file mode 100644
index 0000000..038b47d
--- /dev/null
+++ b/Model/Models/SubProgramItem.cs
@@ -0,0 +1,12 @@
+namespace Model.Models
+{
+ ///
+ /// 子程序项纯数据类(对应 UIShare.UIViewModel.SubProgramItem)
+ ///
+ public class SubProgramItem
+ {
+ public string Name { get; set; } = "";
+
+ public string FilePath { get; set; } = "";
+ }
+}
diff --git a/SettingModule/ViewModels/Dialogs/SerialPortConfigViewModel.cs b/SettingModule/ViewModels/Dialogs/SerialPortConfigViewModel.cs
index 3b1473e..14da83b 100644
--- a/SettingModule/ViewModels/Dialogs/SerialPortConfigViewModel.cs
+++ b/SettingModule/ViewModels/Dialogs/SerialPortConfigViewModel.cs
@@ -10,7 +10,7 @@ namespace SettingModule.ViewModels.Dialogs
{
///
/// 串口连接配置对话框 VM。
- /// 通过 DialogParameters 接收宿主 DeviceInfoModel;保存时把副本写回宿主。
+ /// 通过 DialogParameters 接收宿主 DeviceInfoVM;保存时把副本写回宿主。
///
public class SerialPortConfigViewModel : DialogViewModelBase
{
@@ -23,8 +23,8 @@ namespace SettingModule.ViewModels.Dialogs
set => SetProperty(ref _title, value);
}
- private SerialPortConnectionConfig _config = new();
- public SerialPortConnectionConfig Config
+ private SerialPortConfigVM _config = new();
+ public SerialPortConfigVM Config
{
get => _config;
set => SetProperty(ref _config, value);
@@ -70,7 +70,7 @@ namespace SettingModule.ViewModels.Dialogs
public ICommand RefreshPortsCommand { get; }
#endregion
- private DeviceInfoModel? _hostDevice;
+ private DeviceInfoVM? _hostDevice;
public SerialPortConfigViewModel(IContainerProvider containerProvider) : base(containerProvider)
{
@@ -126,7 +126,7 @@ namespace SettingModule.ViewModels.Dialogs
if (_hostDevice != null)
{
- _hostDevice.SerialPortConfig ??= new SerialPortConnectionConfig();
+ _hostDevice.SerialPortConfig ??= new SerialPortConfigVM();
Config.CopyTo(_hostDevice.SerialPortConfig);
_hostDevice.ConnectionType = "Serial";
}
@@ -143,13 +143,13 @@ namespace SettingModule.ViewModels.Dialogs
if (parameters.ContainsKey("Device"))
{
- _hostDevice = parameters.GetValue("Device");
+ _hostDevice = parameters.GetValue("Device");
Title = $"串口连接配置 - {_hostDevice?.DeviceName}";
- Config = new SerialPortConnectionConfig(_hostDevice?.SerialPortConfig);
+ Config = new SerialPortConfigVM(_hostDevice?.SerialPortConfig);
}
else if (parameters.ContainsKey("Config"))
{
- Config = new SerialPortConnectionConfig(parameters.GetValue("Config"));
+ Config = new SerialPortConfigVM(parameters.GetValue("Config"));
}
RefreshPorts();
diff --git a/SettingModule/ViewModels/Dialogs/TCPConfigViewModel.cs b/SettingModule/ViewModels/Dialogs/TCPConfigViewModel.cs
index a45b8fc..4ecd64c 100644
--- a/SettingModule/ViewModels/Dialogs/TCPConfigViewModel.cs
+++ b/SettingModule/ViewModels/Dialogs/TCPConfigViewModel.cs
@@ -9,7 +9,7 @@ namespace SettingModule.ViewModels.Dialogs
{
///
/// TCP 连接配置对话框 VM。
- /// 通过 DialogParameters 接收宿主 DeviceInfoModel;保存时把副本写回宿主。
+ /// 通过 DialogParameters 接收宿主 DeviceInfoVM;保存时把副本写回宿主。
///
public class TCPConfigViewModel : DialogViewModelBase
{
@@ -23,8 +23,8 @@ namespace SettingModule.ViewModels.Dialogs
}
/// 编辑用的副本,取消时不会污染宿主对象。
- private TcpConnectionConfig _config = new();
- public TcpConnectionConfig Config
+ private TcpConfigVM _config = new();
+ public TcpConfigVM Config
{
get => _config;
set => SetProperty(ref _config, value);
@@ -57,7 +57,7 @@ namespace SettingModule.ViewModels.Dialogs
#endregion
// 用于保存时把副本回写到原对象
- private DeviceInfoModel? _hostDevice;
+ private DeviceInfoVM? _hostDevice;
public TCPConfigViewModel(IContainerProvider containerProvider) : base(containerProvider)
{
@@ -103,7 +103,7 @@ namespace SettingModule.ViewModels.Dialogs
// 把副本写回宿主
if (_hostDevice != null)
{
- _hostDevice.TcpConfig ??= new TcpConnectionConfig();
+ _hostDevice.TcpConfig ??= new TcpConfigVM();
Config.CopyTo(_hostDevice.TcpConfig);
_hostDevice.ConnectionType = "TCP";
}
@@ -120,13 +120,13 @@ namespace SettingModule.ViewModels.Dialogs
if (parameters.ContainsKey("Device"))
{
- _hostDevice = parameters.GetValue("Device");
+ _hostDevice = parameters.GetValue("Device");
Title = $"TCP 连接配置 - {_hostDevice?.DeviceName}";
- Config = new TcpConnectionConfig(_hostDevice?.TcpConfig);
+ Config = new TcpConfigVM(_hostDevice?.TcpConfig);
}
else if (parameters.ContainsKey("Config"))
{
- Config = new TcpConnectionConfig(parameters.GetValue("Config"));
+ Config = new TcpConfigVM(parameters.GetValue("Config"));
}
}
diff --git a/SettingModule/ViewModels/SettingViewModel.cs b/SettingModule/ViewModels/SettingViewModel.cs
index 55f0aa9..2b30092 100644
--- a/SettingModule/ViewModels/SettingViewModel.cs
+++ b/SettingModule/ViewModels/SettingViewModel.cs
@@ -28,7 +28,7 @@ namespace SettingModule.ViewModels
set => SetProperty(ref _testStatus, value);
}
- public DeviceInfoModel? SelectedDevice
+ public DeviceInfoVM? SelectedDevice
{
get => _selectedDevice;
set
@@ -40,7 +40,7 @@ namespace SettingModule.ViewModels
}
}
- public ObservableCollection DeviceList
+ public ObservableCollection DeviceList
{
get => _deviceList;
set => SetProperty(ref _deviceList, value);
@@ -70,8 +70,8 @@ namespace SettingModule.ViewModels
private GlobalInfo _globalInfo { get; }
private bool IsInitiated = false;
private string _testStatus = string.Empty;
- private DeviceInfoModel? _selectedDevice;
- private ObservableCollection _deviceList;
+ private DeviceInfoVM? _selectedDevice;
+ private ObservableCollection _deviceList;
private string _statusMessage = "请在左侧选择设备查看 / 编辑配置";
#endregion
public SettingViewModel(IContainerExtension container) : base(container)
diff --git a/TestingModule/ViewModels/CommandTreeViewModel.cs b/TestingModule/ViewModels/CommandTreeViewModel.cs
index 3b1405f..e6ecf03 100644
--- a/TestingModule/ViewModels/CommandTreeViewModel.cs
+++ b/TestingModule/ViewModels/CommandTreeViewModel.cs
@@ -18,7 +18,7 @@ using System.Windows.Controls;
using System.Windows.Input;
using System.Xml;
using Model;
-using static UIShare.UIViewModel.ParameterModel;
+using static UIShare.UIViewModel.ParameterVM;
using UIShare.ViewModelBase;
using NLog;
@@ -34,14 +34,14 @@ namespace TestingModule.ViewModels
get => _SearchText;
set => SetProperty(ref _SearchText, value);
}
- private ObservableCollection _instructionTree = new();
- public ObservableCollection InstructionTree
+ private ObservableCollection _instructionTree = new();
+ public ObservableCollection InstructionTree
{
get => _instructionTree;
set => SetProperty(ref _instructionTree, value);
}
- public ProgramModel Program
+ public ProgramVM Program
{
get => _ScopedContext.Program;
set
@@ -67,15 +67,15 @@ namespace TestingModule.ViewModels
}
}
- private ObservableCollection _subPrograms = new();
- public ObservableCollection SubPrograms
+ private ObservableCollection _subPrograms = new();
+ public ObservableCollection SubPrograms
{
get => _subPrograms;
set => SetProperty(ref _subPrograms, value);
}
- private Dictionary