824 lines
33 KiB
C#
824 lines
33 KiB
C#
using MQTT_WinformV1.Model;
|
||
using MqttClient;
|
||
using MySqlX.XDevAPI.Relational;
|
||
using Newtonsoft.Json;
|
||
using NPOI.SS.UserModel;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Data;
|
||
using System.Drawing;
|
||
using System.Drawing.Drawing2D;
|
||
using System.IO;
|
||
using System.Linq;
|
||
using System.Reflection;
|
||
using System.Threading.Tasks;
|
||
using System.Timers;
|
||
using System.Windows.Forms;
|
||
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
|
||
|
||
namespace MQTT_WinformV1
|
||
{
|
||
public partial class Form1 : Form
|
||
{
|
||
private System.Timers.Timer _timer;
|
||
private MqttClientService _mqttService;
|
||
private DataTable dtPeiFang;
|
||
private DataTable dtMqttDic;
|
||
private string strPeiFangId1;
|
||
private DataRow drPeiFang1;
|
||
private string strPeiFangId2;
|
||
private DataRow drPeiFang2;
|
||
|
||
// 日志文件相关路径
|
||
private string _logDirectory = "log";
|
||
private string _currentLogFile;
|
||
private DateTime _lastLogDate = DateTime.MinValue;
|
||
|
||
|
||
private List<DataRow> drPeiFang1List; // 设备1选择的配方(多行)
|
||
private List<DataRow> drPeiFang2List; // 设备2选择的配方(多行)
|
||
public Form1()
|
||
{
|
||
InitializeComponent();
|
||
|
||
_mqttService = new MqttClientService();
|
||
_mqttService.MessageReceived += OnMqttMessage;
|
||
dtPeiFang = new DataTable();
|
||
dtMqttDic = new DataTable();
|
||
buttonDisconnect.Enabled = false;
|
||
|
||
// 初始化日志目录
|
||
InitializeLogDirectory();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 初始化日志目录
|
||
/// </summary>
|
||
private void InitializeLogDirectory()
|
||
{
|
||
if (!Directory.Exists(_logDirectory))
|
||
{
|
||
Directory.CreateDirectory(_logDirectory);
|
||
}
|
||
UpdateLogFile();
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 更新当前日志文件(每日一个新文件)
|
||
/// </summary>
|
||
private void UpdateLogFile()
|
||
{
|
||
DateTime today = DateTime.Now.Date;
|
||
if (today != _lastLogDate)
|
||
{
|
||
_lastLogDate = today;
|
||
_currentLogFile = Path.Combine(_logDirectory, $"log_{today:yyyyMMdd}.txt");
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
private void Form1_Load(object sender, EventArgs e)
|
||
{
|
||
// 调用方法将指定 Panel 变成圆形
|
||
MakePanelRound(panelLed);
|
||
getPeiFang();
|
||
InitMqttDic();//查询字典表,为dtMqttDic赋值。
|
||
timer1.Enabled = true;
|
||
}
|
||
|
||
private void MakePanelRound(Panel panel)
|
||
{
|
||
int size = Math.Min(panel.Width, panel.Height);
|
||
panel.Size = new Size(size, size);
|
||
GraphicsPath path = new GraphicsPath();
|
||
path.AddEllipse(0, 0, panel.Width, panel.Height);
|
||
panel.Region = new Region(path);
|
||
}
|
||
|
||
private async void getPeiFang()
|
||
{
|
||
//DataTable dt = await _mqttService.QueryPeifangAsync();//从数据库中查询配方信息
|
||
//if (dt != null)
|
||
//{
|
||
// DataRow drNew = dt.NewRow();//新建一个空白行NewRow()
|
||
// drNew["id"] = -1;//将空白行id设置为-1
|
||
// dt.Rows.InsertAt(drNew, 0);//将空白行插入到第 0 行,也就是数据源的第一行。
|
||
|
||
// // 新增一列用于组合显示“零件号+零件名”
|
||
// if (!dt.Columns.Contains("part_display"))
|
||
// {
|
||
// dt.Columns.Add("part_display", typeof(string));
|
||
// }
|
||
|
||
// foreach (DataRow row in dt.Rows)
|
||
// {
|
||
// string partNumber = row["part_number"]?.ToString() ?? "";
|
||
// string partName = row["part_name"]?.ToString() ?? "";
|
||
// row["part_display"] = $"{partNumber} {partName}";
|
||
// }
|
||
|
||
// dtPeiFang = dt;//得到新的配方表(多了第一行的空白行)
|
||
// bsPF.DataSource = dtPeiFang;//为bsPF设置数据源
|
||
// bsPF2.DataSource = dtPeiFang;//为bsPF2设置数据源
|
||
// this.comboBox1.DisplayMember = "part_name";//下拉框里显示part_name字段的值(零件名)
|
||
// this.comboBox1.ValueMember = "id";
|
||
// this.comboBox2.DisplayMember = "part_name";//下拉框里显示part_name字段的值(零件名)
|
||
// this.comboBox2.ValueMember = "id";
|
||
//}
|
||
DataTable dt = await _mqttService.QueryPeifangAsync(); // 从数据库查询配方信息
|
||
if (dt != null && dt.Rows.Count > 0)
|
||
{
|
||
// 新增列用于拼接 part_number|part_name
|
||
if (!dt.Columns.Contains("part_number_name"))
|
||
dt.Columns.Add("part_number_name", typeof(string));
|
||
|
||
foreach (DataRow row in dt.Rows)
|
||
{
|
||
row["part_number_name"] = row["part_number"].ToString() + "|" + row["part_name"].ToString();
|
||
}
|
||
|
||
// 使用 LINQ 去重,按 part_number + part_name
|
||
var uniqueParts = dt.AsEnumerable()
|
||
.GroupBy(r => r["part_number_name"].ToString())
|
||
.Select(g => g.First())
|
||
.ToList();
|
||
|
||
// 新建 DataTable 用于绑定下拉框
|
||
DataTable dtUnique = dt.Clone(); // 保留原有列
|
||
foreach (var row in uniqueParts)
|
||
{
|
||
dtUnique.ImportRow(row);
|
||
}
|
||
|
||
// 新建空白行
|
||
DataRow drNew = dtUnique.NewRow();
|
||
drNew["id"] = -1;
|
||
drNew["part_number_name"] = ""; // 空行值
|
||
dtUnique.Rows.InsertAt(drNew, 0);
|
||
|
||
dtPeiFang = dt; // 原始配方表(多行)
|
||
bsPF.DataSource = dtUnique;
|
||
bsPF2.DataSource = dtUnique;
|
||
|
||
comboBox1.DisplayMember = "part_number_name"; // 显示“零件号|零件名”
|
||
comboBox1.ValueMember = "part_number_name";
|
||
comboBox2.DisplayMember = "part_number_name";
|
||
comboBox2.ValueMember = "part_number_name";
|
||
|
||
// 自定义显示格式:显示“零件号 - 零件名”
|
||
comboBox1.Format += (s, e) =>
|
||
{
|
||
if (e.ListItem is DataRowView drv)
|
||
{
|
||
e.Value = string.IsNullOrEmpty(drv["part_number_name"].ToString()) ? "" :
|
||
drv["part_number"].ToString() + " - " + drv["part_name"].ToString();
|
||
}
|
||
};
|
||
comboBox2.Format += (s, e) =>
|
||
{
|
||
if (e.ListItem is DataRowView drv)
|
||
{
|
||
e.Value = string.IsNullOrEmpty(drv["part_number_name"].ToString()) ? "" :
|
||
drv["part_number"].ToString() + " - " + drv["part_name"].ToString();
|
||
}
|
||
};
|
||
}
|
||
|
||
|
||
|
||
}
|
||
|
||
//初始化MQTT字典
|
||
private async void InitMqttDic()
|
||
{
|
||
DataTable dt = await _mqttService.InitMqttDic();
|
||
if (dt != null)
|
||
{
|
||
dtMqttDic = dt;
|
||
}
|
||
}
|
||
|
||
private async void buttonConnect_Click(object sender, EventArgs e)
|
||
{
|
||
try
|
||
{
|
||
AppendLog("正在连接MQTT服务器...");
|
||
await _mqttService.MqttClientStartAsync();
|
||
AppendLog("连接成功!");
|
||
panelLed.BackColor = Color.Green;
|
||
toolStripStatusLabel1.Text = "已连接";
|
||
buttonConnect.Enabled = false;
|
||
buttonDisconnect.Enabled = true;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
panelLed.BackColor = Color.Red;
|
||
AppendLog($"连接失败:{ex.Message}");
|
||
toolStripStatusLabel1.Text = "连接失败";
|
||
}
|
||
}
|
||
|
||
private async void buttonDisconnect_Click(object sender, EventArgs e)
|
||
{
|
||
await _mqttService.MqttClientStopAsync();
|
||
AppendLog("已断开连接。");
|
||
panelLed.BackColor = Color.Red;
|
||
toolStripStatusLabel1.Text = "未连接";
|
||
buttonConnect.Enabled = true;
|
||
buttonDisconnect.Enabled = false;
|
||
}
|
||
|
||
private void OnMqttMessage(string msg)
|
||
{
|
||
if (InvokeRequired)
|
||
{
|
||
BeginInvoke(new Action<string>(OnMqttMessage), msg);
|
||
return;
|
||
}
|
||
AppendLog($"收到消息: {msg}");
|
||
}
|
||
|
||
|
||
//public void AppendLog(string message)
|
||
//{
|
||
// try
|
||
// {
|
||
// if (InvokeRequired)
|
||
// {
|
||
// BeginInvoke(new Action<string>(AppendLog), message);
|
||
// return;
|
||
// }
|
||
|
||
// string timeStamped = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] {message}\r\n";
|
||
// textBoxLog.AppendText(timeStamped);
|
||
// }
|
||
// catch (Exception ex)
|
||
// {
|
||
|
||
// }
|
||
//}
|
||
|
||
|
||
/// <summary>
|
||
/// 写入日志到文本框并保存到文件
|
||
/// </summary>
|
||
public void AppendLog(string message)
|
||
{
|
||
try
|
||
{
|
||
if (InvokeRequired)
|
||
{
|
||
BeginInvoke(new Action<string>(AppendLog), message);
|
||
return;
|
||
}
|
||
|
||
// 格式化带时间戳的日志
|
||
string timeStamped = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] {message}\r\n";
|
||
|
||
// 保存到日志文件
|
||
SaveToLogFile(timeStamped);
|
||
|
||
// 添加到文本框并限制行数
|
||
textBoxLog.AppendText(timeStamped);
|
||
LimitLogLines(500);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
// 可以在这里添加错误处理,例如写入错误日志
|
||
// MessageBox.Show($"日志处理错误: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 将日志保存到文件
|
||
/// </summary>
|
||
private void SaveToLogFile(string logContent)
|
||
{
|
||
try
|
||
{
|
||
UpdateLogFile(); // 确保使用当天的日志文件
|
||
// 追加写入日志,使用UTF8编码避免中文乱码
|
||
File.AppendAllText(_currentLogFile, logContent, System.Text.Encoding.UTF8);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
// 文件写入错误处理
|
||
// MessageBox.Show($"日志文件写入错误: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 限制日志文本框的最大行数
|
||
/// </summary>
|
||
private void LimitLogLines(int maxLines)
|
||
{
|
||
// 按换行符分割所有行
|
||
string[] lines = textBoxLog.Text.Split(new[] { "\r\n" }, StringSplitOptions.None);
|
||
|
||
// 如果超过最大行数,只保留最后maxLines行
|
||
if (lines.Length > maxLines)
|
||
{
|
||
// 计算需要保留的起始索引
|
||
int startIndex = lines.Length - maxLines;
|
||
string[] newLines = new string[maxLines];
|
||
Array.Copy(lines, startIndex, newLines, 0, maxLines);
|
||
|
||
// 重新设置文本框内容并保持滚动到最底部
|
||
textBoxLog.Text = string.Join("\r\n", newLines);
|
||
// 滚动到最新内容
|
||
textBoxLog.SelectionStart = textBoxLog.TextLength;
|
||
textBoxLog.ScrollToCaret();
|
||
}
|
||
else
|
||
{
|
||
// 未超过限制时也滚动到最底部
|
||
textBoxLog.SelectionStart = textBoxLog.TextLength;
|
||
textBoxLog.ScrollToCaret();
|
||
}
|
||
}
|
||
|
||
|
||
|
||
private async void Form1_FormClosing(object sender, FormClosingEventArgs e)
|
||
{
|
||
await _mqttService.MqttClientStopAsync();
|
||
|
||
}
|
||
|
||
//配方导入功能
|
||
private async void button1_Click(object sender, EventArgs e)
|
||
{
|
||
try
|
||
{
|
||
//弹出文件选择窗口
|
||
OpenFileDialog openFile = new OpenFileDialog();
|
||
if (openFile.ShowDialog() == DialogResult.OK)
|
||
{
|
||
string filePath = openFile.FileName;
|
||
DataTable excelDt = GetExcel(filePath);
|
||
if (excelDt != null && excelDt.Rows.Count > 0)
|
||
{
|
||
await _mqttService.SavePeiFangByExcel(excelDt);
|
||
getPeiFang();
|
||
MessageBox.Show("配方信息已导入!");
|
||
}
|
||
else
|
||
{
|
||
MessageBox.Show("不允许导入空表!");
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
AppendLog($"配方导入失败:{ex.Message}");
|
||
}
|
||
}
|
||
|
||
// <summary>
|
||
/// 获取Excel到Datatable中
|
||
/// </summary>
|
||
/// <param name="filePath">Excel路径</param>
|
||
/// <returns>返回DataTable数据</returns>
|
||
public static DataTable GetExcel(string filePath)
|
||
{
|
||
IWorkbook iwkX;
|
||
using (FileStream fs = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||
{
|
||
iwkX = WorkbookFactory.Create(fs);
|
||
fs.Close();
|
||
}
|
||
//sheet
|
||
DataTable dt = new DataTable();
|
||
for (int h = 0; h < iwkX.NumberOfSheets; h++)
|
||
{
|
||
ISheet sheet = iwkX.GetSheetAt(h);
|
||
var rows = sheet.GetRowEnumerator();
|
||
bool isMove = rows.MoveNext();
|
||
//循环sheet
|
||
if (isMove)
|
||
{
|
||
var Cols = (IRow)rows.Current;
|
||
dt.TableName = sheet.SheetName;
|
||
for (int i = 0; i < Cols.LastCellNum; i++)
|
||
{
|
||
string str = Cols.GetCell(i).ToString();
|
||
dt.Columns.Add(Cols.GetCell(i).ToString());
|
||
}
|
||
while (rows.MoveNext())
|
||
{
|
||
var row = (IRow)rows.Current;
|
||
var dr = dt.NewRow();
|
||
for (int i = 0; i < row.LastCellNum; i++)
|
||
{
|
||
var cell = row.GetCell(i);
|
||
if (cell == null)
|
||
{
|
||
dr[i] = "";
|
||
}
|
||
else
|
||
{
|
||
string strdr = cell.ToString();
|
||
dr[i] = cell.ToString();
|
||
}
|
||
}
|
||
dt.Rows.Add(dr);
|
||
}
|
||
}
|
||
}
|
||
return dt;
|
||
}
|
||
|
||
//上传宜搭
|
||
private async void button2_Click(object sender, EventArgs e)
|
||
{
|
||
try
|
||
{
|
||
if (toolStripStatusLabel1.Text != "已连接")//如果 MQTT 没连接,就不允许上传。
|
||
{
|
||
MessageBox.Show("请先连接MQTT网关!");
|
||
return;
|
||
}
|
||
if (this.comboBox1.Text.Length == 0 && this.comboBox2.Text.Length == 0)
|
||
{//如果两个下拉框都还没数据,说明没导入过配方,直接中止。
|
||
MessageBox.Show("请先导入配方信息,再刷新!");
|
||
return;
|
||
}
|
||
this.button2.Enabled = false;
|
||
////取出设备1选择的配方ID(ValueMember="id")
|
||
////在配方表 dtPeiFang 中找到那一行的完整记录,赋值给 drPeiFang1,这里是通过SelectedValue
|
||
//strPeiFangId1 = this.comboBox1.SelectedValue.ToString();
|
||
//drPeiFang1 = dtPeiFang.Select("id = '" + strPeiFangId1 + "'")[0];
|
||
////判断是否选了“空选项”,选了这个空项,程序会清空对应的配方引用。
|
||
//if (strPeiFangId1 == "-1")
|
||
//{
|
||
// strPeiFangId1 = "";
|
||
// drPeiFang1 = null;
|
||
//}
|
||
// 设备1选择配方
|
||
string selected1 = this.comboBox1.SelectedValue?.ToString();
|
||
if (string.IsNullOrEmpty(selected1) || selected1 == "-1")
|
||
{
|
||
drPeiFang1List = null;
|
||
}
|
||
else
|
||
{
|
||
string[] arr1 = selected1.Split('|');
|
||
if (arr1.Length == 2)
|
||
{
|
||
string partNumber1 = arr1[0];
|
||
string partName1 = arr1[1];
|
||
drPeiFang1List = dtPeiFang.AsEnumerable()
|
||
.Where(r => r.Field<string>("part_number") == partNumber1
|
||
&& r.Field<string>("part_name") == partName1)
|
||
.ToList();
|
||
}
|
||
else
|
||
{
|
||
drPeiFang1List = null;
|
||
}
|
||
}
|
||
|
||
|
||
//strPeiFangId2 = this.comboBox2.SelectedValue.ToString();
|
||
//drPeiFang2 = dtPeiFang.Select("id = '" + strPeiFangId2 + "'")[0];
|
||
//if (strPeiFangId2 == "-1")
|
||
//{
|
||
// strPeiFangId2 = "";
|
||
// drPeiFang2 = null;
|
||
//}
|
||
|
||
// 设备2选择配方
|
||
string selected2 = this.comboBox2.SelectedValue?.ToString();
|
||
if (string.IsNullOrEmpty(selected2) || selected2 == "-1")
|
||
{
|
||
drPeiFang2List = null;
|
||
}
|
||
else
|
||
{
|
||
string[] arr2 = selected2.Split('|');
|
||
if (arr2.Length == 2)
|
||
{
|
||
string partNumber2 = arr2[0];
|
||
string partName2 = arr2[1];
|
||
drPeiFang2List = dtPeiFang.AsEnumerable()
|
||
.Where(r => r.Field<string>("part_number") == partNumber2
|
||
&& r.Field<string>("part_name") == partName2)
|
||
.ToList();
|
||
}
|
||
else
|
||
{
|
||
drPeiFang2List = null;
|
||
}
|
||
}
|
||
|
||
double seconds;
|
||
if (!double.TryParse(txtLUploadPL.Text, out seconds) || seconds <= 0)
|
||
{
|
||
seconds = 10;//控制上传间隔,默认10秒。
|
||
}
|
||
|
||
// 立即上传一次
|
||
await MQttYiDaUpload();
|
||
|
||
_timer = new System.Timers.Timer(seconds * 1000);
|
||
_timer.Elapsed += async (s, evt) =>
|
||
{
|
||
await MQttYiDaUpload();
|
||
|
||
};
|
||
_timer.AutoReset = true; // 是否重复
|
||
_timer.Enabled = true; // 开始计时
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
this.button2.Enabled = true;
|
||
AppendLog($"上传宜搭失败:{ex.Message}");
|
||
}
|
||
}
|
||
|
||
private void _timer_Tick(object sender, ElapsedEventArgs e)
|
||
{
|
||
MQttYiDaUpload();
|
||
AppendLog("宜搭数据已上传!");
|
||
}
|
||
|
||
//上传宜搭
|
||
private async Task MQttYiDaUpload()
|
||
{
|
||
//获取最新的2台设备数据,各取最新1条。
|
||
DataTable dtMqtt = await _mqttService.GetLatestMqttDataAsync();
|
||
if (dtMqtt != null && dtMqtt.Rows.Count > 0)//有设备数据才会执行
|
||
{
|
||
foreach (DataRow dr in dtMqtt.Rows)//遍历dtMqtt中数据,一行代表一个设备的数据,一共2行
|
||
{
|
||
//DataRow drPeiFang = null;//先将drPeiFang设为空
|
||
//if (dr["device_code"].ToString() == "device1")//如果是设备1的数据
|
||
//{
|
||
// if (strPeiFangId1.Length > 0 && drPeiFang1 != null)//如果设备1选择了配方
|
||
// {
|
||
// drPeiFang = drPeiFang1;//drPeiFang的数据来源于drPeiFang1
|
||
// }
|
||
//}
|
||
//else if (dr["device_code"].ToString() == "device2")//如果是设备2的数据
|
||
//{
|
||
// if (strPeiFangId2.Length > 0 && drPeiFang2 != null)//如果设备2选择了配方
|
||
// {
|
||
// drPeiFang = drPeiFang2;//drPeiFang的数据来源于drPeiFang2
|
||
// }
|
||
//}
|
||
List<DataRow> drPeiFangList = null;
|
||
string site = null;
|
||
if (dr["device_code"].ToString() == "device1")
|
||
{
|
||
drPeiFangList = drPeiFang1List;
|
||
site = "1号设备";
|
||
}
|
||
else if (dr["device_code"].ToString() == "device2")
|
||
{
|
||
drPeiFangList = drPeiFang2List;
|
||
site = "2号设备";
|
||
}
|
||
|
||
|
||
|
||
////如果drPeiFang为空,说明设备1或者设备2没有选择配方,不需要将数据上传至宜搭平台,结束本轮循环,。
|
||
//if (drPeiFang == null)
|
||
//{
|
||
// continue;
|
||
//}
|
||
if (drPeiFangList == null || drPeiFangList.Count == 0) continue;
|
||
|
||
|
||
//取出一条字段 MESSAGE
|
||
string strMessage = dr["MESSAGE"].ToString();
|
||
//反序列化设备收到的数据,取出里面的参数(@params)。根据MqttDataModel 的定义。
|
||
MqttDataModel data = JsonConvert.DeserializeObject<MqttDataModel>(strMessage);
|
||
//如果反序列化失败或 params 为空,就跳过。
|
||
if (data == null || data.@params == null)
|
||
{
|
||
continue;
|
||
}
|
||
//获取 @params 的实际类型。
|
||
Type paramsType = data.@params.GetType();
|
||
//properties—>paramsType 的所有字段信息,[Value01, Value02, …, Value10]。
|
||
PropertyInfo[] properties = paramsType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
|
||
List<MQTTModel> mqttLists = new List<MQTTModel>();
|
||
List<YIDAModel> yidaLists = new List<YIDAModel>();
|
||
//遍历参数构造数据项
|
||
foreach (PropertyInfo prop in properties)
|
||
{
|
||
//parameter_name,参数名,比如 "Value01"
|
||
string name = prop.Name;
|
||
//parameter_value,参数值,比如 24.6
|
||
object value = prop.GetValue(data.@params);
|
||
|
||
// 跳过空值(null 或 "")
|
||
if (value == null || string.IsNullOrWhiteSpace(value.ToString()))
|
||
{
|
||
continue;
|
||
}
|
||
|
||
|
||
//查映射表
|
||
//如果找到了映射,就替换 name 为中文显示名,
|
||
//dtMqttDic在Form1_Load方法中已经被赋值,是字典表中的数据。
|
||
DataRow[] drs = dtMqttDic.Select("col_code = '" + name + "'");
|
||
if (drs != null && drs.Length > 0)
|
||
{
|
||
name = drs[0]["name"].ToString();
|
||
}
|
||
|
||
DataRow drMatch = drPeiFangList.FirstOrDefault(r => r.Field<string>("parameter_name") == name);
|
||
if (drMatch == null) continue; // 没找到匹配行就跳过
|
||
|
||
|
||
//构造 MQTTModel(用于存数据库)
|
||
MQTTModel mqttNew = new MQTTModel();
|
||
//把当前参数数据与选中的配方信息(drPeiFang)融合,形成一个完整记录。
|
||
mqttNew.SupplierCode = drMatch["supplier_code"].ToString();//供应商代码
|
||
mqttNew.SupplierName = drMatch["supplier_name"].ToString();//供应商名称
|
||
mqttNew.VehicleModel = drMatch["vehicle_model"].ToString();//车型
|
||
mqttNew.PartNumber = drMatch["part_number"].ToString();//零件号
|
||
mqttNew.PartName = drMatch["part_name"].ToString();//零件名
|
||
|
||
mqttNew.ParameterName = name;//parameter_name,参数名
|
||
mqttNew.ParameterValue = value == null ? "" : value.ToString();//parameter_value,参数值
|
||
mqttNew.ToleranceLower = drMatch["tolerance_lower"].ToString();//下公差
|
||
mqttNew.ToleranceUpper = drMatch["tolerance_upper"].ToString();//上公差
|
||
mqttNew.LeaderPart = drMatch["leader_part"].ToString();//零件负责人
|
||
|
||
mqttNew.WorkStation = site;//工位
|
||
|
||
mqttNew.LeaderOutProtection = drMatch["leader_out_protection"].ToString();//外保负责人
|
||
|
||
//构造 YIDAModel(用于宜搭上传)
|
||
//把当前参数数据与选中的配方信息(drPeiFang)融合,形成一个完整记录。
|
||
YIDAModel yidaNew = new YIDAModel();
|
||
yidaNew.textField_mha98neu = drMatch["supplier_code"].ToString();//供应商代码
|
||
yidaNew.textField_mha98nev = drMatch["supplier_name"].ToString();//供应商名称
|
||
yidaNew.textField_mha98new = drMatch["vehicle_model"].ToString();//车型
|
||
yidaNew.textField_mha98nex = drMatch["part_number"].ToString();//零件号
|
||
yidaNew.textField_mha98ney = drMatch["part_name"].ToString();//零件名
|
||
|
||
yidaNew.textField_mha98nf1 = name;//parameter_name,参数名
|
||
yidaNew.textField_mhx44i2i = value == null ? "" : value.ToString();//parameter_value,参数值
|
||
yidaNew.textField_mhx44i2j = drMatch["tolerance_lower"].ToString();//下公差
|
||
yidaNew.textField_mhx44i2k = drMatch["tolerance_upper"].ToString();//上公差
|
||
yidaNew.textField_mha98nf7 = drMatch["leader_part"].ToString();//零件负责人
|
||
|
||
yidaNew.textField_mha98nf0 = site; //工位
|
||
yidaNew.textField_mha98nfh = drMatch["leader_out_protection"].ToString(); //外保负责人
|
||
|
||
//新增合格判断逻辑代码
|
||
if (name == "报警信息")
|
||
{
|
||
if (string.Equals(value?.ToString(), "无错误", StringComparison.Ordinal))
|
||
{
|
||
mqttNew.IsQualification = "合格";
|
||
yidaNew.textField_mha98nf5 = "合格";
|
||
}
|
||
else
|
||
{
|
||
mqttNew.IsQualification = "不合格";
|
||
yidaNew.textField_mha98nf5 = "不合格";
|
||
}
|
||
}
|
||
else if (name == "开模总数实时" || name == "托模次数")
|
||
{
|
||
mqttNew.IsQualification = "合格";
|
||
yidaNew.textField_mha98nf5 = "合格";
|
||
}
|
||
else
|
||
{
|
||
// 关键修正:用参数值(value)比较,而非参数名(name)
|
||
// 安全转换参数值、下公差、上公差为float
|
||
if (float.TryParse(value?.ToString(), out float paramValue) &&
|
||
float.TryParse(drMatch["tolerance_lower"].ToString(), out float toleranceLower) &&
|
||
float.TryParse(drMatch["tolerance_upper"].ToString(), out float toleranceUpper))
|
||
{
|
||
// 数值在公差范围内则合格
|
||
if (paramValue >= toleranceLower && paramValue <= toleranceUpper)
|
||
{
|
||
mqttNew.IsQualification = "合格";
|
||
yidaNew.textField_mha98nf5 = "合格";
|
||
}
|
||
else
|
||
{
|
||
mqttNew.IsQualification = "不合格";
|
||
yidaNew.textField_mha98nf5 = "不合格";
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 转换失败(如参数值非数值、公差为空),判定为不合格或跳过
|
||
mqttNew.IsQualification = "不合格";
|
||
yidaNew.textField_mha98nf5 = "不合格";
|
||
// 可选:输出日志排查转换失败的字段
|
||
this.AppendLog($"数值转换失败:参数名={name},参数值={value},下公差={drMatch["tolerance_lower"]},上公差={drMatch["tolerance_upper"]}");
|
||
}
|
||
}
|
||
|
||
mqttLists.Add(mqttNew);
|
||
yidaLists.Add(yidaNew);
|
||
|
||
}
|
||
int len = Math.Min(mqttLists.Count, yidaLists.Count);
|
||
if (len > 0)
|
||
{
|
||
List<MQTTModel> mqttLists1 = mqttLists.Take(len).ToList();
|
||
List<YIDAModel> yidaLists1 = yidaLists.Take(len).ToList();
|
||
|
||
string token = MqttClientService.GetDingDingToken();
|
||
if (string.IsNullOrEmpty(token))
|
||
{
|
||
MessageBox.Show("获取 token 失败,请检查 AppKey/AppSecret");
|
||
return;
|
||
}
|
||
|
||
MqttClientService.UploadDatabaseDataToYidaWithLogging(token, yidaLists1, mqttLists1, this);
|
||
}
|
||
|
||
|
||
//List<MQTTModel> mqttLists1 = mqttLists;
|
||
//List<YIDAModel> yidaLists1 = yidaLists;
|
||
|
||
//// 融合
|
||
//// 获取钉钉 token
|
||
//string token = MqttClientService.GetDingDingToken();
|
||
//if (string.IsNullOrEmpty(token))
|
||
//{
|
||
// MessageBox.Show("获取 token 失败,请检查 AppKey/AppSecret");
|
||
// return;
|
||
//}
|
||
|
||
//// 上传数据库数据到宜搭
|
||
//MqttClientService.UploadDatabaseDataToYidaWithLogging(token, yidaLists1, mqttLists1, this);
|
||
|
||
//if (result)
|
||
// MessageBox.Show("数据上传宜搭成功!");
|
||
//else
|
||
// MessageBox.Show("部分数据上传失败,请查看日志。");
|
||
|
||
////记载宜搭上传成功日志
|
||
//_mqttService.RecordSuccessLog(mqttLists1);
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
|
||
|
||
private void btnRefresh_Click(object sender, EventArgs e)
|
||
{
|
||
getPeiFang();
|
||
}
|
||
|
||
//中止上传
|
||
private void button3_Click(object sender, EventArgs e)
|
||
{
|
||
this.button2.Enabled = true;
|
||
if (this._timer != null)
|
||
{
|
||
this._timer.Enabled = false;
|
||
}
|
||
AppendLog("停止上传数据");
|
||
MessageBox.Show("待程序完成后,将停止自动上传", "信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
}
|
||
|
||
private void txtLUploadPL_KeyPress(object sender, KeyPressEventArgs e)
|
||
{
|
||
if (e.KeyChar == (char)Keys.Back)
|
||
{
|
||
e.Handled = false;
|
||
return;
|
||
}
|
||
if (char.IsDigit(e.KeyChar))
|
||
{
|
||
e.Handled = false;
|
||
}
|
||
else if (e.KeyChar == '.' && !txtLUploadPL.Text.Contains("."))
|
||
{
|
||
e.Handled = false;
|
||
}
|
||
else
|
||
{
|
||
e.Handled = true;
|
||
}
|
||
}
|
||
|
||
private void timer1_Tick(object sender, EventArgs e)
|
||
{
|
||
// 每秒更新一次时间显示
|
||
this.label4.Text = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
|
||
}
|
||
|
||
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
|
||
{
|
||
|
||
}
|
||
}
|
||
}
|