This commit is contained in:
2026-03-02 11:20:08 +08:00
parent 74338fdb3a
commit 5be18ded2e
21 changed files with 5984 additions and 224 deletions

View File

@@ -27,6 +27,44 @@ namespace CapMachine.Wpf.ViewModels
private long _canLinConfigProId;
private bool _enableHardwareCycleSchedule = true;
private bool _useCanFdSchedule;
/// <summary>
/// 是否启用“加入定时调度表ZLG auto_send”能力。
/// 说明:该能力仅适用于 ZLG CAN/CANFD 硬件 auto_sendLIN 当前使用软件调度,不允许写入 CANScheduleConfig。
/// </summary>
public bool EnableHardwareCycleSchedule
{
get { return _enableHardwareCycleSchedule; }
private set
{
_enableHardwareCycleSchedule = value;
RaisePropertyChanged();
RaisePropertyChanged(nameof(CanAddCycleTimeSch));
}
}
/// <summary>
/// 是否允许执行“加入定时调度表”操作。
/// 说明:
/// - 需要 <see cref="EnableHardwareCycleSchedule"/> 打开(调用方允许硬件调度表能力);
/// - 且弹窗处于可编辑态(<see cref="IsEditable"/>)。
/// </summary>
public bool CanAddCycleTimeSch
{
get { return EnableHardwareCycleSchedule && IsEditable; }
}
/// <summary>
/// 是否使用 CANFD 调度表(决定“加入定时调度表”写入 <see cref="CANFdScheduleConfig"/> 还是 <see cref="CANScheduleConfig"/>)。
/// </summary>
public bool UseCanFdSchedule
{
get { return _useCanFdSchedule; }
private set { _useCanFdSchedule = value; RaisePropertyChanged(); }
}
/// <summary>
/// 构造函数。
/// </summary>
@@ -153,6 +191,105 @@ namespace CapMachine.Wpf.ViewModels
/// </summary>
public CanLinRWConfigDto? SelectedWriteConfig { get; set; }
private DelegateCommand? _addCycleTimeSch;
/// <summary>
/// 将当前选中的写入配置对应的报文加入“硬件定时调度表”ZLG auto_send
/// </summary>
/// <remarks>
/// 说明:
/// - 调度表按“报文/帧MsgFrameName”维度配置同一报文可包含多个写入信号但调度表只需要一条。
/// - 该命令会直接落库到 <see cref="CANScheduleConfig"/>,随后由主界面刷新配置程序时加载显示。
/// </remarks>
public DelegateCommand AddCycleTimeSch => _addCycleTimeSch ??= new DelegateCommand(AddCycleTimeSchMethod);
/// <summary>
/// 加入定时调度表命令处理。
/// </summary>
private void AddCycleTimeSchMethod()
{
if (!EnableHardwareCycleSchedule)
{
MessageBox.Show("当前模式不支持加入硬件定时调度表LIN 使用软件调度表)", "提示", MessageBoxButton.OK, MessageBoxImage.Hand);
return;
}
if (!IsEditable)
{
MessageBox.Show("当前状态禁止修改", "提示", MessageBoxButton.OK, MessageBoxImage.Hand);
return;
}
if (_canLinConfigProId <= 0)
{
MessageBox.Show("配置程序ID无效无法加入调度表", "提示", MessageBoxButton.OK, MessageBoxImage.Hand);
return;
}
if (SelectedWriteConfig == null)
{
MessageBox.Show("请先选中写入配置中的一行", "提示", MessageBoxButton.OK, MessageBoxImage.Hand);
return;
}
if (string.IsNullOrWhiteSpace(SelectedWriteConfig.MsgFrameName))
{
MessageBox.Show("写入配置的【消息名称】为空,无法加入调度表", "提示", MessageBoxButton.OK, MessageBoxImage.Hand);
return;
}
var msgName = SelectedWriteConfig.MsgFrameName.Trim();
try
{
var exists = UseCanFdSchedule
? _freeSql.Select<CANFdScheduleConfig>()
.Where(a => a.CanLinConfigProId == _canLinConfigProId)
.Where(a => a.MsgName == msgName)
.Any()
: _freeSql.Select<CANScheduleConfig>()
.Where(a => a.CanLinConfigProId == _canLinConfigProId)
.Where(a => a.MsgName == msgName)
.Any();
if (exists)
{
MessageBox.Show($"该报文已在定时调度表中:{msgName}", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
return;
}
if (UseCanFdSchedule)
{
_freeSql.Insert<CANFdScheduleConfig>(new CANFdScheduleConfig
{
CanLinConfigProId = _canLinConfigProId,
MsgName = msgName,
Cycle = 100,
OrderSend = 1,
SchTabIndex = 0,
}).ExecuteAffrows();
}
else
{
_freeSql.Insert<CANScheduleConfig>(new CANScheduleConfig
{
CanLinConfigProId = _canLinConfigProId,
MsgName = msgName,
Cycle = 100,
OrderSend = 1,
SchTabIndex = 0,
}).ExecuteAffrows();
}
MessageBox.Show($"已加入定时调度表:{msgName}(默认周期 100ms可在调度表中修改", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
}
catch (Exception ex)
{
_logService.Error($"加入定时调度表失败:{msgName}{ex}");
MessageBox.Show(ex.Message, "错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
/// <summary>
/// 当前选中的读取配置行。
/// </summary>
@@ -402,8 +539,18 @@ namespace CapMachine.Wpf.ViewModels
{
_canLinConfigProId = parameters.GetValue<long>("CanLinConfigProId");
EnableHardwareCycleSchedule = parameters.ContainsKey("EnableHardwareCycleSchedule")
? parameters.GetValue<bool>("EnableHardwareCycleSchedule")
: true;
// 兼容参数命名:调用方传入的 key 为 "IsCanFdSchedule"。
UseCanFdSchedule = parameters.ContainsKey("IsCanFdSchedule")
? parameters.GetValue<bool>("IsCanFdSchedule")
: false;
IsEditable = parameters.ContainsKey("IsEditable") ? parameters.GetValue<bool>("IsEditable") : true;
RaisePropertyChanged(nameof(IsEditable));
RaisePropertyChanged(nameof(CanAddCycleTimeSch));
if (parameters.ContainsKey("WriteConfigs"))
{
@@ -557,6 +704,9 @@ namespace CapMachine.Wpf.ViewModels
var desiredAll = desiredWrite.Concat(desiredRead).ToList();
// 以 (RWInfo + SignalName) 作为“业务主键”对齐数据库:
// - desiredKeySet本次保存期望存在的 key 集合
// - existingByKey当前数据库已存在的 key -> 实体
var desiredKeySet = new HashSet<string>(desiredAll.Select(a => BuildKey(a.Rw, a.SignalName)), StringComparer.Ordinal);
var existingByKey = existing.ToDictionary(a => BuildKey(a.RWInfo, a.SignalName ?? string.Empty), a => a, StringComparer.Ordinal);
@@ -566,6 +716,7 @@ namespace CapMachine.Wpf.ViewModels
var key = BuildKey(old.RWInfo, old.SignalName ?? string.Empty);
if (!desiredKeySet.Contains(key))
{
// 保持与 UI 一致:用户在弹窗中移除的项,需要同步删除数据库记录。
_freeSql.Delete<CanLinRWConfig>(old.Id).ExecuteAffrows();
}
}