You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
288 lines
12 KiB
288 lines
12 KiB
using System;
|
|
using System.Windows;
|
|
using System.Windows.Media;
|
|
using System.Windows.Threading;
|
|
using marking_gui.Models;
|
|
using marking_gui.Services;
|
|
|
|
namespace marking_gui
|
|
{
|
|
/// <summary>
|
|
/// MainWindow.xaml에 대한 상호 작용 논리
|
|
/// </summary>
|
|
public partial class MainWindow : Window
|
|
{
|
|
private DispatcherTimer _measurementTimer;
|
|
private DispatcherTimer _clockTimer;
|
|
private int _timerTickCount = 0;
|
|
|
|
// 비즈니스 로직 및 가상 하드웨어/DB 서비스 분리
|
|
private readonly MssqlDatabaseService _database = new MssqlDatabaseService();
|
|
private readonly MockMeasurer _measurer = new MockMeasurer();
|
|
private MeasurementLimits _limits = new MeasurementLimits();
|
|
private readonly Housing.Login.StartupLoginWindowResult _loginInfo;
|
|
|
|
public MainWindow() : this(new Housing.Login.StartupLoginWindowResult { Operator = "SYSTEM", Model = "DEFAULT", LineNo = "DEFAULT" })
|
|
{
|
|
}
|
|
|
|
public MainWindow(Housing.Login.StartupLoginWindowResult loginResult)
|
|
{
|
|
InitializeComponent();
|
|
_loginInfo = loginResult ?? new Housing.Login.StartupLoginWindowResult { Operator = "SYSTEM", Model = "DEFAULT", LineNo = "DEFAULT" };
|
|
|
|
InitializeTimer();
|
|
InitializeClock();
|
|
ResetUI();
|
|
InitializeLimits();
|
|
DisplayLoginInfo();
|
|
}
|
|
|
|
private void DisplayLoginInfo()
|
|
{
|
|
if (txtLoginInfo != null)
|
|
{
|
|
txtLoginInfo.Text = string.Format("[작업자: {0} | 모델: {1} | 라인: {2}]",
|
|
_loginInfo.Operator,
|
|
string.IsNullOrEmpty(_loginInfo.Model) ? "N/A" : _loginInfo.Model,
|
|
string.IsNullOrEmpty(_loginInfo.LineNo) ? "N/A" : _loginInfo.LineNo);
|
|
}
|
|
}
|
|
|
|
private void InitializeTimer()
|
|
{
|
|
_measurementTimer = new DispatcherTimer();
|
|
_measurementTimer.Interval = TimeSpan.FromMilliseconds(200); // 0.2초마다 갱신 (시뮬레이션 효과 연출)
|
|
_measurementTimer.Tick += MeasurementTimer_Tick;
|
|
}
|
|
|
|
private void InitializeClock()
|
|
{
|
|
_clockTimer = new DispatcherTimer();
|
|
_clockTimer.Interval = TimeSpan.FromSeconds(1);
|
|
_clockTimer.Tick += (s, e) => {
|
|
txtCurrentTime.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
|
};
|
|
_clockTimer.Start();
|
|
txtCurrentTime.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
|
}
|
|
|
|
private void InitializeLimits()
|
|
{
|
|
UpdateRangeGuides();
|
|
}
|
|
|
|
private void UpdateRangeGuides()
|
|
{
|
|
txtVoltageRangeGuide.Text = string.Format("기준범위: {0:F1}V ~ {1:F1}V", _limits.MinVoltage, _limits.MaxVoltage);
|
|
txtCurrentRangeGuide.Text = string.Format("기준범위: {0:F1}A ~ {1:F1}A", _limits.MinCurrent, _limits.MaxCurrent);
|
|
}
|
|
|
|
private void btnOpenSettings_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
SettingsWindow settings = new SettingsWindow(_limits);
|
|
settings.Owner = this;
|
|
|
|
if (settings.ShowDialog() == true)
|
|
{
|
|
_limits = settings.Limits;
|
|
UpdateRangeGuides();
|
|
MessageBox.Show("기준 범위 설정이 적용되었습니다.", "설정 완료", MessageBoxButton.OK, MessageBoxImage.Information);
|
|
}
|
|
}
|
|
|
|
// UI 초기화 상태
|
|
private void ResetUI()
|
|
{
|
|
txtSystemStatus.Text = "상태: 대기 중";
|
|
txtSystemStatus.Foreground = new SolidColorBrush(Color.FromRgb(156, 163, 175)); // Gray
|
|
|
|
txtPrevHousing.Text = "대기";
|
|
txtPrevHousing.Foreground = new SolidColorBrush(Color.FromRgb(156, 163, 175));
|
|
txtPrevCal.Text = "대기";
|
|
txtPrevCal.Foreground = new SolidColorBrush(Color.FromRgb(156, 163, 175));
|
|
txtPrevEol.Text = "대기";
|
|
txtPrevEol.Foreground = new SolidColorBrush(Color.FromRgb(156, 163, 175));
|
|
|
|
txtVoltage.Text = "---.-";
|
|
txtVoltage.Foreground = new SolidColorBrush(Color.FromRgb(31, 41, 55));
|
|
txtCurrent.Text = "--.-";
|
|
txtCurrent.Foreground = new SolidColorBrush(Color.FromRgb(31, 41, 55));
|
|
|
|
txtFinalResult.Text = "대 기 중";
|
|
txtFinalResult.Foreground = new SolidColorBrush(Color.FromRgb(156, 163, 175));
|
|
borderFinalResult.Background = new SolidColorBrush(Color.FromRgb(229, 231, 235)); // Light Gray
|
|
txtFinalSerial.Text = "S/N: ---";
|
|
|
|
btnStart.IsEnabled = false;
|
|
}
|
|
|
|
// 시리얼 텍스트 박스 포커스 이벤트
|
|
private void txtSerial_GotFocus(object sender, RoutedEventArgs e)
|
|
{
|
|
txtSerial.SelectAll();
|
|
}
|
|
|
|
// S/N 조회 버튼 클릭
|
|
private void btnSearchSerial_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
string serial = txtSerial.Text.Trim().ToUpper();
|
|
|
|
if (string.IsNullOrEmpty(serial))
|
|
{
|
|
MessageBox.Show("S/N을 입력해주세요.", "알림", MessageBoxButton.OK, MessageBoxImage.Warning);
|
|
return;
|
|
}
|
|
|
|
ResetUI();
|
|
txtFinalSerial.Text = "S/N: " + serial;
|
|
|
|
// 데이터베이스 서비스 조회 호출 (예외 방어 처리)
|
|
Product product = null;
|
|
try
|
|
{
|
|
product = _database.GetProductBySerial(serial);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageBox.Show(ex.Message, "DB 조회 오류", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
txtSystemStatus.Text = "상태: DB 연동 에러";
|
|
txtSystemStatus.Foreground = new SolidColorBrush(Color.FromRgb(239, 68, 68));
|
|
return;
|
|
}
|
|
|
|
if (product != null)
|
|
{
|
|
// 이전 검사 결과 바인딩 및 색상 설정
|
|
txtPrevHousing.Text = product.HousingResult;
|
|
txtPrevHousing.Foreground = product.HousingResult == "PASS"
|
|
? new SolidColorBrush(Color.FromRgb(16, 185, 129))
|
|
: new SolidColorBrush(Color.FromRgb(239, 68, 68));
|
|
|
|
txtPrevCal.Text = product.CalResult;
|
|
txtPrevCal.Foreground = product.CalResult == "PASS"
|
|
? new SolidColorBrush(Color.FromRgb(16, 185, 129))
|
|
: new SolidColorBrush(Color.FromRgb(239, 68, 68));
|
|
|
|
txtPrevEol.Text = product.EolResult;
|
|
txtPrevEol.Foreground = product.EolResult == "PASS"
|
|
? new SolidColorBrush(Color.FromRgb(16, 185, 129))
|
|
: new SolidColorBrush(Color.FromRgb(239, 68, 68));
|
|
|
|
if (product.IsPreviousStepsPassed)
|
|
{
|
|
txtSystemStatus.Text = "상태: 검사 가능 (이전 단계 합격)";
|
|
txtSystemStatus.Foreground = new SolidColorBrush(Color.FromRgb(16, 185, 129));
|
|
|
|
// 스타트 버튼 활성화
|
|
btnStart.IsEnabled = true;
|
|
}
|
|
else
|
|
{
|
|
string failedStep = string.Empty;
|
|
if (product.HousingResult == "FAIL") failedStep = "Housing 검사";
|
|
else if (product.CalResult == "FAIL") failedStep = "Calibration 검사";
|
|
else if (product.EolResult == "FAIL") failedStep = "EOL 검사";
|
|
|
|
txtSystemStatus.Text = "상태: 진행 불가 (이전 단계 불합격)";
|
|
txtSystemStatus.Foreground = new SolidColorBrush(Color.FromRgb(239, 68, 68));
|
|
|
|
// 스타트 버튼 비활성화
|
|
btnStart.IsEnabled = false;
|
|
|
|
MessageBox.Show(string.Format("이전 공정 단계({0})가 불합격 상태이므로 최종 성능 검사를 시작할 수 없습니다.", failedStep), "검사 제한", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
MessageBox.Show("등록되지 않은 S/N입니다.\n테스트용 S/N(PASS1234 또는 FAIL5678)을 입력해 주세요.", "조회 실패", MessageBoxButton.OK, MessageBoxImage.Information);
|
|
}
|
|
}
|
|
|
|
// 엔터 키 입력 시 조회 처리
|
|
private void txtSerial_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
|
|
{
|
|
if (e.Key == System.Windows.Input.Key.Enter)
|
|
{
|
|
btnSearchSerial_Click(sender, e);
|
|
}
|
|
}
|
|
|
|
// 스타트 버튼 클릭
|
|
private void btnStart_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
btnStart.IsEnabled = false;
|
|
btnSearchSerial.IsEnabled = false;
|
|
txtSerial.IsEnabled = false;
|
|
|
|
txtSystemStatus.Text = "상태: 검사 진행 중...";
|
|
txtSystemStatus.Foreground = new SolidColorBrush(Color.FromRgb(59, 130, 246)); // Blue
|
|
|
|
txtFinalResult.Text = "측 정 중";
|
|
txtFinalResult.Foreground = new SolidColorBrush(Color.FromRgb(59, 130, 246));
|
|
borderFinalResult.Background = new SolidColorBrush(Color.FromRgb(219, 234, 254)); // Light Blue
|
|
|
|
// 시뮬레이션 타이머 시작
|
|
_timerTickCount = 0;
|
|
_measurementTimer.Start();
|
|
}
|
|
|
|
// 타이머 틱 이벤트 (측정값 변화 시뮬레이션)
|
|
private void MeasurementTimer_Tick(object sender, EventArgs e)
|
|
{
|
|
_timerTickCount++;
|
|
|
|
if (_timerTickCount < 10) // 약 2초 동안 측정값 흔들림 효과 연출
|
|
{
|
|
double tempVoltage, tempCurrent;
|
|
_measurer.GenerateNoiseValues(_limits, out tempVoltage, out tempCurrent);
|
|
|
|
txtVoltage.Text = tempVoltage.ToString("F1");
|
|
txtCurrent.Text = tempCurrent.ToString("F1");
|
|
}
|
|
else // 최종 측정 완료 및 판정
|
|
{
|
|
_measurementTimer.Stop();
|
|
|
|
double finalVoltage, finalCurrent;
|
|
_measurer.GenerateFinalValues(_limits, out finalVoltage, out finalCurrent);
|
|
|
|
txtVoltage.Text = finalVoltage.ToString("F1");
|
|
txtCurrent.Text = finalCurrent.ToString("F1");
|
|
|
|
// 합/불 판정
|
|
bool isVoltageOk = finalVoltage >= _limits.MinVoltage && finalVoltage <= _limits.MaxVoltage;
|
|
bool isCurrentOk = finalCurrent >= _limits.MinCurrent && finalCurrent <= _limits.MaxCurrent;
|
|
bool isFinalPass = isVoltageOk && isCurrentOk;
|
|
|
|
// 측정값 색상 표시 (통과 시 검은색, 실패 시 빨간색)
|
|
txtVoltage.Foreground = isVoltageOk ? new SolidColorBrush(Color.FromRgb(31, 41, 55)) : new SolidColorBrush(Color.FromRgb(239, 68, 68));
|
|
txtCurrent.Foreground = isCurrentOk ? new SolidColorBrush(Color.FromRgb(31, 41, 55)) : new SolidColorBrush(Color.FromRgb(239, 68, 68));
|
|
|
|
if (isFinalPass)
|
|
{
|
|
txtSystemStatus.Text = "상태: 검사 완료 (합격)";
|
|
txtSystemStatus.Foreground = new SolidColorBrush(Color.FromRgb(16, 185, 129));
|
|
|
|
txtFinalResult.Text = "PASS";
|
|
txtFinalResult.Foreground = new SolidColorBrush(Color.FromRgb(16, 185, 129));
|
|
borderFinalResult.Background = new SolidColorBrush(Color.FromRgb(209, 250, 229)); // Light Green
|
|
}
|
|
else
|
|
{
|
|
txtSystemStatus.Text = "상태: 검사 완료 (불합격)";
|
|
txtSystemStatus.Foreground = new SolidColorBrush(Color.FromRgb(239, 68, 68));
|
|
|
|
txtFinalResult.Text = "FAIL";
|
|
txtFinalResult.Foreground = new SolidColorBrush(Color.FromRgb(239, 68, 68));
|
|
borderFinalResult.Background = new SolidColorBrush(Color.FromRgb(254, 226, 226)); // Light Red
|
|
}
|
|
|
|
// 컨트롤 원상 복구 (재검사를 위해)
|
|
btnSearchSerial.IsEnabled = true;
|
|
txtSerial.IsEnabled = true;
|
|
btnStart.IsEnabled = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|