refactor: 插件窗体由 static 单例状态改为实例字段(对齐 TextViewer)

将 10 个 CycleGUI 窗体/管理器从进程级 static 单例状态改为实例字段 + 实例方法,
消除本地端/Web 端共享同一可变状态的隐患(对齐 TextViewer 正例)。

每个类保留一个 private static _instance 单实例持有者;静态入口 Open()/OpenViewer()
与实例 Show() 均转发到该实例,调用方零改动、单实例“置前”行为不变。

涉及:ChargeStationManagementForm、ChargeStrategyConfigForm、CommunicationMonitorForm、
AlarmConfigManagementForm、ButtonBoxManager、DoorManager、DoorMonitor、
LoopViewer、DeliveryViewer、TrafficInterlockViewer。

构建:dotnet build StandardScene.sln --no-incremental → 0 错误,30 警告(与基线一致,无新增)。
This commit is contained in:
zhaowei.huang
2026-06-26 15:31:02 +08:00
parent a0dc1e6cd0
commit 54cda958db
10 changed files with 297 additions and 257 deletions
@@ -18,29 +18,33 @@ namespace StandardScene.Charge
public class ChargeStationManagementForm
{
private const string TableId = "charge-station-list";
private static readonly string[] StatusFilterNames = { "全部状态", "空闲", "充电中", "故障", "离线" };
private static readonly string[] TypeNames = { "FRLD高款充电桩", "FRLD矮款充电桩", "牧星充电桩" };
private static readonly string[] MethodNames = { "地充", "尾充", "侧充" };
private static readonly string[] CarTypeNames = { "FRLD充电", "牧星充电桩充电" };
private readonly string[] StatusFilterNames = { "全部状态", "空闲", "充电中", "故障", "离线" };
private readonly string[] TypeNames = { "FRLD高款充电桩", "FRLD矮款充电桩", "牧星充电桩" };
private readonly string[] MethodNames = { "地充", "尾充", "侧充" };
private readonly string[] CarTypeNames = { "FRLD充电", "牧星充电桩充电" };
private static readonly ChargeStationDataService DataService = ChargeStationDataService.Instance;
private static readonly Ping Ping = new Ping();
private readonly ChargeStationDataService DataService = ChargeStationDataService.Instance;
private readonly Ping Ping = new Ping();
private static Panel _panel;
private static Panel _editDialog;
private static List<ChargeStation> _snapshot = new List<ChargeStation>();
private static volatile bool _refreshing;
private static DateTime _lastFlush = DateTime.MinValue;
private static readonly TimeSpan FlushInterval = TimeSpan.FromSeconds(3);
private Panel _panel;
private Panel _editDialog;
private List<ChargeStation> _snapshot = new List<ChargeStation>();
private volatile bool _refreshing;
private DateTime _lastFlush = DateTime.MinValue;
private readonly TimeSpan FlushInterval = TimeSpan.FromSeconds(3);
private static int _statusFilterIdx;
private static string _searchText = "";
private static string _statsText = "";
private static string _status = "";
private int _statusFilterIdx;
private string _searchText = "";
private string _statsText = "";
private string _status = "";
public void Show() => Open();
public static void Open()
public static void Open() => (_instance ??= new ChargeStationManagementForm()).OpenCore();
private static ChargeStationManagementForm _instance;
private void OpenCore()
{
if (_panel != null)
{
@@ -137,7 +141,7 @@ namespace StandardScene.Charge
});
}
private static void EnsureSnapshotFresh()
private void EnsureSnapshotFresh()
{
if (_refreshing) return;
if (DateTime.Now - _lastFlush < FlushInterval) return;
@@ -164,7 +168,7 @@ namespace StandardScene.Charge
});
}
private static List<ChargeStation> FilterSnapshot(List<ChargeStation> src)
private List<ChargeStation> FilterSnapshot(List<ChargeStation> src)
{
IEnumerable<ChargeStation> q = src;
if (_statusFilterIdx > 0)
@@ -183,7 +187,7 @@ namespace StandardScene.Charge
return q.ToList();
}
private static void UpdateStats(List<ChargeStation> all)
private void UpdateStats(List<ChargeStation> all)
{
_statsText = $"总数: {all.Count} | 空闲: {all.Count(s => s.Status == ChargeStationStatus.Idle)} | " +
$"充电中: {all.Count(s => s.Status == ChargeStationStatus.Charging)} | " +
@@ -191,7 +195,7 @@ namespace StandardScene.Charge
$"AGV电池已接入: {all.Count(s => s.Status == ChargeStationStatus.Battery)}";
}
private static void OpenEditDialog(ChargeStation existing)
private void OpenEditDialog(ChargeStation existing)
{
if (_editDialog != null)
{
@@ -296,7 +300,7 @@ namespace StandardScene.Charge
});
}
private static bool TryBuildStation(bool isAdd, ChargeStation existing, string stationId, string name,
private bool TryBuildStation(bool isAdd, ChargeStation existing, string stationId, string name,
int typeIdx, int methodIdx, int carTypeIdx, string ip, string port, string voltage, string current,
string siteIdText, string remarks, bool enabled, bool shield,
out ChargeStation station, out string err)
@@ -335,7 +339,7 @@ namespace StandardScene.Charge
return true;
}
private static void ConfirmDelete(ChargeStation station)
private void ConfirmDelete(ChargeStation station)
{
CycleUiHelper.ConfirmThen($"确定删除充电桩 [{station.StationId}] {station.Name}", () =>
{
@@ -359,7 +363,7 @@ namespace StandardScene.Charge
});
}
private static void ExportData(PanelBuilder pb)
private void ExportData(PanelBuilder pb)
{
if (!pb.SaveFile("导出充电桩", "*.json;*.csv", out var path) || string.IsNullOrEmpty(path)) return;
try
@@ -385,7 +389,7 @@ namespace StandardScene.Charge
catch (Exception ex) { CycleUiHelper.Alert("错误", $"导出失败: {ex.Message}"); }
}
private static void ApplyRowColor(PanelBuilder.Row row, ChargeStation s)
private void ApplyRowColor(PanelBuilder.Row row, ChargeStation s)
{
if (s.HasAlarm) row.SetColor(Color.FromArgb(255, 205, 210));
else if (s.Status == ChargeStationStatus.Idle) row.SetColor(Color.FromArgb(232, 245, 233));
@@ -394,7 +398,7 @@ namespace StandardScene.Charge
else if (s.Status == ChargeStationStatus.Battery) row.SetColor(Color.FromArgb(238, 238, 238));
}
private static ChargeStationStatus GetStatusFromFilterIndex(int idx) => idx switch
private ChargeStationStatus GetStatusFromFilterIndex(int idx) => idx switch
{
1 => ChargeStationStatus.Idle,
2 => ChargeStationStatus.Charging,
@@ -403,7 +407,7 @@ namespace StandardScene.Charge
_ => ChargeStationStatus.Idle
};
private static string GetStatusText(ChargeStationStatus status) => status switch
private string GetStatusText(ChargeStationStatus status) => status switch
{
ChargeStationStatus.Idle => "空闲",
ChargeStationStatus.Charging => "充电中",
@@ -412,7 +416,7 @@ namespace StandardScene.Charge
_ => "未知"
};
private static string GetTypeText(ChargeStationType type) => type switch
private string GetTypeText(ChargeStationType type) => type switch
{
ChargeStationType.FRLDTall => "FRLD高款充电桩",
ChargeStationType.FRLDShort => "FRLD矮款充电桩",
@@ -420,7 +424,7 @@ namespace StandardScene.Charge
_ => "未知"
};
private static string GetMethodText(ChargeMethodType m) => m switch
private string GetMethodText(ChargeMethodType m) => m switch
{
ChargeMethodType.Ground => "地充",
ChargeMethodType.Rear => "尾充",
@@ -428,7 +432,7 @@ namespace StandardScene.Charge
_ => "未知"
};
private static string FormatComm(CommunicationStatus s) => s switch
private string FormatComm(CommunicationStatus s) => s switch
{
CommunicationStatus.Normal => "✓ 正常",
CommunicationStatus.Delayed => "⚠ 延迟",
@@ -438,7 +442,7 @@ namespace StandardScene.Charge
_ => "? 未知"
};
private static string FormatMech(MechanismStatus s) => s switch
private string FormatMech(MechanismStatus s) => s switch
{
MechanismStatus.Extended => "◆ 伸出",
MechanismStatus.Retracted => "◇ 缩回",
@@ -446,7 +450,7 @@ namespace StandardScene.Charge
_ => "? 未知"
};
private static string FormatAlarm(ChargeStation s)
private string FormatAlarm(ChargeStation s)
{
if (!s.HasAlarm) return "正常";
return string.IsNullOrWhiteSpace(s.AlarmMessage) ? $"【{s.AlarmLevel}】" : s.AlarmMessage;