using AutoMapper; using CapMachine.Core; using CapMachine.Model.CANLIN; using CapMachine.Wpf.Dtos; using Prism.Commands; using Prism.Services.Dialogs; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Windows; namespace CapMachine.Wpf.ViewModels { /// /// ZLG CAN FD 调度表配置弹窗 ViewModel。 /// 说明: /// - 调度表项本身由“读写设置”弹窗中的“加入定时调度表”能力生成,这里主要负责: /// 1) 设置发送方式(并行/顺序) /// 2) 配置周期(Cycle) /// 3) 删除与保存落库 /// - 保存时会使用 InsertOrUpdate 做 Upsert,并在保存完成后从数据库重载,作为权威数据再回传给调用方。 /// public class DialogZlgCANFDSchConfigViewModel : DialogViewModel { /// /// 构造函数。 /// /// FreeSql。 /// AutoMapper。 public DialogZlgCANFDSchConfigViewModel(IFreeSql freeSql, IMapper mapper) { Title = "调度表 CANFD 配置"; FreeSql = freeSql; Mapper = mapper; SendOrderCbxItems = new ObservableCollection() { new CbxItems(){ Key="0", Text="并行", }, new CbxItems(){ Key="1", Text="顺序", }, }; SchTabIndexCbxItems = new ObservableCollection() { new CbxItems(){ Key="0", Text="0", }, }; } /// /// FreeSql。 /// public IFreeSql FreeSql { get; } /// /// AutoMapper。 /// public IMapper Mapper { get; } private ObservableCollection _listCANFdScheduleConfigDto = new ObservableCollection(); /// /// CAN FD 调度表数据集合。 /// public ObservableCollection ListCANFdScheduleConfigDto { get { return _listCANFdScheduleConfigDto; } set { _listCANFdScheduleConfigDto = value; RaisePropertyChanged(); } } /// /// 消息名列表。 /// public List? ListMsg { get; set; } private ObservableCollection _msgCbxItems; /// /// 消息名称下拉框数据。 /// public ObservableCollection MsgCbxItems { get { return _msgCbxItems; } set { _msgCbxItems = value; RaisePropertyChanged(); } } /// /// 选中的程序 Id。 /// public long SelectCanLinConfigProId { get; set; } private ObservableCollection _sendOrderCbxItems; /// /// 发送方式集合。 /// public ObservableCollection SendOrderCbxItems { get { return _sendOrderCbxItems; } set { _sendOrderCbxItems = value; RaisePropertyChanged(); } } private string? _curSendOrder; /// /// 当前发送方式。 /// public string? CurSendOrder { get { return _curSendOrder; } set { _curSendOrder = value; RaisePropertyChanged(); } } private ObservableCollection _schTabIndexCbxItems; /// /// 调度器序号集合。 /// public ObservableCollection SchTabIndexCbxItems { get { return _schTabIndexCbxItems; } set { _schTabIndexCbxItems = value; RaisePropertyChanged(); } } private CANFdScheduleConfigDto _curSelectedItem; /// /// 当前选中项。 /// public CANFdScheduleConfigDto CurSelectedItem { get { return _curSelectedItem; } set { _curSelectedItem = value; RaisePropertyChanged(); } } private DelegateCommand _gridSelectionChangedCmd; /// /// DataGrid 选中行变化。 /// public DelegateCommand GridSelectionChangedCmd { get { if (_gridSelectionChangedCmd == null) { _gridSelectionChangedCmd = new DelegateCommand(GridSelectionChangedCmdMethod); } return _gridSelectionChangedCmd; } } /// /// 选中行变化处理。 /// /// 选中项。 private void GridSelectionChangedCmdMethod(object par) { var selected = par as CANFdScheduleConfigDto; if (selected != null) { CurSelectedItem = selected; } } private DelegateCommand _opCmd; /// /// 操作命令(删除)。 /// public DelegateCommand OpCmd { get { if (_opCmd == null) { _opCmd = new DelegateCommand(OpCmdCall); } return _opCmd; } } /// /// 操作命令处理。 /// /// 参数。 private void OpCmdCall(string par) { switch (par) { case "Add": MessageBox.Show("调度表项由【读写设置】中的写入配置通过“加入定时调度表”生成,这里不支持新增。", "提示", MessageBoxButton.OK, MessageBoxImage.Hand); break; case "Delete": if (CurSelectedItem != null) { FreeSql.Delete(CurSelectedItem.Id).ExecuteAffrows(); ListCANFdScheduleConfigDto.Remove(CurSelectedItem); CurSelectedItem = null; } else { MessageBox.Show("请选中后再进行【删除】操作?", "提示", MessageBoxButton.OK, MessageBoxImage.Hand); } break; default: break; } } private DelegateCommand _saveCmd; /// /// 保存命令。 /// public DelegateCommand SaveCmd { get { if (_saveCmd == null) { _saveCmd = new DelegateCommand(SaveCmdMethod); } return _saveCmd; } } /// /// 保存命令处理。 /// private void SaveCmdMethod() { // 校验:确保每个调度项具备最小可用字段,避免落库无效配置。 foreach (var item in ListCANFdScheduleConfigDto) { // 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; } } foreach (var item in ListCANFdScheduleConfigDto) { // Upsert:逐项落库。 FreeSql.InsertOrUpdate() .SetSource(Mapper.Map(item)) .ExecuteAffrows(); } // 保存完成后重载: // - 避免 UI 集合与数据库实际数据不一致; // - 同时让新增项获取真实 Id。 ListCANFdScheduleConfigDto = new ObservableCollection( Mapper.Map>( FreeSql.Select() .Where(a => a.CanLinConfigProId == SelectCanLinConfigProId) .ToList())); DialogParameters pars = new DialogParameters { { "ReturnValue", ListCANFdScheduleConfigDto } }; RaiseRequestClose(new DialogResult(ButtonResult.OK, pars)); } private DelegateCommand _cancelCmd; /// /// 取消命令。 /// public DelegateCommand CancelCmd { get { if (_cancelCmd == null) { _cancelCmd = new DelegateCommand(CancelCmdMethod); } return _cancelCmd; } } /// /// 取消命令处理。 /// private void CancelCmdMethod() { RaiseRequestClose(new DialogResult(ButtonResult.Cancel)); } /// /// 弹窗打开时参数接收并初始化 UI。 /// 说明: /// - ListMsg:用于构造消息名下拉框(候选); /// - ListCANFdScheduleConfigDto:用于回显当前调度表; /// - SelectCanLinConfigProId:用于 Save 后按配置程序 id 重载。 /// /// 参数。 public override void OnDialogOpened(IDialogParameters parameters) { if (parameters.ContainsKey("ListMsg")) { ListMsg = parameters.GetValue>("ListMsg"); if (ListMsg != null) { // 转换为 CbxItems 集合(Key/Text 都使用消息名)。 MsgCbxItems = new ObservableCollection( ListMsg.Select(value => new CbxItems { Key = value, Text = value })); } } ListCANFdScheduleConfigDto = parameters.GetValue>("ListCANFdScheduleConfigDto"); if (ListCANFdScheduleConfigDto == null) ListCANFdScheduleConfigDto = new ObservableCollection(); if (ListCANFdScheduleConfigDto.Count > 0) { // 回显:默认取第一条的 OrderSend。 CurSendOrder = ListCANFdScheduleConfigDto.FirstOrDefault()!.OrderSend.ToString(); } else { // 默认:顺序发送。 CurSendOrder = "1"; } SelectCanLinConfigProId = parameters.GetValue("SelectCanLinConfigProId"); } } }