From b544d5cccd76735e034c8055918a50927b437474 Mon Sep 17 00:00:00 2001
From: wenxiangchao <wenxiangchao@ihengxin.com.cn>
Date: 星期二, 10 十一月 2026 08:29:04 +0800
Subject: [PATCH] fix: 维护模式重复进入失败与按钮灰死 + Broker 并发验证用例
---
Plugin.DeviceDebug/DeviceDebug.xaml.cs | 613 ++++++-------------------------------------------------
1 files changed, 74 insertions(+), 539 deletions(-)
diff --git a/Plugin.DeviceDebug/DeviceDebug.xaml.cs b/Plugin.DeviceDebug/DeviceDebug.xaml.cs
index dc82505..f82274d 100644
--- a/Plugin.DeviceDebug/DeviceDebug.xaml.cs
+++ b/Plugin.DeviceDebug/DeviceDebug.xaml.cs
@@ -4,58 +4,41 @@
using HMI.Core.Util;
using HMI.UI.Util;
using log4net;
-using Plugin.DeviceDebug.Entity;
using Plugin.DeviceDebug.Model;
-using Plugin.DeviceDebug.Panels;
using System;
+using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
-using System.Threading;
using System.Windows;
using System.Windows.Controls;
-using System.Windows.Media;
namespace Plugin.DeviceDebug
{
/// <summary>
- /// DeviceDebug.xaml 鐨勪氦浜掗�昏緫
+ /// 纭欢璋冭瘯鎻掍欢锛堝3锛夛細瑁呴厤骞舵寔鏈夊叡浜熀纭�璁炬柦锛堜細璇濈鐞嗗櫒/璁惧鏈嶅姟/閰嶇疆搴撹矾寰勶級锛�
+ /// 浠� TabControl 鎵胯浇澶氫釜 <see cref="DeviceDebugTab"/>锛屾敮鎸佸悓鏃惰皟璇曞涓澶囷紝
+ /// 姣忎釜 Tab 鎷ユ湁鐙珛浼氳瘽涓庣淮鎶ょ绾︺�傝澶囦笅鎷変粎鍒楀嚭灏氭湭鎵撳紑鐨勮澶囥��
/// </summary>
[ObservableObject]
public partial class DeviceDebug : SimpleMaskControl
{
- private static readonly ILog _log = LogManager.GetLogger(typeof(DeviceDebug));
+ private static readonly ILog log = LogManager.GetLogger(typeof(DeviceDebug));
private DeviceDebugModel _debugModel;
private DebugSessionManager _sessionManager;
- // 鍩虹璁炬柦灞傛湇鍔�
- private IDeviceManager? _deviceManager;
- private IDeviceService? _deviceService;
- private IResourceManager? _resourceManager;
+ private IDeviceManager _deviceManager;
+ private IDeviceService _deviceService;
+ private IResourceManager _resourceManager;
- // 璁惧閰嶇疆鏁版嵁搴撹矾寰勶紙涓� DeviceConfig 鎻掍欢鍏变韩锛�
private string _deviceConfigDbPath;
+
+ // 鍏ㄩ噺璁惧锛�"id [kind]"锛変笌宸叉墦寮�鏍囩鏄犲皠锛坉eviceId 鈫� TabItem锛�
+ private readonly List<string> _allDevices = new();
+ private readonly Dictionary<string, TabItem> _openTabs = new(StringComparer.OrdinalIgnoreCase);
[ObservableProperty] private ObservableCollection<string> _deviceList = new();
[ObservableProperty] private string _selectedDevice;
- [ObservableProperty] private DebugSession _currentSession;
- [ObservableProperty] private ObservableCollection<DebugOperation> _operationLogs = new();
- [ObservableProperty] private string _connectionStateText = "鏈繛鎺�";
- [ObservableProperty] private string _sessionStateText = "";
- [ObservableProperty] private string _reservationStatusText = "";
- [ObservableProperty] private string _currentDeviceId = "";
- [ObservableProperty] private string _currentDeviceKind = "";
- [ObservableProperty] private string _currentEffectiveVersion = "";
- [ObservableProperty] private string _currentEndpoint = "";
- [ObservableProperty] private string _currentDriverType = "";
- [ObservableProperty] private Brush _connectionBrush = new SolidColorBrush(Colors.Gray);
- [ObservableProperty] private Brush _sessionStateBrush = new SolidColorBrush(Colors.Gray);
- [ObservableProperty] private bool _canEnterMaintenance;
- [ObservableProperty] private bool _canExitMaintenance;
- [ObservableProperty] private bool _hasDevice;
-
- // 缂撳瓨褰撳墠閫変腑鐨勮澶囩被鍨�
- private string _currentDeviceKindStr;
public DeviceDebug()
{
@@ -63,13 +46,10 @@
InitializeComponent();
}
- /// <summary>
- /// 寮哄埗鍒锋柊璁惧鍒楄〃锛堜緵闆嗘垚娴嬭瘯棰勭疆璁惧鍚庤皟鐢級
- /// </summary>
public void ForceRefreshForTest()
{
try { LoadDeviceList(); }
- catch (Exception ex) { _log.Error("ForceRefreshForTest Error.", ex); }
+ catch (Exception ex) { log.Error("ForceRefreshForTest Error.", ex); }
}
public override void InitFinish()
@@ -77,21 +57,16 @@
base.InitFinish();
try
{
- // 鍒濆鍖栬皟璇曟暟鎹簱
_debugModel = new DeviceDebugModel();
string dbPath = Path.Combine(BaseFolder, "debug.db");
_debugModel.InitDatabase(dbPath);
- // 浠� UtilContainer 鑾峰彇鍩虹璁炬柦鏈嶅姟
var container = new UtilContainer();
_deviceManager = container.GetUtil<IDeviceManager>("DeviceManager");
_deviceService = container.GetUtil<IDeviceService>("DeviceService");
_resourceManager = container.GetUtil<IResourceManager>("ResourceManager");
- // 鍒涘缓浼氳瘽绠$悊鍣紙浼犲叆 ResourceManager锛�
_sessionManager = new DebugSessionManager(_debugModel, _resourceManager);
-
- // 璁惧閰嶇疆鏁版嵁搴撹矾寰勶紙涓� DeviceConfig 鍏变韩锛�
_deviceConfigDbPath = Path.Combine(BaseFolder, "data.db");
log.Info("纭欢璋冭瘯妯″潡鍒濆鍖栧畬鎴�");
@@ -103,9 +78,14 @@
}
}
- /// <summary>
- /// 鍔犺浇璁惧鍒楄〃
- /// </summary>
+ private void SimpleMaskControl_Loaded(object sender, RoutedEventArgs e)
+ {
+ LoadDeviceList();
+ Loaded -= SimpleMaskControl_Loaded;
+ }
+
+ private void RfhBtn_Click(object sender, RoutedEventArgs e) => LoadDeviceList();
+
private void LoadDeviceList()
{
try
@@ -120,16 +100,12 @@
var sqliteHelper = new SqliteHelper(_deviceConfigDbPath);
var dt = sqliteHelper.GetDataTable("SELECT DeviceId, Kind FROM DeviceDefinition ORDER BY DeviceId");
- var list = new ObservableCollection<string>();
+ _allDevices.Clear();
foreach (System.Data.DataRow row in dt.Rows)
- {
- string deviceId = row["DeviceId"].ToString();
- string kind = row["Kind"].ToString();
- list.Add($"{deviceId} [{kind}]");
- }
+ _allDevices.Add($"{row["DeviceId"]} [{row["Kind"]}]");
- DeviceList = list;
- log.Info($"鍔犺浇璁惧鍒楄〃瀹屾垚锛屽叡 {list.Count} 涓澶�");
+ RefreshAvailableList();
+ log.Info($"鍔犺浇璁惧鍒楄〃瀹屾垚锛屽叡 {_allDevices.Count} 涓澶�");
}
catch (Exception ex)
{
@@ -138,20 +114,23 @@
}
}
- /// <summary>
- /// 瑙f瀽璁惧閫夋嫨瀛楃涓诧紝鑾峰彇 DeviceId
- /// </summary>
- private string ParseDeviceId(string selection)
+ /// <summary>涓嬫媺浠呭垪鍑烘湭鎵撳紑鐨勮澶囷紙涓�浼氫竴璁惧锛夈��</summary>
+ private void RefreshAvailableList()
+ {
+ var avail = _allDevices
+ .Where(d => !_openTabs.ContainsKey(ParseDeviceId(d)))
+ .ToList();
+ DeviceList = new ObservableCollection<string>(avail);
+ }
+
+ private static string ParseDeviceId(string selection)
{
if (string.IsNullOrEmpty(selection)) return string.Empty;
int idx = selection.IndexOf(" [");
return idx > 0 ? selection.Substring(0, idx) : selection;
}
- /// <summary>
- /// 瑙f瀽璁惧閫夋嫨瀛楃涓诧紝鑾峰彇 Kind
- /// </summary>
- private string ParseDeviceKind(string selection)
+ private static string ParseDeviceKind(string selection)
{
if (string.IsNullOrEmpty(selection)) return string.Empty;
int start = selection.IndexOf(" [");
@@ -161,508 +140,64 @@
return string.Empty;
}
- /// <summary>
- /// 鍔犺浇璁惧璇︾粏淇℃伅
- /// </summary>
- private void LoadDeviceInfo(string deviceId)
- {
- try
- {
- if (!File.Exists(_deviceConfigDbPath)) return;
-
- var sqliteHelper = new SqliteHelper(_deviceConfigDbPath);
- var dt = sqliteHelper.GetDataTable(
- $"SELECT DeviceId, Kind, EffectiveVersion, Endpoint, DriverType FROM DeviceDefinition WHERE DeviceId = '{deviceId}'");
-
- if (dt.Rows.Count > 0)
- {
- var row = dt.Rows[0];
- CurrentDeviceId = row["DeviceId"].ToString();
- CurrentDeviceKind = row["Kind"].ToString();
- CurrentEffectiveVersion = row["EffectiveVersion"]?.ToString() ?? "";
- CurrentEndpoint = row["Endpoint"]?.ToString() ?? "";
- CurrentDriverType = row["DriverType"]?.ToString() ?? "";
-
- // 缂撳瓨璁惧绫诲瀷
- _currentDeviceKindStr = CurrentDeviceKind;
- }
- }
- catch (Exception ex)
- {
- log.Error($"鍔犺浇璁惧淇℃伅澶辫触: {deviceId}", ex);
- }
- }
-
- /// <summary>
- /// 閫夋嫨璁惧鏃讹細鎵撳紑浼氳瘽锛圧eadOnly锛夛紝鍔犺浇瀵瑰簲闈㈡澘
- /// </summary>
- private void OnDeviceSelected()
+ private void AddDeviceBtn_Click(object sender, RoutedEventArgs e)
{
try
{
if (string.IsNullOrEmpty(SelectedDevice))
{
- HasDevice = false;
- panelContainer.Content = new TextBlock
- {
- Text = "璇烽�夋嫨璁惧",
- HorizontalAlignment = HorizontalAlignment.Center,
- VerticalAlignment = VerticalAlignment.Center,
- FontSize = 16,
- Foreground = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#999"))
- };
+ ToastHelper.Warning("璇峰厛鍦ㄨ澶囦笅鎷変腑閫夋嫨璁惧");
return;
}
-
string deviceId = ParseDeviceId(SelectedDevice);
string kind = ParseDeviceKind(SelectedDevice);
- // 鍔犺浇璁惧璇︾粏淇℃伅
- LoadDeviceInfo(deviceId);
-
- HasDevice = true;
-
- // 鎵撳紑浼氳瘽锛圧eadOnly锛�
- CurrentSession = _sessionManager.OpenSession(deviceId, "", "operator", CurrentEffectiveVersion);
-
- // 閫氳繃 DeviceManager 杩炴帴璁惧
- if (_deviceManager != null)
+ // 宸叉墦寮�鍒欒仛鐒﹀叾 Tab锛堥槻寰℃�э細涓嬫媺鏈凡杩囨护锛�
+ if (_openTabs.TryGetValue(deviceId, out var existing))
{
- try
- {
- _deviceManager.ConnectAsync(deviceId, CancellationToken.None)
- .GetAwaiter().GetResult();
- ConnectionStateText = "宸茶繛鎺�";
- ConnectionBrush = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#4CAF50"));
- }
- catch (Exception ex)
- {
- log.Warn($"閫氳繃 DeviceManager 杩炴帴璁惧澶辫触: {ex.Message}");
- ConnectionStateText = "杩炴帴澶辫触";
- ConnectionBrush = new SolidColorBrush(Colors.OrangeRed);
- }
- }
-
- // 鍔犺浇鎿嶄綔鏃ュ織
- LoadOperationLogs();
-
- // 鏇存柊鎸夐挳鐘舵��
- UpdateButtonStates();
-
- // 鍔犺浇瀵瑰簲闈㈡澘
- LoadPanel(kind);
-
- log.Info($"宸查�夋嫨璁惧: {deviceId}, 绫诲瀷: {kind}");
- }
- catch (Exception ex)
- {
- log.Error("閫夋嫨璁惧澶辫触", ex);
- ToastHelper.Error($"閫夋嫨璁惧澶辫触: {ex.Message}");
- }
- }
-
- /// <summary>
- /// 鏍规嵁璁惧绫诲瀷鍔犺浇瀵瑰簲鐨勮皟璇曢潰鏉�
- /// </summary>
- private void LoadPanel(string deviceKind)
- {
- try
- {
- UIElement panel = null;
-
- switch (deviceKind)
- {
- case "PowerSupply":
- var powerPanel = new PowerSupplyDebugPanel();
- powerPanel.IsMaintenanceMode = CurrentSession?.State == DebugSessionState.MaintenanceActive;
- powerPanel.OnCommandExecute += Panel_OnCommandExecute;
- panel = powerPanel;
- break;
- case "CanDevice":
- var canPanel = new CanDebugPanel
- {
- DeviceId = CurrentDeviceId,
- InitialBusName = ParseCanBusName(CurrentEndpoint),
- InitialNodeIndex = ParseCanNodeIndex(CurrentEndpoint),
- AutoConnectOnLoad = true
- };
- canPanel.IsMaintenanceMode = CurrentSession?.State == DebugSessionState.MaintenanceActive;
- canPanel.OnCommandExecute += Panel_OnCommandExecute;
- panel = canPanel;
- break;
- case "PlcDevice":
- var plcPanel = new PlcDebugPanel();
- plcPanel.IsMaintenanceMode = CurrentSession?.State == DebugSessionState.MaintenanceActive;
- plcPanel.OnCommandExecute += Panel_OnCommandExecute;
- panel = plcPanel;
- break;
- default:
- panel = new TextBlock
- {
- Text = $"涓嶆敮鎸佺殑璁惧绫诲瀷: {deviceKind}",
- HorizontalAlignment = HorizontalAlignment.Center,
- VerticalAlignment = VerticalAlignment.Center,
- FontSize = 14,
- Foreground = new SolidColorBrush(Colors.OrangeRed)
- };
- break;
- }
-
- panelContainer.Content = panel;
- }
- catch (Exception ex)
- {
- log.Error($"鍔犺浇璋冭瘯闈㈡澘澶辫触: {deviceKind}", ex);
- ToastHelper.Error($"鍔犺浇闈㈡澘澶辫触: {ex.Message}");
- }
- }
-
- /// <summary>
- /// 闈㈡澘鍛戒护鎵ц浜嬩欢澶勭悊
- /// </summary>
- private void Panel_OnCommandExecute(object sender, DebugCommand command)
- {
- try
- {
- if (CurrentSession == null)
- {
- ToastHelper.Warning("璇峰厛閫夋嫨璁惧");
- return;
- }
-
- // 楠岃瘉鍛戒护鏉冮檺
- if (!_sessionManager.ValidateCommand(CurrentSession.SessionId, command))
- {
- ToastHelper.Warning("褰撳墠浼氳瘽鐘舵�佷笉鍏佽鎵ц姝ゆ搷浣滐紝璇峰厛杩涘叆缁存姢妯″紡");
- return;
- }
-
- // 閫氳繃 DeviceService 鎵ц瀹為檯鍛戒护
- if (_deviceService != null)
- {
- ExecuteViaDeviceService(command);
- }
- else
- {
- // 闄嶇骇妯″紡锛氬熀纭�璁炬柦鏈垵濮嬪寲鏃朵繚鐣欏師鏈夎涓�
- log.Warn("DeviceService 鏈垵濮嬪寲锛屼娇鐢ㄩ檷绾фā寮忚褰曞懡浠�");
- ExecuteFallback(command);
- }
- }
- catch (Exception ex)
- {
- log.Error($"鎵ц鍛戒护澶辫触: {command.CommandType}", ex);
- ToastHelper.Error($"鍛戒护鎵ц澶辫触: {ex.Message}");
-
- // 璁板綍澶辫触鎿嶄綔
- var operation = new DebugOperation
- {
- SessionId = CurrentSession?.SessionId ?? "",
- CommandType = command.CommandType,
- Parameters = SerializeParameters(command),
- Outcome = "Failed",
- ErrorMessage = ex.Message,
- Timestamp = DateTime.Now
- };
- _debugModel.RecordOperation(operation);
- OperationLogs.Insert(0, operation);
- }
- }
-
- /// <summary>
- /// 閫氳繃 DeviceService 鎵ц璁惧鍛戒护
- /// </summary>
- private void ExecuteViaDeviceService(DebugCommand command)
- {
- try
- {
- var ownerToken = new ResourceOwnerToken(
- OwnerType.Maintenance,
- CurrentSession.SessionId);
-
- var deviceCommand = BuildDeviceCommand(command);
-
- var result = _deviceService.ExecuteCommandAsync(
- command.DeviceId,
- deviceCommand,
- ownerToken,
- CancellationToken.None).GetAwaiter().GetResult();
-
- var operation = new DebugOperation
- {
- SessionId = CurrentSession.SessionId,
- CommandType = command.CommandType,
- Parameters = SerializeParameters(command),
- Outcome = result.Success ? "Success" : "Failed",
- DeviceReadback = result.Readback ?? "",
- ErrorCode = result.ErrorCode ?? "",
- ErrorMessage = result.ErrorMessage ?? "",
- Timestamp = DateTime.Now
- };
-
- _debugModel.RecordOperation(operation);
- OperationLogs.Insert(0, operation);
-
- if (result.Success)
- ToastHelper.Success($"鍛戒护 {command.CommandType} 鎵ц鎴愬姛");
- else
- ToastHelper.Warning($"鍛戒护鎵ц澶辫触: {result.ErrorMessage}");
-
- log.Info($"鎵ц鍛戒护: {command.CommandType}, 璁惧: {command.DeviceId}, 缁撴灉: {(result.Success ? "鎴愬姛" : "澶辫触")}");
- }
- catch (Exception ex)
- {
- log.Error($"DeviceService 鎵ц鍛戒护澶辫触: {ex.Message}", ex);
- ToastHelper.Error($"璁惧閫氫俊澶辫触: {ex.Message}");
-
- var operation = new DebugOperation
- {
- SessionId = CurrentSession.SessionId,
- CommandType = command.CommandType,
- Parameters = SerializeParameters(command),
- Outcome = "Failed",
- ErrorMessage = ex.Message,
- Timestamp = DateTime.Now
- };
- _debugModel.RecordOperation(operation);
- OperationLogs.Insert(0, operation);
- }
- }
-
- /// <summary>
- /// 闄嶇骇妯″紡锛氭棤 DeviceService 鏃剁殑鍚庡澶勭悊
- /// </summary>
- private void ExecuteFallback(DebugCommand command)
- {
- var operation = new DebugOperation
- {
- SessionId = CurrentSession.SessionId,
- CommandType = command.CommandType,
- Parameters = SerializeParameters(command),
- Outcome = "Success",
- Timestamp = DateTime.Now
- };
-
- _debugModel.RecordOperation(operation);
- OperationLogs.Insert(0, operation);
-
- ToastHelper.Success($"鍛戒护 {command.CommandType} 宸插彂閫侊紙闄嶇骇妯″紡锛�");
- log.Info($"[闄嶇骇妯″紡] 鎵ц鍛戒护: {command.CommandType}, 璁惧: {command.DeviceId}");
- }
-
- /// <summary>
- /// 鏍规嵁鍛戒护绫诲瀷鏋勫缓瀹為檯璁惧鍛戒护瀛楃涓�
- /// </summary>
- private string BuildDeviceCommand(DebugCommand command)
- {
- if (command is PowerSetCommand psc)
- {
- return $"VOLT {psc.Voltage};CURR {psc.CurrentLimit};OUTP {(psc.Output ? "ON" : "OFF")}";
- }
- else if (command is PowerMeasureCommand)
- {
- return "MEAS:ALL?";
- }
- else if (command is CanSendCommand csc)
- {
- return $"CAN:SEND {csc.Frame}";
- }
- else if (command is PlcWriteCommand pwc)
- {
- return $"WRITE:{pwc.IoAddress}:{(pwc.Value ? "TRUE" : "FALSE")}";
- }
- return command.CommandType;
- }
-
- /// <summary>
- /// 搴忓垪鍖栧懡浠ゅ弬鏁颁负JSON瀛楃涓�
- /// </summary>
- private string SerializeParameters(DebugCommand command)
- {
- try
- {
- switch (command)
- {
- case PowerSetCommand psc:
- return $"{{Voltage:{psc.Voltage},CurrentLimit:{psc.CurrentLimit},Output:{psc.Output}}}";
- case PowerMeasureCommand _:
- return "{}";
- case CanSendCommand csc:
- return $"{{Frame:{csc.Frame},Data:{BitConverter.ToString(csc.Data)}}}";
- case PlcWriteCommand pwc:
- return $"{{IoAddress:{pwc.IoAddress},Value:{pwc.Value}}}";
- default:
- return "{}";
- }
- }
- catch
- {
- return "{}";
- }
- }
-
- /// <summary>
- /// 鍔犺浇鎿嶄綔鏃ュ織
- /// </summary>
- private void LoadOperationLogs()
- {
- try
- {
- if (CurrentSession == null) return;
-
- var ops = _debugModel.GetOperationsBySession(CurrentSession.SessionId);
- OperationLogs = new ObservableCollection<DebugOperation>(ops.Take(100));
- }
- catch (Exception ex)
- {
- log.Error("鍔犺浇鎿嶄綔鏃ュ織澶辫触", ex);
- }
- }
-
- /// <summary>
- /// 鏇存柊鎸夐挳鍚敤鐘舵��
- /// </summary>
- private void UpdateButtonStates()
- {
- if (CurrentSession == null)
- {
- CanEnterMaintenance = false;
- CanExitMaintenance = false;
- SessionStateText = "";
- return;
- }
-
- var state = CurrentSession.State;
- CanEnterMaintenance = state == DebugSessionState.ReadOnly;
- CanExitMaintenance = state == DebugSessionState.MaintenanceActive;
-
- // 鏇存柊浼氳瘽鐘舵�佹枃鏈拰棰滆壊
- SessionStateText = state.ToString();
- SessionStateBrush = state switch
- {
- DebugSessionState.ReadOnly => new SolidColorBrush((Color)ColorConverter.ConvertFromString("#2196F3")),
- DebugSessionState.MaintenanceActive => new SolidColorBrush((Color)ColorConverter.ConvertFromString("#4CAF50")),
- DebugSessionState.Faulted => new SolidColorBrush(Colors.Red),
- DebugSessionState.RecoveryRequired => new SolidColorBrush(Colors.Orange),
- _ => new SolidColorBrush(Colors.Gray)
- };
-
- // 鏇存柊闈㈡澘鐨勭淮鎶ゆā寮�
- if (panelContainer.Content is PowerSupplyDebugPanel powerPanel)
- powerPanel.IsMaintenanceMode = state == DebugSessionState.MaintenanceActive;
- else if (panelContainer.Content is CanDebugPanel canPanel)
- canPanel.IsMaintenanceMode = state == DebugSessionState.MaintenanceActive;
- else if (panelContainer.Content is PlcDebugPanel plcPanel)
- plcPanel.IsMaintenanceMode = state == DebugSessionState.MaintenanceActive;
- }
-
- #region 浜嬩欢澶勭悊
-
- private void SimpleMaskControl_Loaded(object sender, RoutedEventArgs e)
- {
- LoadDeviceList();
- Loaded -= SimpleMaskControl_Loaded;
- }
-
- private void DeviceSelector_SelectionChanged(object sender, SelectionChangedEventArgs e)
- {
- OnDeviceSelected();
- }
-
- private void RfhBtn_Click(object sender, RoutedEventArgs e)
- {
- LoadDeviceList();
- }
-
- private void EnterMaintenanceBtn_Click(object sender, RoutedEventArgs e)
- {
- try
- {
- if (CurrentSession == null) return;
-
- // 璇锋眰缁存姢妯″紡
- if (_sessionManager.RequestMaintenance(CurrentSession.SessionId))
- {
- // 婵�娲荤淮鎶ゆā寮�
- _sessionManager.ActivateMaintenance(CurrentSession.SessionId);
- UpdateButtonStates();
-
- // 閲嶆柊鍔犺浇闈㈡澘浠ユ洿鏂癐sMaintenanceMode
- LoadPanel(CurrentDeviceKind);
-
- ToastHelper.Success("宸茶繘鍏ョ淮鎶ゆ帶鍒舵ā寮�");
- log.Info($"浼氳瘽 {CurrentSession.SessionId} 杩涘叆缁存姢妯″紡");
- }
- else
- {
- ToastHelper.Warning("鏃犳硶杩涘叆缁存姢妯″紡锛岃妫�鏌ヨ澶囩姸鎬�");
- }
- }
- catch (Exception ex)
- {
- log.Error("杩涘叆缁存姢妯″紡澶辫触", ex);
- ToastHelper.Error($"杩涘叆缁存姢妯″紡澶辫触: {ex.Message}");
- }
- }
-
- private void ExitMaintenanceBtn_Click(object sender, RoutedEventArgs e)
- {
- try
- {
- if (CurrentSession == null) return;
-
- if (MsgBoxHelper.WarnMessage(Window.GetWindow(this), "纭畾瑕侀��鍑虹淮鎶ゆā寮忓悧锛�") == MessageBoxResult.OK)
- {
- _sessionManager.CloseSession(CurrentSession.SessionId);
- CurrentSession = null;
- UpdateButtonStates();
-
- // 娓呯┖闈㈡澘
- panelContainer.Content = new TextBlock
- {
- Text = "璇烽�夋嫨璁惧",
- HorizontalAlignment = HorizontalAlignment.Center,
- VerticalAlignment = VerticalAlignment.Center,
- FontSize = 16,
- Foreground = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#999"))
- };
-
- HasDevice = false;
+ debugTabs.SelectedItem = existing;
SelectedDevice = null;
-
- ToastHelper.Success("宸查��鍑虹淮鎶ゆā寮�");
- log.Info("宸查��鍑虹淮鎶ゆā寮�");
+ return;
}
+
+ var tabContent = new DeviceDebugTab();
+ tabContent.Initialize(_debugModel, _sessionManager, _deviceManager, _deviceService,
+ _deviceConfigDbPath, deviceId, kind);
+
+ var tab = new TabItem { Header = deviceId, Content = tabContent, Tag = deviceId };
+ debugTabs.Items.Add(tab);
+ debugTabs.SelectedItem = tab;
+ _openTabs[deviceId] = tab;
+
+ RefreshAvailableList();
+ SelectedDevice = null;
+ log.Info($"宸插姞鍏ヨ皟璇曡澶�: {deviceId}锛堝綋鍓� {debugTabs.Items.Count} 涓爣绛撅級");
}
catch (Exception ex)
{
- log.Error("閫�鍑虹淮鎶ゆā寮忓け璐�", ex);
- ToastHelper.Error($"閫�鍑虹淮鎶ゆā寮忓け璐�: {ex.Message}");
+ log.Error("鍔犲叆璋冭瘯璁惧澶辫触", ex);
+ ToastHelper.Error($"鍔犲叆璋冭瘯澶辫触: {ex.Message}");
}
}
- /// <summary>
- /// 浠� CAN Endpoint 瑙f瀽鎬荤嚎鍚嶇О锛堟牸寮�: 鎬荤嚎鍚�:鑺傜偣缂栧彿锛�
- /// </summary>
- private string ParseCanBusName(string endpoint)
+ private void CloseTabBtn_Click(object sender, RoutedEventArgs e)
{
- if (string.IsNullOrEmpty(endpoint)) return "CAN_BUS_1";
- int idx = endpoint.IndexOf(':');
- return idx > 0 ? endpoint.Substring(0, idx) : endpoint;
+ try
+ {
+ if (debugTabs.SelectedItem is not TabItem tab) return;
+ string deviceId = tab.Tag as string ?? "";
+ if (tab.Content is DeviceDebugTab content)
+ content.CloseSessionSilently(); // 鍏抽棴鍗抽噴鏀剧淮鎶ょ绾︼紝鏉滅粷娉勬紡
+ debugTabs.Items.Remove(tab);
+ if (!string.IsNullOrEmpty(deviceId)) _openTabs.Remove(deviceId);
+ RefreshAvailableList();
+ log.Info($"宸插叧闂皟璇曟爣绛惧苟閲婃斁浼氳瘽: {deviceId}");
+ }
+ catch (Exception ex)
+ {
+ log.Error("鍏抽棴璋冭瘯鏍囩澶辫触", ex);
+ ToastHelper.Error($"鍏抽棴澶辫触: {ex.Message}");
+ }
}
-
- /// <summary>
- /// 浠� CAN Endpoint 瑙f瀽鑺傜偣缂栧彿
- /// </summary>
- private int? ParseCanNodeIndex(string endpoint)
- {
- if (string.IsNullOrEmpty(endpoint)) return 0;
- int idx = endpoint.IndexOf(':');
- if (idx > 0 && idx < endpoint.Length - 1 && int.TryParse(endpoint.Substring(idx + 1), out int n))
- return n;
- return 0;
- }
-
- #endregion
}
}
--
Gitblit v1.9.1