From 8336def8cc1669a57362d8a8fd1b790c1244c5a3 Mon Sep 17 00:00:00 2001 From: hjjeong Date: Tue, 16 Dec 2025 17:33:39 +0900 Subject: [PATCH 1/2] =?UTF-8?q?=EA=B3=B5=EC=A0=95=EA=B2=80=EC=82=AC?= =?UTF-8?q?=EA=B4=80=EB=A6=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../incomingInspectionProgressPopUp.jsp | 2 +- .../quality/processInspectionFormPopUp.jsp | 229 ++++++++++++++---- .../view/quality/processInspectionList.jsp | 21 +- src/com/pms/mapper/common.xml | 10 + src/com/pms/mapper/quality.xml | 82 +++++-- src/com/pms/service/QualityService.java | 13 +- 6 files changed, 283 insertions(+), 74 deletions(-) diff --git a/WebContent/WEB-INF/view/quality/incomingInspectionProgressPopUp.jsp b/WebContent/WEB-INF/view/quality/incomingInspectionProgressPopUp.jsp index a825251..f7e55bf 100644 --- a/WebContent/WEB-INF/view/quality/incomingInspectionProgressPopUp.jsp +++ b/WebContent/WEB-INF/view/quality/incomingInspectionProgressPopUp.jsp @@ -358,7 +358,7 @@ function fn_initRightGrid() { } }, {title:'검사일', field:'INSPECTION_DATE', headerHozAlign:'center', hozAlign:'center', width:100, - editor:"input" + editor:"date" }, {title:'검사자', field:'INSPECTOR_ID', headerHozAlign:'center', hozAlign:'center', width:100, editor: fnc_customSelectEditor, diff --git a/WebContent/WEB-INF/view/quality/processInspectionFormPopUp.jsp b/WebContent/WEB-INF/view/quality/processInspectionFormPopUp.jsp index 62517ed..8d62ff1 100644 --- a/WebContent/WEB-INF/view/quality/processInspectionFormPopUp.jsp +++ b/WebContent/WEB-INF/view/quality/processInspectionFormPopUp.jsp @@ -48,6 +48,7 @@ String connector = person.getUserId(); var _editable = true; var grid; var rowIndex = 0; +var _filePopupOpen = false; // 파일 팝업 열림 여부 // 진행공정 목록 var _PROCESS_LIST = []; @@ -69,6 +70,8 @@ var _MEASURING_DEVICE_LIST = [ var _DEPT_LIST = []; // 담당자 목록 var _USER_LIST = []; +// 검사자 목록 +var _INSPECTOR_LIST = []; // 검사결과 목록 var _INSPECTION_RESULT_LIST = [ {"CODE": "", "NAME": "선택"}, @@ -85,9 +88,9 @@ $(document).ready(function(){ fnc_getJsonAllDataListBySqlId({"sqlId": "common.getCodeselect", "code": "0001870"}) ); - // 프로젝트 목록 조회 - _PROJECT_LIST = [{"CODE": "", "NAME": "선택"}].concat( - fnc_getJsonAllDataListBySqlId({"sqlId": "common.getProjectNameList"}) + // 프로젝트 목록 조회 (제품구분 포함) + _PROJECT_LIST = [{"CODE": "", "NAME": "선택", "PRODUCT_NAME": ""}].concat( + fnc_getJsonAllDataListBySqlId({"sqlId": "common.getProjectNameListWithProduct"}) ); // 담당팀 목록 조회 @@ -100,6 +103,11 @@ $(document).ready(function(){ fnc_getJsonAllDataListBySqlId({"sqlId": "common.getUserselect"}) ); + // 검사자 목록 조회 + _INSPECTOR_LIST = [{"CODE": "", "NAME": "선택"}].concat( + fnc_getJsonAllDataListBySqlId({"sqlId": "common.getUserselect"}) + ); + // 검사일 기본 설정 (저장된 값 없으면 오늘 날짜) var savedInspectionDate = "${info.inspection_date}"; if(savedInspectionDate != '' && savedInspectionDate != 'null'){ @@ -157,6 +165,9 @@ function fn_getPartListByProject(projectNo) { // 그리드 초기화 및 조회 function fn_search(){ + // 파일 팝업이 열려있는 동안에는 새로고침 방지 + if(_filePopupOpen) return; + var columns = [ {formatter:"rowSelection", titleFormatter:"rowSelection", hozAlign:"center", headerSort:false, width:30}, {title:'진행공정', field:'PROCESS_CD', headerHozAlign:'center', hozAlign:'center', width:130, @@ -167,11 +178,66 @@ function fn_search(){ editorParams: {valueId:"CODE", labelId:"NAME", values:_PROCESS_LIST} }, {title:'프로젝트번호', field:'PROJECT_OBJID', headerHozAlign:'center', hozAlign:'center', width:130, - editor: fnc_customSelectEditor, + editor: function(cell, onRendered, success, cancel, editorParams) { + var cellValue = cell.getValue(); + var select = document.createElement("select"); + select.style.width = "100%"; + select.style.boxSizing = "border-box"; + + // 옵션 생성 + _PROJECT_LIST.forEach(function(item) { + var option = document.createElement("option"); + option.value = item.CODE; + option.text = item.NAME; + if(item.CODE == cellValue) option.selected = true; + select.appendChild(option); + }); + + // 선택 변경 시 즉시 적용 및 제품구분 업데이트 + select.addEventListener("change", function() { + var selectedValue = select.value; + var productName = ""; + + // 제품구분 찾기 + for(var i = 0; i < _PROJECT_LIST.length; i++) { + if(_PROJECT_LIST[i].CODE == selectedValue) { + productName = _PROJECT_LIST[i].PRODUCT_NAME || ""; + break; + } + } + + // 파트 목록 미리 로드 + if(selectedValue) { + fn_getPartListByProject(selectedValue); + } + + // 제품구분 및 파트 초기화 + cell.getRow().update({ + "PART_OBJID": "", + "PART_NO": "", + "PART_NAME": "", + "PRODUCT_NAME": productName + }); + + success(selectedValue); + }); + + select.addEventListener("blur", function() { + success(select.value); + }); + + onRendered(function() { + select.focus(); + }); + + return select; + }, formatter: function(cell) { return fnc_customSelectFormatter(cell, {valueId:"CODE", labelId:"NAME", values:_PROJECT_LIST}); - }, - editorParams: {valueId:"CODE", labelId:"NAME", values:_PROJECT_LIST} + } + }, + {title:'제품구분', field:'PRODUCT_NAME', headerHozAlign:'center', hozAlign:'center', width:130, + editor: false }, {title:'품번', field:'PART_OBJID', headerHozAlign:'center', hozAlign:'left', width:250, editor: fnc_customSelectEditor, @@ -225,6 +291,16 @@ function fn_search(){ }, editorParams: {valueId:"CODE", labelId:"NAME", values:_USER_LIST} }, + {title:'검사일', field:'INSPECTION_DATE', headerHozAlign:'center', hozAlign:'center', width:110, + editor:"date" + }, + {title:'검사자', field:'INSPECTOR_ID', headerHozAlign:'center', hozAlign:'center', width:100, + editor: fnc_customSelectEditor, + formatter: function(cell) { + return fnc_customSelectFormatter(cell, {valueId:"CODE", labelId:"NAME", values:_INSPECTOR_LIST}); + }, + editorParams: {valueId:"CODE", labelId:"NAME", values:_INSPECTOR_LIST} + }, {title:'특이사항', field:'REMARK', headerHozAlign:'center', hozAlign:'left', width:150, editor:"input" }, @@ -240,6 +316,28 @@ function fn_search(){ return fnc_customSelectFormatter(cell, {valueId:"CODE", labelId:"NAME", values:_INSPECTION_RESULT_LIST}); }, editorParams: {valueId:"CODE", labelId:"NAME", values:_INSPECTION_RESULT_LIST} + }, + {title:'이미지파일', field:'IMAGE_FILE_CNT', headerHozAlign:'center', hozAlign:'center', width:90, + formatter: fnc_subInfoValueFormatter, + cellClick: function(e, cell) { + var objId = fnc_checkNull(cell.getData().OBJID); + if(objId) { + fn_openImageFilePopUp(objId); + } else { + Swal.fire("먼저 저장 후 이미지를 등록할 수 있습니다."); + } + } + }, + {title:'첨부파일', field:'ATTACH_FILE_CNT', headerHozAlign:'center', hozAlign:'center', width:90, + formatter: fnc_subInfoValueFormatter, + cellClick: function(e, cell) { + var objId = fnc_checkNull(cell.getData().OBJID); + if(objId) { + fn_openAttachFilePopUp(objId); + } else { + Swal.fire("먼저 저장 후 파일을 등록할 수 있습니다."); + } + } } ]; @@ -259,23 +357,6 @@ function fn_search(){ var row = cell.getRow(); var field = cell.getField(); - // 프로젝트 변경 시 파트 초기화 및 목록 갱신 - if (field === 'PROJECT_OBJID') { - var projectObjid = cell.getValue(); - // 파트 목록 미리 로드 (캐시에 저장) - if (projectObjid) { - fn_getPartListByProject(projectObjid); - } - // 파트 초기화 - row.update({ - "PART_OBJID": "", - "PART_NO": "", - "PART_NAME": "" - }); - // 행 다시 렌더링 - row.reformat(); - } - // 파트 선택 시 품번/품명 자동 설정 if (field === 'PART_OBJID') { var partObjid = cell.getValue(); @@ -318,9 +399,11 @@ function fn_search(){ function fn_addRow(){ rowIndex++; var newRow = { + "OBJID": fnc_createObjId(), // OBJID 미리 생성 (파일 첨부 가능하도록) "ROW_INDEX": rowIndex, "PROCESS_CD": "", "PROJECT_OBJID": "", + "PRODUCT_NAME": "", "PART_OBJID": "", "PART_NO": "", "PART_NAME": "", @@ -330,9 +413,14 @@ function fn_addRow(){ "MEASURING_DEVICE": "", "DEPT_CD": "", "USER_ID": "", + "INSPECTION_DATE": "${today}", // 검사일 기본값: 오늘 + "INSPECTOR_ID": "<%=connector%>", // 검사자 기본값: 접속자 "REMARK": "", "ACTION_STATUS": "", - "INSPECTION_RESULT": "" + "INSPECTION_RESULT": "", + "IMAGE_FILE_CNT": 0, + "ATTACH_FILE_CNT": 0, + "GRID_STATUS": "I" // 신규 행 표시 }; grid.addRow(newRow, false); } @@ -362,20 +450,6 @@ function fn_deleteRow(){ // 저장 function fn_save(){ - var inspectionDate = $("#INSPECTION_DATE").val(); - var inspectorId = $("#INSPECTOR_ID").val(); - - if(inspectionDate == ''){ - Swal.fire("검사일을 입력하세요."); - $("#INSPECTION_DATE").focus(); - return; - } - if(inspectorId == ''){ - Swal.fire("검사자를 선택하세요."); - $("#INSPECTOR_ID").focus(); - return; - } - var gridData = grid.getData(); if(gridData.length == 0){ Swal.fire("저장할 데이터가 없습니다."); @@ -407,8 +481,6 @@ function fn_save(){ type: "POST", data: { "MASTER_OBJID": $("#MASTER_OBJID").val(), - "INSPECTION_DATE": inspectionDate, - "INSPECTOR_ID": inspectorId, "dataList": JSON.stringify(gridData) }, dataType: "json", @@ -446,6 +518,79 @@ function fn_save(){ }); } +// 이미지 파일 팝업 +function fn_openImageFilePopUp(objId) { + _filePopupOpen = true; // 파일 팝업 열림 플래그 설정 + + var popup_width = 650; + var popup_height = 550; + var url = "/common/ImageRegistPopup.do?targetObjId=" + objId + "&docType=PROCESS_INSPECTION_IMAGE&docTypeName=공정검사이미지"; + var popup = window.open(url, "imageFilePopUp", "width=" + popup_width + ",height=" + popup_height + ",scrollbars=yes,resizable=yes"); + + // 팝업 닫힘 감지하여 해당 행의 파일 카운트만 업데이트 + fn_watchPopupClose(popup, objId, 'IMAGE_FILE_CNT', 'PROCESS_INSPECTION_IMAGE'); +} + +// 첨부파일 팝업 +function fn_openAttachFilePopUp(objId) { + _filePopupOpen = true; // 파일 팝업 열림 플래그 설정 + + var popup_width = 800; + var popup_height = 300; + var params = "?targetObjId=" + objId + "&docType=PROCESS_INSPECTION_FILE&docTypeName=공정검사첨부"; + var url = "/common/FileRegistPopup.do" + params; + var popup = window.open(url, "attachFilePopUp", "width=" + popup_width + ",height=" + popup_height + ",scrollbars=yes,resizable=yes"); + + // 팝업 닫힘 감지하여 해당 행의 파일 카운트만 업데이트 + fn_watchPopupClose(popup, objId, 'ATTACH_FILE_CNT', 'PROCESS_INSPECTION_FILE'); +} + +// 팝업 닫힘 감지 및 파일 카운트 업데이트 +function fn_watchPopupClose(popup, objId, fieldName, docType) { + var checkPopup = setInterval(function() { + if(popup.closed) { + clearInterval(checkPopup); + _filePopupOpen = false; // 파일 팝업 닫힘 플래그 해제 + // 파일 카운트 조회 후 해당 행만 업데이트 + fn_updateGridFileCnt(objId, fieldName, docType); + } + }, 500); +} + +// 그리드 파일 카운트 업데이트 +function fn_updateGridFileCnt(objId, fieldName, docType) { + $.ajax({ + url: "/common/getFileList.do", + type: "POST", + data: { targetObjId: objId, docType: docType }, + dataType: "json", + success: function(data) { + var cnt = data ? data.length : 0; + var rows = grid.getRows(); + rows.forEach(function(row) { + if(row.getData().OBJID === objId) { + var updateData = {}; + updateData[fieldName] = cnt; + row.update(updateData); + } + }); + } + }); +} + +// 공통 fnc_tabulCallbackFnc 오버라이드 (이 페이지에서는 grid 사용) +function fnc_tabulCallbackFnc(objId, docType, columnField, fileCnt) { + var rows = grid.getRows(); + rows.forEach(function(row) { + if(row.getData().OBJID === objId) { + var updateData = {}; + var targetField = (columnField && columnField !== '') ? columnField : 'FILE_CNT'; + updateData[targetField] = fileCnt; + row.update(updateData); + } + }); +} + // 팝업 닫힐 때 부모 새로고침 window.addEventListener('unload', function() { if(window.opener && window.opener.fn_search) { @@ -468,7 +613,7 @@ window.addEventListener('unload', function() { -
+
diff --git a/WebContent/WEB-INF/view/quality/processInspectionList.jsp b/WebContent/WEB-INF/view/quality/processInspectionList.jsp index 4fc59a7..a79f3de 100644 --- a/WebContent/WEB-INF/view/quality/processInspectionList.jsp +++ b/WebContent/WEB-INF/view/quality/processInspectionList.jsp @@ -89,20 +89,25 @@ $(document).ready(function(){ // 컬럼: 검사일, 프로젝트번호, 품번, 품명, 불량수량, 작업환경상태, 측정기, 검사자, 검사결과 var columns = [ + + {headerHozAlign:'center', hozAlign:'center', minWidth:150, widthGrow:2, title:'프로젝트번호', field:'PROJECT_NO'}, + {headerHozAlign:'center', hozAlign:'center', minWidth:110, widthGrow:1, title:'제품구분', field:'PRODUCT_NAME'}, + {headerHozAlign:'center', hozAlign:'left', minWidth:180, widthGrow:2, title:'품번', field:'PART_NO'}, + {headerHozAlign:'center', hozAlign:'left', minWidth:200, widthGrow:3, title:'품명', field:'PART_NAME'}, + {headerHozAlign:'center', hozAlign:'right', minWidth:100, widthGrow:1, title:'검사수량 합계', field:'INSPECTION_QTY', + formatter:"money", formatterParams:{thousand:",", precision:false} + }, + {headerHozAlign:'center', hozAlign:'right', minWidth:100, widthGrow:1, title:'불량수량 합계', field:'DEFECT_QTY', + formatter:"money", formatterParams:{thousand:",", precision:false} + }, + {headerHozAlign:'center', hozAlign:'center', minWidth:120, widthGrow:1, title:'작업환경상태', field:'WORK_ENV_STATUS'}, + {headerHozAlign:'center', hozAlign:'center', minWidth:100, widthGrow:1, title:'측정기', field:'MEASURING_DEVICE'}, {headerHozAlign:'center', hozAlign:'center', minWidth:110, widthGrow:1, title:'검사일', field:'INSPECTION_DATE', formatter: fnc_createGridAnchorTag, cellClick: function(e, cell){ fn_openFormPopUp(cell.getData().OBJID); } }, - {headerHozAlign:'center', hozAlign:'center', minWidth:150, widthGrow:2, title:'프로젝트번호', field:'PROJECT_NO'}, - {headerHozAlign:'center', hozAlign:'left', minWidth:180, widthGrow:2, title:'품번', field:'PART_NO'}, - {headerHozAlign:'center', hozAlign:'left', minWidth:200, widthGrow:3, title:'품명', field:'PART_NAME'}, - {headerHozAlign:'center', hozAlign:'right', minWidth:100, widthGrow:1, title:'불량수량 합계', field:'DEFECT_QTY', - formatter:"money", formatterParams:{thousand:",", precision:false} - }, - {headerHozAlign:'center', hozAlign:'center', minWidth:120, widthGrow:1, title:'작업환경상태', field:'WORK_ENV_STATUS'}, - {headerHozAlign:'center', hozAlign:'center', minWidth:100, widthGrow:1, title:'측정기', field:'MEASURING_DEVICE'}, {headerHozAlign:'center', hozAlign:'center', minWidth:100, widthGrow:1, title:'검사자', field:'INSPECTOR_NAME'}, {headerHozAlign:'center', hozAlign:'center', minWidth:100, widthGrow:1, title:'검사결과', field:'INSPECTION_RESULT', formatter: function(cell, formatterParams, onRendered){ diff --git a/src/com/pms/mapper/common.xml b/src/com/pms/mapper/common.xml index 4d52e19..7ef025a 100644 --- a/src/com/pms/mapper/common.xml +++ b/src/com/pms/mapper/common.xml @@ -2785,6 +2785,16 @@ ORDER BY COALESCE(T.REVISION, '1.0') --> + + + SELECT PIM.OBJID - , PIM.INSPECTION_DATE - , PIM.INSPECTOR_ID - , (SELECT USER_NAME FROM USER_INFO WHERE USER_ID = PIM.INSPECTOR_ID) AS INSPECTOR_NAME - + /* 검사일 (외 N건) - 디테일 테이블에서 집계 */ + , (SELECT + CASE WHEN COUNT(DISTINCT PID.INSPECTION_DATE) > 1 + THEN MIN(PID.INSPECTION_DATE) || ' 외 ' || (COUNT(DISTINCT PID.INSPECTION_DATE) - 1) || '건' + WHEN COUNT(DISTINCT PID.INSPECTION_DATE) = 1 + THEN MIN(PID.INSPECTION_DATE) + ELSE '' + END + FROM PROCESS_INSPECTION_DETAIL PID WHERE PID.MASTER_OBJID = PIM.OBJID AND PID.INSPECTION_DATE IS NOT NULL AND PID.INSPECTION_DATE != '' + ) AS INSPECTION_DATE + /* 검사자 (외 N건) - 디테일 테이블에서 집계 */ + , (SELECT + CASE WHEN COUNT(DISTINCT PID.INSPECTOR_ID) > 1 + THEN (SELECT USER_NAME FROM USER_INFO WHERE USER_ID = MIN(PID.INSPECTOR_ID)) || ' 외 ' || (COUNT(DISTINCT PID.INSPECTOR_ID) - 1) || '건' + WHEN COUNT(DISTINCT PID.INSPECTOR_ID) = 1 + THEN (SELECT USER_NAME FROM USER_INFO WHERE USER_ID = MIN(PID.INSPECTOR_ID)) + ELSE '' + END + FROM PROCESS_INSPECTION_DETAIL PID WHERE PID.MASTER_OBJID = PIM.OBJID AND PID.INSPECTOR_ID IS NOT NULL AND PID.INSPECTOR_ID != '' + ) AS INSPECTOR_NAME + /* 제품구분 (외 N건) */ + , (SELECT + CASE WHEN COUNT(DISTINCT PID.PROJECT_OBJID) > 1 + THEN (SELECT CODE_NAME(PRODUCT) FROM PROJECT_MGMT WHERE OBJID = MIN(PID.PROJECT_OBJID)) || ' 외 ' || (COUNT(DISTINCT PID.PROJECT_OBJID) - 1) || '건' + ELSE (SELECT CODE_NAME(PRODUCT) FROM PROJECT_MGMT WHERE OBJID = MIN(PID.PROJECT_OBJID)) + END + FROM PROCESS_INSPECTION_DETAIL PID WHERE PID.MASTER_OBJID = PIM.OBJID + ) AS PRODUCT_NAME + /* 프로젝트명 (외 N건) */ , (SELECT CASE WHEN COUNT(DISTINCT PID.PROJECT_OBJID) > 1 THEN (SELECT PROJECT_NO FROM PROJECT_MGMT WHERE OBJID = MIN(PID.PROJECT_OBJID)) || ' 외 ' || (COUNT(DISTINCT PID.PROJECT_OBJID) - 1) || '건' @@ -1023,7 +1048,7 @@ END FROM PROCESS_INSPECTION_DETAIL PID WHERE PID.MASTER_OBJID = PIM.OBJID ) AS PROJECT_NO - + /* 품번 (외 N건) */ , (SELECT CASE WHEN COUNT(*) > 1 THEN MIN(PID.PART_NO) || ' 외 ' || (COUNT(*) - 1) || '건' @@ -1031,7 +1056,7 @@ END FROM PROCESS_INSPECTION_DETAIL PID WHERE PID.MASTER_OBJID = PIM.OBJID ) AS PART_NO - + /* 품명 (외 N건) */ , (SELECT CASE WHEN COUNT(*) > 1 THEN MIN(PID.PART_NAME) || ' 외 ' || (COUNT(*) - 1) || '건' @@ -1039,17 +1064,19 @@ END FROM PROCESS_INSPECTION_DETAIL PID WHERE PID.MASTER_OBJID = PIM.OBJID ) AS PART_NAME - - , (SELECT COALESCE(SUM(PID.DEFECT_QTY), 0) FROM PROCESS_INSPECTION_DETAIL PID WHERE PID.MASTER_OBJID = PIM.OBJID) AS DEFECT_QTY - + /* 검사수량 합계 */ + , (SELECT COALESCE(SUM(PID.INSPECTION_QTY), 0) FROM PROCESS_INSPECTION_DETAIL PID WHERE PID.MASTER_OBJID = PIM.OBJID) AS INSPECTION_QTY + /* 불량수량 합계 */ + , (SELECT COALESCE(SUM(PID.DEFECT_QTY), 0) FROM PROCESS_INSPECTION_DETAIL PID WHERE PID.MASTER_OBJID = PIM.OBJID) AS DEFECT_QTY + /* 작업환경상태 (하나라도 불량이면 불량) */ , (SELECT CASE WHEN COUNT(CASE WHEN PID.WORK_ENV_STATUS = '불량' THEN 1 END) > 0 THEN '불량' ELSE '양호' END FROM PROCESS_INSPECTION_DETAIL PID WHERE PID.MASTER_OBJID = PIM.OBJID ) AS WORK_ENV_STATUS - + /* 측정기 (하나라도 불량이면 불량) */ , (SELECT CASE WHEN COUNT(CASE WHEN PID.MEASURING_DEVICE = '불량' THEN 1 END) > 0 THEN '불량' ELSE '양호' END FROM PROCESS_INSPECTION_DETAIL PID WHERE PID.MASTER_OBJID = PIM.OBJID ) AS MEASURING_DEVICE - + /* 검사결과 (하나라도 NG면 NG) */ , (SELECT CASE WHEN COUNT(CASE WHEN PID.INSPECTION_RESULT = 'NG' THEN 1 END) > 0 THEN 'NG' ELSE 'OK' END FROM PROCESS_INSPECTION_DETAIL PID WHERE PID.MASTER_OBJID = PIM.OBJID ) AS INSPECTION_RESULT @@ -1073,22 +1100,27 @@ AND UPPER(PID.PART_NAME) LIKE UPPER('%' || #{search_part_name} || '%')) - AND ( - UPPER(PIM.INSPECTOR_ID) LIKE UPPER('%' || #{search_inspector} || '%') - OR UPPER((SELECT USER_NAME FROM USER_INFO WHERE USER_ID = PIM.INSPECTOR_ID)) LIKE UPPER('%' || #{search_inspector} || '%') - ) + AND EXISTS (SELECT 1 FROM PROCESS_INSPECTION_DETAIL PID + LEFT JOIN USER_INFO U ON U.USER_ID = PID.INSPECTOR_ID + WHERE PID.MASTER_OBJID = PIM.OBJID + AND (UPPER(PID.INSPECTOR_ID) LIKE UPPER('%' || #{search_inspector} || '%') + OR UPPER(U.USER_NAME) LIKE UPPER('%' || #{search_inspector} || '%'))) - AND PIM.INSPECTION_DATE =]]> #{search_inspection_date_from} + AND EXISTS (SELECT 1 FROM PROCESS_INSPECTION_DETAIL PID + WHERE PID.MASTER_OBJID = PIM.OBJID + AND PID.INSPECTION_DATE =]]> #{search_inspection_date_from}) - AND PIM.INSPECTION_DATE #{search_inspection_date_to} + AND EXISTS (SELECT 1 FROM PROCESS_INSPECTION_DETAIL PID + WHERE PID.MASTER_OBJID = PIM.OBJID + AND PID.INSPECTION_DATE #{search_inspection_date_to}) AND (SELECT CASE WHEN COUNT(CASE WHEN PID.INSPECTION_RESULT = 'NG' THEN 1 END) > 0 THEN 'NG' ELSE 'OK' END FROM PROCESS_INSPECTION_DETAIL PID WHERE PID.MASTER_OBJID = PIM.OBJID) = #{search_inspection_result} - ORDER BY PIM.INSPECTION_DATE DESC, PIM.REG_DATE DESC + ORDER BY PIM.REG_DATE DESC @@ -1112,6 +1144,7 @@ , (SELECT CODE_NAME FROM COMM_CODE WHERE CODE_ID = PID.PROCESS_CD) AS PROCESS_NAME , PID.PROJECT_OBJID , (SELECT PROJECT_NO FROM PROJECT_MGMT WHERE OBJID = PID.PROJECT_OBJID) AS PROJECT_NO + , (SELECT CODE_NAME(PRODUCT) FROM PROJECT_MGMT WHERE OBJID = PID.PROJECT_OBJID) AS PRODUCT_NAME , PID.PART_OBJID , PID.PART_NO , PID.PART_NAME @@ -1123,9 +1156,16 @@ , (SELECT DEPT_NAME FROM DEPT_INFO WHERE OBJID::VARCHAR = PID.DEPT_CD) AS DEPT_NAME , PID.USER_ID , (SELECT USER_NAME FROM USER_INFO WHERE USER_ID = PID.USER_ID) AS USER_NAME + , PID.INSPECTION_DATE + , PID.INSPECTOR_ID + , (SELECT USER_NAME FROM USER_INFO WHERE USER_ID = PID.INSPECTOR_ID) AS INSPECTOR_NAME , PID.REMARK , PID.ACTION_STATUS , PID.INSPECTION_RESULT + /* 이미지파일 카운트 */ + , (SELECT COUNT(*) FROM ATTACH_FILE_INFO F WHERE F.TARGET_OBJID = PID.OBJID AND F.DOC_TYPE = 'PROCESS_INSPECTION_IMAGE' AND UPPER(F.STATUS) = 'ACTIVE') AS IMAGE_FILE_CNT + /* 첨부파일 카운트 */ + , (SELECT COUNT(*) FROM ATTACH_FILE_INFO F WHERE F.TARGET_OBJID = PID.OBJID AND F.DOC_TYPE = 'PROCESS_INSPECTION_FILE' AND UPPER(F.STATUS) = 'ACTIVE') AS ATTACH_FILE_CNT FROM PROCESS_INSPECTION_DETAIL PID WHERE PID.MASTER_OBJID = #{MASTER_OBJID} ORDER BY PID.REG_DATE @@ -1176,6 +1216,8 @@ , MEASURING_DEVICE , DEPT_CD , USER_ID + , INSPECTION_DATE + , INSPECTOR_ID , REMARK , ACTION_STATUS , INSPECTION_RESULT @@ -1195,6 +1237,8 @@ , #{MEASURING_DEVICE} , #{DEPT_CD} , #{USER_ID} + , #{INSPECTION_DATE} + , #{INSPECTOR_ID} , #{REMARK} , #{ACTION_STATUS} , #{INSPECTION_RESULT} @@ -1213,6 +1257,8 @@ , MEASURING_DEVICE = #{MEASURING_DEVICE} , DEPT_CD = #{DEPT_CD} , USER_ID = #{USER_ID} + , INSPECTION_DATE = #{INSPECTION_DATE} + , INSPECTOR_ID = #{INSPECTOR_ID} , REMARK = #{REMARK} , ACTION_STATUS = #{ACTION_STATUS} , INSPECTION_RESULT = #{INSPECTION_RESULT} diff --git a/src/com/pms/service/QualityService.java b/src/com/pms/service/QualityService.java index 5f7b8c2..ccd56dd 100644 --- a/src/com/pms/service/QualityService.java +++ b/src/com/pms/service/QualityService.java @@ -888,10 +888,7 @@ public class QualityService extends BaseService{ // 수정 masterParamMap.put("OBJID", masterObjId); sqlSession.update("quality.updateProcessInspectionMaster", masterParamMap); - // 기존 디테일 삭제 후 재등록 - Map deleteParamMap = new HashMap(); - deleteParamMap.put("MASTER_OBJID", masterObjId); - sqlSession.delete("quality.deleteProcessInspectionDetailByMaster", deleteParamMap); + // 디테일은 삭제하지 않고 UPSERT로 처리 (파일 첨부 연동 유지) } // 디테일 저장 @@ -903,7 +900,11 @@ public class QualityService extends BaseService{ for(Map rowData : dataList){ Map sqlParamMap = new HashMap(); - String detailObjId = CommonUtils.checkNull(CommonUtils.createObjId()); + // 클라이언트에서 전달한 OBJID 사용 (파일 첨부 연동을 위해) + String detailObjId = CommonUtils.checkNull(rowData.get("OBJID")); + if(detailObjId.isEmpty()) { + detailObjId = CommonUtils.checkNull(CommonUtils.createObjId()); + } sqlParamMap.put("OBJID", detailObjId); sqlParamMap.put("MASTER_OBJID", masterObjId); @@ -918,6 +919,8 @@ public class QualityService extends BaseService{ sqlParamMap.put("MEASURING_DEVICE", CommonUtils.checkNull(rowData.get("MEASURING_DEVICE"))); sqlParamMap.put("DEPT_CD", CommonUtils.checkNull(rowData.get("DEPT_CD"))); sqlParamMap.put("USER_ID", CommonUtils.checkNull(rowData.get("USER_ID"))); + sqlParamMap.put("INSPECTION_DATE", CommonUtils.checkNull(rowData.get("INSPECTION_DATE"))); + sqlParamMap.put("INSPECTOR_ID", CommonUtils.checkNull(rowData.get("INSPECTOR_ID"))); sqlParamMap.put("REMARK", CommonUtils.checkNull(rowData.get("REMARK"))); sqlParamMap.put("ACTION_STATUS", CommonUtils.checkNull(rowData.get("ACTION_STATUS"))); sqlParamMap.put("INSPECTION_RESULT", CommonUtils.checkNull(rowData.get("INSPECTION_RESULT"))); From 805d0da1dfbada84799990f6cb47fecfe8854810 Mon Sep 17 00:00:00 2001 From: hjjeong Date: Tue, 16 Dec 2025 18:06:04 +0900 Subject: [PATCH 2/2] =?UTF-8?q?=EA=B3=B5=EC=A0=95=EA=B2=80=EC=82=AC?= =?UTF-8?q?=EA=B4=80=EB=A6=AC=20=EA=B2=80=EC=83=89=EC=A1=B0=EA=B1=B4=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../view/quality/processInspectionList.jsp | 123 ++++++++++++------ src/com/pms/controller/QualityController.java | 14 ++ src/com/pms/mapper/common.xml | 1 - src/com/pms/mapper/quality.xml | 37 +++++- 4 files changed, 129 insertions(+), 46 deletions(-) diff --git a/WebContent/WEB-INF/view/quality/processInspectionList.jsp b/WebContent/WEB-INF/view/quality/processInspectionList.jsp index a79f3de..0449a98 100644 --- a/WebContent/WEB-INF/view/quality/processInspectionList.jsp +++ b/WebContent/WEB-INF/view/quality/processInspectionList.jsp @@ -45,14 +45,13 @@ String menuName = CommonUtils.getMenuName(menuObjId, "공정검사 관리"); .select2-container .select2-selection--multiple .select2-selection__rendered { overflow: auto !important; } + #search_part_no + .select2-container, + #search_part_name + .select2-container { + width: 210px !important; + } /* 검사결과 스타일 */ .inspection-ng { color: #dc3545; font-weight: bold; } .inspection-ok { color: #28a745; font-weight: bold; } - - /* 검색필터 아이템 스타일 */ - .search-item { display: flex; align-items: center; gap: 5px; } - .search-item label { font-weight: bold; white-space: nowrap; min-width: 50px; } - .search-item input, .search-item select { height: 28px; }