Files
CapMachine/CapMachine.Wpf/ViewModels/DialogZlgCANSchConfigViewModel.cs
2026-03-02 11:20:08 +08:00

403 lines
13 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using AutoMapper;
using CapMachine.Core;
using CapMachine.Model;
using CapMachine.Model.CANLIN;
using CapMachine.Wpf.Dtos;
using CapMachine.Wpf.Services;
using ImTools;
using Prism.Commands;
using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace CapMachine.Wpf.ViewModels
{
/// <summary>
/// ZLG CAN 调度表配置
/// </summary>
public class DialogZlgCANSchConfigViewModel : DialogViewModel
{
/// <summary>
/// 构造函数
/// </summary>
public DialogZlgCANSchConfigViewModel(IFreeSql freeSql, IMapper mapper)
{
Title = "调度表 CAN 配置";
FreeSql = freeSql;
Mapper = mapper;
SendOrderCbxItems = new ObservableCollection<CbxItems>()
{
new CbxItems(){
Key="0",
Text="并行",
},
new CbxItems(){
Key="1",
Text="顺序",
},
};
//默认只能用1号调度器
SchTabIndexCbxItems = new ObservableCollection<CbxItems>()
{
new CbxItems(){
Key="0",
Text="0",
},
//new CbxItems(){
// Key="1",
// Text="1",
//},
//new CbxItems(){
// Key="2",
// Text="2",
//},
//new CbxItems(){
// Key="3",
// Text="3",
//},
//new CbxItems(){
// Key="4",
// Text="4",
//},
};
}
/// <summary>
/// FreeSql用于调度表项的删除/保存落库)。
/// </summary>
public IFreeSql FreeSql { get; }
/// <summary>
/// AutoMapperDTO 与实体映射)。
/// </summary>
public IMapper Mapper { get; }
private string name;
/// <summary>
/// 名称
/// </summary>
public string Name
{
get { return name; }
set { name = value; RaisePropertyChanged(); }
}
private ObservableCollection<CANScheduleConfigDto> _ListCANScheduleConfigDto = new ObservableCollection<CANScheduleConfigDto>();
/// <summary>
/// CAN 调度表数据集合
/// </summary>
public ObservableCollection<CANScheduleConfigDto> ListCANScheduleConfigDto
{
get { return _ListCANScheduleConfigDto; }
set { _ListCANScheduleConfigDto = value; RaisePropertyChanged(); }
}
/// <summary>
/// 消息/帧报文信息集合
/// </summary>
public List<string>? ListMsg { get; set; }
private ObservableCollection<CbxItems> _MsgCbxItems;
/// <summary>
/// 消息名称 集合信息
/// </summary>
public ObservableCollection<CbxItems> MsgCbxItems
{
get { return _MsgCbxItems; }
set { _MsgCbxItems = value; RaisePropertyChanged(); }
}
/// <summary>
/// 选中的程序的Id
/// </summary>
public long SelectCanLinConfigProId { get; set; }
private ObservableCollection<CbxItems> _SendOrderCbxItems;
/// <summary>
/// 发送方式 集合信息
/// </summary>
public ObservableCollection<CbxItems> SendOrderCbxItems
{
get { return _SendOrderCbxItems; }
set { _SendOrderCbxItems = value; RaisePropertyChanged(); }
}
private string? _CurSendOrder;
/// <summary>
/// 当前发送方式
/// </summary>
public string? CurSendOrder
{
get { return _CurSendOrder; }
set { _CurSendOrder = value; RaisePropertyChanged(); }
}
private ObservableCollection<CbxItems> _SchTabIndexCbxItems;
/// <summary>
/// 调度器序号 集合信息
/// </summary>
public ObservableCollection<CbxItems> SchTabIndexCbxItems
{
get { return _SchTabIndexCbxItems; }
set { _SchTabIndexCbxItems = value; RaisePropertyChanged(); }
}
private CANScheduleConfigDto _CurSelectedItem;
/// <summary>
/// 当前选中的调度表项(用于删除等操作)。
/// </summary>
public CANScheduleConfigDto CurSelectedItem
{
get { return _CurSelectedItem; }
set { _CurSelectedItem = value; RaisePropertyChanged(); }
}
private DelegateCommand<object> _GridSelectionChangedCmd;
/// <summary>
/// DataGrid 选中行变化。
/// </summary>
public DelegateCommand<object> GridSelectionChangedCmd
{
set
{
_GridSelectionChangedCmd = value;
}
get
{
if (_GridSelectionChangedCmd == null)
{
_GridSelectionChangedCmd = new DelegateCommand<object>((par) => GridSelectionChangedCmdMethod(par));
}
return _GridSelectionChangedCmd;
}
}
private void GridSelectionChangedCmdMethod(object par)
{
// 先判断是否是正确的集合数据,防止 DataGrid 的 ItemsSource 刷新导致的误触发。
var Selecteddata = par as CANScheduleConfigDto;
if (Selecteddata != null)
{
CurSelectedItem = Selecteddata;
}
}
private DelegateCommand<string> _OpCmd;
/// <summary>
/// 操作命令(删除)。
/// 说明:新增调度表项由“读写设置”弹窗内的“加入定时调度表”生成,此处仅允许删除与保存。
/// </summary>
public DelegateCommand<string> OpCmd
{
set
{
_OpCmd = value;
}
get
{
if (_OpCmd == null)
{
_OpCmd = new DelegateCommand<string>((Par) => OpCmdCall(Par));
}
return _OpCmd;
}
}
private void OpCmdCall(string Par)
{
switch (Par)
{
case "Add":
MessageBox.Show("调度表项由【读写设置】中的写入配置通过“加入定时调度表”生成,这里不支持新增。", "提示", MessageBoxButton.OK, MessageBoxImage.Hand);
break;
case "Delete":
if (CurSelectedItem != null)
{
// 直接落库删除(无论 UI 是否还有引用,都以数据库为准)。
FreeSql.Delete<CANScheduleConfig>(CurSelectedItem.Id).ExecuteAffrows();
ListCANScheduleConfigDto.Remove(CurSelectedItem);
CurSelectedItem = null;
}
else
{
MessageBox.Show("请选中后再进行【删除】操作?", "提示", MessageBoxButton.OK, MessageBoxImage.Hand);
}
break;
default:
break;
}
}
private DelegateCommand saveCmd;
/// <summary>
/// 保存命令
/// </summary>
public DelegateCommand SaveCmd
{
set
{
saveCmd = value;
}
get
{
if (saveCmd == null)
{
saveCmd = new DelegateCommand(() => SaveCmdMethod());
}
return saveCmd;
}
}
/// <summary>
/// 保存命令方法。
/// 说明:
/// - 先做必要校验MsgName/Cycle/发送方式等),避免写入无效配置;
/// - 使用 InsertOrUpdate 保证“新增/修改”统一处理;
/// - 保存完成后重新从数据库加载,作为最终权威数据,并通过 DialogResult 回传给调用方。
/// </summary>
private void SaveCmdMethod()
{
// 校验:确保每个调度项具备最小可用字段。
foreach (var item in ListCANScheduleConfigDto)
{
// UI 上的“发送方式”是全局下拉框,这里同步写回到每个子项,确保落库数据一致。
item.OrderSend = CurSendOrder == "0" ? 0 : 1;
if (string.IsNullOrEmpty(item.MsgName))
{
MessageBox.Show("消息名为空:请在【读写设置】-> 写入配置中选择报文后点击“加入定时调度表”,再回到此处设置周期。", "提示", MessageBoxButton.OK, MessageBoxImage.Hand);
return;
}
if (item.Cycle <= 0)
{
MessageBox.Show("请确认周期是否正确", "提示", MessageBoxButton.OK, MessageBoxImage.Hand);
return;
}
if (item.OrderSend >= 2)
{
MessageBox.Show("请确认发送方式是否正确", "提示", MessageBoxButton.OK, MessageBoxImage.Hand);
return;
}
}
//发送的控制帧都放到同一个调度表中,不需要检查了
////检查重复设置问题
//bool isRepeat = ListCANScheduleConfigDto.GroupBy(i => i.MsgName).Any(g => g.Count() > 1);
//if (isRepeat)
//{
// MessageBox.Show("请确认是否重复设置", "提示", MessageBoxButton.OK, MessageBoxImage.Hand);
// return;
//}
// Upsert逐项落库。
foreach (var item in ListCANScheduleConfigDto)
{
FreeSql.InsertOrUpdate<CANScheduleConfig>()
.SetSource(Mapper.Map<CANScheduleConfig>(item)).
ExecuteAffrows();
}
// 保存完成后重新加载:
// - 防止 UI 缓存与数据库实际数据不一致;
// - 同时也让新增项拿到真实 Id。
ListCANScheduleConfigDto = new ObservableCollection<CANScheduleConfigDto>(Mapper.Map<List<CANScheduleConfigDto>>(FreeSql.Select<CANScheduleConfig>().Where(a => a.CanLinConfigProId == SelectCanLinConfigProId).ToList()));
DialogParameters pars = new DialogParameters
{
{ "ReturnValue", ListCANScheduleConfigDto }
};
RaiseRequestClose(new DialogResult(ButtonResult.OK, pars));
}
private DelegateCommand cancelCmd;
/// <summary>
/// 取消命令。
/// </summary>
public DelegateCommand CancelCmd
{
set
{
cancelCmd = value;
}
get
{
if (cancelCmd == null)
{
cancelCmd = new DelegateCommand(() => CancelCmdMethod());
}
return cancelCmd;
}
}
/// <summary>
/// 取消命令方法。
/// </summary>
private void CancelCmdMethod()
{
RaiseRequestClose(new DialogResult(ButtonResult.Cancel));
}
/// <summary>
/// 弹窗打开时接收参数并初始化 UI。
/// 说明:
/// - ListMsg 用于构造消息名下拉框;
/// - ListCANScheduleConfigDto 用于回显现有调度表;
/// - SelectCanLinConfigProId 用于 Save 时按配置程序 id 过滤重载。
/// </summary>
/// <param name="parameters"></param>
public override void OnDialogOpened(IDialogParameters parameters)
{
if (parameters.ContainsKey("ListMsg"))
{
ListMsg = parameters.GetValue<List<string>>("ListMsg");
if (ListMsg != null)
{
// 转换为CbxItems集合都是文本内容
MsgCbxItems = new ObservableCollection<CbxItems>(
ListMsg.Select(value => new CbxItems
{
Key = value,
Text = value
}));
}
}
ListCANScheduleConfigDto = parameters.GetValue<ObservableCollection<CANScheduleConfigDto>>("ListCANScheduleConfigDto");
//防止返回的数据为空,就无法增加了
if (ListCANScheduleConfigDto == null) ListCANScheduleConfigDto = new ObservableCollection<CANScheduleConfigDto>();
//Name = parameters.GetValue<string>("Name");
if (ListCANScheduleConfigDto.Count > 0)
{
// 回显:默认取第一条的 OrderSend 作为当前下拉框选择。
CurSendOrder = ListCANScheduleConfigDto.FirstOrDefault()!.OrderSend.ToString();
}
else
{
// 默认:顺序发送。
CurSendOrder = "1";
}
SelectCanLinConfigProId = parameters.GetValue<long>("SelectCanLinConfigProId");
}
}
}