using System; using System.Collections.Generic; using System.Data; using System.Threading.Tasks; using MQTT_WinformV1; using MySql.Data.MySqlClient; using Newtonsoft.Json; using NPOI.SS.UserModel; using YiDa_WinForm.Config; using YiDa_WinForm.Model; namespace YiDa_WinForm.Service { public class ButtonOperationService { public string _formulaValue = null; // 配方字段 // 通知UI层 public event Action MessageReceived; /// /// 保存配方表格数据到数据库中 /// /// public async Task SaveFormulaByExcel(DataTable dtExcel) { try { // 1. 定义列名映射(保持原有逻辑) Dictionary columnMap = new Dictionary() { { "供应商代码", "供应商代码" }, { "供应商名称", "供应商名称" }, { "车型", "车型" }, { "零件号", "零件号" }, { "零件名", "零件名" }, { "参数名", "参数名" }, { "下公差", "下公差" }, { "上公差", "上公差" }, { "整改图片", "整改图片" }, { "零件负责人", "零件负责人" }, { "外保负责人", "外保负责人" } }; // 2. 准备批量插入的参数列表 List parametersList = new List(); string sqlInsert = @"INSERT INTO yida_formula (supplier_code, supplier_name, vehicle_model, part_number, part_name, parameter_name, tolerance_lower, tolerance_upper, reformation_picture, leader_part, leader_out_protection) VALUES (@supplier_code, @supplier_name, @vehicle_model, @part_number, @part_name, @parameter_name, @tolerance_lower, @tolerance_upper, @reformation_picture, @leader_part, @leader_out_protection)"; // 3. 遍历Excel数据,批量构建参数(无循环插入,仅构建参数) foreach (DataRow dr in dtExcel.Rows) { try { string paramName = GetExcelCellValue(dr, columnMap["参数名"]).ToString(); if (paramName == "报废图片") _formulaValue = "报废图片"; if (paramName == "连杆测试") _formulaValue = "连杆测试"; // 构建单行参数 MySqlParameter[] parameters = new MySqlParameter[] { new MySqlParameter("@supplier_code", GetExcelCellValue(dr, columnMap["供应商代码"])), new MySqlParameter("@supplier_name", GetExcelCellValue(dr, columnMap["供应商名称"])), new MySqlParameter("@vehicle_model", GetExcelCellValue(dr, columnMap["车型"])), new MySqlParameter("@part_number", GetExcelCellValue(dr, columnMap["零件号"])), new MySqlParameter("@part_name", GetExcelCellValue(dr, columnMap["零件名"])), new MySqlParameter("@parameter_name", paramName), new MySqlParameter("@tolerance_lower", GetExcelCellValue(dr, columnMap["下公差"])), new MySqlParameter("@tolerance_upper", GetExcelCellValue(dr, columnMap["上公差"])), new MySqlParameter("@reformation_picture", GetExcelCellValue(dr, columnMap["整改图片"])), new MySqlParameter("@leader_part", GetExcelCellValue(dr, columnMap["零件负责人"])), new MySqlParameter("@leader_out_protection", GetExcelCellValue(dr, columnMap["外保负责人"])) }; parametersList.Add(parameters); } catch (Exception rowEx) { MessageReceived?.Invoke($"警告:当前行数据构建失败,跳过该行。错误:{rowEx.Message}"); continue; } } // 4. 先删除原有配方(单次执行) string sqlDel = @"DELETE FROM yida_formula;"; await DbHelper.ExecuteNonQueryAsync(sqlDel); // 5. 批量插入新配方(核心优化:单次连接+事务,批量执行) if (parametersList.Count > 0) { int insertCount = await DbHelper.ExecuteBatchInsertAsync(sqlInsert, parametersList); MessageReceived?.Invoke($"配方数据导入数据库成功,共插入 {insertCount} 条有效数据"); } else { MessageReceived?.Invoke("无有效配方数据可插入"); } } catch (Exception ex) { MessageReceived?.Invoke($"保存配方表格到数据库时出错:{ex.Message} {ex.InnerException?.Message}"); } } /// /// 获取数据库配方 /// /// public async Task QueryFormulaAsync() { try { string strSql = @"SELECT * FROM yida_formula"; // 调用公共查询方法,返回DataTable return await DbHelper.ExecuteQueryAsync(strSql); } catch (Exception ex) { MessageReceived?.Invoke($"查询配方数据失败:{ex.Message} {ex.InnerException?.Message}"); return new DataTable(); // 返回空DataTable,避免UI层空引用 } } /// /// 获取MQTT参数字典 /// /// public async Task InitMqttDic() { try { string strSql = @"SELECT * from yida_upload_param"; // 调用公共查询方法 return await DbHelper.ExecuteQueryAsync(strSql); } catch (Exception ex) { MessageReceived?.Invoke($"查询MQTT参数字典失败:{ex.Message} {ex.InnerException?.Message}"); return new DataTable(); } } /// /// 获取MQTT数据 /// /// public async Task GetLatestMqttDataAsync(string selection, string device) { try { string strSql = null; if (selection != null && device == null) { if (selection.Contains("1")) { strSql = @"SELECT * FROM yida_mqtt_message where device_code='device1' and pv_status = 1 ORDER BY create_time DESC LIMIT 1"; } else if (selection.Contains("2")) { strSql = @"SELECT * FROM yida_mqtt_message where device_code='device2' and pv_status = 1 ORDER BY create_time DESC LIMIT 1"; } else { strSql= @"SELECT * FROM yida_mqtt_message where (device_code = 'device1' or device_code = 'device2') and pv_status = 1 ORDER BY create_time DESC LIMIT 1"; } } else { if (device.Equals("device1")) { if (selection.Equals("1")) { strSql = @"SELECT * FROM yida_mqtt_message where device_code = 'device1' and pv_status = 1 and img_status1 = 1 ORDER BY create_time DESC LIMIT 1"; } else { strSql = @"SELECT * FROM yida_mqtt_message where device_code = 'device1' and pv_status = 1 and img_status2 = 1 ORDER BY create_time DESC LIMIT 1"; } } else if (device.Equals("device2")) { if (selection.Equals("1")) { strSql = @"SELECT * FROM yida_mqtt_message where device_code = 'device2' and pv_status = 1 and img_status3 = 1 ORDER BY create_time DESC LIMIT 1"; } else { strSql = @"SELECT * FROM yida_mqtt_message where device_code = 'device2' and pv_status = 1 and img_status4 = 1 ORDER BY create_time DESC LIMIT 1"; } } else { strSql= @"SELECT * FROM yida_mqtt_message where (device_code = 'device1' or device_code = 'device2') and pv_status = 1 and (img_status1 = 1 or img_status2 = 1 or img_status3 = 1 or img_status4 = 1) ORDER BY create_time DESC LIMIT 1"; } } // 调用公共查询方法 return await DbHelper.ExecuteQueryAsync(strSql); } catch (Exception ex) { MessageReceived?.Invoke($"查询最新MQTT数据失败:{ex.Message} {ex.InnerException?.Message}"); return new DataTable(); } } /// /// 保存上传至宜搭平台成功的数据到数据库中 /// /// public async Task CreateSuccessLog(List mqttLists) { try { DateTime time = DateTime.Now; string sqlInsert = @"INSERT INTO yida_success_log (supplier_code, supplier_name, vehicle_model,part_number,part_name,parameter_name,parameter_value,configuration,leader_part,time_upload_database) VALUES (@supplier_code, @supplier_name, @vehicle_model,@part_number,@part_name,@parameter_name,@parameter_value,@configuration,@leader_part,@time_upload_database)"; foreach (MqttModel mqttItem in mqttLists) { // 调用批量执行方法,传入参数赋值逻辑 await DbHelper.ExecuteBatchNonQueryAsync(sqlInsert, cmd => { cmd.Parameters.Clear(); cmd.Parameters.AddWithValue("@supplier_code", mqttItem.SupplierCode); cmd.Parameters.AddWithValue("@supplier_name", mqttItem.SupplierName); cmd.Parameters.AddWithValue("@vehicle_model", mqttItem.VehicleModel); cmd.Parameters.AddWithValue("@part_number", mqttItem.PartNumber); cmd.Parameters.AddWithValue("@part_name", mqttItem.PartName); cmd.Parameters.AddWithValue("@parameter_name", mqttItem.ParameterName); cmd.Parameters.AddWithValue("@parameter_value", mqttItem.ParameterValue); cmd.Parameters.AddWithValue("@configuration", mqttItem.Configuration); cmd.Parameters.AddWithValue("@leader_part", mqttItem.LeaderPart); cmd.Parameters.AddWithValue("@time_upload_database", time); }); } } catch (Exception ex) { MessageReceived?.Invoke($"宜搭日志写入数据库失败:{ex.Message} {ex.InnerException?.Message}"); } } /// /// 合并数据到Mysql数据 /// public async Task MergeAndSaveData(string operationStatus, string deviceCode) { try { string getLatestSql; if (deviceCode.Equals("device1")) { getLatestSql = @"SELECT id, receive_data FROM yida_mqtt_message WHERE device_code = 'device1' and pv_status = 1 ORDER BY id DESC LIMIT 1"; } else { getLatestSql = @"SELECT id, receive_data FROM yida_mqtt_message WHERE device_code = 'device2' and pv_status = 1 ORDER BY id DESC LIMIT 1"; } // 读取最新注塑机数据的receive_data DataTable dtLatest = await DbHelper.ExecuteQueryAsync(getLatestSql); // 无注塑机数据时直接返回 if (dtLatest.Rows.Count == 0) { LogHelper.AppendLog("数据库中无注塑机数据,无法合并"); return; } // 提取查询结果中的主键ID和JSON数据 long latestId = Convert.ToInt64(dtLatest.Rows[0]["id"]); string latestReceiveData = dtLatest.Rows[0]["receive_data"] == DBNull.Value ? null : dtLatest.Rows[0]["receive_data"].ToString(); if (string.IsNullOrEmpty(latestReceiveData)) { LogHelper.AppendLog("数据库中注塑机数据无有效receive_data"); return; } // 3. 反序列化注塑机JSON数据 var dataModel = JsonConvert.DeserializeObject(latestReceiveData); if (dataModel == null || dataModel.@params == null) { dataModel = new SQLDataModel { time = DateTime.Now.Millisecond, @params = new SQLParamModel() }; } if (operationStatus == "1") { dataModel.@params.BU = "报废图片已上传"; } else { dataModel.@params.CR = "连杆强度测试图片已上传"; } // 5. 重新序列化为JSON string mergedData = JsonConvert.SerializeObject(dataModel); // 6. 更新数据库(调用DbHelper执行更新) string updateSql = null; if (deviceCode.Equals("device1")) { if (operationStatus == "1") { updateSql = @"UPDATE yida_mqtt_message SET receive_data = @mergedData, img_status1 = 1 WHERE id = @latestId and pv_status = 1 and device_code = 'device1'"; } else { updateSql = @"UPDATE yida_mqtt_message SET receive_data = @mergedData, img_status2 = 1 WHERE id = @latestId and pv_status = 1 and device_code = 'device1'"; } } if (deviceCode.Equals("device2")) { if (operationStatus == "2") { updateSql = @"UPDATE yida_mqtt_message SET receive_data = @mergedData, img_status3 = 1 WHERE id = @latestId and pv_status = 1 and device_code = 'device2'"; } else { updateSql = @"UPDATE yida_mqtt_message SET receive_data = @mergedData, img_status4 = 1 WHERE id = @latestId and pv_status = 1 and device_code = 'device2'"; } } var updateParameters = new[] { new MySql.Data.MySqlClient.MySqlParameter("@mergedData", mergedData), new MySql.Data.MySqlClient.MySqlParameter("@latestId", latestId) }; // 调用DbHelper执行更新并获取受影响行数 int affectedRows = await DbHelper.ExecuteNonQueryAsync(updateSql, updateParameters); if (affectedRows > 0) { LogHelper.AppendLog($"成功合并字段,更新ID={latestId}"); } else { LogHelper.AppendLog("更新失败:未找到匹配的注塑机数据"); } } catch (Exception ex) { LogHelper.AppendLog($"合并并入库失败:{ex.Message} {ex.InnerException?.Message}"); } } /// /// 双参数版本:安全获取Excel解析后的DataRow单元格值(适配你的调用场景) /// /// Excel解析后的DataRow /// 列名(如"参数名"、"供应商代码") /// 处理后的字符串值,避免空引用和格式问题 private static string GetExcelCellValue(DataRow dr, string columnName) { // 1. 校验两个参数,避免空引用 if (dr == null) { return string.Empty; } if (string.IsNullOrEmpty(columnName) || !dr.Table.Columns.Contains(columnName)) { return string.Empty; } // 2. 处理DBNull和空值 if (dr[columnName] == DBNull.Value || dr[columnName] == null) { return string.Empty; } // 3. 统一转为字符串并去空格,返回最终结果 return dr[columnName].ToString().Trim(); } } }