using MQTT_WinformV1.Model; using MySql.Data.MySqlClient; using MySqlX.XDevAPI.Common; using NPOI.OpenXmlFormats.Dml; using System; using System.Collections.Generic; using System.Data; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace MQTT_WinformV1.Service { public class DataUploadService { //private readonly string sendconnectionString = "server=139.224.232.211;port=3308;database=ay2509055-guiyang-fluorescence-lmes;user=root;password=doantech123;"; private string sendconnectionString = string.Empty; private readonly string receiveconnectionString = new MySqlConnectionStringBuilder { Server = Globalstatic.mesIP, Port = uint.Parse(Globalstatic.mesPort), // 端口转成uint(匹配Builder的Port类型) Database = Globalstatic.mesDBName, UserID = Globalstatic.mesUser, Password = Globalstatic.mesPwd, CharacterSet = "utf8mb4" }.ConnectionString; public async Task QueryDataAsync(string strIP,string strPort,string strDBName,string strUser,string strPwd) { try { #region 作废20251209MES主动抓数据 //DataTable sendDb = await getSendDB(); //int totalCount = 0; //foreach (DataRow dr in sendDb.Rows) //{ // string strSend = dr["config_value"].ToString(); // var (firstMachineData, finalMachineData) = await GetTodayInspectionDataAsync(strSend); // int iResult = await InsertDataAsync(firstMachineData, finalMachineData, receiveconnectionString); // if (iResult > 0) // { // //变更上传状态 // await BatchUpdateTodayStatusAsync(strSend); // } // totalCount += iResult; //} //return totalCount; #endregion MySqlConnectionStringBuilder connStrBuilder = new MySqlConnectionStringBuilder(); connStrBuilder.Server = strIP; uint.TryParse(strPort, out uint portNum); connStrBuilder.Port = portNum; connStrBuilder.UserID = strUser; connStrBuilder.Password = strPwd; connStrBuilder.Database = strDBName; connStrBuilder.CharacterSet = "utf8mb4"; sendconnectionString = connStrBuilder.ConnectionString; var (firstMachineData, finalMachineData) = await GetTodayInspectionDataAsync(sendconnectionString); int iResult = await InsertDataAsync(firstMachineData, finalMachineData, receiveconnectionString); if (iResult > 0) { //变更上传状态 await BatchUpdateTodayStatusAsync(sendconnectionString, firstMachineData, finalMachineData); } return iResult; } catch (Exception ex) { return 0; } } public async Task BatchUpdateTodayStatusAsync(string connectionString, DataTable firstMachineData, DataTable finalMachineData) { List firstIds = new List(); foreach (DataRow dr in firstMachineData.Rows) { firstIds.Add(int.Parse(dr["Id"].ToString())); } List finalIds = new List(); foreach (DataRow dr in finalMachineData.Rows) { finalIds.Add(int.Parse(dr["Id"].ToString())); } if (firstIds.Count == 0 && finalIds.Count == 0) { return 0; } // 存储所有参数 List allParams = new List(); // 构建第一个表的ID参数 string firstIdParams = ""; for (int i = 0; i < firstIds.Count; i++) { string paramName = $"@FirstId{i}"; firstIdParams += (firstIdParams == "" ? "" : ",") + paramName; allParams.Add(new MySqlParameter(paramName, firstIds[i])); } // 构建第二个表的ID参数 string finalIdParams = ""; for (int i = 0; i < finalIds.Count; i++) { string paramName = $"@FinalId{i}"; finalIdParams += (finalIdParams == "" ? "" : ",") + paramName; allParams.Add(new MySqlParameter(paramName, finalIds[i])); } // 拼接更新SQL(仅更新有ID的表) StringBuilder updateSql = new StringBuilder(); if (firstIds.Count > 0) { updateSql.Append($@" UPDATE qc_firstarticle_inspection SET isload = 1, updated_time = NOW() WHERE isload = 0 AND Id IN ({firstIdParams});"); } if (finalIds.Count > 0) { updateSql.Append($@" UPDATE qc_final_inspection SET isload = 1, updated_time = NOW() WHERE isload = 0 AND Id IN ({finalIdParams});"); } using (var conn = new MySqlConnection(connectionString)) { await conn.OpenAsync(); using (var cmd = new MySqlCommand(updateSql.ToString(), conn)) { // 添加所有参数 cmd.Parameters.AddRange(allParams.ToArray()); // 执行多语句更新,返回总行数 return await cmd.ExecuteNonQueryAsync(); } } } //将首检终检数据插入数据库 private async Task InsertDataAsync( DataTable firstMachineData, DataTable finalMachineData, string receiveconnectionString) { int totalInserted = 0; if (firstMachineData?.Rows.Count > 0) { totalInserted += await BatchInsertFirstMachineDataAsync( firstMachineData, receiveconnectionString); } if (finalMachineData?.Rows.Count > 0) { totalInserted += await BatchInsertFinalMachineDataAsync( finalMachineData, receiveconnectionString); } return totalInserted; } private async Task BatchInsertFirstMachineDataAsync( DataTable data, string connectionString) { const string insertSql = @" INSERT INTO qc_firstarticle_inspection ( fk_workorder, factoryCode, lineCode, machineCode, productCode, productname, SNnumber, paramter_name, standard_paramter_value, real_paramter_value, up_range_limit, low_range_limit, unit, checkResult, paramTime, createdby, updatedby, created_time, updated_time ) VALUES ( @fk_workorder, @factoryCode, @lineCode, @machineCode, @productCode, @productname, @SNnumber, @paramter_name, @standard_paramter_value, @real_paramter_value, @up_range_limit, @low_range_limit, @unit, @checkResult, @paramTime, @createdby, @updatedby, @created_time, @updated_time )"; return await BatchInsertAsync(connectionString, insertSql, data, MapFirstMachineParameters); } private async Task BatchInsertFinalMachineDataAsync( DataTable data, string connectionString) { const string insertSql = @" INSERT INTO qc_final_inspection ( fk_workorder, factoryCode, lineCode, machineCode, productCode, productname, SNnumber, paramter_name, standard_paramter_value, real_paramter_value, up_range_limit, low_range_limit, unit, checkResult, paramTime, createdby, updatedby, created_time, updated_time ) VALUES ( @fk_workorder, @factoryCode, @lineCode, @machineCode, @productCode, @productname, @SNnumber, @paramter_name, @standard_paramter_value, @real_paramter_value, @up_range_limit, @low_range_limit, @unit, @checkResult, @paramTime, @createdby, @updatedby, @created_time, @updated_time )"; return await BatchInsertAsync(connectionString, insertSql, data, MapFirstMachineParameters); } private async Task BatchInsertAsync( string connectionString, string sql, DataTable data, Action parameterMapper) { int insertedCount = 0; using (var conn = new MySqlConnection(connectionString)) { await conn.OpenAsync(); using (var transaction = await conn.BeginTransactionAsync()) { try { foreach (DataRow row in data.Rows) { using (var cmd = new MySqlCommand(sql, conn, transaction)) { parameterMapper(cmd, row); insertedCount += await cmd.ExecuteNonQueryAsync(); } } await transaction.CommitAsync(); return insertedCount; } catch(Exception ex) { Console.WriteLine(ex.Message); await transaction.RollbackAsync(); throw; } } } } private void MapFirstMachineParameters(MySqlCommand cmd, DataRow row) { cmd.Parameters.AddWithValue("@fk_workorder", row["fk_workorder"]); cmd.Parameters.AddWithValue("@factoryCode", row["factoryCode"]); cmd.Parameters.AddWithValue("@lineCode", row["lineCode"]); cmd.Parameters.AddWithValue("@machineCode", row["machineCode"]); cmd.Parameters.AddWithValue("@productCode", row["productCode"]); cmd.Parameters.AddWithValue("@productname", row["productname"]); cmd.Parameters.AddWithValue("@SNnumber", row["SNnumber"]); cmd.Parameters.AddWithValue("@paramter_name", row["paramter_name"]); cmd.Parameters.AddWithValue("@standard_paramter_value", ConvertToDecimal(row["standard_paramter_value"])); cmd.Parameters.AddWithValue("@real_paramter_value", ConvertToDecimal(row["real_paramter_value"])); cmd.Parameters.AddWithValue("@up_range_limit", ConvertToDecimal(row["up_range_limit"])); cmd.Parameters.AddWithValue("@low_range_limit", ConvertToDecimal(row["low_range_limit"])); cmd.Parameters.AddWithValue("@unit", row["unit"]); cmd.Parameters.AddWithValue("@checkResult", ConvertToBoolean(row["checkResult"])); cmd.Parameters.AddWithValue("@paramTime", ConvertToDateTime(row["paramTime"])); cmd.Parameters.AddWithValue("@createdby", row["createdby"]); cmd.Parameters.AddWithValue("@updatedby", row["updatedby"]); cmd.Parameters.AddWithValue("@created_time", DateTime.Now); cmd.Parameters.AddWithValue("@updated_time", DateTime.Now); } private decimal ConvertToDecimal(object value) { if (value == null || value == DBNull.Value) return 0; return Convert.ToDecimal(value); } private DateTime ConvertToDateTime(object value) { if (value == null || value == DBNull.Value) return DateTime.Now; return Convert.ToDateTime(value); } private bool ConvertToBoolean(object value) { if (value == null || value == DBNull.Value) return false; return Convert.ToBoolean(value); } // 提取公共方法 public async Task<(DataTable FirstMachine, DataTable FinalMachine)> GetTodayInspectionDataAsync(string connectionString) { // 获取今天的日期范围 var (startTime, endTime) = GetTodayDateRange(); // 并行执行查询以提高性能 var tasks = new[] { QueryInspectionDataAsync(connectionString, "qc_firstarticle_inspection", startTime, endTime), QueryInspectionDataAsync(connectionString, "qc_final_inspection", startTime, endTime) }; var results = await Task.WhenAll(tasks); return (results[0], results[1]); } // 参数化查询方法 private async Task QueryInspectionDataAsync( string connectionString, string tableName, DateTime startTime, DateTime endTime) { // 参数化查询,防止SQL注入 string sql = $@" SELECT * FROM {tableName} f WHERE f.created_time >= @startTime AND f.created_time <= @endTime AND f.isload = 0 LIMIT 1000"; return await QueryAsync(connectionString, sql, new MySqlParameter("@startTime", startTime), new MySqlParameter("@endTime", endTime)); } // 重构的 QueryAsync 方法,支持参数化查询 public async Task QueryAsync(string connectionString, string sql, params MySqlParameter[] parameters) { DataTable dt = new DataTable(); using (var conn = new MySqlConnection(connectionString)) { await conn.OpenAsync(); using (var cmd = new MySqlCommand(sql, conn)) { cmd.CommandTimeout = 60; // 添加参数 if (parameters != null && parameters.Length > 0) { cmd.Parameters.AddRange(parameters); } using (var reader = await cmd.ExecuteReaderAsync()) { dt.Load(reader); } } } return dt; } // 获取今天日期范围的辅助方法 private (DateTime StartTime, DateTime EndTime) GetTodayDateRange() { DateTime today = DateTime.Today; // 使用小于下一天的方式,避免精度问题 DateTime startTime = today; DateTime endTime = today.AddDays(1).AddSeconds(-1); return (startTime, endTime); } // 更简洁的版本 private (DateTime StartTime, DateTime EndTime) GetTodayDateRangeSimple() { var today = DateTime.Today; return (today, today.AddDays(1).AddTicks(-1)); // 精确到23:59:59.9999999 } public async Task getSendDB() { try { return await QueryAsync(receiveconnectionString, "select * from qc_db_config"); } catch (Exception ex) { Console.WriteLine(ex.Message); return null; } } } }