From 64354c82a2a70a200c29bb5d0e52c9a80ddbdf98 Mon Sep 17 00:00:00 2001 From: seuuung Date: Wed, 5 Aug 2026 15:48:45 +0900 Subject: [PATCH] =?UTF-8?q?=EC=83=88=20=EB=8F=84=EB=A9=B4,=20=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=A0=80=20=EA=B8=B0=EA=B3=84=20=EC=B5=9C=EC=A0=81?= =?UTF-8?q?=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vs/marking_gui.slnx/v18/.suo | Bin 92160 -> 92160 bytes docs/developer_manual.md | 40 +- docs/knowledge_base.md | 13 +- marking_gui/MainWindow.xaml | 88 ++- marking_gui/MainWindow.xaml.cs | 598 ++++++++++++++++-- marking_gui/Manual/.obsidian/workspace.json | 14 +- marking_gui/Manual/02_초기_설정.md | 2 +- marking_gui/Manual/03_메인_화면.md | 10 +- marking_gui/Manual/07_시험_프로세스.md | 14 +- marking_gui/Manual/08_로그_관리.md | 2 +- marking_gui/Manual/09_오류_대응.md | 6 +- marking_gui/Manual/Manual_Merged.md | 22 +- marking_gui/Manual/사용자_메뉴얼.md | 4 +- marking_gui/PortSettingsWindow.xaml.cs | 40 +- marking_gui/QrVerificationWindow.xaml.cs | 19 +- marking_gui/Services/DatabaseService.cs | 61 +- .../Services/EquipmentMeasurementService.cs | 37 ++ marking_gui/Services/EzdMarkingService.cs | 73 ++- marking_gui/Services/IMarkingService.cs | 5 + marking_gui/Services/LoginServicesStub.cs | 5 +- marking_gui/Services/MarkingConfigService.cs | 29 +- marking_gui/Setting.ini | 3 - marking_gui/SettingsWindow.xaml.cs | 27 +- marking_gui/StartupLoginWindow.xaml | 7 + marking_gui/StartupLoginWindow.xaml.cs | 15 +- 25 files changed, 921 insertions(+), 213 deletions(-) diff --git a/.vs/marking_gui.slnx/v18/.suo b/.vs/marking_gui.slnx/v18/.suo index 630793541705f3ba55626fc8faabd511bce25f85..67c01aa6d83c46c7bf6a1a26766969d860276b65 100644 GIT binary patch delta 3545 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 diff --git a/docs/developer_manual.md b/docs/developer_manual.md index 8b1f1c9..acb42a2 100644 --- a/docs/developer_manual.md +++ b/docs/developer_manual.md @@ -46,24 +46,22 @@ test=false [Tags] ; 도안(.ezd) 파일 내의 텍스트 오브젝트 치환용 태그명 매핑 리스트 ; (도안에 정의된 오브젝트명과 동일하게 설정해야 정상 작동합니다) +; ※ 아래 5개 태그만 치환됩니다. 불필요 태그는 사용하지 않습니다. -; 일련번호 (Serial Number) 치환 태그 +; 일련번호 4자리 순번 치환 태그 (예: 0001) SerialTag=SERIAL -; 작업 년월일 (Lot No) 치환 태그 +; 작업 Lot No 치환 태그 (로그인 입력값 YYMMDDLL 전체 전달, 예: 26080401) LotNoTag=YYMMDD -; 제품 모델명 (Product Name) 치환 태그 -ProductTag=PRODUCT +; QR 코드 데이터 치환 태그 (IC_SN;도면품번;HKMC품번;각인번호; 포맷) +QrCodeTag=DATAMATRIX -; QR 코드 데이터 치환 태그 -QrCodeTag=QRCODETAG +; 도면 품번 치환 태그 +DrawingNoTag=PARTNO -; 검사 라인 코드 치환 태그 -LineTag=LCODE - -; 작업 조 (Shift) 치환 태그 -ShiftTag=BAN +; HKMC 품번 치환 태그 +HkmcNoTag=HKMCPO ; ================================================================= @@ -188,18 +186,18 @@ Channel=1 - `IsActive` (BIT): 활성 상태 여부 - **`[dbo].[Marking]` (최종 성능 계측값 및 마킹 결과 저장 테이블)** - - `IC_SN` (VARCHAR(50), PRIMARY KEY): 센서 일련번호 - - `Marking_QR` (VARCHAR(100), UNIQUE): 고유 QR 코드 문자열 (yyMMdd + 일련번호) - - `Maker` (VARCHAR(50)), `Model` (VARCHAR(50)): 제품 사양 정보 - - `Variant_1`, `Variant_2` (VARCHAR(50)) - - `Operator` (VARCHAR(50)): 담당 작업자 ID + - `IC_SN` (NVARCHAR(30), PRIMARY KEY, NOT NULL): 센서 IC 일련번호 (30자 초과 시 코드 내에서 절삭) + - `PCB_Barcode` (NVARCHAR(30), NOT NULL): PCB 바코드 — 정상 검사 시 스캔값, 강제검사(BYPASS) 시 `IC_SN` 값으로 대체 저장 + - `Marking_QR` (NVARCHAR(60), NOT NULL): 각인 QR 코드 전체 문자열 (`IC_SN;도면품번;HKMC품번;각인번호;` 포맷, 60자 초과 시 절삭) + - `Maker` (VARCHAR(10)), `Model` (VARCHAR(10)): 제품 사양 정보 (10자 초과 시 코드 내에서 절삭) + - `Variant_1`, `Variant_2` (VARCHAR(10)): 제품 변형 코드 (10자 초과 시 절삭) + - `Operator` (VARCHAR(10)): 담당 작업자 ID (10자 초과 시 절삭) - `Production_Date` (DATETIME): 생산 일자 및 계측 시간 - `Line` (VARCHAR(10)): 생산 라인 (최대 10자 제한, 초과 시 코드 내에서 절삭) - - `Lot_No` (VARCHAR(8)): 로트 번호 (최대 8자 제한, 초과 시 코드 내에서 절삭) - - `Jig_No` (VARCHAR(10)): 지그 번호 - - `PT_Vol_1` (DECIMAL(18,2)), `PT_Current_1` (DECIMAL(18,2)), `PT_Resistance_1` (DECIMAL(18,3)): 실측 전압, 전류, 저항값 - - `Result` (VARCHAR(10)): 최종 종합 판정 (`PASS` 또는 `FAIL`) - - `MarkedSerial` (VARCHAR(50)): 최종 마킹된 시퀀스 코드 + - `Lot_No` (VARCHAR(10)): 로트 번호 — `YYMMDDLL` 형식 입력 (최대 10자 제한, 초과 시 코드 내에서 절삭) + - `Jig_No` (VARCHAR(10)): 지그 번호 (10자 초과 시 절삭) + - `PT_Vol_1` (DECIMAL(4,2)), `PT_Current_1` (DECIMAL(4,2)), `PT_Resistance_1` (DECIMAL(5,3)): 실측 전압(V), 전류(mA), 저항(kΩ) — 소수점 이하 2~3자리로 반올림 적재 + - `Result` (VARCHAR(10)): 최종 종합 판정 — **`OK`** (QR 검증 통과) 또는 **`NG`** (불합격 또는 QR 검증 실패) ### 3.2 이전 공정 결과 교차 검증 (Subquery) 검사 개시 시점, 제품의 S/N(`IC_SN`)을 기반으로 선행 공정이 완료되었는지 조회합니다. diff --git a/docs/knowledge_base.md b/docs/knowledge_base.md index e3e1cd0..e27b41a 100644 --- a/docs/knowledge_base.md +++ b/docs/knowledge_base.md @@ -31,7 +31,7 @@ 전압과 전류에 국한되었던 기존 시스템에 저항 검사 프로세스를 추가하여 3대 전기 파라미터를 완성했습니다. - **물리적 개연성 반영:** V = I * R 연계를 고려하여, 전압(4~6V) 및 전류(8~10A) 조건에서 저항 기본 범위를 **0.4Ω ~ 0.8Ω**으로 세팅했습니다. - **UI 및 환경설정 연동:** 메인 화면에 세 번째 Column으로 `측정 저항 (Resistance)` 카드를 시각적으로 추가하고 설정 창(SettingsWindow)의 세로 크기를 늘려 저항 판정 임계치 입력란을 통합했습니다. -- **판정 결합:** `isFinalPass = isVoltageOk && isCurrentOk && isResistanceOk` 조건을 통해 세 항목 중 하나라도 이탈 시 자동으로 빨간색 텍스트 및 대형 FAIL 판정이 출력되도록 비즈니스 로직을 보강했습니다. +- **판정 결합:** `isFinalPass = isVoltageOk && isCurrentOk && isResistanceOk` 조건을 통해 세 항목 중 하나라도 이탈 시 자동으로 빨간색 텍스트 및 대형 **`NG`** 판정이 출력되도록 비즈니스 로직을 보강했습니다. ### 2.2. 로그인 저장 프로시저 호출 연동 인라인 SQL 질의 구조를 탈피하여 외부 설정에 명시된 SQL Server 저장 프로시저를 직접 호출하도록 구현했습니다. @@ -105,10 +105,13 @@ - 작업자의 고유 ID(`OperatorId`), 패스워드(`Password`), 이름(`Name`) 및 계정 상태(`IsActive`)를 관리합니다. - 로그인 조회 속도를 향상시키기 위해 `OperatorId` 컬럼에 UNIQUE 제약 조건을 할당했습니다. - **[dbo].[Marking] (공정 메타데이터 및 성능 계측값 저장 테이블):** - - 바코드 S/N(`IC_SN`, 기본키)을 키로 하며, 고유 식별을 위해 메타데이터와 날짜 조합의 고유 키 `Marking_QR` (Unique Key)이 생성됩니다. - - 공정 정보(`Maker`, `Model`, `Variant_1`, `Variant_2`, `Operator`, `Production_Date`, `Line`, `Lot_No`, `Jig_No`) 및 최종 판정(`Result`)이 통합 적재됩니다. - - 3단계에 걸친 전압/전류/저항 컬럼(`PT_Vol_1~3`, `PT_Current_1~3`, `PT_Resistance_1~3`)이 존재하며, 현재는 1번 컬럼들에 최종 계측 수치(소수점 2자리 반올림)를 저장하고 2, 3번 컬럼은 `0.00`으로 기본값을 보정하여 저장합니다. - - DB 필드 크기 한계를 초과하여 적재 에러가 나지 않도록, `Line` 컬럼은 최대 5자, `Lot_No` 컬럼은 최대 8자 등으로 자르는(Truncate) 방어적 코드 처리가 수행됩니다. + - 바코드 S/N(`IC_SN`, NVARCHAR(30), 기본키, NOT NULL)을 키로 하며, 30자 초과 시 코드 내에서 절삭합니다. + - `PCB_Barcode` (NVARCHAR(30), NOT NULL): 정상 검사 시 PCB 바코드 스캔값, 강제검사(BYPASS) 시 `IC_SN` 값으로 자동 대체 저장됩니다. + - 고유 QR 코드 문자열 `Marking_QR` (NVARCHAR(60)): `IC_SN;도면품번;HKMC품번;각인번호;` 포맷으로 구성되며, 60자 초과 시 절삭합니다. + - 공정 정보(`Maker`, `Model`, `Variant_1`, `Variant_2`, `Operator`, `Production_Date`, `Line`, `Lot_No`, `Jig_No`) 및 최종 판정(`Result`)이 통합 적재됩니다. 각 문자열 컬럼은 최대 10자로 초과 시 절삭 처리됩니다. + - 3단계에 걸친 전압/전류/저항 컬럼(`PT_Vol_1~3`, `PT_Current_1~3`, `PT_Resistance_1~3`)이 존재하며, 현재는 1번 컬럼들에 최종 계측 수치(소수점 2~3자리 반올림)를 저장하고 2, 3번 컬럼은 `0.00`으로 기본값을 보정하여 저장합니다. + - `Result` 컬럼에는 **`OK`** (QR 검증 통과 시) 또는 **`NG`** (불합격 또는 QR 검증 실패 시) 두 가지 값만 저장됩니다. + - `Lot_No` 컬럼은 `YYMMDDLL` 형식(예: `26080401`)으로 입력되며 최대 **10자**까지 허용됩니다. ### 4.2. 로그인 검증 저장 프로시저 ([CheckOperator]) - **프로시저 기능:** 입력된 ID와 패스워드가 활성 상태인 작업자 테이블에 매칭되는지 대소문자 구분 없이 카운팅합니다. diff --git a/marking_gui/MainWindow.xaml b/marking_gui/MainWindow.xaml index a4c8c69..d4eb44c 100644 --- a/marking_gui/MainWindow.xaml +++ b/marking_gui/MainWindow.xaml @@ -11,6 +11,12 @@ WindowStartupLocation="CenterScreen" Background="#F3F4F6" ContentRendered="Window_ContentRendered"> + + + + + + + + + +