|
|
|
|
using System;
|
|
|
|
|
using System.Data.SqlClient;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using leak_test_project.Models;
|
|
|
|
|
|
|
|
|
|
namespace leak_test_project.Services
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// EOL 검사 데이터를 MSSQL 데이터베이스에 저장하는 서비스 클래스.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class EolDatabaseService
|
|
|
|
|
{
|
|
|
|
|
private readonly string _connectionString;
|
|
|
|
|
|
|
|
|
|
public EolDatabaseService(string connectionString)
|
|
|
|
|
{
|
|
|
|
|
_connectionString = connectionString;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// EOL 검사 결과를 데이터베이스에 저장합니다. (동일 ID 존재 시 업데이트, 미존재 시 삽입)
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="inspectData">검사 결과 데이터</param>
|
|
|
|
|
/// <returns>저장 성공 여부 (성공: true, 실패: false)</returns>
|
|
|
|
|
public async Task<bool> SaveEolDataAsync(InspectData inspectData, Housing.Login.StartupLoginWindowResult loginInfo)
|
|
|
|
|
{
|
|
|
|
|
if (inspectData == null) return false;
|
|
|
|
|
|
|
|
|
|
// MSSQL MERGE 문을 사용한 UPSERT 처리 (신규 dbo.EOL 스키마 적용)
|
|
|
|
|
const string query = @"
|
|
|
|
|
MERGE INTO [dbo].[EOL] AS Target
|
|
|
|
|
USING (SELECT @IC_SN AS IC_SN) AS Source
|
|
|
|
|
ON (Target.IC_SN = Source.IC_SN)
|
|
|
|
|
WHEN MATCHED THEN
|
|
|
|
|
UPDATE SET
|
|
|
|
|
Target.PCB_Barcode = @PCB_Barcode,
|
|
|
|
|
Target.Maker = @Maker,
|
|
|
|
|
Target.Model = @Model,
|
|
|
|
|
Target.Variant_1 = @Variant_1,
|
|
|
|
|
Target.Variant_2 = @Variant_2,
|
|
|
|
|
Target.Operator = @Operator,
|
|
|
|
|
Target.Production_Date = @Production_Date,
|
|
|
|
|
Target.Line = @Line,
|
|
|
|
|
Target.Lot_No = @Lot_No,
|
|
|
|
|
Target.Jig_No = @Jig_No,
|
|
|
|
|
Target.Channel = @Channel,
|
|
|
|
|
Target.Spec_UL = @Spec_UL,
|
|
|
|
|
Target.Spec_LL = @Spec_LL,
|
|
|
|
|
Target.Leak_Value = @Leak_Value,
|
|
|
|
|
Target.Result = @Result
|
|
|
|
|
WHEN NOT MATCHED THEN
|
|
|
|
|
INSERT (IC_SN, PCB_Barcode, Maker, Model, Variant_1, Variant_2, Operator, Production_Date, Line, Lot_No, Jig_No, Channel, Spec_UL, Spec_LL, Leak_Value, Result)
|
|
|
|
|
VALUES (@IC_SN, @PCB_Barcode, @Maker, @Model, @Variant_1, @Variant_2, @Operator, @Production_Date, @Line, @Lot_No, @Jig_No, @Channel, @Spec_UL, @Spec_LL, @Leak_Value, @Result);";
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var maker = loginInfo?.Maker ?? string.Empty;
|
|
|
|
|
var model = loginInfo?.Model ?? string.Empty;
|
|
|
|
|
var variant1 = loginInfo?.Variant1 ?? string.Empty;
|
|
|
|
|
var variant2 = loginInfo?.Variant2 ?? string.Empty;
|
|
|
|
|
var operatorId = loginInfo?.Operator ?? string.Empty;
|
|
|
|
|
var lineNo = loginInfo?.LineNo ?? string.Empty;
|
|
|
|
|
var lotNo = loginInfo?.LotNo ?? string.Empty;
|
|
|
|
|
var jigNo = loginInfo?.JigNo ?? string.Empty;
|
|
|
|
|
|
|
|
|
|
using (var conn = new SqlConnection(_connectionString))
|
|
|
|
|
{
|
|
|
|
|
using (var cmd = new SqlCommand(query, conn))
|
|
|
|
|
{
|
|
|
|
|
cmd.Parameters.AddWithValue("@IC_SN", string.IsNullOrEmpty(inspectData.IcSn) ? "-" : inspectData.IcSn);
|
|
|
|
|
cmd.Parameters.AddWithValue("@PCB_Barcode", string.IsNullOrEmpty(inspectData.PcbBarcode) ? "-" : inspectData.PcbBarcode);
|
|
|
|
|
cmd.Parameters.AddWithValue("@Maker", maker);
|
|
|
|
|
cmd.Parameters.AddWithValue("@Model", model);
|
|
|
|
|
cmd.Parameters.AddWithValue("@Variant_1", variant1);
|
|
|
|
|
cmd.Parameters.AddWithValue("@Variant_2", variant2);
|
|
|
|
|
cmd.Parameters.AddWithValue("@Operator", operatorId);
|
|
|
|
|
cmd.Parameters.AddWithValue("@Production_Date", inspectData.ProductionDate ?? DateTime.Now);
|
|
|
|
|
cmd.Parameters.AddWithValue("@Line", lineNo);
|
|
|
|
|
cmd.Parameters.AddWithValue("@Lot_No", lotNo);
|
|
|
|
|
cmd.Parameters.AddWithValue("@Jig_No", jigNo);
|
|
|
|
|
cmd.Parameters.AddWithValue("@Channel", string.IsNullOrEmpty(inspectData.Channel) ? "N/A" : inspectData.Channel);
|
|
|
|
|
|
|
|
|
|
// Spec_UL, Spec_LL, Leak_Value 형 변환 및 대입
|
|
|
|
|
decimal specUL = 0;
|
|
|
|
|
if (decimal.TryParse(inspectData.SpecUL, out var parsedUL)) specUL = parsedUL;
|
|
|
|
|
cmd.Parameters.AddWithValue("@Spec_UL", specUL);
|
|
|
|
|
|
|
|
|
|
decimal specLL = 0;
|
|
|
|
|
if (decimal.TryParse(inspectData.SpecLL, out var parsedLL)) specLL = parsedLL;
|
|
|
|
|
cmd.Parameters.AddWithValue("@Spec_LL", specLL);
|
|
|
|
|
|
|
|
|
|
decimal leakValue = 0;
|
|
|
|
|
if (decimal.TryParse(inspectData.MeasuredValue, out var parsedValue)) leakValue = parsedValue;
|
|
|
|
|
cmd.Parameters.AddWithValue("@Leak_Value", leakValue);
|
|
|
|
|
|
|
|
|
|
cmd.Parameters.AddWithValue("@Result", string.IsNullOrEmpty(inspectData.Judgment) ? "NG" : inspectData.Judgment);
|
|
|
|
|
|
|
|
|
|
await conn.OpenAsync();
|
|
|
|
|
await cmd.ExecuteNonQueryAsync();
|
|
|
|
|
Console.WriteLine($"[DB SUCCESS] EOL Data saved/updated for IC_SN: {inspectData.ProductId}");
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
// 실시간 검사 공정 루프 흐름이 DB 커넥션 예외로 중단되지 않도록 예외 격리 처리
|
|
|
|
|
Console.WriteLine($"[DB ERROR] Failed to upsert EOL Data: {ex.Message}");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 데이터베이스 연결 상태를 비동기로 확인합니다.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns>연결 성공 시 true, 실패 시 false</returns>
|
|
|
|
|
public async Task<bool> CheckConnectionAsync()
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var builder = new SqlConnectionStringBuilder(_connectionString)
|
|
|
|
|
{
|
|
|
|
|
ConnectTimeout = 2
|
|
|
|
|
};
|
|
|
|
|
using (var conn = new SqlConnection(builder.ConnectionString))
|
|
|
|
|
{
|
|
|
|
|
await conn.OpenAsync();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
System.Diagnostics.Debug.WriteLine($"[DB Connection Check Error] {ex.Message}");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|