using SimpleCore; using System; using System.Drawing; using System.Linq; using System.Net.NetworkInformation; using System.Windows.Forms; namespace StandardScene.Charge { /// /// 充电桩管理窗口 /// 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(); } /// /// 初始化自动刷新定时器 /// private void InitializeAutoRefresh() { autoRefreshTimer = new System.Windows.Forms.Timer(); autoRefreshTimer.Interval = 3000; // 每3秒刷新一次 autoRefreshTimer.Tick += AutoRefreshTimer_Tick; autoRefreshTimer.Start(); } /// /// 自动刷新事件 /// 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; } } } } /// /// 窗体关闭时停止定时器 /// 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(); } /// /// 设置表头文字垂直排列 /// 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; } /// /// 自定义绘制列标题(垂直文字) /// 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}"); } } } /// /// 初始化状态筛选下拉框 /// 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; // 默认显示全部 } } /// /// 加载充电桩列表 /// 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); } } /// /// 根据筛选器索引获取状态 /// 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; } } /// /// 更新标题显示筛选信息 /// 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}"; } } /// /// 更新统计信息 /// 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}"; } /// /// 获取状态文本 /// 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 "未知"; } } /// /// 格式化时间为 mm:ss 格式 /// private string FormatTimeToMinuteSecond(DateTime? dateTime) { if (dateTime == null) { return "--:--"; } return dateTime.Value.ToString("mm:ss"); } /// /// 格式化机构伸缩状态显示 /// private string FormatMechanismStatusDisplay(MechanismStatus status) { switch (status) { case MechanismStatus.Extended: return "◆ 伸出"; case MechanismStatus.Retracted: return "◇ 缩回"; case MechanismStatus.Extending: return "▶ 运动中"; default: return "? 未知"; } } /// /// 格式化充电指令状态显示 /// private string FormatChargeCommandStatusDisplay(ChargeCommandStatus status) { switch (status) { case ChargeCommandStatus.Stopped: return "◯ 停止"; case ChargeCommandStatus.Started: return "▶ 启动"; default: return "◯ 停止"; } } /// /// 格式化通讯状态显示 /// 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 "? 未知"; } } /// /// 格式化报警信息显示 /// private string FormatAlarmDisplay(ChargeStation station) { if (!station.HasAlarm) { return "正常"; } string levelText = GetAlarmLevelText(station.AlarmLevel); if (string.IsNullOrWhiteSpace(station.AlarmMessage)) { return $"【{levelText}】"; } return $"{station.AlarmMessage}"; } /// /// 获取报警级别文本 /// 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 "未知"; } } /// /// 获取类型文本 /// private string GetTypeText(ChargeStationType type) { switch (type) { case ChargeStationType.FRLDTall: return "FRLD高款充电桩"; case ChargeStationType.FRLDShort: return "FRLD矮款充电桩"; case ChargeStationType.MuXing: return "牧星充电桩"; default: return "未知"; } } /// /// 获取充电方式文本 /// private string GetChargeMethodText(ChargeMethodType method) { switch (method) { case ChargeMethodType.Ground: return "地充"; case ChargeMethodType.Rear: return "尾充"; case ChargeMethodType.Side: return "侧充"; default: return "未知"; } } /// /// 设置编辑模式 /// /// /// 清空编辑区 /// 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; } /// /// 清空实时状态显示区域 /// 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; } /// /// 设置编辑模式 /// /// true=可编辑,false=只读 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; } /// /// 从编辑区创建充电桩对象 /// 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; } /// /// 加载充电桩到编辑区 /// 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; } /// /// 加载实时状态信息到显示区域 /// 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); // 绿色 } } // ==================== 事件处理 ==================== /// /// 充电方式改变事件 - 控制"屏蔽机构状态交互"选项的显示 /// 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(); } /// /// 应用搜索和状态筛选 /// 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); } } } }