334 lines
12 KiB
C#
334 lines
12 KiB
C#
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;
|
||
|
||
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 readonly string receiveconnectionString = "server=139.224.232.211;port=3308;database=GXAssembly;user=root;password=doantech123;";
|
||
|
||
public async Task<int> QueryDataAsync()
|
||
{
|
||
try
|
||
{
|
||
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(sendconnectionString);
|
||
}
|
||
totalCount += iResult;
|
||
}
|
||
return totalCount;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
public async Task<int> BatchUpdateTodayStatusAsync(string connectionString)
|
||
{
|
||
const string updateBothTablesSql = @"
|
||
UPDATE qc_firstarticle_inspection
|
||
SET isload = 1,
|
||
updated_time = NOW()
|
||
WHERE isload = 0
|
||
AND DATE(created_time) = CURDATE();
|
||
|
||
UPDATE qc_final_inspection
|
||
SET isload = 1,
|
||
updated_time = NOW()
|
||
WHERE isload = 0
|
||
AND DATE(created_time) = CURDATE();";
|
||
|
||
using (var conn = new MySqlConnection(connectionString))
|
||
{
|
||
await conn.OpenAsync();
|
||
|
||
using (var cmd = new MySqlCommand(updateBothTablesSql, conn))
|
||
{
|
||
// 执行多语句更新,返回两个更新操作的总行数
|
||
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";
|
||
|
||
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;
|
||
}
|
||
}
|
||
}
|
||
}
|