409 lines
15 KiB
C#
409 lines
15 KiB
C#
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<int> 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<int> BatchUpdateTodayStatusAsync(string connectionString, DataTable firstMachineData, DataTable finalMachineData)
|
||
{
|
||
List<int> firstIds = new List<int>();
|
||
foreach (DataRow dr in firstMachineData.Rows)
|
||
{
|
||
firstIds.Add(int.Parse(dr["Id"].ToString()));
|
||
}
|
||
List<int> finalIds = new List<int>();
|
||
foreach (DataRow dr in finalMachineData.Rows)
|
||
{
|
||
finalIds.Add(int.Parse(dr["Id"].ToString()));
|
||
}
|
||
if (firstIds.Count == 0 && finalIds.Count == 0)
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
// 存储所有参数
|
||
List<MySqlParameter> allParams = new List<MySqlParameter>();
|
||
// 构建第一个表的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<int> 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<int> 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<int> 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<int> BatchInsertAsync(
|
||
string connectionString,
|
||
string sql,
|
||
DataTable data,
|
||
Action<MySqlCommand, DataRow> 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<DataTable> 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<DataTable> 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<DataTable> getSendDB()
|
||
{
|
||
try
|
||
{
|
||
return await QueryAsync(receiveconnectionString, "select * from qc_db_config");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine(ex.Message);
|
||
return null;
|
||
}
|
||
}
|
||
}
|
||
}
|