Files
zhaowei.huang a0dc1e6cd0 refactor: 插件 UI 从 WinForms 迁移到 CycleGUI,并修复代码质量问题
将 StandardScene 各插件的配置/监控窗体从 WinForms 迁移到 CycleGUI(删除 .Designer.cs/.resx,重写为 PanelBuilder 立即模式 UI,新增 CycleUiHelper 统一对话框)。

同时修复代码审核中的问题:
- 后台文件写入加锁 + try/catch(ButtonBoxManager / DoorManager,对齐 LoopViewer.SaveTasks 模式)
- CoderFieldsMetadata.cs 启用 #nullable enable,消除 CS8632 警告
- DummyCar 移除已废弃的 rightClickAction()/SetPosition()
- CarRemoteHelper.OpenVehicleWebPage 的 Process.Start 加 try/catch
- 重命名名不副实的 Mstsc()(现为打开网页)
- 统一弃元命名为 _
- TrafficInterlockViewer 改用稳定 Id(GUID)做选择/编辑,替代行索引
- csproj 改用 $(CGUILibDir) 解析 CycleGUI,绝对路径收敛到 Directory.Build.props

构建:dotnet build StandardScene.sln → 0 错误,30 警告(均为历史遗留)。
注:static 单例状态重构(审核第 8 项)暂未处理,留待单独任务。
2026-06-26 15:00:53 +08:00

260 lines
9.7 KiB
C#

using System;
using CycleGUI;
using StandardScene.Utils;
namespace StandardScene.Charge
{
/// <summary>
/// 充电策略配置界面(CycleGUI 版,替代原 WinForms 窗体)。
/// </summary>
public class ChargeStrategyConfigForm
{
private static Panel _panel;
private static readonly ChargeStrategyConfigService ConfigService = ChargeStrategyConfigService.Instance;
private static ChargeStrategyConfig _config;
private static string _status = "";
// SOC 参数
private static float _mustChargeSoc;
private static float _idleChargeSoc;
private static float _taskAvailableSoc;
private static float _fullChargeSoc;
private static float _allowInterruptSoc;
// 时间参数
private static float _idleChargeSeconds;
private static float _idleSeconds;
private static float _mustChargeSeconds;
private static float _topUpMinutes;
// 任务参数
private static int _minAllowFreeCarToChargeTaskCnt;
// 开关参数
private static bool _allowInterruptTask;
private static bool _useLowerSocForCharge;
private static bool _enableErrorChargeDetection;
private static bool _useChargeSiteFilter;
/// <summary>打开(或置前)充电策略配置面板。兼容原 <c>new ChargeStrategyConfigForm().Show()</c> 调用方式。</summary>
public void Show() => Open();
/// <summary>打开(或置前)充电策略配置面板。</summary>
public static void Open()
{
if (_panel != null)
{
try
{
_panel.BringToFront();
return;
}
catch
{
_panel = null;
}
}
if (!TryLoadConfig())
return;
var panel = GUI.DeclarePanel()
.ShowTitle("充电策略配置")
.SetDefaultDocking(Panel.Docking.None)
.InitSize(780, 680)
.InitPos(false, 0, 0, 0.5f, 0.5f, 0.5f, 0.5f);
_panel = panel;
panel.IfTerminalQuit(() => _panel = null);
panel.Define(pb =>
{
if (pb.Closing())
{
panel.Exit();
_panel = null;
return;
}
pb.SeparatorText("SOC 参数 (电量百分比)");
pb.DragFloat("1. 必充电量 (%)", ref _mustChargeSoc, step: 0.1f, min: 0, max: 100);
pb.DragFloat("2. 空闲充电电量 (%)", ref _idleChargeSoc, step: 0.1f, min: 0, max: 100);
pb.DragFloat("3. 任务可用电量 (%)", ref _taskAvailableSoc, step: 0.1f, min: 0, max: 100);
pb.DragFloat("4. 满电电量 (%)", ref _fullChargeSoc, step: 0.1f, min: 0, max: 100);
pb.DragFloat("5. 允许中断电量 (%)", ref _allowInterruptSoc, step: 0.1f, min: 0, max: 100);
pb.SeparatorText("时间参数");
pb.DragFloat("6. 空闲充电时间 (秒)", ref _idleChargeSeconds, step: 0.1f, min: 0, max: 10000);
pb.DragFloat("7. 空闲时间 (秒)", ref _idleSeconds, step: 0.1f, min: 0, max: 10000);
pb.DragFloat("8. 必充时间 (秒)", ref _mustChargeSeconds, step: 0.1f, min: 0, max: 10000);
pb.DragFloat("9. 补电时间 (分钟)", ref _topUpMinutes, step: 0.1f, min: 0, max: 1000);
pb.SeparatorText("任务参数");
pb.SliderInt("10. 允许空闲车充电的最小任务数", ref _minAllowFreeCarToChargeTaskCnt, min: 0, max: 100);
pb.SeparatorText("开关参数");
pb.CheckBox("11. 允许中断充电任务", ref _allowInterruptTask);
pb.CheckBox("12. 优先使用低电量车辆充电", ref _useLowerSocForCharge);
pb.CheckBox("13. 启用充电错误检测", ref _enableErrorChargeDetection);
pb.CheckBox("14. 使用充电站点筛选", ref _useChargeSiteFilter);
pb.Separator();
if (!string.IsNullOrEmpty(_status))
pb.Label(_status);
pb.Separator();
if (pb.Button("保存", distinct: "charge-strategy-save"))
TrySave(closeAfterSave: false);
pb.SameLine(8);
if (pb.Button("应用", distinct: "charge-strategy-apply"))
TrySave(closeAfterSave: false);
pb.SameLine(8);
if (pb.Button("恢复默认", distinct: "charge-strategy-restore"))
RestoreDefaults();
pb.SameLine(8);
if (pb.Button("取消", distinct: "charge-strategy-cancel"))
{
panel.Exit();
_panel = null;
}
});
}
private static bool TryLoadConfig()
{
try
{
_config = ConfigService.LoadConfig();
ApplyConfigToUi(_config);
_status = "配置加载成功";
return true;
}
catch (Exception ex)
{
CycleUiHelper.Alert("错误", $"加载配置失败: {ex.Message}");
_status = "配置加载失败";
return false;
}
}
private static void ApplyConfigToUi(ChargeStrategyConfig config)
{
_mustChargeSoc = (float)config.MustChargeSoc;
_idleChargeSoc = (float)config.IdleChargeSoc;
_taskAvailableSoc = (float)config.TaskAvailableSoc;
_fullChargeSoc = (float)config.FullChargeSoc;
_allowInterruptSoc = (float)config.AllowInterruptSoc;
_idleChargeSeconds = (float)config.IdleChargeSeconds;
_idleSeconds = (float)config.IdleSeconds;
_mustChargeSeconds = (float)config.MustChargeSeconds;
_topUpMinutes = (float)config.TopUpMinutes;
_minAllowFreeCarToChargeTaskCnt = config.MinAllowFreeCarToChargeTaskCnt;
_allowInterruptTask = config.AllowInterruptTask;
_useLowerSocForCharge = config.UseLowerSocForCharge;
_enableErrorChargeDetection = config.EnableErrorChargeDetection;
_useChargeSiteFilter = config.UseChargeSiteFilter;
}
private static void ApplyUiToConfig()
{
_config.MustChargeSoc = _mustChargeSoc;
_config.IdleChargeSoc = _idleChargeSoc;
_config.TaskAvailableSoc = _taskAvailableSoc;
_config.FullChargeSoc = _fullChargeSoc;
_config.AllowInterruptSoc = _allowInterruptSoc;
_config.IdleChargeSeconds = _idleChargeSeconds;
_config.IdleSeconds = _idleSeconds;
_config.MustChargeSeconds = _mustChargeSeconds;
_config.TopUpMinutes = _topUpMinutes;
_config.MinAllowFreeCarToChargeTaskCnt = _minAllowFreeCarToChargeTaskCnt;
_config.AllowInterruptTask = _allowInterruptTask;
_config.UseLowerSocForCharge = _useLowerSocForCharge;
_config.EnableErrorChargeDetection = _enableErrorChargeDetection;
_config.UseChargeSiteFilter = _useChargeSiteFilter;
}
/// <summary>验证 SOC 阈值之间的逻辑关系(保存前)。</summary>
private static bool ValidateSocRanges(out string errorMessage)
{
if (_mustChargeSoc >= _idleChargeSoc)
{
errorMessage = "必充电量必须小于空闲充电电量";
return false;
}
if (_taskAvailableSoc <= _mustChargeSoc)
{
errorMessage = "任务可用电量必须大于必充电量";
return false;
}
if (_fullChargeSoc < _idleChargeSoc)
{
errorMessage = "满电电量必须大于等于空闲充电电量";
return false;
}
if (_allowInterruptSoc <= _mustChargeSoc)
{
errorMessage = "允许中断电量必须大于必充电量";
return false;
}
errorMessage = string.Empty;
return true;
}
private static void TrySave(bool closeAfterSave)
{
ApplyUiToConfig();
if (!ValidateSocRanges(out var socError))
{
CycleUiHelper.Alert("验证失败", socError);
_status = "配置保存失败";
_panel?.Repaint();
return;
}
try
{
ConfigService.SaveConfig(_config);
_status = "配置保存成功";
CycleUiHelper.Alert("成功", "充电策略配置保存成功!");
if (closeAfterSave)
{
_panel?.Exit();
_panel = null;
}
else
{
_panel?.Repaint();
}
}
catch (Exception ex)
{
CycleUiHelper.Alert("错误", $"保存配置失败: {ex.Message}");
_status = "配置保存失败";
_panel?.Repaint();
}
}
private static void RestoreDefaults()
{
CycleUiHelper.ConfirmThen("确定要恢复默认配置吗?当前配置将被覆盖。", () =>
{
_config = ChargeStrategyConfig.CreateDefault();
ApplyConfigToUi(_config);
_status = "已恢复默认配置(未保存)";
_panel?.Repaint();
});
}
}
}