1390 lines
58 KiB
C#
1390 lines
58 KiB
C#
using SimpleCore;
|
||
using System;
|
||
using System.Drawing;
|
||
using System.Linq;
|
||
using System.Net.NetworkInformation;
|
||
using System.Windows.Forms;
|
||
|
||
namespace StandardScene.Charge
|
||
{
|
||
/// <summary>
|
||
/// 充电桩管理窗口
|
||
/// </summary>
|
||
public partial class ChargeStationManagementForm : Form
|
||
{
|
||
private ChargeStationDataService dataService;
|
||
private ChargeStation selectedStation;
|
||
private System.Windows.Forms.Timer autoRefreshTimer;
|
||
private Ping Ping = new Ping();
|
||
private CommunicationMonitorForm communicationMonitorForm;
|
||
|
||
public ChargeStationManagementForm()
|
||
{
|
||
InitializeComponent();
|
||
dataService = ChargeStationDataService.Instance;
|
||
InitializeForm();
|
||
InitializeAutoRefresh();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 初始化自动刷新定时器
|
||
/// </summary>
|
||
private void InitializeAutoRefresh()
|
||
{
|
||
autoRefreshTimer = new System.Windows.Forms.Timer();
|
||
autoRefreshTimer.Interval = 3000; // 每3秒刷新一次
|
||
autoRefreshTimer.Tick += AutoRefreshTimer_Tick;
|
||
autoRefreshTimer.Start();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 自动刷新事件
|
||
/// </summary>
|
||
private void AutoRefreshTimer_Tick(object sender, EventArgs e)
|
||
{
|
||
// 保存当前选中的充电桩ID
|
||
string selectedStationId = null;
|
||
if (dgvStations.SelectedRows.Count > 0)
|
||
{
|
||
selectedStationId = dgvStations.SelectedRows[0].Cells[0].Value?.ToString();
|
||
}
|
||
|
||
// 刷新列表
|
||
LoadStations();
|
||
|
||
// 恢复选中状态
|
||
if (!string.IsNullOrEmpty(selectedStationId))
|
||
{
|
||
foreach (DataGridViewRow row in dgvStations.Rows)
|
||
{
|
||
if (row.Cells[0].Value?.ToString() == selectedStationId)
|
||
{
|
||
row.Selected = true;
|
||
dgvStations.CurrentCell = row.Cells[0];
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 窗体关闭时停止定时器
|
||
/// </summary>
|
||
protected override void OnFormClosing(FormClosingEventArgs e)
|
||
{
|
||
if (autoRefreshTimer != null)
|
||
{
|
||
autoRefreshTimer.Stop();
|
||
autoRefreshTimer.Dispose();
|
||
}
|
||
base.OnFormClosing(e);
|
||
}
|
||
|
||
private void InitializeForm()
|
||
{
|
||
// 设置窗口属性
|
||
this.Text = "充电桩管理系统";
|
||
this.Size = new Size(1200, 700);
|
||
this.StartPosition = FormStartPosition.CenterScreen;
|
||
this.MinimumSize = new Size(1000, 600);
|
||
|
||
// 设置表头文字垂直排列
|
||
SetupVerticalHeaderText();
|
||
|
||
// 初始化状态筛选下拉框
|
||
InitializeStatusFilter();
|
||
|
||
// 加载数据
|
||
LoadStations();
|
||
|
||
// 设置默认状态为新增模式
|
||
ClearEditFields();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置表头文字垂直排列
|
||
/// </summary>
|
||
private void SetupVerticalHeaderText()
|
||
{
|
||
if (dgvStations == null)
|
||
return;
|
||
|
||
// 增加列标题高度以容纳垂直文字
|
||
dgvStations.ColumnHeadersHeight = 100;
|
||
|
||
// 订阅列标题绘制事件
|
||
dgvStations.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
|
||
dgvStations.CellPainting += DgvStations_CellPainting;
|
||
|
||
// 固定行高度
|
||
dgvStations.RowTemplate.Height = 35;
|
||
dgvStations.AllowUserToResizeRows = false;
|
||
dgvStations.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.DisableResizing;
|
||
dgvStations.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 自定义绘制列标题(垂直文字)
|
||
/// </summary>
|
||
private void DgvStations_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
|
||
{
|
||
// 只处理列标题行
|
||
if (e.RowIndex == -1 && e.ColumnIndex >= 0)
|
||
{
|
||
try
|
||
{
|
||
// 绘制背景
|
||
e.PaintBackground(e.CellBounds, true);
|
||
|
||
// 获取列标题文本
|
||
string headerText = dgvStations.Columns[e.ColumnIndex].HeaderText;
|
||
|
||
// 设置文字格式(垂直排列,从上到下)
|
||
using (var brush = new SolidBrush(dgvStations.ColumnHeadersDefaultCellStyle.ForeColor))
|
||
using (var format = new StringFormat())
|
||
{
|
||
format.Alignment = StringAlignment.Center;
|
||
format.LineAlignment = StringAlignment.Near;
|
||
format.FormatFlags = StringFormatFlags.DirectionVertical; // 垂直文字
|
||
|
||
// 计算绘制位置(居中)
|
||
float x = e.CellBounds.Left + (e.CellBounds.Width - e.Graphics.MeasureString("测", dgvStations.ColumnHeadersDefaultCellStyle.Font).Width) / 2;
|
||
float y = e.CellBounds.Top + 5;
|
||
|
||
// 绘制垂直文字
|
||
e.Graphics.DrawString(
|
||
headerText,
|
||
dgvStations.ColumnHeadersDefaultCellStyle.Font,
|
||
brush,
|
||
new RectangleF(x, y, e.CellBounds.Width, e.CellBounds.Height - 10),
|
||
format);
|
||
}
|
||
|
||
// 绘制边框
|
||
e.Paint(e.CellBounds, DataGridViewPaintParts.Border);
|
||
|
||
// 标记为已处理
|
||
e.Handled = true;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
System.Diagnostics.Debug.WriteLine($"绘制列标题失败: {ex.Message}");
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 初始化状态筛选下拉框
|
||
/// </summary>
|
||
private void InitializeStatusFilter()
|
||
{
|
||
if (cmbStatusFilter != null)
|
||
{
|
||
cmbStatusFilter.Items.Clear();
|
||
cmbStatusFilter.Items.Add("全部状态");
|
||
cmbStatusFilter.Items.Add("空闲");
|
||
cmbStatusFilter.Items.Add("充电中");
|
||
cmbStatusFilter.Items.Add("故障");
|
||
cmbStatusFilter.Items.Add("离线");
|
||
cmbStatusFilter.SelectedIndex = 0; // 默认显示全部
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 加载充电桩列表
|
||
/// </summary>
|
||
private void LoadStations()
|
||
{
|
||
try
|
||
{
|
||
var stations = dataService.GetAllStations();
|
||
|
||
// 根据状态筛选
|
||
if (cmbStatusFilter != null && cmbStatusFilter.SelectedIndex > 0)
|
||
{
|
||
var filterStatus = GetStatusFromFilterIndex(cmbStatusFilter.SelectedIndex);
|
||
stations = stations.Where(s => s.Status == filterStatus).ToList();
|
||
}
|
||
|
||
dgvStations.Rows.Clear();
|
||
|
||
foreach (var station in stations)
|
||
{
|
||
|
||
try
|
||
{
|
||
if (Ping.Send(station.IpAddress, 1000).Status == IPStatus.Success)
|
||
{
|
||
station.CommStatus = CommunicationStatus.Normal;
|
||
}
|
||
else
|
||
{
|
||
station.CommStatus = CommunicationStatus.Error;
|
||
}
|
||
}
|
||
catch (Exception)
|
||
{
|
||
|
||
station.CommStatus = CommunicationStatus.Error;
|
||
}
|
||
|
||
|
||
var index = dgvStations.Rows.Add(
|
||
station.StationId,
|
||
station.Name,
|
||
GetTypeText(station.Type),
|
||
GetChargeMethodText(station.ChargeMethod),
|
||
//station.IpAddress,
|
||
//station.Port,
|
||
station.SiteId?.ToString() ?? "",
|
||
FormatTimeToMinuteSecond(station.LastSendTime),
|
||
FormatTimeToMinuteSecond(station.LastReceiveTime),
|
||
FormatCommStatusDisplay(station.CommStatus),
|
||
FormatChargeCommandStatusDisplay(station.ChargeCommandStatus),
|
||
FormatMechanismStatusDisplay(station.MechanismStatus),
|
||
string.IsNullOrWhiteSpace(station.CurrentVehicle) ? "-" : station.CurrentVehicle,
|
||
station.BatteryLevel > 0 ? $"{station.BatteryLevel:F1}%" : "-",
|
||
FormatAlarmDisplay(station),
|
||
//station.SetVoltage,
|
||
//station.SetElectricCurrent,
|
||
station.RealTimeVoltage.ToString("F1"),
|
||
station.RealTimeCurrent.ToString("F1"),
|
||
GetStatusText(station.Status),
|
||
station.Enabled ? "是" : "否",
|
||
station.Remarks
|
||
);
|
||
|
||
// 根据状态设置行颜色(扁平化设计)
|
||
var row = dgvStations.Rows[index];
|
||
|
||
// 通讯状态列样式设置(第9列,因为增加了充电方式列)
|
||
var commCell = row.Cells[9];
|
||
switch (station.CommStatus)
|
||
{
|
||
case CommunicationStatus.Normal:
|
||
commCell.Style.ForeColor = Color.FromArgb(76, 175, 80); // 绿色
|
||
// commCell.Style.Font = new Font(commCell.Style.Font ?? row.DefaultCellStyle.Font, FontStyle.Bold);
|
||
break;
|
||
case CommunicationStatus.Delayed:
|
||
commCell.Style.ForeColor = Color.FromArgb(255, 152, 0); // 橙色
|
||
// commCell.Style.Font = new Font(commCell.Style.Font ?? row.DefaultCellStyle.Font, FontStyle.Bold);
|
||
break;
|
||
case CommunicationStatus.Timeout:
|
||
case CommunicationStatus.Disconnected:
|
||
case CommunicationStatus.Error:
|
||
commCell.Style.ForeColor = Color.FromArgb(244, 67, 54); // 红色
|
||
// commCell.Style.Font = new Font(commCell.Style.Font ?? row.DefaultCellStyle.Font, FontStyle.Bold);
|
||
break;
|
||
case CommunicationStatus.Unknown:
|
||
commCell.Style.ForeColor = Color.FromArgb(158, 158, 158); // 灰色
|
||
break;
|
||
}
|
||
|
||
// 充电指令状态列样式设置(第10列)
|
||
var chargeCommandCell = row.Cells[10];
|
||
switch (station.ChargeCommandStatus)
|
||
{
|
||
case ChargeCommandStatus.Stopped:
|
||
chargeCommandCell.Style.ForeColor = Color.FromArgb(158, 158, 158); // 灰色
|
||
break;
|
||
case ChargeCommandStatus.Started:
|
||
chargeCommandCell.Style.ForeColor = Color.FromArgb(76, 175, 80); // 绿色
|
||
// chargeCommandCell.Style.Font = new Font(chargeCommandCell.Style.Font ?? row.DefaultCellStyle.Font, FontStyle.Bold);
|
||
break;
|
||
}
|
||
|
||
// 机构状态列样式设置(第11列)
|
||
var mechanismCell = row.Cells[11];
|
||
switch (station.MechanismStatus)
|
||
{
|
||
|
||
case MechanismStatus.Retracted:
|
||
mechanismCell.Style.ForeColor = Color.FromArgb(76, 175, 80); // 绿色
|
||
//mechanismCell.Style.Font = new Font(mechanismCell.Style.Font ?? row.DefaultCellStyle.Font, FontStyle.Bold);
|
||
break;
|
||
case MechanismStatus.Extending:
|
||
mechanismCell.Style.ForeColor = Color.FromArgb(33, 150, 243); // 蓝色
|
||
//mechanismCell.Style.Font = new Font(mechanismCell.Style.Font ?? row.DefaultCellStyle.Font, FontStyle.Bold);
|
||
break;
|
||
case MechanismStatus.Extended:
|
||
mechanismCell.Style.ForeColor = Color.FromArgb(255, 0, 0); //
|
||
//mechanismCell.Style.Font = new Font(mechanismCell.Style.Font ?? row.DefaultCellStyle.Font, FontStyle.Bold);
|
||
break;
|
||
break;
|
||
}
|
||
|
||
// 电量列样式设置(第13列)
|
||
if (station.BatteryLevel > 0)
|
||
{
|
||
var batteryCell = row.Cells[13];
|
||
if (station.BatteryLevel >= 80)
|
||
{
|
||
batteryCell.Style.ForeColor = Color.FromArgb(76, 175, 80); // 绿色 - 电量充足
|
||
//batteryCell.Style.Font = new Font(batteryCell.Style.Font ?? row.DefaultCellStyle.Font, FontStyle.Bold);
|
||
}
|
||
else if (station.BatteryLevel >= 50)
|
||
{
|
||
batteryCell.Style.ForeColor = Color.FromArgb(33, 150, 243); // 蓝色 - 电量中等
|
||
//batteryCell.Style.Font = new Font(batteryCell.Style.Font ?? row.DefaultCellStyle.Font, FontStyle.Bold);
|
||
}
|
||
else if (station.BatteryLevel >= 20)
|
||
{
|
||
batteryCell.Style.ForeColor = Color.FromArgb(255, 152, 0); // 橙色 - 电量偏低
|
||
//batteryCell.Style.Font = new Font(batteryCell.Style.Font ?? row.DefaultCellStyle.Font, FontStyle.Bold);
|
||
}
|
||
else
|
||
{
|
||
batteryCell.Style.ForeColor = Color.FromArgb(244, 67, 54); // 红色 - 电量低
|
||
//batteryCell.Style.Font = new Font(batteryCell.Style.Font ?? row.DefaultCellStyle.Font, FontStyle.Bold);
|
||
}
|
||
}
|
||
|
||
// 如果有报警,整行显示红色
|
||
if (station.HasAlarm)
|
||
{
|
||
row.DefaultCellStyle.BackColor = Color.FromArgb(255, 205, 210); // 浅红色背景 #FFCDD2
|
||
row.DefaultCellStyle.ForeColor = Color.FromArgb(198, 40, 40); // 深红色文字
|
||
var baseFont = row.DefaultCellStyle.Font ?? dgvStations.DefaultCellStyle.Font ?? new Font("微软雅黑", 9F);
|
||
row.DefaultCellStyle.Font = new Font(baseFont, FontStyle.Bold);
|
||
}
|
||
else
|
||
{
|
||
// 根据状态设置颜色
|
||
switch (station.Status)
|
||
{
|
||
case ChargeStationStatus.Idle:
|
||
row.DefaultCellStyle.BackColor = Color.FromArgb(232, 245, 233); // 浅绿色 #E8F5E9
|
||
row.DefaultCellStyle.ForeColor = Color.FromArgb(46, 125, 50); // 深绿色文字
|
||
break;
|
||
case ChargeStationStatus.Charging:
|
||
row.DefaultCellStyle.BackColor = Color.FromArgb(200, 230, 201); // 亮绿色 #C8E6C9
|
||
row.DefaultCellStyle.ForeColor = Color.FromArgb(27, 94, 32); // 深绿色文字
|
||
break;
|
||
case ChargeStationStatus.Fault:
|
||
row.DefaultCellStyle.BackColor = Color.FromArgb(255, 205, 210); // 浅红色 #FFCDD2
|
||
row.DefaultCellStyle.ForeColor = Color.FromArgb(198, 40, 40); // 深红色文字
|
||
break;
|
||
case ChargeStationStatus.Battery:
|
||
row.DefaultCellStyle.BackColor = Color.FromArgb(238, 238, 238); // 浅灰色 #EEEEEE
|
||
row.DefaultCellStyle.ForeColor = Color.FromArgb(97, 97, 97); // 深灰色文字
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 更新统计信息
|
||
UpdateStatistics();
|
||
|
||
// 更新标题显示筛选状态
|
||
UpdateTitleWithFilter(stations.Count);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show($"加载数据失败: {ex.Message}\n\n堆栈:\n{ex.StackTrace}", "错误",
|
||
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 根据筛选器索引获取状态
|
||
/// </summary>
|
||
private ChargeStationStatus GetStatusFromFilterIndex(int index)
|
||
{
|
||
switch (index)
|
||
{
|
||
case 1: return ChargeStationStatus.Idle; // 空闲
|
||
case 2: return ChargeStationStatus.Charging; // 充电中
|
||
case 3: return ChargeStationStatus.Fault; // 故障
|
||
case 4: return ChargeStationStatus.Battery; // 离线
|
||
default: return ChargeStationStatus.Idle;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更新标题显示筛选信息
|
||
/// </summary>
|
||
private void UpdateTitleWithFilter(int displayCount)
|
||
{
|
||
var totalCount = dataService.GetAllStations().Count;
|
||
if (cmbStatusFilter != null && cmbStatusFilter.SelectedIndex > 0)
|
||
{
|
||
this.Text = $"充电桩管理系统 - 显示: {displayCount}/{totalCount} ({cmbStatusFilter.Text})";
|
||
}
|
||
else
|
||
{
|
||
this.Text = $"充电桩管理系统 - 总数: {totalCount}";
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更新统计信息
|
||
/// </summary>
|
||
private void UpdateStatistics()
|
||
{
|
||
var stations = dataService.GetAllStations();
|
||
var total = stations.Count;
|
||
var idle = stations.Count(s => s.Status == ChargeStationStatus.Idle);
|
||
var charging = stations.Count(s => s.Status == ChargeStationStatus.Charging);
|
||
var fault = stations.Count(s => s.Status == ChargeStationStatus.Fault);
|
||
var offline = stations.Count(s => s.Status == ChargeStationStatus.Battery);
|
||
|
||
lblStatistics.Text = $"总数: {total} | 空闲: {idle} | 充电中: {charging} | 故障: {fault} | AGV电池已接入: {offline}";
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取状态文本
|
||
/// </summary>
|
||
private string GetStatusText(ChargeStationStatus status)
|
||
{
|
||
switch (status)
|
||
{
|
||
case ChargeStationStatus.Idle: return "空闲";
|
||
case ChargeStationStatus.Charging: return "充电中";
|
||
case ChargeStationStatus.Fault: return "故障";
|
||
case ChargeStationStatus.Battery: return "AGV电池已接入";
|
||
default: return "未知";
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 格式化时间为 mm:ss 格式
|
||
/// </summary>
|
||
private string FormatTimeToMinuteSecond(DateTime? dateTime)
|
||
{
|
||
if (dateTime == null)
|
||
{
|
||
return "--:--";
|
||
}
|
||
return dateTime.Value.ToString("mm:ss");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 格式化机构伸缩状态显示
|
||
/// </summary>
|
||
private string FormatMechanismStatusDisplay(MechanismStatus status)
|
||
{
|
||
switch (status)
|
||
{
|
||
case MechanismStatus.Extended:
|
||
return "◆ 伸出";
|
||
case MechanismStatus.Retracted:
|
||
return "◇ 缩回";
|
||
case MechanismStatus.Extending:
|
||
return "▶ 运动中";
|
||
default:
|
||
return "? 未知";
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 格式化充电指令状态显示
|
||
/// </summary>
|
||
private string FormatChargeCommandStatusDisplay(ChargeCommandStatus status)
|
||
{
|
||
switch (status)
|
||
{
|
||
case ChargeCommandStatus.Stopped:
|
||
return "◯ 停止";
|
||
case ChargeCommandStatus.Started:
|
||
return "▶ 启动";
|
||
default:
|
||
return "◯ 停止";
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 格式化通讯状态显示
|
||
/// </summary>
|
||
private string FormatCommStatusDisplay(CommunicationStatus status)
|
||
{
|
||
switch (status)
|
||
{
|
||
case CommunicationStatus.Normal:
|
||
return "✓ 正常";
|
||
case CommunicationStatus.Delayed:
|
||
return "⚠ 延迟";
|
||
case CommunicationStatus.Timeout:
|
||
return "✗ 超时";
|
||
case CommunicationStatus.Disconnected:
|
||
return "✗ 断开";
|
||
case CommunicationStatus.Error:
|
||
return "✗ 错误";
|
||
case CommunicationStatus.Unknown:
|
||
default:
|
||
return "? 未知";
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 格式化报警信息显示
|
||
/// </summary>
|
||
private string FormatAlarmDisplay(ChargeStation station)
|
||
{
|
||
if (!station.HasAlarm)
|
||
{
|
||
return "正常";
|
||
}
|
||
|
||
string levelText = GetAlarmLevelText(station.AlarmLevel);
|
||
if (string.IsNullOrWhiteSpace(station.AlarmMessage))
|
||
{
|
||
return $"【{levelText}】";
|
||
}
|
||
|
||
return $"{station.AlarmMessage}";
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取报警级别文本
|
||
/// </summary>
|
||
private string GetAlarmLevelText(AlarmLevel level)
|
||
{
|
||
switch (level)
|
||
{
|
||
case AlarmLevel.None: return "无";
|
||
case AlarmLevel.Low: return "低";
|
||
case AlarmLevel.Medium: return "中";
|
||
case AlarmLevel.High: return "高";
|
||
case AlarmLevel.Critical: return "严重";
|
||
default: return "未知";
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取类型文本
|
||
/// </summary>
|
||
private string GetTypeText(ChargeStationType type)
|
||
{
|
||
switch (type)
|
||
{
|
||
case ChargeStationType.FRLDTall: return "FRLD高款充电桩";
|
||
case ChargeStationType.FRLDShort: return "FRLD矮款充电桩";
|
||
case ChargeStationType.MuXing: return "牧星充电桩";
|
||
default: return "未知";
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取充电方式文本
|
||
/// </summary>
|
||
private string GetChargeMethodText(ChargeMethodType method)
|
||
{
|
||
switch (method)
|
||
{
|
||
case ChargeMethodType.Ground: return "地充";
|
||
case ChargeMethodType.Rear: return "尾充";
|
||
case ChargeMethodType.Side: return "侧充";
|
||
default: return "未知";
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置编辑模式
|
||
/// </summary>
|
||
/// <summary>
|
||
/// 清空编辑区
|
||
/// </summary>
|
||
private void ClearEditFields()
|
||
{
|
||
selectedStation = null;
|
||
txtStationId.Text = ""; // 手动输入编号
|
||
txtName.Text = "";
|
||
cmbType.SelectedIndex = 1;
|
||
cmbChargeMethod.SelectedIndex = 0; // 默认地充
|
||
chargeCarType.SelectedIndex = 0;
|
||
// 触发充电方式改变事件,更新"屏蔽机构状态交互"的可见性
|
||
cmbChargeMethod_SelectedIndexChanged(null, null);
|
||
|
||
txtIpAddress.Text = "192.168.";
|
||
numPort.Value = 2000;
|
||
numVoltage.Value = 48;
|
||
numCurrent.Value = 32;
|
||
chkEnabled.Checked = true;
|
||
chkShieldSiteMechanismStatus.Checked = false;
|
||
numSiteId.Value = 0;
|
||
txtRemarks.Text = "";
|
||
|
||
// 清空实时状态显示
|
||
ClearRealTimeInfo();
|
||
|
||
// 新增模式:所有字段可编辑
|
||
SetEditMode(true);
|
||
btnSave.Text = "保存";
|
||
btnDelete.Enabled = false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 清空实时状态显示区域
|
||
/// </summary>
|
||
private void ClearRealTimeInfo()
|
||
{
|
||
lblCurrentVehicleValue.Text = "-";
|
||
lblCurrentVehicleValue.ForeColor = Color.Gray;
|
||
|
||
lblBatteryLevelValue.Text = "-";
|
||
lblBatteryLevelValue.ForeColor = Color.Gray;
|
||
|
||
lblRealTimeVoltageValue.Text = "0.0 V";
|
||
lblRealTimeVoltageValue.ForeColor = Color.Gray;
|
||
|
||
lblRealTimeCurrentValue.Text = "0.0 A";
|
||
lblRealTimeCurrentValue.ForeColor = Color.Gray;
|
||
|
||
lblCommStatusValue.Text = "? 未知";
|
||
lblCommStatusValue.ForeColor = Color.Gray;
|
||
|
||
lblChargeCommandStatusValue.Text = "◯ 停止";
|
||
lblChargeCommandStatusValue.ForeColor = Color.Gray;
|
||
|
||
lblMechanismStatusValue.Text = "? 未知";
|
||
lblMechanismStatusValue.ForeColor = Color.Gray;
|
||
|
||
lblAlarmValue.Text = "-";
|
||
lblAlarmValue.ForeColor = Color.Gray;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置编辑模式
|
||
/// </summary>
|
||
/// <param name="editable">true=可编辑,false=只读</param>
|
||
private void SetEditMode(bool editable, bool isList = false)
|
||
{
|
||
// 编号在新增时可编辑,编辑时只读
|
||
if (selectedStation == null)
|
||
{
|
||
// 新增模式:编号可编辑
|
||
txtStationId.ReadOnly = false;
|
||
txtStationId.BackColor = Color.White;
|
||
}
|
||
else
|
||
{
|
||
// 编辑模式:编号只读
|
||
txtStationId.ReadOnly = true;
|
||
txtStationId.BackColor = Color.LightGray;
|
||
}
|
||
|
||
// 其他字段根据参数设置
|
||
txtName.ReadOnly = !editable;
|
||
cmbType.Enabled = isList ? false : editable;
|
||
cmbChargeMethod.Enabled = editable;
|
||
txtIpAddress.ReadOnly = !editable;
|
||
numPort.ReadOnly = !editable;
|
||
numVoltage.ReadOnly = !editable;
|
||
numCurrent.ReadOnly = !editable;
|
||
chkEnabled.Enabled = editable;
|
||
chkShieldSiteMechanismStatus.Enabled = editable;
|
||
numSiteId.ReadOnly = !editable;
|
||
txtRemarks.ReadOnly = !editable;
|
||
|
||
// 设置背景颜色
|
||
if (!editable)
|
||
{
|
||
txtName.BackColor = Color.WhiteSmoke;
|
||
txtIpAddress.BackColor = Color.WhiteSmoke;
|
||
txtRemarks.BackColor = Color.WhiteSmoke;
|
||
}
|
||
else
|
||
{
|
||
txtName.BackColor = Color.White;
|
||
txtIpAddress.BackColor = Color.White;
|
||
txtRemarks.BackColor = Color.White;
|
||
}
|
||
|
||
// 控制按钮状态
|
||
btnSave.Enabled = editable;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 从编辑区创建充电桩对象
|
||
/// </summary>
|
||
private ChargeStation CreateStationFromFields()
|
||
{
|
||
//var station = selectedStation ?? new ChargeStation();
|
||
var station = new ChargeStation();
|
||
station.StationId = txtStationId.Text.Trim();
|
||
station.Name = txtName.Text.Trim();
|
||
station.Type = (ChargeStationType)cmbType.SelectedIndex;
|
||
station.ChargeMethod = (ChargeMethodType)cmbChargeMethod.SelectedIndex;
|
||
station.IpAddress = txtIpAddress.Text.Trim();
|
||
station.Port = (int)numPort.Value;
|
||
station.SetVoltage = (double)numVoltage.Value;
|
||
station.SetElectricCurrent = (double)numCurrent.Value;
|
||
station.Enabled = chkEnabled.Checked;
|
||
station.ShieldSiteMechanismStatus = chkShieldSiteMechanismStatus.Checked;
|
||
station.GroupCarType = (ChargeStationCarType)chargeCarType.SelectedIndex;
|
||
station.SiteId = numSiteId.Value > 0 ? (int?)numSiteId.Value : null;
|
||
station.Remarks = txtRemarks.Text.Trim();
|
||
|
||
return station;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 加载充电桩到编辑区
|
||
/// </summary>
|
||
private void LoadStationToFields(ChargeStation station)
|
||
{
|
||
selectedStation = station;
|
||
|
||
// 加载基本信息(可编辑部分)
|
||
txtStationId.Text = station.StationId;
|
||
txtName.Text = station.Name;
|
||
cmbType.SelectedIndex = (int)station.Type;
|
||
cmbChargeMethod.SelectedIndex = (int)station.ChargeMethod;
|
||
|
||
// 触发充电方式改变事件,更新"屏蔽机构状态交互"的可见性
|
||
cmbChargeMethod_SelectedIndexChanged(null, null);
|
||
|
||
txtIpAddress.Text = station.IpAddress;
|
||
numPort.Value = station.Port;
|
||
numVoltage.Value = (decimal)station.SetVoltage;
|
||
numCurrent.Value = (decimal)station.SetElectricCurrent;
|
||
chkEnabled.Checked = station.Enabled;
|
||
chkShieldSiteMechanismStatus.Checked = station.ShieldSiteMechanismStatus;
|
||
chargeCarType.SelectedIndex = (int)station.GroupCarType;
|
||
numSiteId.Value = station.SiteId ?? 0;
|
||
txtRemarks.Text = station.Remarks ?? "";
|
||
|
||
// 加载实时状态信息(只读部分)
|
||
LoadRealTimeInfo(station);
|
||
|
||
// 查看模式:所有字段只读
|
||
SetEditMode(false);
|
||
btnSave.Text = "修改";
|
||
btnDelete.Enabled = true;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 加载实时状态信息到显示区域
|
||
/// </summary>
|
||
private void LoadRealTimeInfo(ChargeStation station)
|
||
{
|
||
// 当前车辆
|
||
lblCurrentVehicleValue.Text = string.IsNullOrWhiteSpace(station.CurrentVehicle) ? "-" : station.CurrentVehicle;
|
||
|
||
// 电量
|
||
if (station.BatteryLevel > 0)
|
||
{
|
||
lblBatteryLevelValue.Text = $"{station.BatteryLevel:F1}%";
|
||
if (station.BatteryLevel >= 80)
|
||
{
|
||
lblBatteryLevelValue.ForeColor = Color.FromArgb(76, 175, 80); // 绿色
|
||
}
|
||
else if (station.BatteryLevel >= 50)
|
||
{
|
||
lblBatteryLevelValue.ForeColor = Color.FromArgb(33, 150, 243); // 蓝色
|
||
}
|
||
else if (station.BatteryLevel >= 20)
|
||
{
|
||
lblBatteryLevelValue.ForeColor = Color.FromArgb(255, 152, 0); // 橙色
|
||
}
|
||
else
|
||
{
|
||
lblBatteryLevelValue.ForeColor = Color.FromArgb(244, 67, 54); // 红色
|
||
}
|
||
}
|
||
else
|
||
{
|
||
lblBatteryLevelValue.Text = "-";
|
||
lblBatteryLevelValue.ForeColor = Color.Gray;
|
||
}
|
||
|
||
// 实时电压
|
||
lblRealTimeVoltageValue.Text = $"{station.RealTimeVoltage:F1} V";
|
||
lblRealTimeVoltageValue.ForeColor = station.RealTimeVoltage > 0
|
||
? Color.FromArgb(33, 150, 243) // 蓝色
|
||
: Color.Gray;
|
||
|
||
// 实时电流
|
||
lblRealTimeCurrentValue.Text = $"{station.RealTimeCurrent:F1} A";
|
||
lblRealTimeCurrentValue.ForeColor = station.RealTimeCurrent > 0
|
||
? Color.FromArgb(33, 150, 243) // 蓝色
|
||
: Color.Gray;
|
||
|
||
// 通讯状态
|
||
lblCommStatusValue.Text = FormatCommStatusDisplay(station.CommStatus);
|
||
switch (station.CommStatus)
|
||
{
|
||
case CommunicationStatus.Normal:
|
||
lblCommStatusValue.ForeColor = Color.FromArgb(76, 175, 80); // 绿色
|
||
break;
|
||
case CommunicationStatus.Delayed:
|
||
lblCommStatusValue.ForeColor = Color.FromArgb(255, 193, 7); // 黄色
|
||
break;
|
||
case CommunicationStatus.Timeout:
|
||
case CommunicationStatus.Disconnected:
|
||
case CommunicationStatus.Error:
|
||
lblCommStatusValue.ForeColor = Color.FromArgb(244, 67, 54); // 红色
|
||
break;
|
||
default:
|
||
lblCommStatusValue.ForeColor = Color.Gray;
|
||
break;
|
||
}
|
||
|
||
// 充电指令状态
|
||
lblChargeCommandStatusValue.Text = FormatChargeCommandStatusDisplay(station.ChargeCommandStatus);
|
||
lblChargeCommandStatusValue.ForeColor = station.ChargeCommandStatus == ChargeCommandStatus.Started
|
||
? Color.FromArgb(76, 175, 80) // 绿色
|
||
: Color.Gray;
|
||
|
||
// 机构状态
|
||
lblMechanismStatusValue.Text = FormatMechanismStatusDisplay(station.MechanismStatus);
|
||
switch (station.MechanismStatus)
|
||
{
|
||
|
||
case MechanismStatus.Retracted:
|
||
lblMechanismStatusValue.ForeColor = Color.FromArgb(76, 175, 80); // 绿色
|
||
break;
|
||
case MechanismStatus.Extending:
|
||
lblMechanismStatusValue.ForeColor = Color.FromArgb(33, 150, 243); // 蓝色
|
||
break;
|
||
case MechanismStatus.Extended:
|
||
lblMechanismStatusValue.ForeColor = Color.FromArgb(255, 0, 0); // 蓝色
|
||
break;
|
||
default:
|
||
lblMechanismStatusValue.ForeColor = Color.Gray;
|
||
break;
|
||
}
|
||
|
||
// 报警信息
|
||
if (station.HasAlarm)
|
||
{
|
||
string levelText = "";
|
||
switch (station.AlarmLevel)
|
||
{
|
||
case AlarmLevel.Critical:
|
||
levelText = "严重";
|
||
lblAlarmValue.ForeColor = Color.FromArgb(183, 28, 28); // 深红色
|
||
break;
|
||
case AlarmLevel.High:
|
||
levelText = "高";
|
||
lblAlarmValue.ForeColor = Color.FromArgb(244, 67, 54); // 红色
|
||
break;
|
||
case AlarmLevel.Medium:
|
||
levelText = "中";
|
||
lblAlarmValue.ForeColor = Color.FromArgb(255, 152, 0); // 橙色
|
||
break;
|
||
case AlarmLevel.Low:
|
||
levelText = "低";
|
||
lblAlarmValue.ForeColor = Color.FromArgb(255, 193, 7); // 黄色
|
||
break;
|
||
default:
|
||
levelText = "未知";
|
||
lblAlarmValue.ForeColor = Color.Gray;
|
||
break;
|
||
}
|
||
lblAlarmValue.Text = $"【{levelText}】{station.AlarmMessage}";
|
||
}
|
||
else
|
||
{
|
||
lblAlarmValue.Text = "正常";
|
||
lblAlarmValue.ForeColor = Color.FromArgb(76, 175, 80); // 绿色
|
||
}
|
||
}
|
||
|
||
|
||
// ==================== 事件处理 ====================
|
||
|
||
/// <summary>
|
||
/// 充电方式改变事件 - 控制"屏蔽机构状态交互"选项的显示
|
||
/// </summary>
|
||
private void cmbChargeMethod_SelectedIndexChanged(object sender, EventArgs e)
|
||
{
|
||
// 只有侧充(Side=2)时才显示"屏蔽机构状态交互"选项
|
||
bool isSideCharge = cmbChargeMethod.SelectedIndex == (int)ChargeMethodType.Side;
|
||
chkShieldSiteMechanismStatus.Visible = isSideCharge;
|
||
|
||
// 如果不是侧充,自动取消勾选
|
||
if (!isSideCharge)
|
||
{
|
||
chkShieldSiteMechanismStatus.Checked = false;
|
||
}
|
||
}
|
||
|
||
private void btnSave_Click(object sender, EventArgs e)
|
||
{
|
||
try
|
||
{
|
||
// 如果当前是只读模式(查看模式),点击"修改"按钮切换到编辑模式
|
||
if (btnSave.Text == "修改")
|
||
{
|
||
SetEditMode(true);
|
||
btnSave.Text = "保存";
|
||
return;
|
||
}
|
||
|
||
// 以下是保存逻辑
|
||
// 充电桩编号验证:1-99之间的数字
|
||
string stationId = txtStationId.Text.Trim();
|
||
if (string.IsNullOrEmpty(stationId))
|
||
{
|
||
MessageBox.Show("请输入充电桩编号(1-99)", "验证失败",
|
||
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||
txtStationId.Focus();
|
||
return;
|
||
}
|
||
|
||
// 验证是否为数字且在1-99范围内
|
||
if (!int.TryParse(stationId, out int stationNumber) || stationNumber < 1 || stationNumber > 99)
|
||
{
|
||
MessageBox.Show("充电桩编号必须是1-99之间的数字", "验证失败",
|
||
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||
txtStationId.Focus();
|
||
return;
|
||
}
|
||
|
||
// 检查编号是否重复(新增时)
|
||
if (selectedStation == null)
|
||
{
|
||
var existingStations = dataService.GetAllStations();
|
||
if (existingStations.Any(s => s.StationId == stationId))
|
||
{
|
||
MessageBox.Show($"充电桩编号 {stationId} 已存在,请输入其他编号", "验证失败",
|
||
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||
txtStationId.Focus();
|
||
return;
|
||
}
|
||
}
|
||
|
||
|
||
var Site = SimpleLib.GetSite((int)numSiteId.Value);
|
||
if (Site == null) //判断站点是否在S里。
|
||
{
|
||
MessageBox.Show($"站点ID{numSiteId.Value} 未在调度系统上", "验证失败",
|
||
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||
numSiteId.Focus();
|
||
return;
|
||
}
|
||
|
||
var station = CreateStationFromFields();
|
||
string errorMessage;
|
||
|
||
bool success;
|
||
if (selectedStation == null)
|
||
{
|
||
// 新增
|
||
success = dataService.AddStation(station, out errorMessage);
|
||
}
|
||
else
|
||
{
|
||
// 更新
|
||
success = dataService.UpdateStation(station, out errorMessage, true);
|
||
}
|
||
|
||
if (success)
|
||
{
|
||
Site.name = station.Name;
|
||
//Site.fields["chargeNum"] = station.StationId;
|
||
//Site.fields["stationIP"] = station.IpAddress;
|
||
//Site.fields["stationPort"] = station.Port.ToString();
|
||
//switch (station.Type)
|
||
//{
|
||
// case ChargeStationType.FRLDTall:
|
||
// Site.fields["Charge"] = "FLChargeStation";
|
||
// break;
|
||
// case ChargeStationType.FRLDShort:
|
||
// Site.fields["Charge"] = "PCBChargeStation";
|
||
// Site.fields["CommunicationType"] = "UDP";
|
||
// break;
|
||
// case ChargeStationType.MuXing:
|
||
// Site.fields["Charge"] = "MuXingChargeStation";
|
||
// break;
|
||
// default:
|
||
// break;
|
||
//}
|
||
Site.fields["setVoltage"] = station.SetVoltage.ToString();
|
||
Site.fields["setElectricCurrent"] = station.SetElectricCurrent.ToString();
|
||
if (!station.Enabled)
|
||
{
|
||
Site.fields["group"] = "禁用";
|
||
}
|
||
else
|
||
{
|
||
Site.fields["group"] = station.GroupCarType.ToString();
|
||
}
|
||
|
||
LoadStations();
|
||
ClearEditFields();
|
||
MessageBox.Show("保存成功", "提示",
|
||
MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
}
|
||
else
|
||
{
|
||
MessageBox.Show($"保存失败: {errorMessage}", "错误",
|
||
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show($"保存失败: {ex.Message}", "错误",
|
||
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
|
||
private void btnDelete_Click(object sender, EventArgs e)
|
||
{
|
||
if (dgvStations.SelectedRows.Count == 0)
|
||
{
|
||
MessageBox.Show("请先选择要删除的充电桩", "提示",
|
||
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||
return;
|
||
}
|
||
|
||
var stationId = dgvStations.SelectedRows[0].Cells[0].Value.ToString();
|
||
var stationName = dgvStations.SelectedRows[0].Cells[1].Value.ToString();
|
||
|
||
var result = MessageBox.Show(
|
||
$"确定要删除充电桩 [{stationId}] {stationName} 吗?",
|
||
"确认删除",
|
||
MessageBoxButtons.YesNo,
|
||
MessageBoxIcon.Question);
|
||
|
||
if (result == DialogResult.Yes)
|
||
{
|
||
if (dataService.DeleteStation(stationId, out string errorMessage))
|
||
{
|
||
|
||
var Site = SimpleLib.GetSite((int)numSiteId.Value);
|
||
if (Site != null) //判断站点是否在S里。
|
||
{
|
||
Site.name = "NoName";
|
||
Site.fields.Remove("setVoltage");
|
||
Site.fields.Remove("setElectricCurrent");
|
||
Site.fields.Remove("Charge");
|
||
Site.fields.Remove("group");
|
||
|
||
|
||
}
|
||
MessageBox.Show("删除成功!", "提示",
|
||
MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
LoadStations();
|
||
ClearEditFields();
|
||
}
|
||
else
|
||
{
|
||
MessageBox.Show($"删除失败: {errorMessage}", "错误",
|
||
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
private void btnCancel_Click(object sender, EventArgs e)
|
||
{
|
||
// 如果有选中的充电桩,恢复到只读模式
|
||
//if (selectedStation != null)
|
||
//{
|
||
// LoadStationToFields(selectedStation);
|
||
//}
|
||
//else
|
||
{
|
||
// 否则清空为新增模式
|
||
ClearEditFields();
|
||
}
|
||
}
|
||
|
||
private void btnRefresh_Click(object sender, EventArgs e)
|
||
{
|
||
dataService.Reload();
|
||
LoadStations();
|
||
MessageBox.Show("刷新成功!", "提示",
|
||
MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
}
|
||
|
||
private void dgvStations_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
|
||
{
|
||
if (e.RowIndex >= 0)
|
||
{
|
||
var stationId = dgvStations.Rows[e.RowIndex].Cells[0].Value.ToString();
|
||
var station = dataService.GetStationById(stationId);
|
||
if (station != null)
|
||
{
|
||
LoadStationToFields(station);
|
||
SetEditMode(true, true);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
private void txtSearch_TextChanged(object sender, EventArgs e)
|
||
{
|
||
ApplyFilters();
|
||
}
|
||
|
||
private void cmbStatusFilter_SelectedIndexChanged(object sender, EventArgs e)
|
||
{
|
||
ApplyFilters();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 应用搜索和状态筛选
|
||
/// </summary>
|
||
private void ApplyFilters()
|
||
{
|
||
var stations = dataService.GetAllStations();
|
||
|
||
// 应用搜索筛选
|
||
var searchText = txtSearch.Text.Trim().ToLower();
|
||
if (!string.IsNullOrEmpty(searchText))
|
||
{
|
||
stations = stations
|
||
.Where(s => s.StationId.ToLower().Contains(searchText) ||
|
||
s.Name.ToLower().Contains(searchText) ||
|
||
s.IpAddress.Contains(searchText) ||
|
||
GetTypeText(s.Type).Contains(searchText))
|
||
.ToList();
|
||
}
|
||
|
||
// 应用状态筛选
|
||
if (cmbStatusFilter != null && cmbStatusFilter.SelectedIndex > 0)
|
||
{
|
||
var filterStatus = GetStatusFromFilterIndex(cmbStatusFilter.SelectedIndex);
|
||
stations = stations.Where(s => s.Status == filterStatus).ToList();
|
||
}
|
||
|
||
// 显示结果
|
||
dgvStations.Rows.Clear();
|
||
foreach (var station in stations)
|
||
{
|
||
var index = dgvStations.Rows.Add(
|
||
station.StationId,
|
||
station.Name,
|
||
GetTypeText(station.Type),
|
||
GetChargeMethodText(station.ChargeMethod),
|
||
//station.IpAddress,
|
||
//station.Port,
|
||
station.SiteId?.ToString() ?? "",
|
||
FormatTimeToMinuteSecond(station.LastSendTime),
|
||
FormatTimeToMinuteSecond(station.LastReceiveTime),
|
||
FormatCommStatusDisplay(station.CommStatus),
|
||
FormatChargeCommandStatusDisplay(station.ChargeCommandStatus),
|
||
FormatMechanismStatusDisplay(station.MechanismStatus),
|
||
string.IsNullOrWhiteSpace(station.CurrentVehicle) ? "-" : station.CurrentVehicle,
|
||
station.BatteryLevel > 0 ? $"{station.BatteryLevel:F1}%" : "-",
|
||
FormatAlarmDisplay(station),
|
||
//station.SetVoltage,
|
||
//station.SetElectricCurrent,
|
||
station.RealTimeVoltage.ToString("F1"),
|
||
station.RealTimeCurrent.ToString("F1"),
|
||
GetStatusText(station.Status),
|
||
station.Enabled ? "是" : "否",
|
||
station.Remarks
|
||
);
|
||
|
||
// 根据状态设置行颜色(扁平化设计)
|
||
var row = dgvStations.Rows[index];
|
||
|
||
// 通讯状态列样式设置(第9列)
|
||
var commCell = row.Cells[9];
|
||
switch (station.CommStatus)
|
||
{
|
||
case CommunicationStatus.Normal:
|
||
commCell.Style.ForeColor = Color.FromArgb(76, 175, 80); // 绿色
|
||
// commCell.Style.Font = new Font(commCell.Style.Font ?? row.DefaultCellStyle.Font, FontStyle.Bold);
|
||
break;
|
||
case CommunicationStatus.Delayed:
|
||
commCell.Style.ForeColor = Color.FromArgb(255, 152, 0); // 橙色
|
||
// commCell.Style.Font = new Font(commCell.Style.Font ?? row.DefaultCellStyle.Font, FontStyle.Bold);
|
||
break;
|
||
case CommunicationStatus.Timeout:
|
||
case CommunicationStatus.Disconnected:
|
||
commCell.Style.ForeColor = Color.FromArgb(244, 67, 54); // 红色
|
||
// commCell.Style.Font = new Font(commCell.Style.Font ?? row.DefaultCellStyle.Font, FontStyle.Bold);
|
||
break;
|
||
case CommunicationStatus.Unknown:
|
||
commCell.Style.ForeColor = Color.FromArgb(158, 158, 158); // 灰色
|
||
break;
|
||
}
|
||
|
||
// 充电指令状态列样式设置(第10列)
|
||
var chargeCommandCell = row.Cells[10];
|
||
switch (station.ChargeCommandStatus)
|
||
{
|
||
case ChargeCommandStatus.Stopped:
|
||
chargeCommandCell.Style.ForeColor = Color.FromArgb(158, 158, 158); // 灰色
|
||
break;
|
||
case ChargeCommandStatus.Started:
|
||
chargeCommandCell.Style.ForeColor = Color.FromArgb(76, 175, 80); // 绿色
|
||
//chargeCommandCell.Style.Font = new Font(chargeCommandCell.Style.Font ?? row.DefaultCellStyle.Font, FontStyle.Bold);
|
||
break;
|
||
}
|
||
|
||
// 机构状态列样式设置(第11列)
|
||
var mechanismCell = row.Cells[11];
|
||
switch (station.MechanismStatus)
|
||
{
|
||
|
||
case MechanismStatus.Retracted:
|
||
mechanismCell.Style.ForeColor = Color.FromArgb(76, 175, 80); // 绿色
|
||
// mechanismCell.Style.Font = new Font(mechanismCell.Style.Font ?? mechanismCell.Style.Font, FontStyle.Bold);
|
||
break;
|
||
case MechanismStatus.Extending:
|
||
mechanismCell.Style.ForeColor = Color.FromArgb(33, 150, 243); // 蓝色
|
||
// mechanismCell.Style.Font = new Font(mechanismCell.Style.Font ?? row.DefaultCellStyle.Font, FontStyle.Bold);
|
||
break;
|
||
}
|
||
|
||
// 电量列样式设置(第13列)
|
||
if (station.BatteryLevel > 0)
|
||
{
|
||
var batteryCell = row.Cells[13];
|
||
if (station.BatteryLevel >= 80)
|
||
{
|
||
batteryCell.Style.ForeColor = Color.FromArgb(76, 175, 80); // 绿色 - 电量充足
|
||
//batteryCell.Style.Font = new Font(batteryCell.Style.Font ?? batteryCell.Style.Font, FontStyle.Bold);
|
||
}
|
||
else if (station.BatteryLevel >= 50)
|
||
{
|
||
batteryCell.Style.ForeColor = Color.FromArgb(33, 150, 243); // 蓝色 - 电量中等
|
||
//batteryCell.Style.Font = new Font(batteryCell.Style.Font ?? batteryCell.Style.Font, FontStyle.Bold);
|
||
}
|
||
else if (station.BatteryLevel >= 20)
|
||
{
|
||
batteryCell.Style.ForeColor = Color.FromArgb(255, 152, 0); // 橙色 - 电量偏低
|
||
//batteryCell.Style.Font = new Font(batteryCell.Style.Font ?? batteryCell.Style.Font, FontStyle.Bold);
|
||
}
|
||
else
|
||
{
|
||
batteryCell.Style.ForeColor = Color.FromArgb(244, 67, 54); // 红色 - 电量低
|
||
//batteryCell.Style.Font = new Font(batteryCell.Style.Font ?? batteryCell.Style.Font, FontStyle.Bold);
|
||
}
|
||
}
|
||
|
||
// 如果有报警,整行显示红色
|
||
if (station.HasAlarm)
|
||
{
|
||
row.DefaultCellStyle.BackColor = Color.FromArgb(255, 205, 210); // 浅红色背景 #FFCDD2
|
||
row.DefaultCellStyle.ForeColor = Color.FromArgb(198, 40, 40); // 深红色文字
|
||
// row.DefaultCellStyle.Font = new Font(row.DefaultCellStyle.Font, FontStyle.Bold);
|
||
}
|
||
else
|
||
{
|
||
// 根据状态设置颜色
|
||
switch (station.Status)
|
||
{
|
||
case ChargeStationStatus.Idle:
|
||
row.DefaultCellStyle.BackColor = Color.FromArgb(232, 245, 233); // 浅绿色 #E8F5E9
|
||
// row.DefaultCellStyle.ForeColor = Color.FromArgb(46, 125, 50); // 深绿色文字
|
||
break;
|
||
case ChargeStationStatus.Charging:
|
||
row.DefaultCellStyle.BackColor = Color.FromArgb(200, 230, 201); // 亮绿色 #C8E6C9
|
||
// row.DefaultCellStyle.ForeColor = Color.FromArgb(27, 94, 32); // 深绿色文字
|
||
break;
|
||
case ChargeStationStatus.Fault:
|
||
row.DefaultCellStyle.BackColor = Color.FromArgb(255, 205, 210); // 浅红色 #FFCDD2
|
||
// row.DefaultCellStyle.ForeColor = Color.FromArgb(198, 40, 40); // 深红色文字
|
||
break;
|
||
case ChargeStationStatus.Battery:
|
||
row.DefaultCellStyle.BackColor = Color.FromArgb(238, 238, 238); // 浅灰色 #EEEEEE
|
||
// row.DefaultCellStyle.ForeColor = Color.FromArgb(97, 97, 97); // 深灰色文字
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 更新标题和统计
|
||
UpdateTitleWithFilter(stations.Count);
|
||
}
|
||
|
||
private void btnStrategyConfig_Click(object sender, EventArgs e)
|
||
{
|
||
try
|
||
{
|
||
// 打开充电策略配置界面
|
||
var strategyConfigForm = new ChargeStrategyConfigForm();
|
||
strategyConfigForm.ShowDialog();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show($"打开策略配置界面失败: {ex.Message}", "错误",
|
||
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
|
||
private void btnCommMonitor_Click(object sender, EventArgs e)
|
||
{
|
||
try
|
||
{
|
||
// 通讯监控窗口仅允许单实例
|
||
if (communicationMonitorForm == null || communicationMonitorForm.IsDisposed)
|
||
{
|
||
communicationMonitorForm = new CommunicationMonitorForm();
|
||
communicationMonitorForm.FormClosed += (s, args) => communicationMonitorForm = null;
|
||
communicationMonitorForm.Show();
|
||
}
|
||
else
|
||
{
|
||
if (communicationMonitorForm.WindowState == FormWindowState.Minimized)
|
||
{
|
||
communicationMonitorForm.WindowState = FormWindowState.Normal;
|
||
}
|
||
communicationMonitorForm.BringToFront();
|
||
communicationMonitorForm.Activate();
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show($"打开通讯监控界面失败: {ex.Message}", "错误",
|
||
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
|
||
private void btnAlarmConfig_Click(object sender, EventArgs e)
|
||
{
|
||
try
|
||
{
|
||
// 打开报警配置界面
|
||
var alarmConfigForm = new AlarmConfigManagementForm();
|
||
alarmConfigForm.ShowDialog();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show($"打开报警配置失败: {ex.Message}", "错误",
|
||
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
|
||
private void btnExport_Click(object sender, EventArgs e)
|
||
{
|
||
try
|
||
{
|
||
var saveDialog = new SaveFileDialog
|
||
{
|
||
Filter = "JSON文件|*.json|CSV文件|*.csv",
|
||
FileName = $"ChargeStations_{DateTime.Now:yyyyMMddHHmmss}"
|
||
};
|
||
|
||
if (saveDialog.ShowDialog() == DialogResult.OK)
|
||
{
|
||
var stations = dataService.GetAllStations();
|
||
if (saveDialog.FilterIndex == 1) // JSON
|
||
{
|
||
var json = Newtonsoft.Json.JsonConvert.SerializeObject(stations, Newtonsoft.Json.Formatting.Indented);
|
||
System.IO.File.WriteAllText(saveDialog.FileName, json);
|
||
}
|
||
else // CSV
|
||
{
|
||
var csv = "编号,名称,类型,IP地址,端口,电压,电流,功率,状态,启用,停靠车的类型,站点ID,备注\n";
|
||
foreach (var s in stations)
|
||
{
|
||
csv += $"{s.StationId},{s.Name},{GetTypeText(s.Type)},{s.IpAddress},{s.Port},{s.SetVoltage},{s.SetElectricCurrent},{s.Power},{GetStatusText(s.Status)},{(s.Enabled ? "是" : "否")},{s.GroupCarType},{s.SiteId},{s.Remarks}\n";
|
||
}
|
||
System.IO.File.WriteAllText(saveDialog.FileName, csv, System.Text.Encoding.UTF8);
|
||
}
|
||
|
||
MessageBox.Show("导出成功!", "提示",
|
||
MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show($"导出失败: {ex.Message}", "错误",
|
||
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|