2026-01-21 19:31:27 +08:00
using System ;
using System.Collections.Generic ;
using System.Data ;
using System.Threading.Tasks ;
2026-01-29 20:29:12 +08:00
using MQTT_WinformV1 ;
2026-01-21 19:31:27 +08:00
using MySql.Data.MySqlClient ;
2026-01-29 20:29:12 +08:00
using Newtonsoft.Json ;
using NPOI.SS.UserModel ;
2026-01-21 19:31:27 +08:00
using YiDa_WinForm.Config ;
using YiDa_WinForm.Model ;
2026-01-22 16:59:41 +08:00
namespace YiDa_WinForm.Service
2026-01-21 19:31:27 +08:00
{
public class ButtonOperationService
{
2026-01-23 16:25:57 +08:00
public string _formulaValue = null ; // 配方字段
2026-01-21 19:31:27 +08:00
// 通知UI层
public event Action < string > MessageReceived ;
2026-01-29 20:29:12 +08:00
2026-01-21 19:31:27 +08:00
/// <summary>
/// 保存配方表格数据到数据库中
/// </summary>
/// <param name="dtExcel"></param>
public async Task SaveFormulaByExcel ( DataTable dtExcel )
{
try
{
2026-01-29 20:29:12 +08:00
// 1. 定义列名映射(保持原有逻辑)
Dictionary < string , string > columnMap = new Dictionary < string , string > ( )
2026-01-21 19:31:27 +08:00
{
2026-01-29 20:29:12 +08:00
{ "供应商代码" , "供应商代码" } ,
{ "供应商名称" , "供应商名称" } ,
{ "车型" , "车型" } ,
{ "零件号" , "零件号" } ,
{ "零件名" , "零件名" } ,
{ "参数名" , "参数名" } ,
{ "下公差" , "下公差" } ,
{ "上公差" , "上公差" } ,
{ "整改图片" , "整改图片" } ,
{ "零件负责人" , "零件负责人" } ,
{ "外保负责人" , "外保负责人" }
} ;
// 2. 准备批量插入的参数列表
List < MySqlParameter [ ] > parametersList = new List < MySqlParameter [ ] > ( ) ;
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 ) ";
2026-01-21 19:31:27 +08:00
2026-01-29 20:29:12 +08:00
// 3. 遍历Excel数据, 批量构建参数( 无循环插入, 仅构建参数)
foreach ( DataRow dr in dtExcel . Rows )
{
try
2026-01-21 19:31:27 +08:00
{
2026-01-29 20:29:12 +08:00
string paramName = GetExcelCellValue ( dr , columnMap [ "参数名" ] ) . ToString ( ) ;
if ( paramName = = "报废图片" ) _formulaValue = "报废图片" ;
if ( paramName = = "连杆测试" ) _formulaValue = "连杆测试" ;
// 构建单行参数
MySqlParameter [ ] parameters = new MySqlParameter [ ]
2026-01-21 19:31:27 +08:00
{
2026-01-29 20:29:12 +08:00
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 ;
2026-01-21 19:31:27 +08:00
}
}
2026-01-29 20:29:12 +08:00
// 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 ( "无有效配方数据可插入" ) ;
}
2026-01-21 19:31:27 +08:00
}
catch ( Exception ex )
{
MessageReceived ? . Invoke ( $"保存配方表格到数据库时出错:{ex.Message} {ex.InnerException?.Message}" ) ;
}
}
/// <summary>
/// 获取数据库配方
/// </summary>
/// <returns></returns>
public async Task < DataTable > QueryFormulaAsync ( )
{
2026-01-29 20:29:12 +08:00
try
2026-01-21 19:31:27 +08:00
{
string strSql = @"SELECT * FROM yida_formula" ;
2026-01-29 20:29:12 +08:00
// 调用公共查询方法, 返回DataTable
return await DbHelper . ExecuteQueryAsync ( strSql ) ;
}
catch ( Exception ex )
{
MessageReceived ? . Invoke ( $"查询配方数据失败:{ex.Message} {ex.InnerException?.Message}" ) ;
return new DataTable ( ) ; // 返回空DataTable, 避免UI层空引用
2026-01-21 19:31:27 +08:00
}
}
/// <summary>
2026-01-22 16:59:41 +08:00
/// 获取MQTT参数字典
2026-01-21 19:31:27 +08:00
/// </summary>
/// <returns></returns>
2026-01-22 16:59:41 +08:00
public async Task < DataTable > InitMqttDic ( )
2026-01-21 19:31:27 +08:00
{
2026-01-29 20:29:12 +08:00
try
2026-01-21 19:31:27 +08:00
{
2026-01-22 16:59:41 +08:00
string strSql = @"SELECT * from yida_upload_param" ;
2026-01-29 20:29:12 +08:00
// 调用公共查询方法
return await DbHelper . ExecuteQueryAsync ( strSql ) ;
}
catch ( Exception ex )
{
MessageReceived ? . Invoke ( $"查询MQTT参数字典失败: {ex.Message} {ex.InnerException?.Message}" ) ;
return new DataTable ( ) ;
2026-01-21 19:31:27 +08:00
}
}
/// <summary>
/// 获取MQTT数据
/// </summary>
/// <returns></returns>
2026-02-04 09:53:15 +08:00
public async Task < DataTable > GetLatestMqttDataAsync ( string selection , string device )
2026-01-21 19:31:27 +08:00
{
2026-01-29 20:29:12 +08:00
try
2026-01-21 19:31:27 +08:00
{
2026-02-05 14:45:33 +08:00
string strSql = null ;
2026-02-04 09:53:15 +08:00
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
{
2026-02-05 14:45:33 +08:00
if ( device . Equals ( "device1" ) )
2026-02-04 09:53:15 +08:00
{
2026-02-05 14:45:33 +08:00
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" ) )
2026-02-04 09:53:15 +08:00
{
2026-02-05 14:45:33 +08:00
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" ;
}
2026-02-04 09:53:15 +08:00
}
else
{
2026-02-05 14:45:33 +08:00
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" ;
2026-02-04 09:53:15 +08:00
}
}
2026-01-29 20:29:12 +08:00
// 调用公共查询方法
return await DbHelper . ExecuteQueryAsync ( strSql ) ;
}
catch ( Exception ex )
{
MessageReceived ? . Invoke ( $"查询最新MQTT数据失败: {ex.Message} {ex.InnerException?.Message}" ) ;
return new DataTable ( ) ;
2026-01-21 19:31:27 +08:00
}
}
2026-01-29 20:29:12 +08:00
2026-01-23 16:25:57 +08:00
/// <summary>
/// 保存上传至宜搭平台成功的数据到数据库中
/// </summary>
/// <param name="mqttLists"></param>
2026-01-21 19:31:27 +08:00
public async Task CreateSuccessLog ( List < MqttModel > mqttLists )
{
try
{
2026-01-29 20:29:12 +08:00
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 )
2026-01-21 19:31:27 +08:00
{
2026-01-29 20:29:12 +08:00
// 调用批量执行方法,传入参数赋值逻辑
await DbHelper . ExecuteBatchNonQueryAsync ( sqlInsert , cmd = >
2026-01-21 19:31:27 +08:00
{
2026-01-29 20:29:12 +08:00
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 ) ;
} ) ;
2026-01-21 19:31:27 +08:00
}
}
catch ( Exception ex )
{
2026-01-23 16:25:57 +08:00
MessageReceived ? . Invoke ( $"宜搭日志写入数据库失败:{ex.Message} {ex.InnerException?.Message}" ) ;
2026-01-21 19:31:27 +08:00
}
}
2026-01-29 20:29:12 +08:00
/// <summary>
/// 合并数据到Mysql数据
/// </summary>
2026-02-04 16:45:16 +08:00
public async Task MergeAndSaveData ( string operationStatus , string deviceCode )
2026-01-29 20:29:12 +08:00
{
try
{
2026-02-04 09:53:15 +08:00
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
2026-01-29 20:29:12 +08:00
ORDER BY id DESC LIMIT 1 ";
2026-02-04 09:53:15 +08:00
}
// 读取最新注塑机数据的receive_data
2026-01-29 20:29:12 +08:00
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 < SQLDataModel > ( latestReceiveData ) ;
if ( dataModel = = null | | dataModel . @params = = null )
{
dataModel = new SQLDataModel
{
time = DateTime . Now . Millisecond ,
@params = new SQLParamModel ( )
} ;
}
2026-02-04 16:45:16 +08:00
if ( operationStatus = = "1" )
2026-01-29 20:29:12 +08:00
{
2026-02-04 16:45:16 +08:00
dataModel . @params . BU = "报废图片已上传" ;
2026-01-29 20:29:12 +08:00
}
else
{
2026-02-04 16:45:16 +08:00
dataModel . @params . CR = "连杆强度测试图片已上传" ;
2026-01-29 20:29:12 +08:00
}
// 5. 重新序列化为JSON
string mergedData = JsonConvert . SerializeObject ( dataModel ) ;
// 6. 更新数据库( 调用DbHelper执行更新)
2026-02-05 14:45:33 +08:00
string updateSql = null ;
2026-02-04 09:53:15 +08:00
if ( deviceCode . Equals ( "device1" ) )
{
2026-02-05 14:45:33 +08:00
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
2026-02-04 09:53:15 +08:00
WHERE id = @latestId and pv_status = 1 and device_code = ' device1 ' ";
2026-02-05 14:45:33 +08:00
}
2026-02-04 09:53:15 +08:00
}
2026-02-05 14:45:33 +08:00
if ( deviceCode . Equals ( "device2" ) )
2026-02-04 09:53:15 +08:00
{
2026-02-05 14:45:33 +08:00
if ( operationStatus = = "2" )
{
updateSql = @ "UPDATE yida_mqtt_message
SET receive_data = @mergedData , img_status3 = 1
2026-02-04 09:53:15 +08:00
WHERE id = @latestId and pv_status = 1 and device_code = ' device2 ' ";
2026-02-05 14:45:33 +08:00
}
else
{
updateSql = @ "UPDATE yida_mqtt_message
SET receive_data = @mergedData , img_status4 = 1
WHERE id = @latestId and pv_status = 1 and device_code = ' device2 ' ";
}
2026-02-04 09:53:15 +08:00
}
2026-01-29 20:29:12 +08:00
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}" ) ;
}
}
/// <summary>
/// 双参数版本: 安全获取Excel解析后的DataRow单元格值( 适配你的调用场景)
/// </summary>
/// <param name="dr">Excel解析后的DataRow</param>
/// <param name="columnName">列名(如"参数名"、"供应商代码") </param>
/// <returns>处理后的字符串值,避免空引用和格式问题</returns>
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 ( ) ;
}
2026-01-21 19:31:27 +08:00
}
}