2342 lines
97 KiB
C#
2342 lines
97 KiB
C#
using DevExpress.ClipboardSource.SpreadsheetML;
|
||
using DevExpress.Internal;
|
||
using DevExpress.XtraPrinting;
|
||
using Modbus.Device;
|
||
using Newtonsoft.Json;
|
||
using OfficeOpenXml;
|
||
using OfficeOpenXml.Drawing.Slicer.Style;
|
||
using SQLite;
|
||
using Sunny.UI;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Data;
|
||
using System.Drawing;
|
||
using System.IO;
|
||
using System.Linq;
|
||
using System.Net;
|
||
using System.Threading;
|
||
using System.Threading.Tasks;
|
||
using System.Windows.Forms;
|
||
using 口罩泄露定制款.Data;
|
||
using 口罩泄露定制款.Excle;
|
||
using 口罩泄露定制款.Form;
|
||
using 口罩泄露定制款.Log;
|
||
using 口罩泄露定制款.Modbus;
|
||
using 口罩泄露测试仪控制系统_定制款.窗体;
|
||
|
||
namespace 口罩泄露定制款
|
||
{
|
||
public partial class frm_Main : UIForm
|
||
{
|
||
// 暂停功能相关变量
|
||
private bool isPaused = false;
|
||
private int pausedRemainingSeconds = 0;
|
||
private string currentVideoPath = string.Empty;
|
||
|
||
|
||
UserExcleHelper excleHelper = new UserExcleHelper();
|
||
LoginData loginData = new LoginData();
|
||
Modbus_Connect modbus_Connect;
|
||
public ModbusMaster master;
|
||
Connect_TSI Tsi;
|
||
ExperData experData = new ExperData();
|
||
Function fc;
|
||
BoolSignal bool_Stop = new BoolSignal();
|
||
BoolSignal bool_Start = new BoolSignal();
|
||
DataTable dt_Show = new DataTable();
|
||
ExperData_ExcleHelper experExcleHelper = new ExperData_ExcleHelper();
|
||
private Logger _logger = new Logger();
|
||
frm_vidio form2 = new frm_vidio();
|
||
bool isNG = false;
|
||
|
||
// 1. 成员变量
|
||
private List<string> stepList = new List<string>();
|
||
private int currentStepIndex = 0;
|
||
private System.Windows.Forms.Timer autoStepTimer;
|
||
private System.Windows.Forms.Timer autoStepTimer2;
|
||
private int countdownSeconds = 120;//add by xyy,原版120s
|
||
private bool isNeedRun = false;
|
||
private string CreenValue = string.Empty;
|
||
private const string UserDataFilePath = "UserData.json"; // JSON 文件路径
|
||
// 2. 配置读取
|
||
private void LoadIsNeedRunConfig()
|
||
{
|
||
string configPath = Path.Combine(Application.StartupPath, "UserData.json");
|
||
if (File.Exists(configPath))
|
||
{
|
||
var json = File.ReadAllText(configPath);
|
||
dynamic config = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
|
||
isNeedRun = config?.IsNeedRun == true;//是否运行跑步机
|
||
if (config?.ContentString == "自定义")//大声朗读内容
|
||
{
|
||
CreenValue = config?.CustomScreenValue;
|
||
}
|
||
else
|
||
{
|
||
CreenValue = config?.ScreenValue;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 步骤初始化 - 根据新标准调整
|
||
private void InitStepList()
|
||
{
|
||
stepList.Clear();
|
||
stepList.Add("请到指定测试位置");
|
||
stepList.Add("请将采样管插头插入测量接口");
|
||
if (isNeedRun)
|
||
stepList.Add("请按下跑步机启动按钮");
|
||
stepList.Add("头部静止、不说话,2 min");
|
||
stepList.Add("左右转动头部看检测仓左右墙壁(大约15次),2 min");
|
||
stepList.Add("抬头和低头看检测仓顶和地面(大约15次),2 min");
|
||
stepList.Add("大声阅读屏幕显示文字,2 min");
|
||
stepList.Add("头部静止、不说话,2 min");
|
||
stepList.Add("测试完成,拔下采样管插头,走出测量仓");
|
||
comboBox1.Items.Clear();
|
||
foreach (var step in stepList)
|
||
comboBox1.Items.Add(step);
|
||
}
|
||
|
||
// 4. 自动流程Timer
|
||
private void InitAutoStepTimer()
|
||
{
|
||
if (autoStepTimer == null)
|
||
{
|
||
autoStepTimer = new System.Windows.Forms.Timer();
|
||
autoStepTimer.Interval = 1000;
|
||
autoStepTimer.Tick += (s, e) =>
|
||
{
|
||
countdownSeconds--;
|
||
lb_status.Text = $"{stepList[currentStepIndex]} 倒计时: {countdownSeconds}秒";
|
||
|
||
// 更新form2的标签文本,保留原有内容只更新倒计时部分
|
||
int index = form2.uiLabel1.Text.LastIndexOf("\r\n倒计时:");
|
||
if (index > 0)
|
||
{
|
||
form2.uiLabel1.Text = form2.uiLabel1.Text.Substring(0, index) + $"\r\n倒计时: {countdownSeconds}秒";
|
||
}
|
||
|
||
//form2.axWindowsMediaPlayer1.settings.autoStart = true; // 设置自动播放
|
||
//form2.axWindowsMediaPlayer1.Ctlcontrols.play();
|
||
if (countdownSeconds <= 0)
|
||
{
|
||
autoStepTimer?.Stop();
|
||
GoToNextStep();
|
||
}
|
||
};
|
||
}
|
||
|
||
//countdownTimer = new System.Windows.Forms.Timer();
|
||
//countdownTimer.Interval = 1000; // 1 second interval
|
||
// countdownTimer.Tick += new EventHandler(CountdownTimer_Tick);
|
||
|
||
}
|
||
|
||
|
||
private void InitAutoStepTimer2()
|
||
{
|
||
if (autoStepTimer2 == null)
|
||
{
|
||
autoStepTimer2 = new System.Windows.Forms.Timer();
|
||
autoStepTimer2.Interval = 1000;
|
||
autoStepTimer2.Tick += (s, e) =>
|
||
{
|
||
if (float.Parse(lb_tsi_Indoor.Text) < 7)
|
||
{
|
||
master?.WriteSingleCoil(1, 16, true);
|
||
|
||
}
|
||
else if (float.Parse(lb_tsi_Indoor.Text) > 8)
|
||
{
|
||
master?.WriteSingleCoil(1, 16, false);
|
||
|
||
}
|
||
else
|
||
{
|
||
|
||
}
|
||
|
||
//if (currentStepIndex == 1 && float.Parse(lb_tsi_Indoor.Text) >= 4)
|
||
//{
|
||
// currentStepIndex = 2;
|
||
// GoToStep(2);
|
||
//}
|
||
//else
|
||
//{
|
||
|
||
//}
|
||
};
|
||
}
|
||
}
|
||
|
||
// 5. 流程控制
|
||
private void StartProcess()
|
||
{
|
||
currentStepIndex = 0;
|
||
GoToStep(currentStepIndex);
|
||
}
|
||
|
||
private void GoToNextStep()
|
||
{
|
||
currentStepIndex++;
|
||
GoToStep(currentStepIndex);
|
||
}
|
||
|
||
|
||
private void GoToStep(int index)
|
||
{
|
||
isPaused = false;
|
||
Pause1.Text = "暂停测试";
|
||
Pause1.Style = UIStyle.Red;
|
||
// 检查是否超出步骤列表范围
|
||
if (index >= stepList.Count)
|
||
{
|
||
lb_status.Text = "所有流程已完成!";
|
||
form2.uiLabel1.Text = "所有流程已完成!";
|
||
//btn_NextStep.Enabled = false;
|
||
|
||
//master?.WriteSingleCoil(1, 15, false);
|
||
master?.WriteSingleCoil(1, 16, false);
|
||
autoStepTimer?.Stop();
|
||
autoStepTimer2?.Stop();
|
||
|
||
StopVideo(); // 确保视频停止
|
||
return;
|
||
}
|
||
|
||
// 更新选中步骤和状态文本
|
||
comboBox1.SelectedIndex = index;
|
||
string baseStepText = stepList[index];
|
||
lb_status.Text = baseStepText;
|
||
|
||
// 更新form2的标签文本
|
||
form2.uiLabel1.Text = stepList[index].Contains("大声阅读屏幕显示文字")
|
||
? (baseStepText + "\r\n" + CreenValue)
|
||
: baseStepText;
|
||
|
||
// 处理视频路径(保持原有逻辑)
|
||
string basePath = AppDomain.CurrentDomain.BaseDirectory;
|
||
string videoPath = "";
|
||
|
||
if (isNeedRun)
|
||
{
|
||
switch (index)
|
||
{
|
||
case 3: videoPath = Path.Combine(basePath, "头部静止.MP4"); break;
|
||
case 4: videoPath = Path.Combine(basePath, "左右转头.MP4"); break;
|
||
case 5: videoPath = Path.Combine(basePath, "上下抬头.MP4"); break;
|
||
case 6: videoPath = Path.Combine(basePath, "大声说话.MP4"); break;
|
||
case 7: videoPath = Path.Combine(basePath, "头部静止.MP4"); break;
|
||
default: videoPath = string.Empty; break;
|
||
}
|
||
|
||
// 标记当前步骤是否为需要延迟执行AddDgv的步骤
|
||
bool isDelayAddDgvStep = index > 2 && index < 8;
|
||
if (isDelayAddDgvStep)
|
||
{
|
||
|
||
//master?.WriteSingleCoil(1, 16, true); 1
|
||
Thread.Sleep(100);
|
||
// 修复:使用完整的事件处理方法语法
|
||
EventHandler handler = null;
|
||
handler = new EventHandler((s, e) =>
|
||
{
|
||
if (countdownSeconds <= 1)
|
||
{
|
||
AddDgv();
|
||
//// 移除事件(避免重复执行)
|
||
autoStepTimer.Tick -= handler;
|
||
}
|
||
});
|
||
autoStepTimer.Tick += handler;
|
||
}
|
||
else
|
||
{
|
||
//master?.WriteSingleCoil(1, 16, false); 2
|
||
Thread.Sleep(100);
|
||
}
|
||
|
||
|
||
}
|
||
else
|
||
{
|
||
switch (index)
|
||
{
|
||
case 2: videoPath = Path.Combine(basePath, "头部静止.MP4"); break;
|
||
case 3: videoPath = Path.Combine(basePath, "左右转头.MP4"); break;
|
||
case 4: videoPath = Path.Combine(basePath, "上下抬头.MP4"); break;
|
||
case 5: videoPath = Path.Combine(basePath, "大声说话.MP4"); break;
|
||
case 6: videoPath = Path.Combine(basePath, "头部静止.MP4"); break;
|
||
default: videoPath = string.Empty; break;
|
||
}
|
||
|
||
// 标记当前步骤是否为需要延迟执行AddDgv的步骤
|
||
bool isDelayAddDgvStep = index > 1 && index < 7;
|
||
if (isDelayAddDgvStep)
|
||
{
|
||
//master?.WriteSingleCoil(1, 16, true); 1
|
||
Thread.Sleep(100);
|
||
// 修复:使用完整的事件处理方法语法
|
||
EventHandler handler = null;
|
||
handler = new EventHandler((s, e) =>
|
||
{
|
||
if (countdownSeconds <= 1)
|
||
{
|
||
AddDgv();
|
||
// 移除事件(避免重复执行)
|
||
autoStepTimer.Tick -= handler;
|
||
}
|
||
});
|
||
autoStepTimer.Tick += handler;
|
||
}
|
||
else
|
||
{
|
||
//master?.WriteSingleCoil(1, 16, false); 2
|
||
Thread.Sleep(100);
|
||
}
|
||
|
||
}
|
||
if (index == 0)
|
||
{
|
||
master?.WriteSingleCoil(1, 15, false);
|
||
}
|
||
if (index == 1)
|
||
{
|
||
autoStepTimer2.Start();
|
||
}
|
||
if (index == 2)
|
||
{
|
||
master?.WriteSingleCoil(1, 15, true);
|
||
}
|
||
if (index == 7)
|
||
{
|
||
master?.WriteSingleCoil(1, 15, false);
|
||
}
|
||
// 控制视频播放
|
||
if (!string.IsNullOrEmpty(videoPath) && File.Exists(videoPath))
|
||
{
|
||
form2.axWindowsMediaPlayer1.URL = videoPath;
|
||
form2.axWindowsMediaPlayer1.Ctlcontrols.play();
|
||
}
|
||
else
|
||
{
|
||
StopVideo();
|
||
}
|
||
|
||
// 新的倒计时逻辑:前三步(0-2)30秒,后续4-9步(3-8)120秒
|
||
bool isCountdownStep = index >= 0 && index <= 8;
|
||
if (isCountdownStep)
|
||
{
|
||
// 根据步骤索引设置倒计时秒数,原版前三步30秒,后续120秒
|
||
countdownSeconds = index < 2 ? 30 : index == 7 ? 10 : 120;
|
||
|
||
// 更新状态文本,包含倒计时信息
|
||
lb_status.Text = $"{baseStepText} 倒计时: {countdownSeconds}秒";
|
||
form2.uiLabel1.Text = $"{form2.uiLabel1.Text}\r\n倒计时: {countdownSeconds}秒";
|
||
|
||
// 启动计时器
|
||
autoStepTimer?.Start();
|
||
}
|
||
else
|
||
{
|
||
// 不在倒计时范围内,停止计时器
|
||
autoStepTimer?.Stop();
|
||
}
|
||
}
|
||
|
||
public void RefreshMainData()
|
||
{
|
||
LoadIsNeedRunConfig(); // 先读取配置
|
||
InitStepList(); // 再初始化流程步骤和下拉框
|
||
}
|
||
|
||
// 新增:停止视频播放并清除路径的辅助方法
|
||
private void StopVideo()
|
||
{
|
||
form2.axWindowsMediaPlayer1.Ctlcontrols.stop();
|
||
form2.axWindowsMediaPlayer1.URL = string.Empty;
|
||
}
|
||
|
||
|
||
|
||
|
||
public frm_Main()
|
||
{
|
||
InitializeComponent();
|
||
comboBox1.SelectedIndex = 0;
|
||
|
||
}
|
||
|
||
#region 界面初始化
|
||
private void frm_Main_Load(object sender, EventArgs e)
|
||
{
|
||
try
|
||
{
|
||
Pause1.Text = "暂停测试";
|
||
Pause1.Style = UIStyle.Red;
|
||
|
||
///add by xyy
|
||
LoadIsNeedRunConfig(); // 先读取配置
|
||
InitStepList(); // 再初始化流程步骤和下拉框
|
||
|
||
|
||
//add by xyy 192.168.1.10先改100
|
||
modbus_Connect = new Modbus_Connect("192.168.1.10", 502);
|
||
master = modbus_Connect.GetMaster();
|
||
master?.WriteSingleCoil(1, 132, false);
|
||
Task.Run(() => Read_PLC_Data());
|
||
fc = new Function(master);
|
||
|
||
comboBox1.Enabled = false;
|
||
//form2.axWindowsMediaPlayer1.PlayStateChange +=
|
||
// new AxWMPLib._WMPOCXEvents_PlayStateChangeEventHandler(
|
||
// axWindowsMediaPlayer1_PlayStateChange);
|
||
}
|
||
catch (Exception EX)
|
||
{
|
||
MessageBox.Show("控制器连接失败!" + "\n" + "错误原因:" + EX.Message, "错误");
|
||
}
|
||
|
||
try
|
||
{
|
||
Tsi = new Connect_TSI("COM18", "COM8");
|
||
Tsi.Connect();
|
||
|
||
Tsi.Start_Indoor();
|
||
Tsi.Start_Outdoor();
|
||
Tsi.Start_bendidoor();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show("光度计连接失败!" + "\n" + "错误原因:" + ex.Message, "错误");
|
||
}
|
||
bool_Stop.OnRisingEdge += bool_Stop_OnRisingEdge;
|
||
// bool_Start.OnRisingEdge += bool_Start_OnRisingEdge;
|
||
Task.Run(() =>
|
||
{
|
||
while (true)
|
||
{
|
||
bool_Stop.Value = data_M130_M135[2];
|
||
bool_Start.Value = data_M130_M135[0];
|
||
//bool_Stop.Value = false;//add by xyy
|
||
//bool_Stop.Value = true;//add by xyy
|
||
bool_Stop.CheckRisingEdge();
|
||
bool_Start.CheckRisingEdge();
|
||
Thread.Sleep(10);
|
||
|
||
}
|
||
});
|
||
tslb_登录用户.Text = loginData.UserName;
|
||
UserAuthority();
|
||
InitializeDgv();
|
||
experData.TestStatus = comboBox1.Text;
|
||
_logger.Log(experData.ExperName, "登陆系统", loginData.UserPower.ToString());
|
||
form2.Show();
|
||
}
|
||
|
||
void InitializeDgv()
|
||
{
|
||
|
||
|
||
dt_Show.Columns.Add("姓名");
|
||
dt_Show.Columns.Add("性别");
|
||
dt_Show.Columns.Add("年龄");
|
||
dt_Show.Columns.Add("身份证号码");
|
||
dt_Show.Columns.Add("工作单位");
|
||
dt_Show.Columns.Add("工龄");
|
||
|
||
|
||
|
||
dt_Show.Columns.Add("日期");
|
||
dt_Show.Columns.Add("时间");
|
||
dt_Show.Columns.Add("实验员");
|
||
|
||
dt_Show.Columns.Add("样品编号");
|
||
dt_Show.Columns.Add("样品类别");
|
||
dt_Show.Columns.Add("测试状态");
|
||
|
||
dt_Show.Columns.Add("环境温度(℃)");
|
||
dt_Show.Columns.Add("环境湿度(%RH)");
|
||
dt_Show.Columns.Add("本底浓度(mg/m³)");
|
||
dt_Show.Columns.Add("室内浓度平均值(mg/m³)");
|
||
dt_Show.Columns.Add("呼吸器内气溶胶平均值(mg/m³)");
|
||
dt_Show.Columns.Add("泄露率(%)");
|
||
dgv_expirData.DataSource = dt_Show;
|
||
dgv_expirData.Font = new System.Drawing.Font("黑体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
|
||
|
||
dgv_expirData.Columns[12].Width = 250;
|
||
dgv_expirData.Columns[13].Width = 250;
|
||
dgv_expirData.Columns[14].Width = 200;
|
||
dgv_expirData.Columns[15].Width = 250;
|
||
dgv_expirData.Columns[16].Width = 250;
|
||
|
||
}
|
||
|
||
//void AddDgv()
|
||
//{
|
||
// float _TsiIndoorAgv = 0.0f;
|
||
// float _TsiOutdoorAgv = 0.0f;
|
||
// float _Xieloulv = 0.0f;
|
||
// if (dt_Show.Columns.Count != 0)
|
||
// {
|
||
// if (list_Tsi_Indoor_Data.Count != 0 && list_Tsi_Outdoor_Data.Count != 0)
|
||
// {
|
||
// _TsiIndoorAgv = list_Tsi_Indoor_Data.Average();
|
||
// _TsiOutdoorAgv = list_Tsi_Outdoor_Data.Average();
|
||
// _Xieloulv = lsit_XieLoulv.Average();
|
||
// }
|
||
// else
|
||
// {
|
||
// _TsiIndoorAgv = 0.0f;
|
||
// _TsiOutdoorAgv = 0.0f;
|
||
// _Xieloulv = 0.0f;
|
||
// }
|
||
|
||
// 口罩泄露测试仪控制系统_定制款.窗体.UserData userData = new 口罩泄露测试仪控制系统_定制款.窗体.UserData();
|
||
// if (File.Exists(UserDataFilePath))
|
||
// {
|
||
// string json = File.ReadAllText(UserDataFilePath);
|
||
// userData = JsonConvert.DeserializeObject<口罩泄露测试仪控制系统_定制款.窗体.UserData>(json);
|
||
// }
|
||
|
||
// dt_Show.Rows.Add(
|
||
// userData?.Name,
|
||
// userData?.Sex,
|
||
// userData?.Age,
|
||
// userData?.IdNumber,
|
||
// userData?.Company,
|
||
// userData?.CompanyAge,
|
||
// DateTime.Now.ToString("yyyy-MM-dd"),
|
||
// DateTime.Now.ToString("HH-mm-ss"),
|
||
// experData.ExperName,
|
||
// experData.ExperNum,
|
||
// experData.ExperType,
|
||
// comboBox1.Text,
|
||
// experData.HuanJingWenDu,
|
||
// experData.HuanJingShiDu,
|
||
// experData.BenDiNongDu,
|
||
// _TsiIndoorAgv,
|
||
// _TsiOutdoorAgv,
|
||
// _Xieloulv);
|
||
|
||
// this.Invoke(new Action(() =>
|
||
// {
|
||
// dgv_expirData.Refresh();
|
||
|
||
// InsertDataToDatabase();
|
||
// }));
|
||
// }
|
||
|
||
|
||
|
||
|
||
|
||
// // dt_Show.Rows.Add("1","2","3","4","5","6","7","8","9","10");
|
||
//}
|
||
void AddDgv()
|
||
{
|
||
float _TsiIndoorAgv = 0.0f;
|
||
float _TsiOutdoorAgv = 0.0f;
|
||
float _Xieloulv = 0.0f;
|
||
|
||
if (dt_Show.Columns.Count != 0)
|
||
{
|
||
// 使用最后100秒数据计算(标准要求)
|
||
int dataCount = Math.Min(list_Tsi_Indoor_Data.Count, list_Tsi_Outdoor_Data.Count);
|
||
int startIndex = Math.Max(0, dataCount - 100);
|
||
|
||
List<float> last100Indoor = new List<float>();
|
||
List<float> last100Outdoor = new List<float>();
|
||
|
||
for (int i = startIndex; i < dataCount; i++)
|
||
{
|
||
last100Indoor.Add(list_Tsi_Indoor_Data[i]);
|
||
last100Outdoor.Add(list_Tsi_Outdoor_Data[i]);
|
||
}
|
||
|
||
if (last100Indoor.Count > 0 && last100Outdoor.Count > 0)
|
||
{
|
||
_TsiIndoorAgv = last100Indoor.Average();
|
||
_TsiOutdoorAgv = last100Outdoor.Average();
|
||
|
||
// 使用连续采样法计算公式
|
||
_Xieloulv = experData.ContinuousSamplingLeakageRate(
|
||
last100Indoor,
|
||
last100Outdoor,
|
||
experData.BenDiNongDu,
|
||
experData.SamplingFlowRate,
|
||
experData.DryingFlowRate);
|
||
}
|
||
else
|
||
{
|
||
_TsiIndoorAgv = 0.0f;
|
||
_TsiOutdoorAgv = 0.0f;
|
||
_Xieloulv = 0.0f;
|
||
}
|
||
|
||
口罩泄露测试仪控制系统_定制款.窗体.UserData userData = new 口罩泄露测试仪控制系统_定制款.窗体.UserData();
|
||
if (File.Exists(UserDataFilePath))
|
||
{
|
||
string json = File.ReadAllText(UserDataFilePath);
|
||
userData = JsonConvert.DeserializeObject<口罩泄露测试仪控制系统_定制款.窗体.UserData>(json);
|
||
}
|
||
|
||
dt_Show.Rows.Add(
|
||
userData?.Name,
|
||
userData?.Sex,
|
||
userData?.Age,
|
||
userData?.IdNumber,
|
||
userData?.Company,
|
||
userData?.CompanyAge,
|
||
DateTime.Now.ToString("yyyy-MM-dd"),
|
||
DateTime.Now.ToString("HH-mm-ss"),
|
||
experData.ExperName,
|
||
experData.ExperNum,
|
||
experData.ExperType,
|
||
comboBox1.Text,
|
||
experData.HuanJingWenDu.ToString("F1"),
|
||
experData.HuanJingShiDu.ToString("F1"),
|
||
experData.BenDiNongDu.ToString("F3"),
|
||
_TsiIndoorAgv.ToString("F3"),
|
||
_TsiOutdoorAgv.ToString("F3"),
|
||
_Xieloulv.ToString("F2"));
|
||
|
||
this.Invoke(new Action(() =>
|
||
{
|
||
dgv_expirData.Refresh();
|
||
InsertDataToDatabase();
|
||
}));
|
||
}
|
||
}
|
||
|
||
private void InsertDataToDatabase()
|
||
{
|
||
float _Xieloulv = 0.0f;
|
||
_Xieloulv = experData.ContinuousSamplingLeakageRate(
|
||
list_Tsi_Indoor_Data,
|
||
list_Tsi_Outdoor_Data,
|
||
experData.BenDiNongDu,
|
||
experData.SamplingFlowRate,
|
||
experData.DryingFlowRate);
|
||
|
||
|
||
// 读取用户数据
|
||
口罩泄露测试仪控制系统_定制款.窗体.UserData userData = new 口罩泄露测试仪控制系统_定制款.窗体.UserData();
|
||
if (File.Exists(UserDataFilePath))
|
||
{
|
||
string json = File.ReadAllText(UserDataFilePath);
|
||
userData = JsonConvert.DeserializeObject<口罩泄露测试仪控制系统_定制款.窗体.UserData>(json);
|
||
}
|
||
|
||
// 创建 SQLite 连接并初始化
|
||
string dbPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Data.db");
|
||
SQLiteConnection _db = new SQLiteConnection(dbPath);
|
||
_db.CreateTable<Experiment>();
|
||
|
||
// 构建 Experiment 对象
|
||
Experiment experiment = new Experiment
|
||
{
|
||
Name = userData?.Name,
|
||
Sex = userData?.Sex,
|
||
Age = userData?.Age != null ? int.Parse(userData.Age) : (int?)null,
|
||
IdNumber = userData?.IdNumber,
|
||
Company = userData?.Company,
|
||
CompanyAge = userData?.CompanyAge != null ? int.Parse(userData.CompanyAge) : (int?)null,
|
||
Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
||
Time = DateTime.Now.ToString("HH-mm-ss"),
|
||
ExperName = experData.ExperName,
|
||
//ExperNum = experData.ExperNum,
|
||
ExperType = experData.ExperType,
|
||
MaskType = userData.FullMaskType,
|
||
TestStatus = comboBox1.Text,
|
||
HuanJingWenDu = experData.HuanJingWenDu,
|
||
HuanJingShiDu = experData.HuanJingShiDu,
|
||
BenDiNongDu = experData.BenDiNongDu,
|
||
TsiIndoorAgv = list_Tsi_Indoor_Data.Any() ? list_Tsi_Indoor_Data.Average() : 0,
|
||
TsiOutdoorAgv = list_Tsi_Outdoor_Data.Any() ? list_Tsi_Outdoor_Data.Average() : 0,
|
||
Xieloulv = _Xieloulv //lsit_XieLoulv.Any() ? lsit_XieLoulv.Average() : 0
|
||
};
|
||
|
||
// 插入数据
|
||
try
|
||
{
|
||
_db.Insert(experiment);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
// 处理异常,这里可以根据实际需求进行日志记录或者弹窗提示等
|
||
Console.WriteLine($"插入数据失败: {ex.Message}");
|
||
}
|
||
finally
|
||
{
|
||
_db.Close();
|
||
}
|
||
}
|
||
|
||
//private void InsertDataToDatabase()
|
||
//{
|
||
// // 读取用户数据
|
||
// 口罩泄露测试仪控制系统_定制款.窗体.UserData userData = new 口罩泄露测试仪控制系统_定制款.窗体.UserData();
|
||
// if (File.Exists(UserDataFilePath))
|
||
// {
|
||
// string json = File.ReadAllText(UserDataFilePath);
|
||
// userData = JsonConvert.DeserializeObject<口罩泄露测试仪控制系统_定制款.窗体.UserData>(json);
|
||
// }
|
||
|
||
// // 创建 SQLite 连接并初始化
|
||
// string dbPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Data.db");
|
||
// SQLiteConnection _db = new SQLiteConnection(dbPath);
|
||
// _db.CreateTable<Experiment>();
|
||
|
||
// // 构建 Experiment 对象
|
||
// Experiment experiment = new Experiment
|
||
// {
|
||
// Name = userData?.Name,
|
||
// Sex = userData?.Sex,
|
||
// Age = userData?.Age != null ? int.Parse(userData.Age) : (int?)null,
|
||
// IdNumber = userData?.IdNumber,
|
||
// Company = userData?.Company,
|
||
// CompanyAge = userData?.CompanyAge != null ? int.Parse(userData.CompanyAge) : (int?)null,
|
||
// Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
||
// Time = DateTime.Now.ToString("HH-mm-ss"),
|
||
// ExperName = experData.ExperName,
|
||
// //ExperNum = experData.ExperNum,
|
||
// ExperType = experData.ExperType,
|
||
// MaskType = userData.FullMaskType,
|
||
// TestStatus = comboBox1.Text,
|
||
// HuanJingWenDu = experData.HuanJingWenDu,
|
||
// HuanJingShiDu = experData.HuanJingShiDu,
|
||
// BenDiNongDu = experData.BenDiNongDu,
|
||
// TsiIndoorAgv = list_Tsi_Indoor_Data.Any() ? list_Tsi_Indoor_Data.Average() : 0,
|
||
// TsiOutdoorAgv = list_Tsi_Outdoor_Data.Any() ? list_Tsi_Outdoor_Data.Average() : 0,
|
||
// Xieloulv = lsit_XieLoulv.Any() ? lsit_XieLoulv.Average() : 0
|
||
// };
|
||
|
||
// // 插入数据
|
||
// try
|
||
// {
|
||
// _db.Insert(experiment);
|
||
// }
|
||
// catch (Exception ex)
|
||
// {
|
||
// // 处理异常,这里可以根据实际需求进行日志记录或者弹窗提示等
|
||
// Console.WriteLine($"插入数据失败: {ex.Message}");
|
||
// }
|
||
// finally
|
||
// {
|
||
// _db.Close();
|
||
// }
|
||
//}
|
||
|
||
Random rd = new Random();
|
||
private void timer_date_Tick(object sender, EventArgs e)
|
||
{
|
||
//刷新时间
|
||
tslb_time.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
||
//刷新界面数据
|
||
Resfh_UI_Data();
|
||
}
|
||
private void Resfh_UI_Data()
|
||
{
|
||
tslb_实验类型.Text = experData.ExperType;
|
||
tslb_实验编号.Text = experData.ExperNum;
|
||
lb_YangNongdu.Text = experData.O2NongDu.ToString("F2");
|
||
lb_shiDu.Text = experData.HuanJingShiDu.ToString("F2");
|
||
lb_wenDu.Text = experData.HuanJingWenDu.ToString("F2");
|
||
lb_CO2_Indoor.Text = experData.CO2NongDu_Indoor.ToString("F2");
|
||
lb_co2_OutDoor.Text = experData.Mask_CO2NongDu.ToString("F2");
|
||
lb_tsi_Indoor.Text = experData.InDoor_TSINongDu.ToString("F3");
|
||
lb_tsi_OutDoor.Text = experData.Mask_TSINongDu.ToString("F3");
|
||
|
||
|
||
|
||
lb_泄露率.Text = experData.XieLouLv.ToString("F2");
|
||
label16.Text = TestTime.ToString();
|
||
if (data_M6_M7[1])
|
||
{ btn_Light.Text = "照明关"; btn_Light.ForeColor = System.Drawing.Color.Red; }
|
||
else
|
||
{ btn_Light.Text = "照明开"; btn_Light.ForeColor = System.Drawing.Color.Black; }
|
||
if (data_M6_M7[0])
|
||
{ btn_风机.Text = "风机关"; btn_风机.ForeColor = System.Drawing.Color.Red; }
|
||
else
|
||
{ btn_风机.Text = "风机开"; btn_风机.ForeColor = System.Drawing.Color.Black; }
|
||
}
|
||
|
||
//用户权限判断
|
||
void UserAuthority()
|
||
{
|
||
switch (loginData.UserPower)
|
||
{
|
||
case 0:
|
||
ts_新建实验.Enabled = true;
|
||
ts_参数设置.Enabled = true;
|
||
ts_实验数据.Enabled = true;
|
||
ts_审计追踪.Enabled = true;
|
||
ts_用户管理.Enabled = true;
|
||
tsbtn_新增用户.Enabled = true;
|
||
toolStripButton1.Enabled = true;
|
||
break;
|
||
case 1:
|
||
ts_新建实验.Enabled = true;
|
||
ts_参数设置.Enabled = true;
|
||
ts_实验数据.Enabled = true;
|
||
ts_审计追踪.Enabled = true;
|
||
ts_用户管理.Enabled = false;
|
||
tsbtn_新增用户.Enabled = true;
|
||
toolStripButton1.Enabled = false;
|
||
break;
|
||
case 2:
|
||
ts_新建实验.Enabled = true;
|
||
ts_参数设置.Enabled = false;
|
||
ts_实验数据.Enabled = true;
|
||
ts_审计追踪.Enabled = false;
|
||
ts_用户管理.Enabled = false;
|
||
tsbtn_新增用户.Enabled = false;
|
||
toolStripButton1.Enabled = false;
|
||
break;
|
||
case 3:
|
||
ts_新建实验.Enabled = true;
|
||
ts_参数设置.Enabled = false;
|
||
ts_实验数据.Enabled = false;
|
||
ts_审计追踪.Enabled = false;
|
||
ts_用户管理.Enabled = false;
|
||
tsbtn_新增用户.Enabled = false;
|
||
toolStripButton1.Enabled = false;
|
||
break;
|
||
case 4:
|
||
ts_新建实验.Enabled = false;
|
||
ts_参数设置.Enabled = false;
|
||
ts_实验数据.Enabled = false;
|
||
ts_审计追踪.Enabled = false;
|
||
ts_用户管理.Enabled = false;
|
||
tsbtn_新增用户.Enabled = false;
|
||
toolStripButton1.Enabled = false;
|
||
break;
|
||
}
|
||
|
||
}
|
||
#endregion
|
||
|
||
#region 画面切换
|
||
private void tsbtn_新增用户_Click(object sender, EventArgs e)
|
||
{
|
||
frm_AddUser addUser = new frm_AddUser();
|
||
addUser.ShowDialog();
|
||
}
|
||
|
||
private void tsbtn_切换用户_Click(object sender, EventArgs e)
|
||
{
|
||
this.Close();
|
||
}
|
||
|
||
|
||
private void ts_用户管理_Click(object sender, EventArgs e)
|
||
{
|
||
frm_UserSetting userSetting = new frm_UserSetting();
|
||
userSetting.ShowDialog();
|
||
}
|
||
|
||
private void ts_审计追踪_Click(object sender, EventArgs e)
|
||
{
|
||
frm_Audit_Trail audit_Trail = new frm_Audit_Trail();
|
||
audit_Trail.ShowDialog();
|
||
|
||
}
|
||
|
||
private void ts_新建实验_Click(object sender, EventArgs e)
|
||
{
|
||
frm_AddNewExperiment addUser = new frm_AddNewExperiment(this);
|
||
addUser.ShowDialog();
|
||
}
|
||
|
||
private void ts_参数设置_Click(object sender, EventArgs e)
|
||
{
|
||
frm_ExperSetting experSetting = new frm_ExperSetting(master);
|
||
experSetting.ShowDialog();
|
||
}
|
||
|
||
private void ts_实验数据_Click(object sender, EventArgs e)
|
||
{
|
||
frm_ExperData experData = new frm_ExperData();
|
||
experData.ShowDialog();
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region
|
||
private void frm_Main_FormClosing(object sender, System.Windows.Forms.FormClosingEventArgs e)
|
||
{
|
||
Tsi.Stop_Indoor();
|
||
Tsi.Stop_Outdoor();
|
||
Tsi.Stop_bendidoor();
|
||
|
||
Tsi.Disconnect();
|
||
modbus_Connect.DisConnect();
|
||
this.Dispose();
|
||
}
|
||
|
||
|
||
|
||
|
||
#endregion
|
||
|
||
#region PLC数据读取
|
||
|
||
ushort[] data_D300_D320 = new ushort[21];
|
||
ushort[] data_D250_D299 = new ushort[50];
|
||
ushort[] data_D400_D499 = new ushort[100];
|
||
ushort[] data_D500_D507 = new ushort[8];
|
||
bool[] data_M6_M7 = new bool[2];
|
||
bool[] data_M60_M65 = new bool[6];
|
||
bool[] data_M90_M95 = new bool[6];
|
||
bool[] data_M130_M135 = new bool[6];
|
||
DataChange dc = new DataChange();
|
||
int TestTime = 0;
|
||
void Read_PLC_Data()
|
||
{
|
||
while (true)
|
||
{
|
||
if (this.IsDisposed || master == null)
|
||
{
|
||
break;
|
||
}
|
||
|
||
try
|
||
{
|
||
//读取PLC数据
|
||
data_D300_D320 = master?.ReadHoldingRegisters(1, 300, 20);
|
||
data_D250_D299 = master?.ReadHoldingRegisters(1, 250, 50);
|
||
data_D400_D499 = master?.ReadHoldingRegisters(1, 400, 100);
|
||
data_D500_D507 = master?.ReadHoldingRegisters(1, 500, 8);
|
||
data_M6_M7 = master?.ReadCoils(1, 6, 2);
|
||
data_M60_M65 = master?.ReadCoils(1, 60, 6);
|
||
data_M90_M95 = master?.ReadCoils(1, 90, 6);
|
||
data_M130_M135 = master?.ReadCoils(1, 130, 6);
|
||
|
||
//显示PLC数据
|
||
experData.LiuLiang = dc.UshortToFloat(data_D300_D320[1], data_D300_D320[0]);
|
||
experData.Mask_CO2NongDu = dc.UshortToFloat(data_D300_D320[3], data_D300_D320[2]);
|
||
experData.CO2NongDu_Indoor = dc.UshortToFloat(data_D300_D320[5], data_D300_D320[4]);
|
||
experData.O2NongDu = dc.UshortToFloat(data_D300_D320[7], data_D300_D320[6]);
|
||
experData.HuanJingWenDu = dc.UshortToFloat(data_D300_D320[9], data_D300_D320[8]);
|
||
experData.HuanJingShiDu = dc.UshortToFloat(data_D300_D320[11], data_D300_D320[10]);
|
||
experData.InDoor_TSINongDu = Tsi.Indoor_Data;//modified by xyy
|
||
experData.Mask_TSINongDu = Tsi.Outdoor_Data;//modified by xyy
|
||
|
||
//experData.BenDiNongDu = Tsi.sp_bendiData.ToFloat();
|
||
|
||
|
||
TestTime = dc.UshortToInt1(data_D250_D299[0], data_D250_D299[1]);
|
||
Thread.Sleep(100);
|
||
}
|
||
catch
|
||
{
|
||
break;
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
|
||
#endregion
|
||
|
||
private void btn_Light_Click(object sender, EventArgs e)
|
||
{
|
||
fc.BtnClickFunction(Function.ButtonType.切换型, 7);
|
||
}
|
||
|
||
private void btn_风机_Click(object sender, EventArgs e)
|
||
{
|
||
fc.BtnClickFunction(Function.ButtonType.切换型, 6);
|
||
}
|
||
|
||
private void toolStripButton1_Click(object sender, EventArgs e)
|
||
{
|
||
frm_Motor _Motor = new frm_Motor(master);
|
||
_Motor.ShowDialog();
|
||
}
|
||
|
||
|
||
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
|
||
{
|
||
int idx = comboBox1.SelectedIndex;
|
||
if (idx < 0 || idx >= stepList.Count)
|
||
return;
|
||
|
||
string step = stepList[idx];
|
||
lb_status.Text = step;
|
||
|
||
// 判断是否为“朗读文字”步骤
|
||
if (step.Contains("大声阅读屏幕显示文字"))
|
||
{
|
||
form2.uiLabel1.Text = step;
|
||
form2.uiLabel1.Text += CreenValue;
|
||
}
|
||
else
|
||
{
|
||
form2.uiLabel1.Text = step;
|
||
}
|
||
|
||
_logger.Log(loginData.UserName, $"切换了实验状态为【{step}】", loginData.UserPower.ToString());
|
||
}
|
||
|
||
#region 实验数据记录
|
||
List<List<List<float>>> list_AllDaata = new List<List<List<float>>>();//所有数据
|
||
List<List<string>> list_AllTime = new List<List<string>>();//所有时间
|
||
List<List<float>> liatAll = new List<List<float>>();//总数据汇总
|
||
List<string> list_Time = new List<string>();//时间
|
||
List<float> list_Tsi_Indoor_Data = new List<float>();//室内气溶胶浓度
|
||
List<float> list_Tsi_Outdoor_Data = new List<float>();//口罩内气溶胶浓度
|
||
List<float> lsit_XieLoulv = new List<float>();//泄露率
|
||
List<float> list_CO2_Indoor_Data = new List<float>();//室内CO2浓度
|
||
List<float> list_CO2_Outdoor_Data = new List<float>();//口罩内CO2浓度
|
||
List<float> list_O2_Data = new List<float>();//氧气浓度
|
||
List<float> list_HuanJingWenDu_Data = new List<float>();//环境内温度
|
||
List<float> list_HuanJingShiDu_Data = new List<float>();//环境湿度
|
||
// 修改timer_UpdataChart_Tick - 实时泄漏率计算
|
||
private void timer_UpdataChart_Tick(object sender, EventArgs e)
|
||
{
|
||
int currindex = 0;
|
||
if (isNeedRun)
|
||
{
|
||
currindex = 3;
|
||
}
|
||
else
|
||
{
|
||
currindex = 2;
|
||
}
|
||
|
||
if (data_M130_M135[1] && currentStepIndex >= currindex)
|
||
{
|
||
list_Time.Add(DateTime.Now.ToString("HH:mm:ss"));
|
||
list_Tsi_Indoor_Data.Add(experData.InDoor_TSINongDu);
|
||
list_Tsi_Outdoor_Data.Add(experData.Mask_TSINongDu);
|
||
|
||
// 使用最后100秒数据计算实时泄漏率
|
||
int dataCount = Math.Min(list_Tsi_Indoor_Data.Count, list_Tsi_Outdoor_Data.Count);
|
||
int startIndex = Math.Max(0, dataCount - 100);
|
||
|
||
List<float> last100Indoor = new List<float>();
|
||
List<float> last100Outdoor = new List<float>();
|
||
|
||
for (int i = startIndex; i < dataCount; i++)
|
||
{
|
||
last100Indoor.Add(list_Tsi_Indoor_Data[i]);
|
||
last100Outdoor.Add(list_Tsi_Outdoor_Data[i]);
|
||
}
|
||
|
||
if (last100Indoor.Count > 0 && last100Outdoor.Count > 0)
|
||
{
|
||
experData.XieLouLv = experData.ContinuousSamplingLeakageRate(
|
||
last100Indoor,
|
||
last100Outdoor,
|
||
experData.BenDiNongDu,
|
||
experData.SamplingFlowRate,
|
||
experData.DryingFlowRate);
|
||
}
|
||
|
||
lsit_XieLoulv.Add(experData.XieLouLv);
|
||
list_CO2_Indoor_Data.Add(experData.CO2NongDu_Indoor);
|
||
list_CO2_Outdoor_Data.Add(experData.Mask_CO2NongDu);
|
||
list_O2_Data.Add(experData.O2NongDu);
|
||
list_HuanJingWenDu_Data.Add(experData.HuanJingWenDu);
|
||
list_HuanJingShiDu_Data.Add(experData.HuanJingShiDu);
|
||
|
||
chart_TSI.Series[0].Points.DataBindXY(list_Time, list_Tsi_Indoor_Data);
|
||
chart_TSI.Series[1].Points.DataBindXY(list_Time, list_Tsi_Outdoor_Data);
|
||
chart_TSI.Series[2].Points.DataBindXY(list_Time, lsit_XieLoulv);
|
||
chart2.Series[0].Points.DataBindXY(list_Time, list_CO2_Indoor_Data);
|
||
chart2.Series[1].Points.DataBindXY(list_Time, list_CO2_Outdoor_Data);
|
||
chart2.Series[2].Points.DataBindXY(list_Time, list_O2_Data);
|
||
chart2.Series[3].Points.DataBindXY(list_Time, list_HuanJingWenDu_Data);
|
||
chart2.Series[4].Points.DataBindXY(list_Time, list_HuanJingShiDu_Data);
|
||
}
|
||
}
|
||
//结束时写入Excel
|
||
public static int comindex;
|
||
void bool_Stop_OnRisingEdge()
|
||
{
|
||
float xieLouLue_Agv = 0.0f;
|
||
int selectIndex = 0;
|
||
if (lsit_XieLoulv.Count != 0)
|
||
xieLouLue_Agv = lsit_XieLoulv.Average();
|
||
if (xieLouLue_Agv > experData.ExperMaskType)
|
||
{
|
||
form2.Invoke(new Action(() =>
|
||
{
|
||
form2.uiLabel1.Text = "测试失败!请等待指令重做实验!";
|
||
}));
|
||
MessageBox.Show("泄露率达到" + xieLouLue_Agv.ToString("F2") + "\n" + "不符合标准!请重做实验", "失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
|
||
}
|
||
else
|
||
{
|
||
// var result = MessageBox.Show("测试完成!" + "\n" + "是否保存数据?", "完成!", MessageBoxButtons.YesNo);
|
||
//如果点Yes,则写入Excel
|
||
//如果点No,则不写入Excel
|
||
|
||
List<string> _tempTimeList = new List<string>(list_Time);
|
||
List<float> _templist_Tsi_Indoor_Data = new List<float>(list_Tsi_Indoor_Data);
|
||
List<float> _templist_Tsi_Outdoor_Data = new List<float>(list_Tsi_Outdoor_Data);
|
||
List<float> _templsit_XieLoulv = new List<float>(lsit_XieLoulv);
|
||
List<float> _templist_CO2_Indoor_Data = new List<float>(list_CO2_Indoor_Data);
|
||
List<float> _templist_CO2_Outdoor_Data = new List<float>(list_CO2_Outdoor_Data);
|
||
List<float> _templist_O2_Data = new List<float>(list_O2_Data);
|
||
List<float> _templist_HuanJingWenDu_Data = new List<float>(list_HuanJingWenDu_Data);
|
||
List<float> _templist_HuanJingShiDu_Data = new List<float>(list_HuanJingShiDu_Data);
|
||
|
||
liatAll.Add(_templist_Tsi_Indoor_Data);
|
||
liatAll.Add(_templist_Tsi_Outdoor_Data);
|
||
liatAll.Add(_templsit_XieLoulv);
|
||
liatAll.Add(_templist_CO2_Indoor_Data);
|
||
liatAll.Add(_templist_CO2_Outdoor_Data);
|
||
liatAll.Add(_templist_O2_Data);
|
||
liatAll.Add(_templist_HuanJingWenDu_Data);
|
||
liatAll.Add(_templist_HuanJingShiDu_Data);
|
||
|
||
List<List<float>> _templiatAll = new List<List<float>>(liatAll);
|
||
|
||
list_AllDaata.Add(_templiatAll);
|
||
list_AllTime.Add(_tempTimeList);
|
||
//AddDgv();
|
||
this.Invoke(new Action(() =>
|
||
{
|
||
selectIndex = comboBox1.SelectedIndex;
|
||
}));
|
||
//if (selectIndex < stepList.Count - 1)
|
||
//{
|
||
// form2.Invoke(new Action(() =>
|
||
// {
|
||
// form2.uiLabel1.Text = "本次动作测试完成请等待10s后进行下一动作!";
|
||
// }));
|
||
|
||
|
||
// Task.Delay(10000).Wait();
|
||
// this.Invoke(new Action(() =>
|
||
//{
|
||
// comboBox1.SelectedIndex += 1;
|
||
// experData.TestStatus = comboBox1.Text;
|
||
// btn_Start.PerformClick();
|
||
//}));
|
||
|
||
//}
|
||
//else
|
||
//{
|
||
// MessageBox.Show("所有动作测试完成!");
|
||
//}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
#region 按钮事件
|
||
// 修改btn_Start_Click - 加载配置参数
|
||
private void btn_Start_Click(object sender, EventArgs e)
|
||
{
|
||
string configPath = Path.Combine(Application.StartupPath, "UserData.json");
|
||
if (File.Exists(configPath))
|
||
{
|
||
var json = File.ReadAllText(configPath);
|
||
dynamic config = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
|
||
experData.BenDiNongDu = config.BenDiNongdu;
|
||
experData.SamplingFlowRate = config.SamplingFlowRate ?? 2.0f;
|
||
experData.DryingFlowRate = config.DryingFlowRate ?? 1.0f;
|
||
experData.ExperName = config.Category;
|
||
}
|
||
|
||
isPaused = false;
|
||
Pause1.Text = "暂停测试";
|
||
Pause1.Style = UIStyle.Red;
|
||
|
||
// 清空数据
|
||
list_Time.Clear();
|
||
list_Tsi_Indoor_Data.Clear();
|
||
list_Tsi_Outdoor_Data.Clear();
|
||
lsit_XieLoulv.Clear();
|
||
list_CO2_Indoor_Data.Clear();
|
||
list_CO2_Outdoor_Data.Clear();
|
||
list_O2_Data.Clear();
|
||
list_HuanJingWenDu_Data.Clear();
|
||
list_HuanJingShiDu_Data.Clear();
|
||
liatAll.Clear();
|
||
|
||
fc?.BtnClickFunction(Function.ButtonType.复归型, 130);
|
||
|
||
LoadIsNeedRunConfig();
|
||
InitStepList();
|
||
|
||
InitAutoStepTimer();
|
||
InitAutoStepTimer2();
|
||
StartProcess();
|
||
|
||
_logger.Log(loginData.UserName, "点击了【测试开始】按钮", loginData.UserPower.ToString());
|
||
}
|
||
|
||
private void btn_Stop_Click(object sender, EventArgs e)
|
||
{
|
||
isPaused = false;
|
||
Pause1.Text = "暂停测试";
|
||
Pause1.Style = UIStyle.Red;
|
||
|
||
form2.uiLabel1.Text = "测试停止";
|
||
fc?.BtnClickFunction(Function.ButtonType.复归型, 133);
|
||
|
||
master?.WriteSingleCoil(1, 16, false);
|
||
master?.WriteSingleCoil(1, 15, false);
|
||
|
||
|
||
form2.axWindowsMediaPlayer1.URL = string.Empty;
|
||
StopVideo();
|
||
autoStepTimer?.Stop();
|
||
autoStepTimer2?.Stop();
|
||
lb_status.Text = "测试停止";
|
||
_logger.Log(loginData.UserName, "点击了【测试停止】按钮", loginData.UserPower.ToString());
|
||
}
|
||
//private void btn_SaveData_Click(object sender, EventArgs e)
|
||
//{
|
||
|
||
// experExcleHelper.ExportToExcel(dt_Show, list_AllTime, list_AllDaata);
|
||
// _logger.Log(loginData.UserName, "导出了实验数据", loginData.UserPower.ToString());
|
||
//}
|
||
|
||
|
||
|
||
|
||
|
||
// 修正后的按钮点击事件
|
||
private void btn_SaveData_Click(object sender, EventArgs e)
|
||
{
|
||
// 使用支持按钮选择的重载方法(message, title, style, buttons)
|
||
bool isYes = Sunny.UI.UIMessageBox.Show(
|
||
"选择导出类型:\n确定 - 本次实验\n取消 - 历史实验",
|
||
"导出选择",
|
||
Sunny.UI.UIStyle.Blue, // 使用指定样式
|
||
Sunny.UI.UIMessageBoxButtons.OKCancel // 明确指定按钮类型
|
||
);
|
||
|
||
if (isYes) // 注意:此重载返回bool值,true表示Yes,false表示No
|
||
{
|
||
ExportLastExperimentToExcel();
|
||
}
|
||
else
|
||
{
|
||
ExportSelectedHistoricalExperiments();
|
||
}
|
||
|
||
_logger.Log(loginData.UserName, "导出了实验数据", loginData.UserPower.ToString());
|
||
}
|
||
|
||
|
||
|
||
private void ExportLastExperimentToExcel()
|
||
{
|
||
string dbPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Data.db");
|
||
using (var db = new SQLiteConnection(dbPath))
|
||
{
|
||
try
|
||
{
|
||
var latestRecord = db.Table<Experiment>()
|
||
.Where(x => x.IdNumber != null && x.IdNumber != ""
|
||
&& x.Date != null && x.Date != ""
|
||
&& x.Time != null && x.Time != "")
|
||
.OrderByDescending(x => x.Date)
|
||
.ThenByDescending(x => x.Time)
|
||
.FirstOrDefault();
|
||
|
||
if (latestRecord == null || string.IsNullOrEmpty(latestRecord.IdNumber))
|
||
{
|
||
UIMessageBox.Show("没有找到有效的实验数据!", "提示", Sunny.UI.UIStyle.Blue);
|
||
return;
|
||
}
|
||
|
||
string targetIdNumber = latestRecord.IdNumber;
|
||
string targetName = latestRecord.Name ?? "未知姓名";
|
||
|
||
var latestRecordid = latestRecord.Id;
|
||
var startindex = latestRecordid - 5;
|
||
|
||
var experimentRecords = db.Table<Experiment>()
|
||
.Where(x => x.IdNumber == targetIdNumber && x.Id > startindex)
|
||
.OrderBy(x => x.Date)
|
||
.ThenBy(x => x.Time)
|
||
.ToList();
|
||
|
||
if (experimentRecords.Count == 0)
|
||
{
|
||
UIMessageBox.Show($"未找到身份证号{targetIdNumber}的实验数据!", "提示", Sunny.UI.UIStyle.Blue);
|
||
return;
|
||
}
|
||
|
||
using (var package = new ExcelPackage())
|
||
{
|
||
var worksheet = package.Workbook.Worksheets.Add($"[{targetName}]{targetIdNumber}_实验数据");
|
||
|
||
string maskType = experimentRecords.Max(f => f.MaskType);
|
||
string maskTypeName = string.Empty;
|
||
if (maskType != null && (maskType.Contains("半面罩") || maskType.Contains("全面罩")))
|
||
{
|
||
maskTypeName = "IL";
|
||
}
|
||
else if (maskType != null && (maskType.Contains("随弃式")))
|
||
{
|
||
maskTypeName = "TIL";
|
||
}
|
||
|
||
maskTypeName = $"泄漏率{maskTypeName}(%)";
|
||
|
||
// 中文表头映射
|
||
var chineseHeaders = new Dictionary<string, string>
|
||
{
|
||
{ "Name", "姓名" },
|
||
{ "Sex", "性别" },
|
||
{ "Age", "年龄" },
|
||
{ "IdNumber", "身份证号码" },
|
||
{ "Company", "工作单位" },
|
||
{ "CompanyAge", "工龄" },
|
||
{ "Date", "日期" },
|
||
{ "Time", "时间" },
|
||
{ "ExperName", "实验员" },
|
||
{ "ExperType", "样品类别" },
|
||
{ "MaskType", "面罩类型" },
|
||
{ "TestStatus", "测试状态" },
|
||
{ "HuanJingWenDu", "环境温度(℃)" },
|
||
{ "HuanJingShiDu", "环境湿度(%RH)" },
|
||
{ "BenDiNongDu", "本底浓度(mg/m³)" },
|
||
{ "TsiIndoorAgv", "室内浓度平均值(mg/m³)" },
|
||
{ "TsiOutdoorAgv", "呼吸器内气溶胶平均浓度(mg/m³)" },
|
||
{ "Xieloulv", $"{maskTypeName}" },
|
||
{ "TotalXieloulv", "总泄漏率(%)" },
|
||
{ "OverallTotalXieloulv", "总体总泄漏率(%)" } // 新增总体总泄露率表头
|
||
};
|
||
|
||
var properties = typeof(Experiment).GetProperties().ToList();
|
||
|
||
// 计算5个动作的泄露率平均值(过滤无效的0值)
|
||
var validXieloulvList = experimentRecords
|
||
.Where(r => r.Xieloulv > 0) // 排除泄露率为0的无效数据
|
||
.Select(r => r.Xieloulv)
|
||
.ToList();
|
||
var totalXieloulv = validXieloulvList.Any()
|
||
? validXieloulvList.Average()
|
||
: 0;
|
||
|
||
// === 新增:计算总体总泄露率(5个动作的平均值)===
|
||
var fiveActionRecords = experimentRecords
|
||
.Where(r => r.Xieloulv > 0) // 过滤有效数据
|
||
.Take(5) // 取前5个动作
|
||
.ToList();
|
||
|
||
var overallTotalXieloulv = fiveActionRecords.Any()
|
||
? fiveActionRecords.Average(r => r.Xieloulv)
|
||
: 0;
|
||
// === 新增结束 ===
|
||
|
||
// 写入中文表头
|
||
int colIndex = 1;
|
||
foreach (var prop in properties)
|
||
{
|
||
worksheet.Cells[1, colIndex].Value = chineseHeaders.ContainsKey(prop.Name)
|
||
? chineseHeaders[prop.Name]
|
||
: prop.Name;
|
||
worksheet.Cells[1, colIndex].Style.Font.Bold = true;
|
||
colIndex++;
|
||
}
|
||
// 单独写入"总泄漏率(%)"表头
|
||
worksheet.Cells[1, colIndex].Value = chineseHeaders["TotalXieloulv"];
|
||
worksheet.Cells[1, colIndex].Style.Font.Bold = true;
|
||
colIndex++;
|
||
|
||
// 单独写入"总体总泄漏率(%)"表头
|
||
worksheet.Cells[1, colIndex].Value = chineseHeaders["OverallTotalXieloulv"];
|
||
worksheet.Cells[1, colIndex].Style.Font.Bold = true;
|
||
|
||
// 写入数据行
|
||
int rowIndex = 2;
|
||
foreach (var record in experimentRecords)
|
||
{
|
||
colIndex = 1;
|
||
// 写入原有数据列
|
||
foreach (var prop in properties)
|
||
{
|
||
if (prop.Name == "ExperNum")
|
||
{
|
||
continue;
|
||
}
|
||
worksheet.Cells[rowIndex, colIndex].Value = prop.GetValue(record);
|
||
if (prop.PropertyType == typeof(float) || prop.PropertyType == typeof(double))
|
||
{
|
||
worksheet.Cells[rowIndex, colIndex].Style.Numberformat.Format = "0.00";
|
||
}
|
||
colIndex++;
|
||
}
|
||
|
||
// 写入总泄漏率(每行都写入)
|
||
worksheet.Cells[rowIndex, colIndex].Value = record.Xieloulv;
|
||
worksheet.Cells[rowIndex, colIndex].Style.Numberformat.Format = "0.00";
|
||
colIndex++;
|
||
|
||
// 写入总体总泄漏率(仅在最后一行显示)
|
||
if (rowIndex == experimentRecords.Count + 1)
|
||
{
|
||
worksheet.Cells[rowIndex, colIndex].Value = overallTotalXieloulv;
|
||
worksheet.Cells[rowIndex, colIndex].Style.Numberformat.Format = "0.00";
|
||
// 给总体总泄露率行添加背景色,方便识别
|
||
worksheet.Cells[rowIndex, colIndex].Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
|
||
worksheet.Cells[rowIndex, colIndex].Style.Fill.BackgroundColor.SetColor(System.Drawing.Color.LightBlue);
|
||
}
|
||
|
||
rowIndex++;
|
||
}
|
||
|
||
// 调整列宽
|
||
worksheet.Column(13).Width = 25; // 环境温度(℃)
|
||
worksheet.Column(14).Width = 25; // 环境湿度(%RH)
|
||
worksheet.Column(15).Width = 20; // 本底浓度(mg/m³)
|
||
worksheet.Column(16).Width = 25; // 室内浓度平均值(mg/m³)
|
||
worksheet.Column(17).Width = 25; // 口罩内浓度平均值(mg/m³)
|
||
worksheet.Column(18).Width = 25; // 泄漏率IL/TIL(%)
|
||
worksheet.Column(19).Width = 25; // 总泄漏率(%)
|
||
worksheet.Column(20).Width = 25; // 总体总泄漏率(%)(新增列)
|
||
|
||
SaveExcelFile(package, $"[{targetName}]的实验数据(共{experimentRecords.Count}条,总泄露率:{totalXieloulv:F2}%,总体总泄露率:{overallTotalXieloulv:F2}%)导出成功!", $"[{targetName}]{targetIdNumber}_实验数据");
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
UIMessageBox.Show($"导出失败: {ex.Message}", "错误", Sunny.UI.UIStyle.Blue);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
private void ExportSelectedHistoricalExperiments()
|
||
{
|
||
string dbPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Data.db");
|
||
using (var db = new SQLiteConnection(dbPath))
|
||
{
|
||
try
|
||
{
|
||
var personList = db.Table<Experiment>()
|
||
.Where(x => x.IdNumber != null && x.IdNumber != ""
|
||
&& x.Name != null && x.Name != "")
|
||
.Select(x => new { x.IdNumber, x.Name, x.Date, x.Time, x.Id, x.MaskType })
|
||
.OrderByDescending(x => x.Id).ThenByDescending(s => s.Date).ThenByDescending(s => s.Time)
|
||
.ToList();
|
||
|
||
if (personList == null || personList.Count == 0)
|
||
{
|
||
UIMessageBox.Show("没有找到历史实验数据!", "提示", Sunny.UI.UIStyle.Blue);
|
||
return;
|
||
}
|
||
|
||
string maskType = personList.Max(f => f.MaskType);
|
||
string maskTypeName = string.Empty;
|
||
if (maskType != null && (maskType.Contains("半面罩") || maskType.Contains("全面罩")))
|
||
{
|
||
maskTypeName = "IL";
|
||
}
|
||
else if (maskType != null && (maskType.Contains("随弃式")))
|
||
{
|
||
maskTypeName = "TIL";
|
||
}
|
||
|
||
maskTypeName = $"泄漏率{maskTypeName}(%)";
|
||
|
||
|
||
var displayList = personList.Select(p =>
|
||
{
|
||
string idLast4 = p.IdNumber;
|
||
return $"({p.Id})({p.Date} {p.Time})({p.Name})({idLast4})";
|
||
}).ToList();
|
||
|
||
var selectForm = new UISelectForm("选择要导出的人员", displayList);
|
||
if (selectForm.ShowDialog() == DialogResult.OK && selectForm.SelectedItems.Count > 0)
|
||
{
|
||
var selectedIds = new List<string>();
|
||
foreach (var selectedItem in selectForm.SelectedItems)
|
||
{
|
||
var itemStr = selectedItem.ToString();
|
||
|
||
var first = itemStr.IndexOf("(") + 1;
|
||
var second = itemStr.IndexOf(")");
|
||
|
||
|
||
var nameStart = itemStr.LastIndexOf("(") + 1;
|
||
var nameEnd = itemStr.LastIndexOf(")");
|
||
var idStart = itemStr.LastIndexOf("(") + 1;
|
||
var idEnd = itemStr.LastIndexOf(")");
|
||
|
||
if (nameStart < nameEnd && idStart < idEnd)
|
||
{
|
||
|
||
var id = itemStr.Substring(first, second - first);
|
||
var name = itemStr.Substring(nameStart, nameEnd - nameStart);
|
||
var idNumber = itemStr.Substring(idStart, idEnd - idStart);
|
||
var match = personList.FirstOrDefault(p =>
|
||
p.Name == name && p.IdNumber == idNumber);
|
||
//if (match != null && !selectedIds.Contains(match.IdNumber))
|
||
//{
|
||
selectedIds.Add(id.ToString());
|
||
//}
|
||
}
|
||
}
|
||
|
||
if (selectedIds.Count == 0)
|
||
{
|
||
UIMessageBox.Show("未匹配到有效人员数据!", "提示", Sunny.UI.UIStyle.Blue);
|
||
return;
|
||
}
|
||
|
||
using (var package = new ExcelPackage())
|
||
{
|
||
var worksheet = package.Workbook.Worksheets.Add($"选中的{selectedIds.Count / 5}位人员实验数据!");
|
||
|
||
// 中文表头映射(保持不变)
|
||
var chineseHeaders = new Dictionary<string, string>
|
||
{
|
||
{ "Name", "姓名" },
|
||
{ "Sex", "性别" },
|
||
{ "Age", "年龄" },
|
||
{ "IdNumber", "身份证号码" },
|
||
{ "Company", "工作单位" },
|
||
{ "CompanyAge", "工龄" },
|
||
{ "Date", "日期" },
|
||
{ "Time", "时间" },
|
||
{ "ExperName", "实验员" },
|
||
{ "ExperType", "样品类别" },
|
||
{ "MaskType", "面罩类型" },
|
||
{ "TestStatus", "测试状态" },
|
||
{ "HuanJingWenDu", "环境温度(℃)" },
|
||
{ "HuanJingShiDu", "环境湿度(%RH)" },
|
||
{ "BenDiNongDu", "本底浓度(mg/m³)" },
|
||
{ "TsiIndoorAgv", "室内浓度平均值(mg/m³)" },
|
||
{ "TsiOutdoorAgv", "呼吸器内气溶胶平均浓度(mg/m³)" },
|
||
{ "Xieloulv", $"{maskTypeName}" },
|
||
{ "TotalXieloulv", "总体总泄漏率(%)" }
|
||
};
|
||
|
||
var properties = typeof(Experiment).GetProperties().ToList();
|
||
var hiddenColumns = new List<string> { "Sex", "Age", "Company", "CompanyAge" };
|
||
var visibleProperties = properties.Where(p => !hiddenColumns.Contains(p.Name)).ToList();
|
||
|
||
// 1. 写入中文表头(保持不变)
|
||
int colIndex = 1;
|
||
foreach (var prop in visibleProperties)
|
||
{
|
||
worksheet.Cells[1, colIndex].Value = chineseHeaders.ContainsKey(prop.Name)
|
||
? chineseHeaders[prop.Name]
|
||
: prop.Name;
|
||
worksheet.Cells[1, colIndex].Style.Font.Bold = true;
|
||
colIndex++;
|
||
}
|
||
// 单独写入"总泄露率"表头(最后一列)
|
||
worksheet.Cells[1, colIndex].Value = chineseHeaders["TotalXieloulv"];
|
||
worksheet.Cells[1, colIndex].Style.Font.Bold = true;
|
||
var totalColIndex = colIndex;
|
||
|
||
// 2. 按人员写入数据,并计算每人的总泄露率(保持不变)
|
||
int rowIndex = 2;
|
||
var allActionLeakRates = new List<float>(); // 存储所有动作的泄露率
|
||
var allPersonTotalLeakRates = new List<float>(); // 存储所有人的总泄露率
|
||
|
||
|
||
List<int> ids = selectedIds.ConvertAll(int.Parse);
|
||
var lsit = db.Table<Experiment>()
|
||
.Where(x => ids.Contains(x.Id))
|
||
.OrderBy(x => x.Date)
|
||
.ThenBy(x => x.Time)
|
||
.ToList();
|
||
|
||
var selidNumber = lsit.Select(x => x.IdNumber).Distinct().ToList();
|
||
foreach (var id in selidNumber)
|
||
{
|
||
var personExperiments = lsit
|
||
.Where(x => x.IdNumber == id)
|
||
.OrderBy(x => x.Date)
|
||
.ThenBy(x => x.Time)
|
||
.ToList();
|
||
|
||
if (!personExperiments.Any()) continue;
|
||
|
||
// 计算当前人员的总泄露率(过滤无效的0值)
|
||
var validLeakRates = personExperiments
|
||
.Where(exp => exp.Xieloulv > 0)
|
||
.Select(exp => exp.Xieloulv)
|
||
.ToList();
|
||
var personTotalLeakRate = validLeakRates.Any()
|
||
? validLeakRates.Average()
|
||
: 0;
|
||
|
||
// 收集所有动作泄露率和人员总泄露率
|
||
allActionLeakRates.AddRange(validLeakRates);
|
||
allPersonTotalLeakRates.Add(personTotalLeakRate);
|
||
|
||
// 写入当前人员的每条实验记录(保持不变)
|
||
foreach (var exp in personExperiments)
|
||
{
|
||
colIndex = 1;
|
||
foreach (var prop in visibleProperties)
|
||
{
|
||
if (prop.Name == "ExperNum") continue;
|
||
|
||
worksheet.Cells[rowIndex, colIndex].Value = prop.GetValue(exp);
|
||
if (prop.PropertyType == typeof(float) || prop.PropertyType == typeof(double))
|
||
{
|
||
worksheet.Cells[rowIndex, colIndex].Style.Numberformat.Format = "0.00";
|
||
}
|
||
colIndex++;
|
||
}
|
||
worksheet.Cells[rowIndex, totalColIndex].Value = "";
|
||
rowIndex++;
|
||
}
|
||
|
||
// 3. 在当前人员数据末尾添加"总泄露率"汇总行(保持不变)
|
||
colIndex = 1;
|
||
worksheet.Cells[rowIndex, 1].Value = $"{personExperiments[0].Name}(汇总)";
|
||
worksheet.Cells[rowIndex, 1, rowIndex, visibleProperties.Count].Merge = true;
|
||
worksheet.Cells[rowIndex, 1].Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Center;
|
||
worksheet.Cells[rowIndex, totalColIndex].Value = personTotalLeakRate;
|
||
worksheet.Cells[rowIndex, totalColIndex].Style.Numberformat.Format = "0.00";
|
||
worksheet.Cells[rowIndex, 1, rowIndex, totalColIndex].Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
|
||
worksheet.Cells[rowIndex, 1, rowIndex, totalColIndex].Style.Fill.BackgroundColor.SetColor(System.Drawing.Color.LightSkyBlue);
|
||
rowIndex++;
|
||
|
||
// 人员之间添加空行
|
||
rowIndex++;
|
||
}
|
||
|
||
// 4. 在表格最下方添加统计行(新增部分)
|
||
if (selectedIds.Count > 0)
|
||
{
|
||
//// 获取主要口罩类型(假设同一组使用相同类型的口罩)
|
||
//string mainMaskType = db.Table<Experiment>()
|
||
// .Where(x => selectedIds.Contains(x.Id))
|
||
// .Select(x => x.MaskType)
|
||
// .FirstOrDefault() ?? "";
|
||
|
||
var (actionStandard, personStandard) = GetMaskTypeStandards(maskType);
|
||
|
||
// 50个动作合格性统计
|
||
var validActions = allActionLeakRates.Where(r => r > 0).Take(50).ToList();
|
||
int qualifiedActionCount = validActions.Count(r => r <= actionStandard);
|
||
bool isActionsQualified = validActions.Count >= 50 && qualifiedActionCount >= 46;
|
||
|
||
// 10人总体合格性统计
|
||
var validPersons = allPersonTotalLeakRates.Take(10).ToList();
|
||
int qualifiedPersonCount = validPersons.Count(r => r <= personStandard);
|
||
bool isPersonsQualified = validPersons.Count >= 10 && qualifiedPersonCount >= 8;
|
||
|
||
// 添加50个动作合格性统计行
|
||
colIndex = 1;
|
||
worksheet.Cells[rowIndex, 1].Value = "50个动作是否合格";
|
||
worksheet.Cells[rowIndex, 1, rowIndex, visibleProperties.Count].Merge = true;
|
||
worksheet.Cells[rowIndex, 1].Style.Font.Bold = true;
|
||
|
||
string actionResult = isActionsQualified ? "合格" : "不合格";
|
||
if (selectedIds.Count < 50)
|
||
{
|
||
actionResult = $"数据不足({validActions.Count}/50个动作)";
|
||
}
|
||
else
|
||
{
|
||
actionResult = $"{actionResult}({qualifiedActionCount}/50个动作)";
|
||
}
|
||
|
||
worksheet.Cells[rowIndex, totalColIndex].Value = actionResult;
|
||
worksheet.Cells[rowIndex, totalColIndex].Style.Font.Color.SetColor(
|
||
isActionsQualified ? System.Drawing.Color.Green : System.Drawing.Color.Red);
|
||
worksheet.Cells[rowIndex, 1, rowIndex, totalColIndex].Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
|
||
worksheet.Cells[rowIndex, 1, rowIndex, totalColIndex].Style.Fill.BackgroundColor.SetColor(System.Drawing.Color.LightYellow);
|
||
rowIndex++;
|
||
|
||
// 添加10人总体合格性统计行
|
||
colIndex = 1;
|
||
worksheet.Cells[rowIndex, 1].Value = "10人总体是否合格";
|
||
worksheet.Cells[rowIndex, 1, rowIndex, visibleProperties.Count].Merge = true;
|
||
worksheet.Cells[rowIndex, 1].Style.Font.Bold = true;
|
||
|
||
string personResult = isPersonsQualified ? "合格" : "不合格";
|
||
if (validPersons.Count < 10)
|
||
{
|
||
personResult = $"数据不足({validPersons.Count}/10人)";
|
||
}
|
||
else
|
||
{
|
||
personResult = $"{personResult}({qualifiedPersonCount}/10人)";
|
||
}
|
||
|
||
worksheet.Cells[rowIndex, totalColIndex].Value = personResult;
|
||
worksheet.Cells[rowIndex, totalColIndex].Style.Font.Color.SetColor(
|
||
isPersonsQualified ? System.Drawing.Color.Green : System.Drawing.Color.Red);
|
||
worksheet.Cells[rowIndex, 1, rowIndex, totalColIndex].Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
|
||
worksheet.Cells[rowIndex, 1, rowIndex, totalColIndex].Style.Fill.BackgroundColor.SetColor(System.Drawing.Color.LightYellow);
|
||
}
|
||
|
||
// 5. 调整列宽(保持不变)
|
||
worksheet.Column(7).Width = 25;
|
||
worksheet.Column(8).Width = 25;
|
||
worksheet.Column(9).Width = 20;
|
||
worksheet.Column(10).Width = 25;
|
||
worksheet.Column(11).Width = 25;
|
||
worksheet.Column(12).Width = 25;
|
||
worksheet.Column(totalColIndex).Width = 25;
|
||
|
||
SaveExcelFile(package, $"选中的{selectedIds.Count / 5}位人员实验数据导出成功!", $"选中的{selectedIds.Count / 5}位人员实验数据");
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
UIMessageBox.Show($"导出失败: {ex.Message}", "错误", Sunny.UI.UIStyle.Blue);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 新增辅助方法:根据口罩类型获取标准值
|
||
private (float actionStandard, float personStandard) GetMaskTypeStandards(string maskType)
|
||
{
|
||
if (string.IsNullOrEmpty(maskType)) return (0, 0);
|
||
|
||
if (maskType.Contains("KN90") || maskType.Contains("KP90"))
|
||
{
|
||
return (13.0f, 10.0f);
|
||
}
|
||
else if (maskType.Contains("KN95") || maskType.Contains("KP95"))
|
||
{
|
||
return (11.0f, 8.0f);
|
||
}
|
||
else if (maskType.Contains("KN100") || maskType.Contains("KP100"))
|
||
{
|
||
return (5.0f, 2.0f);
|
||
}
|
||
else
|
||
{
|
||
return (0, 0);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 保存Excel文件的通用方法
|
||
/// </summary>
|
||
private void SaveExcelFile(ExcelPackage package, string successMessage, string fileName)
|
||
{
|
||
SaveFileDialog saveFileDialog = new SaveFileDialog
|
||
{
|
||
Filter = "Excel Files|*.xlsx",
|
||
Title = "保存实验数据",
|
||
FileName = $"{fileName}_{DateTime.Now:yyyyMMddHHmmss}.xlsx"
|
||
};
|
||
|
||
if (saveFileDialog.ShowDialog() == DialogResult.OK)
|
||
{
|
||
try
|
||
{
|
||
FileInfo fileInfo = new FileInfo(saveFileDialog.FileName);
|
||
package.SaveAs(fileInfo);
|
||
// 成功提示(带标题)
|
||
UIMessageBox.Show(successMessage, "成功", Sunny.UI.UIStyle.Blue);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
// 错误提示
|
||
UIMessageBox.Show($"保存文件失败: {ex.Message}", "错误", Sunny.UI.UIStyle.Blue);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 人员选择对话框(保持样式一致)
|
||
//public class UISelectForm : Sunny.UI.UIForm
|
||
//{
|
||
// private Sunny.UI.UIListBox listBox;
|
||
// private Sunny.UI.UIButton okButton;
|
||
// private Sunny.UI.UIButton cancelButton;
|
||
|
||
// public List<object> SelectedItems => listBox.SelectedItems.Cast<object>().ToList();
|
||
|
||
// public UISelectForm(string title, List<string> items)
|
||
// {
|
||
// Text = title;
|
||
// Width = 600;
|
||
// Height = 500;
|
||
// StartPosition = FormStartPosition.CenterParent;
|
||
// Style = Sunny.UI.UIStyle.Blue; // 匹配主窗体样式
|
||
|
||
// // 初始化列表框
|
||
// listBox = new Sunny.UI.UIListBox
|
||
// {
|
||
// Dock = DockStyle.Top,
|
||
// Height = 400,
|
||
// SelectionMode = SelectionMode.MultiSimple,
|
||
// Style = this.Style
|
||
// };
|
||
// listBox.Items.AddRange(items.ToArray());
|
||
|
||
// // 初始化按钮
|
||
// okButton = new Sunny.UI.UIButton
|
||
// {
|
||
// Text = "确定",
|
||
// Dock = DockStyle.Left,
|
||
// Width = 100,
|
||
// Style = this.Style
|
||
// };
|
||
// okButton.Click += (s, e) =>
|
||
// {
|
||
// DialogResult = DialogResult.OK;
|
||
// Close();
|
||
// };
|
||
|
||
// cancelButton = new Sunny.UI.UIButton
|
||
// {
|
||
// Text = "取消",
|
||
// Dock = DockStyle.Right,
|
||
// Width = 100,
|
||
// Style = this.Style
|
||
// };
|
||
// cancelButton.Click += (s, e) =>
|
||
// {
|
||
// DialogResult = DialogResult.Cancel;
|
||
// Close();
|
||
// };
|
||
|
||
// // 创建按钮容器
|
||
// var buttonPanel = new Panel
|
||
// {
|
||
// Dock = DockStyle.Bottom,
|
||
// Height = 50,
|
||
// BackColor = System.Drawing.Color.Transparent
|
||
// };
|
||
// buttonPanel.Controls.Add(okButton);
|
||
// buttonPanel.Controls.Add(cancelButton);
|
||
|
||
// Controls.Add(listBox);
|
||
// Controls.Add(buttonPanel);
|
||
// }
|
||
//}
|
||
|
||
public class UISelectForm : UIForm
|
||
{
|
||
private UIListBox listBox;
|
||
private UIButton okButton;
|
||
private UIButton cancelButton;
|
||
private UIButton queryButton;
|
||
private UIDatePicker startDatePicker;
|
||
private UIDatePicker endDatePicker;
|
||
private UILabel startDateLabel;
|
||
private UILabel endDateLabel;
|
||
|
||
// 原始数据源(保存所有未过滤的item,用于重置)
|
||
private List<string> _originalItems;
|
||
// 选中项集合(保持原有逻辑)
|
||
public List<object> SelectedItems => listBox.SelectedItems.Cast<object>().ToList();
|
||
|
||
public UISelectForm(string title, List<string> items)
|
||
{
|
||
// 保存原始数据源
|
||
_originalItems = new List<string>(items);
|
||
|
||
// 基础窗体设置
|
||
Text = title;
|
||
Width = 800; // 加宽窗体以容纳日期控件
|
||
Height = 550;
|
||
StartPosition = FormStartPosition.CenterParent;
|
||
Style = UIStyle.Blue;
|
||
|
||
// 初始化日期筛选控件
|
||
InitDateFilterControls();
|
||
// 初始化列表框
|
||
InitListBox();
|
||
// 初始化按钮(确定/取消/查询)
|
||
InitButtons();
|
||
// 组装控件布局
|
||
AssembleControls();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 初始化日期筛选控件(标签+日期选择器)
|
||
/// </summary>
|
||
private void InitDateFilterControls()
|
||
{
|
||
// 开始日期标签
|
||
startDateLabel = new UILabel
|
||
{
|
||
Text = "开始日期:",
|
||
Size = new Size(80, 30),
|
||
TextAlign = ContentAlignment.MiddleRight,
|
||
Style = this.Style
|
||
};
|
||
|
||
// 开始日期选择器
|
||
startDatePicker = new UIDatePicker
|
||
{
|
||
Size = new Size(200, 30),
|
||
DateFormat = "yyyy-MM-dd HH:mm:ss", // 短日期格式(yyyy-MM-dd)
|
||
Value = DateTime.Now.AddDays(-7), // 默认筛选近7天数据
|
||
Style = this.Style
|
||
};
|
||
|
||
// 结束日期标签
|
||
endDateLabel = new UILabel
|
||
{
|
||
Text = "结束日期:",
|
||
Size = new Size(80, 30),
|
||
TextAlign = ContentAlignment.MiddleRight,
|
||
Style = this.Style
|
||
};
|
||
|
||
// 结束日期选择器
|
||
endDatePicker = new UIDatePicker
|
||
{
|
||
Size = new Size(200, 30),
|
||
DateFormat = "yyyy-MM-dd HH:mm:ss", // 短日期格式(yyyy-MM-dd)
|
||
Value = DateTime.Now, // 默认结束日期为今天
|
||
Style = this.Style
|
||
};
|
||
|
||
// 查询按钮
|
||
queryButton = new UIButton
|
||
{
|
||
Text = "查询",
|
||
Size = new Size(100, 30),
|
||
Style = this.Style
|
||
};
|
||
// 绑定查询事件
|
||
queryButton.Click += QueryButton_Click;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 初始化列表框(保持原有逻辑)
|
||
/// </summary>
|
||
private void InitListBox()
|
||
{
|
||
listBox = new UIListBox
|
||
{
|
||
Dock = DockStyle.Top,
|
||
Height = 400,
|
||
SelectionMode = SelectionMode.MultiSimple,
|
||
Style = this.Style
|
||
};
|
||
// 初始加载所有原始数据
|
||
listBox.Items.AddRange(_originalItems.ToArray());
|
||
}
|
||
|
||
/// <summary>
|
||
/// 初始化按钮(确定/取消)
|
||
/// </summary>
|
||
private void InitButtons()
|
||
{
|
||
okButton = new UIButton
|
||
{
|
||
Text = "确定",
|
||
Dock = DockStyle.Left,
|
||
Width = 100,
|
||
Style = this.Style
|
||
};
|
||
okButton.Click += (s, e) =>
|
||
{
|
||
DialogResult = DialogResult.OK;
|
||
Close();
|
||
};
|
||
|
||
cancelButton = new UIButton
|
||
{
|
||
Text = "取消",
|
||
Dock = DockStyle.Right,
|
||
Width = 100,
|
||
Style = this.Style
|
||
};
|
||
cancelButton.Click += (s, e) =>
|
||
{
|
||
DialogResult = DialogResult.Cancel;
|
||
Close();
|
||
};
|
||
}
|
||
|
||
/// <summary>
|
||
/// 组装所有控件到窗体
|
||
/// </summary>
|
||
private void AssembleControls()
|
||
{
|
||
// 日期筛选面板(横向排列日期控件和查询按钮)
|
||
var filterPanel = new Panel
|
||
{
|
||
Dock = DockStyle.Top,
|
||
Height = 40,
|
||
BackColor = Color.Transparent
|
||
};
|
||
// 添加日期控件到筛选面板(设置位置,避免重叠)
|
||
filterPanel.Controls.Add(startDateLabel);
|
||
startDateLabel.Location = new Point(20, 5);
|
||
|
||
filterPanel.Controls.Add(startDatePicker);
|
||
startDatePicker.Location = new Point(100, 5);
|
||
|
||
filterPanel.Controls.Add(endDateLabel);
|
||
endDateLabel.Location = new Point(320, 5);
|
||
|
||
filterPanel.Controls.Add(endDatePicker);
|
||
endDatePicker.Location = new Point(400, 5);
|
||
|
||
filterPanel.Controls.Add(queryButton);
|
||
queryButton.Location = new Point(620, 5);
|
||
|
||
// 按钮面板(确定/取消)
|
||
var buttonPanel = new Panel
|
||
{
|
||
Dock = DockStyle.Bottom,
|
||
Height = 50,
|
||
BackColor = Color.Transparent
|
||
};
|
||
buttonPanel.Controls.Add(okButton);
|
||
buttonPanel.Controls.Add(cancelButton);
|
||
|
||
// 把控件添加到窗体
|
||
Controls.Add(filterPanel); // 筛选面板在最顶部
|
||
Controls.Add(listBox); // 列表框在中间
|
||
Controls.Add(buttonPanel); // 按钮面板在底部
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询按钮点击事件:根据日期筛选列表数据
|
||
/// </summary>
|
||
private void QueryButton_Click(object sender, EventArgs e)
|
||
{
|
||
// 获取筛选条件(只取日期部分,忽略时间)
|
||
DateTime startDate = startDatePicker.Value.Date;
|
||
DateTime endDate = endDatePicker.Value.Date;
|
||
|
||
// 校验日期逻辑(开始日期不能晚于结束日期)
|
||
if (startDate > endDate)
|
||
{
|
||
UIMessageBox.Show("开始日期不能晚于结束日期!", "提示", UIStyle.Blue, UIMessageBoxButtons.OK);
|
||
return;
|
||
}
|
||
|
||
// 清空现有列表
|
||
listBox.Items.Clear();
|
||
|
||
// 遍历原始数据,筛选符合日期条件的item
|
||
foreach (var item in _originalItems)
|
||
{
|
||
// 解析item中的日期字符串
|
||
if (TryExtractDateFromItem(item, out DateTime itemDate))
|
||
{
|
||
// 判断item日期是否在筛选范围内(包含开始和结束日期)
|
||
if (itemDate.Date >= startDate && itemDate.Date <= endDate)
|
||
{
|
||
listBox.Items.Add(item);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 无法解析日期的item:可选择忽略或保留(这里默认保留,避免数据丢失)
|
||
listBox.Items.Add(item);
|
||
// 可选:输出日志提示格式异常
|
||
// Console.WriteLine($"警告:item格式异常,无法解析日期 - {item}");
|
||
}
|
||
}
|
||
|
||
// 提示筛选结果
|
||
UIMessageBox.Show($"筛选完成!共找到 {listBox.Items.Count} 条符合条件的数据", "提示", UIStyle.Blue, UIMessageBoxButtons.OK);
|
||
}
|
||
|
||
private bool TryExtractDateFromItem(string item, out DateTime itemDate)
|
||
{
|
||
itemDate = DateTime.MinValue;
|
||
|
||
try
|
||
{
|
||
// 步骤1:按括号分割字符串(处理中英文括号,修正Split参数:先指定分隔符数组,再指定StringSplitOptions)
|
||
char[] separators = new[] { '(', ')' };
|
||
var parts = item.Split(separators, StringSplitOptions.RemoveEmptyEntries);
|
||
|
||
// 步骤2:取第二个有效部分(索引1),即日期字符串(格式:2025-11-25 15-42-04)
|
||
if (parts.Length < 2) return false;
|
||
string dateStr = parts[1].Trim();
|
||
|
||
// 步骤3:只替换时间部分的"-"为":"(保留日期部分的"-")
|
||
if (dateStr.Contains(" "))
|
||
{
|
||
var dateTimeParts = dateStr.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||
if (dateTimeParts.Length == 2)
|
||
{
|
||
string datePart = dateTimeParts[0]; // 日期部分:2025-11-25(保留"-")
|
||
string timePart = dateTimeParts[1]; // 时间部分:15-42-04(替换"-"为":")
|
||
timePart = timePart.Replace("-", ":"); // 转换为:15:42:04
|
||
dateStr = $"{datePart} {timePart}"; // 重组为标准格式:2025-11-25 15:42:04
|
||
}
|
||
}
|
||
|
||
// 步骤4:解析标准日期时间格式
|
||
return DateTime.TryParse(dateStr, out itemDate);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"解析item日期失败:{ex.Message} - {item}");
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
|
||
private void ExportCurrentExperimentToExcel(DataTable dataTable, List<List<string>> stringData, List<List<List<float>>> floatData)
|
||
{
|
||
using (var package = new ExcelPackage())
|
||
{
|
||
var worksheet = package.Workbook.Worksheets.Add("Current Experiment");
|
||
|
||
// 写入数据(不包括姓名、性别、年龄、身份证号码、工作单位、工龄)
|
||
string[] headers = {
|
||
"时间", "室内气溶胶浓度", "口罩内气溶胶浓度", "泄露率",
|
||
"室内CO2浓度", "口罩内CO2浓度", "室内氧浓度", "室内温度", "室内湿度"
|
||
};
|
||
|
||
for (int col = 0; col < headers.Length; col++)
|
||
{
|
||
worksheet.Cells[1, col + 1].Value = headers[col];
|
||
}
|
||
|
||
for (int sheetIndex = 0; sheetIndex < stringData.Count; sheetIndex++)
|
||
{
|
||
List<string> currentStringData = stringData[sheetIndex];
|
||
List<List<float>> currentFloatData = floatData[sheetIndex];
|
||
|
||
for (int row = 0; row < currentStringData.Count; row++)
|
||
{
|
||
worksheet.Cells[row + 2, 1].Value = currentStringData[row];
|
||
}
|
||
|
||
for (int col = 0; col < currentFloatData.Count; col++)
|
||
{
|
||
List<float> columnData = currentFloatData[col];
|
||
|
||
for (int row = 0; row < columnData.Count; row++)
|
||
{
|
||
worksheet.Cells[row + 2, col + 2].Value = columnData[row];
|
||
}
|
||
}
|
||
}
|
||
|
||
SaveExcelFile(package);
|
||
}
|
||
}
|
||
|
||
private void ExportHistoricalExperimentToExcel()
|
||
{
|
||
// 从数据库读取历史实验数据
|
||
List<string> names = GetNamesFromDatabase();
|
||
|
||
using (var package = new ExcelPackage())
|
||
{
|
||
foreach (var name in names)
|
||
{
|
||
var worksheet = package.Workbook.Worksheets.Add(name);
|
||
|
||
// 从数据库获取该姓名的实验数据
|
||
DataTable dataTable = GetExperimentDataByName(name);
|
||
|
||
// 写入数据
|
||
for (int col = 0; col < dataTable.Columns.Count; col++)
|
||
{
|
||
worksheet.Cells[1, col + 1].Value = dataTable.Columns[col].ColumnName;
|
||
}
|
||
|
||
for (int row = 0; row < dataTable.Rows.Count; row++)
|
||
{
|
||
for (int col = 0; col < dataTable.Columns.Count; col++)
|
||
{
|
||
worksheet.Cells[row + 2, col + 1].Value = dataTable.Rows[row][col];
|
||
}
|
||
}
|
||
}
|
||
|
||
SaveExcelFile(package);
|
||
}
|
||
}
|
||
|
||
private void SaveExcelFile(ExcelPackage package)
|
||
{
|
||
SaveFileDialog saveFileDialog = new SaveFileDialog
|
||
{
|
||
Filter = "Excel Files|*.xlsx",
|
||
Title = "保存 Excel 文件"
|
||
};
|
||
|
||
if (saveFileDialog.ShowDialog() == DialogResult.OK)
|
||
{
|
||
FileInfo fileInfo = new FileInfo(saveFileDialog.FileName);
|
||
package.SaveAs(fileInfo);
|
||
MessageBox.Show("数据导出成功!");
|
||
}
|
||
}
|
||
|
||
private List<string> GetNamesFromDatabase()
|
||
{
|
||
// 从数据库获取所有姓名
|
||
// 示例代码,需根据实际数据库结构实现
|
||
return new List<string> { "姓名1", "姓名2" };
|
||
}
|
||
|
||
private DataTable GetExperimentDataByName(string name)
|
||
{
|
||
// 从数据库获取指定姓名的实验数据
|
||
// 示例代码,需根据实际数据库结构实现
|
||
return new DataTable();
|
||
}
|
||
|
||
|
||
|
||
#endregion
|
||
|
||
private void btn_ClearData_Click(object sender, EventArgs e)
|
||
{
|
||
dt_Show.Clear();
|
||
list_Time.Clear();
|
||
list_Tsi_Indoor_Data.Clear();
|
||
list_Tsi_Outdoor_Data.Clear();
|
||
//experData.XieLouLv = experData.CumulativeLeakageRate(list_Tsi_Indoor_Data, list_Tsi_Outdoor_Data, experData.BenDiNongDu, 1.0f);
|
||
lsit_XieLoulv.Clear();
|
||
list_CO2_Indoor_Data.Clear();
|
||
list_CO2_Outdoor_Data.Clear();
|
||
list_O2_Data.Clear();
|
||
list_HuanJingWenDu_Data.Clear();
|
||
list_HuanJingShiDu_Data.Clear();
|
||
liatAll.Clear();
|
||
list_AllTime.Clear();
|
||
_logger.Log(loginData.UserName, "点击了【数据清除】按钮", loginData.UserPower.ToString());
|
||
}
|
||
|
||
private void btn_Next_Click(object sender, EventArgs e)
|
||
{
|
||
|
||
GoToNextStep();
|
||
|
||
_logger.Log(loginData.UserName, "进入流程", loginData.UserPower.ToString());
|
||
}
|
||
|
||
private void Pause_Click(object sender, EventArgs e)
|
||
{
|
||
try
|
||
{
|
||
if (!isPaused)
|
||
{
|
||
// 暂停操作
|
||
PauseTest();
|
||
master?.WriteSingleCoil(1, 40, true);
|
||
}
|
||
else
|
||
{
|
||
// 继续操作
|
||
ResumeTest();
|
||
master?.WriteSingleCoil(1, 40, false);
|
||
}
|
||
|
||
_logger.Log(loginData.UserName,
|
||
isPaused ? "点击了【暂停】按钮" : "点击了【继续】按钮",
|
||
loginData.UserPower.ToString());
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show($"暂停/继续操作失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
_logger.Log(loginData.UserName, $"暂停/继续操作失败: {ex.Message}", loginData.UserPower.ToString());
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 暂停测试
|
||
/// </summary>
|
||
private void PauseTest()
|
||
{
|
||
// 停止自动步骤计时器
|
||
autoStepTimer?.Stop();
|
||
|
||
// 保存剩余的秒数
|
||
pausedRemainingSeconds = countdownSeconds;
|
||
|
||
// 暂停视频播放
|
||
if (form2.axWindowsMediaPlayer1.playState == WMPLib.WMPPlayState.wmppsPlaying)
|
||
{
|
||
form2.axWindowsMediaPlayer1.Ctlcontrols.pause();
|
||
// 保存当前视频路径以便恢复时使用
|
||
currentVideoPath = form2.axWindowsMediaPlayer1.URL;
|
||
}
|
||
|
||
// 更新界面状态
|
||
lb_status.Text = $"{stepList[currentStepIndex]} - 已暂停 (剩余: {pausedRemainingSeconds}秒)";
|
||
//form2.uiLabel1.Text = $"{form2.uiLabel1.Text.Replace("倒计时:", "已暂停 - 剩余: ")}";
|
||
|
||
// 更新按钮文本和颜色
|
||
Pause1.Text = "继续测试";
|
||
Pause1.Style = UIStyle.Green; // 使用绿色表示继续
|
||
|
||
// 禁用其他控制按钮(可选)
|
||
//btn_Start.Enabled = false;
|
||
//btn_Stop.Enabled = false;
|
||
//btn_NextStep.Enabled = false;
|
||
|
||
isPaused = true;
|
||
|
||
// 记录暂停日志
|
||
_logger.Log(loginData.UserName,
|
||
$"测试暂停 - 步骤[{currentStepIndex + 1}]: {stepList[currentStepIndex]}, 剩余时间: {pausedRemainingSeconds}秒",
|
||
loginData.UserPower.ToString());
|
||
}
|
||
|
||
/// <summary>
|
||
/// 继续测试
|
||
/// </summary>
|
||
private void ResumeTest()
|
||
{
|
||
// 恢复倒计时秒数
|
||
countdownSeconds = pausedRemainingSeconds;
|
||
|
||
// 恢复视频播放
|
||
if (!string.IsNullOrEmpty(currentVideoPath) && File.Exists(currentVideoPath))
|
||
{
|
||
// 如果视频路径有效,恢复播放
|
||
form2.axWindowsMediaPlayer1.Ctlcontrols.play();
|
||
}
|
||
else if (form2.axWindowsMediaPlayer1.URL != null &&
|
||
File.Exists(form2.axWindowsMediaPlayer1.URL))
|
||
{
|
||
// 如果当前有视频在加载,也尝试恢复
|
||
form2.axWindowsMediaPlayer1.Ctlcontrols.play();
|
||
}
|
||
|
||
// 重新启动计时器
|
||
autoStepTimer?.Start();
|
||
|
||
// 更新界面状态
|
||
lb_status.Text = $"{stepList[currentStepIndex]} 倒计时: {countdownSeconds}秒";
|
||
|
||
//// 更新form2的标签文本,移除暂停提示
|
||
//int index = form2.uiLabel1.Text.LastIndexOf("\r\n[已暂停");
|
||
//if (index > 0)
|
||
//{
|
||
// form2.uiLabel1.Text = form2.uiLabel1.Text.Substring(0, index) + $"\r\n倒计时: {countdownSeconds}秒";
|
||
//}
|
||
//else
|
||
//{
|
||
// form2.uiLabel1.Text = form2.uiLabel1.Text.Replace("[已暂停]", "") + $"\r\n倒计时: {countdownSeconds}秒";
|
||
//}
|
||
|
||
// 更新按钮文本和颜色
|
||
Pause1.Text = "暂停测试";
|
||
Pause1.Style = UIStyle.Red; // 使用红色表示暂停
|
||
|
||
//// 启用其他控制按钮
|
||
//btn_Start.Enabled = true;
|
||
//btn_Stop.Enabled = true;
|
||
btn_NextStep.Enabled = true;
|
||
|
||
isPaused = false;
|
||
|
||
// 记录继续日志
|
||
_logger.Log(loginData.UserName,
|
||
$"测试继续 - 步骤[{currentStepIndex + 1}]: {stepList[currentStepIndex]}, 剩余时间: {countdownSeconds}秒",
|
||
loginData.UserPower.ToString());
|
||
}
|
||
}
|
||
}
|