Compare commits
9 Commits
feature/ne
...
V202511030
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ba78332607 | ||
| 65dc50ced8 | |||
| 8948073527 | |||
| 9f902a9e93 | |||
| 2b3177ead4 | |||
| 87c2fd8f14 | |||
| b719d20ca2 | |||
| 4dbc6eb887 | |||
| 2b79ef456e |
@@ -3197,4 +3197,12 @@ SELECT option_objid::VARCHAR AS CODE
|
||||
|
||||
ORDER BY CODE_ID
|
||||
</select>
|
||||
|
||||
<!-- 사용자 권한 체크 -->
|
||||
<select id="checkUserAuthority" parameterType="map" resultType="int">
|
||||
SELECT COUNT(*)
|
||||
FROM AUTHORITY_SUB_USER
|
||||
WHERE USER_ID = #{userId}
|
||||
AND MASTER_OBJID::varchar = #{masterObjid}
|
||||
</select>
|
||||
</mapper>
|
||||
@@ -149,7 +149,7 @@ String connector = person.getUserId();
|
||||
},
|
||||
*/
|
||||
//{headerHozAlign : 'center', hozAlign : 'left', width : '125', title : '모품번', field : 'PARENT_PART_INFO' },
|
||||
{headerHozAlign : 'center', hozAlign : 'left', width : '200', title : '품번', field : 'PART_NO',
|
||||
{headerHozAlign : 'center', hozAlign : 'left', width : '250', title : '품번', field : 'PART_NO',
|
||||
formatter:fnc_createGridAnchorTag,
|
||||
cellClick:function(e, cell){
|
||||
var objid = fnc_checkNull(cell.getData().OBJID);
|
||||
@@ -185,11 +185,11 @@ String connector = person.getUserId();
|
||||
fnc_fileDetailPopup(objid, docType, docTypeName);
|
||||
}
|
||||
},
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '100', title : '재료', field : 'MATERIAL' },
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '100', title : '열처리경도', field : 'HEAT_TREATMENT_HARDNESS' },
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '100', title : '열처리방법', field : 'HEAT_TREATMENT_METHOD' },
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '100', title : '표면처리', field : 'SURFACE_TREATMENT' },
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '150', title : '공급업체', field : 'MAKER' },
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '120', title : '재료', field : 'MATERIAL' },
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '120', title : '열처리경도', field : 'HEAT_TREATMENT_HARDNESS' },
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '120', title : '열처리방법', field : 'HEAT_TREATMENT_METHOD' },
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '120', title : '표면처리', field : 'SURFACE_TREATMENT' },
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '150', title : '메이커', field : 'MAKER' },
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '100', title : '범주 이름', field : 'PART_TYPE_TITLE' },
|
||||
|
||||
// {headerHozAlign : 'center', hozAlign : 'center', width : '90', title : '재질', field : 'MATERIAL' },
|
||||
@@ -198,11 +198,11 @@ String connector = person.getUserId();
|
||||
// {headerHozAlign : 'center', hozAlign : 'center', width : '80', title : 'MAKER', field : 'MAKER' },
|
||||
// {headerHozAlign : 'center', hozAlign : 'center', width : '80', title : '대분류', field : 'MAJOR_CATEGORY' },
|
||||
// {headerHozAlign : 'center', hozAlign : 'center', width : '80', title : '중분류', field : 'SUB_CATEGORY' },
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '90', title : 'Revision', field : 'REVISION' },
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '90', title : 'EO No', field : 'EO_NO' },
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '80', title : 'EO Date', field : 'EO_DATE' },
|
||||
//{headerHozAlign : 'center', hozAlign : 'center', width : '90', title : 'Revision', field : 'REVISION' },
|
||||
//{headerHozAlign : 'center', hozAlign : 'center', width : '90', title : 'EO No', field : 'EO_NO' },
|
||||
//{headerHozAlign : 'center', hozAlign : 'center', width : '80', title : 'EO Date', field : 'EO_DATE' },
|
||||
// {headerHozAlign : 'center', hozAlign : 'center', width : '88', title : 'PART구분', field : 'PART_TYPE_TITLE' },
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '80', title : '비고', field : 'REMARK' }
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '120', title : '비고', field : 'REMARK' }
|
||||
];
|
||||
|
||||
//var grid;
|
||||
@@ -325,7 +325,7 @@ String connector = person.getUserId();
|
||||
// 파일 분류 및 처리
|
||||
var filesByType = {
|
||||
'3D': [], // stp 파일
|
||||
'2D': [], // dwg 파일
|
||||
'2D': [], // dwg, dxf 파일
|
||||
'PDF': [] // pdf 파일
|
||||
};
|
||||
|
||||
@@ -343,7 +343,7 @@ String connector = person.getUserId();
|
||||
|
||||
if(ext === 'stp' || ext === 'step') {
|
||||
filesByType['3D'].push(file);
|
||||
} else if(ext === 'dwg') {
|
||||
} else if(ext === 'dwg' || ext === 'dxf') {
|
||||
filesByType['2D'].push(file);
|
||||
} else if(ext === 'pdf') {
|
||||
filesByType['PDF'].push(file);
|
||||
@@ -353,14 +353,14 @@ String connector = person.getUserId();
|
||||
// 업로드할 파일이 있는지 확인
|
||||
var totalFiles = filesByType['3D'].length + filesByType['2D'].length + filesByType['PDF'].length;
|
||||
if(totalFiles === 0) {
|
||||
Swal.fire('업로드 가능한 파일 형식이 없습니다. (stp, dwg, pdf만 가능)');
|
||||
Swal.fire('업로드 가능한 파일 형식이 없습니다. (stp, dwg, dxf, pdf만 가능)');
|
||||
return;
|
||||
}
|
||||
|
||||
// 확인 메시지
|
||||
var msg = '총 ' + totalFiles + '개의 파일을 업로드하시겠습니까?\n';
|
||||
msg += '- 3D (STP): ' + filesByType['3D'].length + '개\n';
|
||||
msg += '- 2D (DWG): ' + filesByType['2D'].length + '개\n';
|
||||
msg += '- 2D (DWG/DXF): ' + filesByType['2D'].length + '개\n';
|
||||
msg += '- PDF: ' + filesByType['PDF'].length + '개';
|
||||
|
||||
Swal.fire({
|
||||
@@ -495,7 +495,7 @@ String connector = person.getUserId();
|
||||
<input type="button" value="도면 다중 업로드" class="plm_btns" id="btnDrawingUpload">
|
||||
<input type="button" value="조회" class="plm_btns" id="btnSearch">
|
||||
<input type="button" value="Excel Download" class="plm_btns" id="btnExcel">
|
||||
<input type="file" id="drawingFiles" multiple style="display:none;" accept=".stp,.step,.dwg,.pdf">
|
||||
<input type="file" id="drawingFiles" multiple style="display:none;" accept=".stp,.step,.dwg,.dxf,.pdf">
|
||||
</div>
|
||||
</div>
|
||||
<div id="plmSearchZon">
|
||||
|
||||
@@ -141,7 +141,7 @@ ui-jqgrid tr.jqgrow td {
|
||||
// {headerHozAlign : 'center', hozAlign : 'center', width : '60', title : '순', field : 'RNUM' ,frozen:true},
|
||||
|
||||
// {headerHozAlign : 'center', hozAlign : 'left', width : '125', title : '모품번', field : 'PARENT_PART_INFO' ,frozen:true},
|
||||
{headerHozAlign : 'center', hozAlign : 'left', width : '200', title : '품번', field : 'PART_NO',frozen:true,
|
||||
{headerHozAlign : 'center', hozAlign : 'left', width : '250', title : '품번', field : 'PART_NO',frozen:true,
|
||||
formatter:fnc_createGridAnchorTag,
|
||||
cellClick:function(e, cell){
|
||||
var objid = fnc_checkNull(cell.getData().OBJID);
|
||||
@@ -177,11 +177,11 @@ ui-jqgrid tr.jqgrow td {
|
||||
fn_FileRegist(objid, docType, docTypeName);
|
||||
}
|
||||
},
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '100', title : '재료', field : 'MATERIAL' },
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '100', title : '열처리경도', field : 'HEAT_TREATMENT_HARDNESS' },
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '100', title : '열처리방법', field : 'HEAT_TREATMENT_METHOD' },
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '100', title : '표면처리', field : 'SURFACE_TREATMENT' },
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '150', title : '공급업체', field : 'MAKER' },
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '120', title : '재료', field : 'MATERIAL' },
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '120', title : '열처리경도', field : 'HEAT_TREATMENT_HARDNESS' },
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '120', title : '열처리방법', field : 'HEAT_TREATMENT_METHOD' },
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '120', title : '표면처리', field : 'SURFACE_TREATMENT' },
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '150', title : '메이커', field : 'MAKER' },
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '100', title : '범주 이름', field : 'PART_TYPE_TITLE' },
|
||||
|
||||
// {headerHozAlign : 'center', hozAlign : 'left', width : '190', title : '사양(규격)', field : 'SPEC' },
|
||||
@@ -189,11 +189,11 @@ ui-jqgrid tr.jqgrow td {
|
||||
// {headerHozAlign : 'center', hozAlign : 'center', width : '90', title : 'MAKER', field : 'MAKER' },
|
||||
// {headerHozAlign : 'center', hozAlign : 'center', width : '120', title : '대분류', field : 'MAJOR_CATEGORY' },
|
||||
// {headerHozAlign : 'center', hozAlign : 'center', width : '120', title : '중분류', field : 'SUB_CATEGORY' },
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '90', title : 'Revision', field : 'REVISION' },
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '90', title : 'EO No', field : 'EO_NO' },
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '90', title : 'EO Date', field : 'EO_DATE' },
|
||||
// {headerHozAlign : 'center', hozAlign : 'center', width : '90', title : 'Revision', field : 'REVISION' },
|
||||
// {headerHozAlign : 'center', hozAlign : 'center', width : '90', title : 'EO No', field : 'EO_NO' },
|
||||
// {headerHozAlign : 'center', hozAlign : 'center', width : '90', title : 'EO Date', field : 'EO_DATE' },
|
||||
// {headerHozAlign : 'center', hozAlign : 'center', width : '90', title : 'PART 구분', field : 'PART_TYPE_TITLE' },
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '90', title : '비고', field : 'REMARK' }
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '120', title : '비고', field : 'REMARK' }
|
||||
];
|
||||
|
||||
// 중복 요청 방지 플래그
|
||||
@@ -430,7 +430,7 @@ ui-jqgrid tr.jqgrow td {
|
||||
// 파일 분류 및 처리
|
||||
var filesByType = {
|
||||
'3D': [], // stp 파일
|
||||
'2D': [], // dwg 파일
|
||||
'2D': [], // dwg, dxf 파일
|
||||
'PDF': [] // pdf 파일
|
||||
};
|
||||
|
||||
@@ -448,7 +448,7 @@ ui-jqgrid tr.jqgrow td {
|
||||
|
||||
if(ext === 'stp' || ext === 'step') {
|
||||
filesByType['3D'].push(file);
|
||||
} else if(ext === 'dwg') {
|
||||
} else if(ext === 'dwg' || ext === 'dxf') {
|
||||
filesByType['2D'].push(file);
|
||||
} else if(ext === 'pdf') {
|
||||
filesByType['PDF'].push(file);
|
||||
@@ -458,14 +458,14 @@ ui-jqgrid tr.jqgrow td {
|
||||
// 업로드할 파일이 있는지 확인
|
||||
var totalFiles = filesByType['3D'].length + filesByType['2D'].length + filesByType['PDF'].length;
|
||||
if(totalFiles === 0) {
|
||||
Swal.fire('업로드 가능한 파일 형식이 없습니다. (stp, dwg, pdf만 가능)');
|
||||
Swal.fire('업로드 가능한 파일 형식이 없습니다. (stp, dwg, dxf, pdf만 가능)');
|
||||
return;
|
||||
}
|
||||
|
||||
// 확인 메시지
|
||||
var msg = '총 ' + totalFiles + '개의 파일을 업로드하시겠습니까?\n';
|
||||
msg += '- 3D (STP): ' + filesByType['3D'].length + '개\n';
|
||||
msg += '- 2D (DWG): ' + filesByType['2D'].length + '개\n';
|
||||
msg += '- 2D (DWG/DXF): ' + filesByType['2D'].length + '개\n';
|
||||
msg += '- PDF: ' + filesByType['PDF'].length + '개';
|
||||
|
||||
Swal.fire({
|
||||
@@ -615,7 +615,7 @@ ui-jqgrid tr.jqgrow td {
|
||||
<input type="button" value="등록(Excel Upload)" class="plm_btns" onclick="openExcelPopup();">
|
||||
<input type="button" value="도면 다중 업로드" class="plm_btns" id="btnDrawingUpload">
|
||||
<input type="button" value="조회" class="plm_btns" id="btnSearch">
|
||||
<input type="file" id="drawingFiles" multiple style="display:none;" accept=".stp,.step,.dwg,.pdf">
|
||||
<input type="file" id="drawingFiles" multiple style="display:none;" accept=".stp,.step,.dwg,.dxf,.pdf">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -2,7 +2,27 @@
|
||||
<%@ page import="com.pms.common.utils.*"%>
|
||||
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
|
||||
<%@ page import="java.util.*" %>
|
||||
<%@include file= "/init.jsp" %>
|
||||
<%@include file= "/init.jsp" %>
|
||||
<%
|
||||
// 권한 체크: AUTHORITY_MASTER의 OBJID가 41000668인 그룹에 속한 사용자인지 확인
|
||||
boolean hasStatusChangeAuth = false;
|
||||
try {
|
||||
org.apache.ibatis.session.SqlSession sqlSession = com.pms.common.SqlMapConfig.getInstance().getSqlSession();
|
||||
java.util.Map<String, Object> authParam = new java.util.HashMap<String, Object>();
|
||||
authParam.put("userId", connectUserId);
|
||||
authParam.put("masterObjid", "41000668");
|
||||
|
||||
Integer authCount = (Integer)sqlSession.selectOne("common.checkUserAuthority", authParam);
|
||||
hasStatusChangeAuth = (authCount != null && authCount > 0);
|
||||
|
||||
sqlSession.close();
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
%>
|
||||
<script>
|
||||
var hasStatusChangeAuth = <%=hasStatusChangeAuth%>;
|
||||
</script>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
@@ -165,8 +185,8 @@ var columns = [
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '150', title : 'E-BOM', field : 'BOM_CNT',
|
||||
formatter: fnc_subInfoValueFormatter,
|
||||
cellClick:function(e, cell){
|
||||
var objId = fnc_checkNull(cell.getData().OBJID);
|
||||
//var bomReportObjId = fnc_checkNull(cell.getData().BOM_REPORMECHANICAL_TYPET_OBJID);
|
||||
var objId = fnc_checkNull(cell.getData().OBJID);
|
||||
// 바로 팝업 열기 (팝업창 내부에서 경고 처리)
|
||||
fn_openSetStructure(objId);
|
||||
}
|
||||
},
|
||||
@@ -498,6 +518,16 @@ function fn_openChangeDesignNote(objId){
|
||||
* 상태변경 팝업
|
||||
*/
|
||||
function fn_openStatusChange() {
|
||||
// 권한 체크
|
||||
if(!hasStatusChangeAuth) {
|
||||
Swal.fire({
|
||||
title: '권한 없음',
|
||||
text: '상태변경 권한이 없습니다.',
|
||||
icon: 'error'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
var selectedStructure = _tabulGrid.getSelectedData();
|
||||
|
||||
if(selectedStructure.length == 0){
|
||||
@@ -512,8 +542,33 @@ function fn_openStatusChange() {
|
||||
|
||||
var selectedData = selectedStructure[0];
|
||||
var objId = fnc_checkNull(selectedData.OBJID);
|
||||
var partNo = fnc_checkNull(selectedData.PART_NO);
|
||||
var partName = fnc_checkNull(selectedData.PART_NAME);
|
||||
var currentStatus = fnc_checkNull(selectedData.STATUS);
|
||||
|
||||
window.open("/partMng/structureStatusChangePopup.do?objId=" + objId, "structureStatusChangePopup", "width=500, height=300, resizable=no");
|
||||
// 현재 상태 표시용 텍스트 (Y/N만 존재)
|
||||
var statusText = (currentStatus === 'Y') ? 'Y' : 'N';
|
||||
|
||||
// 상태변경 확인 경고
|
||||
Swal.fire({
|
||||
title: 'E-BOM 상태 변경',
|
||||
html: 'E-BOM의 상태변경을 진행하시겠습니까?<br><br>' +
|
||||
'<strong>품번:</strong> ' + partNo + '<br>' +
|
||||
'<strong>품명:</strong> ' + partName + '<br>' +
|
||||
'<strong>현재 상태:</strong> ' + statusText + '<br><br>' +
|
||||
'상태를 변경하시겠습니까?',
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: '상태변경',
|
||||
cancelButtonText: '취소',
|
||||
reverseButtons: false
|
||||
}).then(result => {
|
||||
if (result.isConfirmed) {
|
||||
window.open("/partMng/structureStatusChangePopup.do?objId=" + objId, "structureStatusChangePopup", "width=500, height=300, resizable=no");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function saveexcelpop() {
|
||||
@@ -552,21 +607,40 @@ function saveexcelpop() {
|
||||
BOM_VERSION = fnc_checkNull(selectedStructure[i].REVISION);
|
||||
}
|
||||
|
||||
// hiddenForm을 사용하여 POST 방식으로 팝업 열기 (한글 인코딩 문제 해결)
|
||||
var hiddenForm = document.hiddenForm;
|
||||
var url = "/partMng/openBomReportExcelImportPopUp.do";
|
||||
var target = "openBomReportExcelImportPopUp";
|
||||
|
||||
hiddenForm.PRODUCT_CD.value = BOM_PRODUCT_CD;
|
||||
hiddenForm.BOM_PART_NAME.value = BOM_PART_NAME;
|
||||
hiddenForm.BOM_PART_NO.value = BOM_PART_NO;
|
||||
hiddenForm.BOM_REPORT_OBJID.value = BOM_REPORT_OBJID;
|
||||
hiddenForm.BOM_VERSION.value = BOM_VERSION;
|
||||
|
||||
window.open('', target, 'width=1920, height=860, menubars=no, scrollbars=yes, resizable=yes');
|
||||
hiddenForm.action = url;
|
||||
hiddenForm.target = target;
|
||||
hiddenForm.submit();
|
||||
// CSV 업로드 확인 경고
|
||||
Swal.fire({
|
||||
title: 'E-BOM CSV 업로드',
|
||||
html: 'CSV 파일을 통해 E-BOM 데이터를 새로 등록합니다.<br><br>' +
|
||||
'<strong>품번:</strong> ' + BOM_PART_NO + '<br>' +
|
||||
'<strong>품명:</strong> ' + BOM_PART_NAME + '<br>' +
|
||||
'<strong>버전:</strong> ' + BOM_VERSION + '<br><br>' +
|
||||
'계속하시겠습니까?',
|
||||
icon: 'question',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: '계속',
|
||||
cancelButtonText: '취소',
|
||||
reverseButtons: false
|
||||
}).then(result => {
|
||||
if (result.isConfirmed) {
|
||||
// hiddenForm을 사용하여 POST 방식으로 팝업 열기 (한글 인코딩 문제 해결)
|
||||
var hiddenForm = document.hiddenForm;
|
||||
var url = "/partMng/openBomReportExcelImportPopUp.do";
|
||||
var target = "openBomReportExcelImportPopUp";
|
||||
|
||||
hiddenForm.PRODUCT_CD.value = BOM_PRODUCT_CD;
|
||||
hiddenForm.BOM_PART_NAME.value = BOM_PART_NAME;
|
||||
hiddenForm.BOM_PART_NO.value = BOM_PART_NO;
|
||||
hiddenForm.BOM_REPORT_OBJID.value = BOM_REPORT_OBJID;
|
||||
hiddenForm.BOM_VERSION.value = BOM_VERSION;
|
||||
|
||||
window.open('', target, 'width=1920, height=860, menubars=no, scrollbars=yes, resizable=yes');
|
||||
hiddenForm.action = url;
|
||||
hiddenForm.target = target;
|
||||
hiddenForm.submit();
|
||||
}
|
||||
});
|
||||
}
|
||||
}else{
|
||||
if($("#customer_cd").val()==""){
|
||||
|
||||
@@ -6,8 +6,34 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title><%=Constants.SYSTEM_NAME%></title>
|
||||
<title><%=Constants.SYSTEM_NAME%></title>
|
||||
|
||||
<script>
|
||||
// confirm/alert 헬퍼 함수
|
||||
function showConfirm(options) {
|
||||
if(typeof options === 'string') {
|
||||
alert(options);
|
||||
return Promise.resolve({isConfirmed: true});
|
||||
}
|
||||
|
||||
var message = '';
|
||||
if(options.title) message += options.title + '\n\n';
|
||||
if(options.html) {
|
||||
// HTML 태그 제거
|
||||
message += options.html.replace(/<br\s*\/?>/gi, '\n').replace(/<[^>]+>/g, '');
|
||||
} else if(options.text) {
|
||||
message += options.text;
|
||||
}
|
||||
|
||||
if(options.showCancelButton !== false && (options.icon === 'warning' || options.icon === 'question')) {
|
||||
var result = confirm(message);
|
||||
return Promise.resolve({isConfirmed: result});
|
||||
} else {
|
||||
alert(message);
|
||||
return Promise.resolve({isConfirmed: true});
|
||||
}
|
||||
}
|
||||
|
||||
$(function(){
|
||||
|
||||
$('.select2').select2();
|
||||
@@ -19,7 +45,7 @@ $(function(){
|
||||
var rightSelectedRows = rightFrame.getSelectedRows ? rightFrame.getSelectedRows() : [];
|
||||
|
||||
if(rightSelectedRows.length === 0) {
|
||||
alert("선택된 파트가 없습니다.");
|
||||
showConfirm("선택된 파트가 없습니다.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -50,7 +76,11 @@ $(function(){
|
||||
var rowData = rightSelectedRows[i].getData();
|
||||
var rightPartNo = rowData.PART_NO;
|
||||
if(rightPartNo == leftPartNo){
|
||||
alert("오류 Part No : ["+rightPartNo+"]\n같은 Part No끼리 연결할 수 없습니다.");
|
||||
showConfirm({
|
||||
title: '연결 불가',
|
||||
html: '오류 Part No : <strong>['+rightPartNo+']</strong><br>같은 Part No끼리 연결할 수 없습니다.',
|
||||
icon: 'error'
|
||||
});
|
||||
isSamePart = true;
|
||||
break;
|
||||
}
|
||||
@@ -73,7 +103,11 @@ $(function(){
|
||||
if("unique" == rightPartType){
|
||||
for(var j = 0 ; j < deniedPartArr.length ; j++){
|
||||
if(rightPartNo == deniedPartArr[j]){
|
||||
alert("오류 Part No : "+"["+rightPartNo+"]\n이미 상위에 등록된 Part No 입니다.");
|
||||
showConfirm({
|
||||
title: '연결 불가',
|
||||
html: '오류 Part No : <strong>['+rightPartNo+']</strong><br>이미 상위에 등록된 Part No 입니다.',
|
||||
icon: 'error'
|
||||
});
|
||||
isDeniedPart = true;
|
||||
break;
|
||||
}
|
||||
@@ -94,12 +128,31 @@ $(function(){
|
||||
if(fnc_checkNull(leftPartNo) == ""){
|
||||
var flag = fn_checkSameTopPartNo(rightCheckedArr);
|
||||
if(flag == "true"){
|
||||
alert("1레벨에 같은 Part No가 중복 등록될 수 없습니다.");
|
||||
showConfirm({
|
||||
title: '중복 등록 불가',
|
||||
text: '1레벨에 같은 Part No가 중복 등록될 수 없습니다.',
|
||||
icon: 'error'
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
fn_relatePartInfo(leftPartChildObjId, rightCheckedArr, leftPartNoQty, leftPartLastObjId, leftPartChildObjId, leftQtyParObjId);
|
||||
// Part 연결 확인
|
||||
showConfirm({
|
||||
title: 'Part 연결',
|
||||
text: '선택한 Part를 연결하시겠습니까?',
|
||||
icon: 'question',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: '연결',
|
||||
cancelButtonText: '취소',
|
||||
reverseButtons: false
|
||||
}).then(result => {
|
||||
if (result.isConfirmed) {
|
||||
fn_relatePartInfo(leftPartChildObjId, rightCheckedArr, leftPartNoQty, leftPartLastObjId, leftPartChildObjId, leftQtyParObjId);
|
||||
}
|
||||
});
|
||||
});
|
||||
//end of Part 연결
|
||||
|
||||
@@ -121,12 +174,12 @@ $(function(){
|
||||
var leftPartNoList = $("input[name=checkedPartNo]:checked", parent.frames['leftFrame'].document);
|
||||
|
||||
if(leftPartNoList.length === 0){
|
||||
alert("선택된 파트가 없습니다.");
|
||||
showConfirm("선택된 파트가 없습니다.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(leftPartNoList.length > 1){
|
||||
alert("한번에 1개의 파트만 변경가능합니다.");
|
||||
showConfirm("한번에 1개의 파트만 변경가능합니다.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -141,12 +194,12 @@ $(function(){
|
||||
var rightSelectedRows = rightFrame.getSelectedRows ? rightFrame.getSelectedRows() : [];
|
||||
|
||||
if(rightSelectedRows.length === 0){
|
||||
alert("선택된 파트가 없습니다.");
|
||||
showConfirm("선택된 파트가 없습니다.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(rightSelectedRows.length > 1){
|
||||
alert("한번에 1개의 파트만 변경가능합니다.");
|
||||
showConfirm("한번에 1개의 파트만 변경가능합니다.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -155,7 +208,24 @@ $(function(){
|
||||
var rightPartRev = rightRowData.REVISION || "";
|
||||
var rightObjId = rightRowData.OBJID;
|
||||
|
||||
fn_changeRelatePartInfo(leftPartBomQtyObjId, rightObjId, leftPartChildObjId, leftParentPartObjid, leftPartChildObjId, leftPartObjid, rightPartNo, rightPartRev);
|
||||
// Part 변경 확인
|
||||
showConfirm({
|
||||
title: 'Part 변경',
|
||||
html: '선택한 Part를 변경하시겠습니까?<br><br>' +
|
||||
'<strong>기존:</strong> ' + leftPartNo + '<br>' +
|
||||
'<strong>변경:</strong> ' + rightPartNo,
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: '변경',
|
||||
cancelButtonText: '취소',
|
||||
reverseButtons: false
|
||||
}).then(result => {
|
||||
if (result.isConfirmed) {
|
||||
fn_changeRelatePartInfo(leftPartBomQtyObjId, rightObjId, leftPartChildObjId, leftParentPartObjid, leftPartChildObjId, leftPartObjid, rightPartNo, rightPartRev);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
@@ -187,11 +257,29 @@ function fn_checkSameTopPartNo(rightCheckedArr){
|
||||
//구조 연결 해제
|
||||
function fn_deletePartRelateInfo(leftObjId, leftPartLastObjId, leftParentPartNo, leftParentObjId, leftPartChildObjId){
|
||||
if(leftObjId == null){
|
||||
alert("연결 해제할 Part를 선택해 주시기 바랍니다.")
|
||||
showConfirm("연결 해제할 Part를 선택해 주시기 바랍니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!confirm("연결 해제하시겠습니까?")) return;
|
||||
showConfirm({
|
||||
title: 'Part 연결 해제',
|
||||
text: '선택한 Part의 연결을 해제하시겠습니까?',
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: '연결 해제',
|
||||
cancelButtonText: '취소',
|
||||
reverseButtons: false
|
||||
}).then(result => {
|
||||
if (!result.isConfirmed) return;
|
||||
|
||||
fn_executeDeletePartRelateInfo(leftObjId, leftPartLastObjId, leftParentPartNo, leftParentObjId, leftPartChildObjId);
|
||||
});
|
||||
}
|
||||
|
||||
// 실제 Part 연결 해제 실행 함수
|
||||
function fn_executeDeletePartRelateInfo(leftObjId, leftPartLastObjId, leftParentPartNo, leftParentObjId, leftPartChildObjId){
|
||||
|
||||
$.ajax({
|
||||
url: "/partMng/deleteStatusPartRelateInfo.do",
|
||||
@@ -222,16 +310,35 @@ function fn_deletePartRelateInfo(leftObjId, leftPartLastObjId, leftParentPartNo,
|
||||
//구조 연결
|
||||
function fn_relatePartInfo(leftObjId, rightCheckedArr, leftPartNoQty, leftPartLastObjId, leftPartChildObjId, leftQtyParObjId){
|
||||
if(typeof rightCheckedArr != "undefined" && rightCheckedArr.length == 0){
|
||||
alert("선택된 Part가 없습니다.");
|
||||
showConfirm("선택된 Part가 없습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(leftObjId == null){
|
||||
if(!confirm("좌측에 선택된 Part정보가 없습니다.\n이대로 연결하면 1레벨로 등록됩니다.\n진행하시겠습니까?")){
|
||||
return;
|
||||
}
|
||||
showConfirm({
|
||||
title: '1레벨 등록 확인',
|
||||
html: '좌측에 선택된 Part정보가 없습니다.<br>이대로 연결하면 1레벨로 등록됩니다.<br><br>진행하시겠습니까?',
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: '진행',
|
||||
cancelButtonText: '취소',
|
||||
reverseButtons: false
|
||||
}).then(result => {
|
||||
if (result.isConfirmed) {
|
||||
fn_executeRelatePartInfo(leftObjId, rightCheckedArr, leftPartNoQty, leftPartLastObjId, leftPartChildObjId, leftQtyParObjId);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
fn_executeRelatePartInfo(leftObjId, rightCheckedArr, leftPartNoQty, leftPartLastObjId, leftPartChildObjId, leftQtyParObjId);
|
||||
}
|
||||
|
||||
// 실제 Part 연결 실행 함수
|
||||
function fn_executeRelatePartInfo(leftObjId, rightCheckedArr, leftPartNoQty, leftPartLastObjId, leftPartChildObjId, leftQtyParObjId){
|
||||
|
||||
$.ajax({
|
||||
url: "/partMng/relatePartInfo.do",
|
||||
method: 'post',
|
||||
|
||||
@@ -438,7 +438,7 @@ function fn_uploadDrawingFiles(files) {
|
||||
// 파일 분류 및 처리
|
||||
var filesByType = {
|
||||
'3D': [], // stp 파일
|
||||
'2D': [], // dwg 파일
|
||||
'2D': [], // dwg, dxf 파일
|
||||
'PDF': [] // pdf 파일
|
||||
};
|
||||
|
||||
@@ -458,24 +458,24 @@ function fn_uploadDrawingFiles(files) {
|
||||
|
||||
if(ext === 'stp' || ext === 'step') {
|
||||
filesByType['3D'].push(file);
|
||||
} else if(ext === 'dwg') {
|
||||
} else if(ext === 'dwg' || ext === 'dxf') {
|
||||
filesByType['2D'].push(file);
|
||||
} else if(ext === 'pdf') {
|
||||
filesByType['PDF'].push(file);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 업로드할 파일이 있는지 확인
|
||||
var totalFiles = filesByType['3D'].length + filesByType['2D'].length + filesByType['PDF'].length;
|
||||
if(totalFiles === 0) {
|
||||
Swal.fire('업로드 가능한 파일 형식이 없습니다. (stp, dwg, pdf만 가능)');
|
||||
Swal.fire('업로드 가능한 파일 형식이 없습니다. (stp, dwg, dxf, pdf만 가능)');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 확인 메시지
|
||||
var msg = '총 ' + totalFiles + '개의 파일을 업로드하시겠습니까?\n';
|
||||
msg += '- 3D (STP): ' + filesByType['3D'].length + '개\n';
|
||||
msg += '- 2D (DWG): ' + filesByType['2D'].length + '개\n';
|
||||
msg += '- 2D (DWG/DXF): ' + filesByType['2D'].length + '개\n';
|
||||
msg += '- PDF: ' + filesByType['PDF'].length + '개';
|
||||
|
||||
Swal.fire({
|
||||
@@ -597,7 +597,7 @@ function fn_processDrawingUpload(bomObjId, filesByType) {
|
||||
</span>
|
||||
<input type="button" value="Excel Download" class="plm_btns structure_btn" id="btnExcel" style="float:right;">
|
||||
<input type="button" value="도면 다중 업로드" class="plm_btns structure_btn" id="btnDrawingUpload" style="float:right; margin-right:5px;">
|
||||
<input type="file" id="drawingFiles" multiple style="display:none;" accept=".stp,.step,.dwg,.pdf">
|
||||
<input type="file" id="drawingFiles" multiple style="display:none;" accept=".stp,.step,.dwg,.dxf,.pdf">
|
||||
</div>
|
||||
<div id="structureGrid"></div>
|
||||
</div>
|
||||
|
||||
@@ -2242,6 +2242,19 @@ public class PartMngController {
|
||||
String fileExt = CommonUtils.checkNull((String)fileInfo.get("fileExt"));
|
||||
long fileSize = Long.parseLong(CommonUtils.checkNull(fileInfo.get("fileSize"), "0"));
|
||||
|
||||
// 파일 크기가 0이면 실제 저장된 파일에서 다시 확인
|
||||
// if(fileSize == 0) {
|
||||
// try {
|
||||
// File savedFile = new File(storagePath + File.separator + savedFileName);
|
||||
// if(savedFile.exists()) {
|
||||
// fileSize = savedFile.length();
|
||||
// System.out.println("파일 크기 재확인: " + fileSize + " bytes");
|
||||
// }
|
||||
// } catch(Exception e) {
|
||||
// System.out.println("파일 크기 재확인 실패: " + e.getMessage());
|
||||
// }
|
||||
// }
|
||||
|
||||
// 확장자 대문자 변환 (이미 점 없이 저장됨)
|
||||
fileExt = fileExt.toUpperCase();
|
||||
|
||||
@@ -2249,6 +2262,7 @@ public class PartMngController {
|
||||
System.out.println("원본 파일명: " + originalFileName);
|
||||
System.out.println("저장 파일명: " + savedFileName);
|
||||
System.out.println("확장자: " + fileExt);
|
||||
System.out.println("파일 크기: " + fileSize + " bytes");
|
||||
System.out.println("===================================");
|
||||
|
||||
// 파일 확장자에 따른 문서 타입 결정
|
||||
@@ -2258,7 +2272,7 @@ public class PartMngController {
|
||||
if("STP".equals(fileExt) || "STEP".equals(fileExt)) {
|
||||
docType = "3D_CAD";
|
||||
docTypeName = "3D CAD 첨부파일";
|
||||
} else if("DWG".equals(fileExt)) {
|
||||
} else if("DWG".equals(fileExt) || "DXF".equals(fileExt)){
|
||||
docType = "2D_DRAWING_CAD";
|
||||
docTypeName = "2D(Drawing) CAD 첨부파일";
|
||||
} else if("PDF".equals(fileExt)) {
|
||||
@@ -2432,6 +2446,19 @@ public class PartMngController {
|
||||
String fileExt = CommonUtils.checkNull((String)fileInfo.get("fileExt"));
|
||||
long fileSize = Long.parseLong(CommonUtils.checkNull(fileInfo.get("fileSize"), "0"));
|
||||
|
||||
// 파일 크기가 0이면 실제 저장된 파일에서 다시 확인
|
||||
// if(fileSize == 0) {
|
||||
// try {
|
||||
// File savedFile = new File(storagePath + File.separator + savedFileName);
|
||||
// if(savedFile.exists()) {
|
||||
// fileSize = savedFile.length();
|
||||
// System.out.println("파일 크기 재확인: " + fileSize + " bytes");
|
||||
// }
|
||||
// } catch(Exception e) {
|
||||
// System.out.println("파일 크기 재확인 실패: " + e.getMessage());
|
||||
// }
|
||||
// }
|
||||
|
||||
// 확장자 대문자 변환
|
||||
fileExt = fileExt.toUpperCase();
|
||||
|
||||
@@ -2439,6 +2466,7 @@ public class PartMngController {
|
||||
System.out.println("원본 파일명: " + originalFileName);
|
||||
System.out.println("저장 파일명: " + savedFileName);
|
||||
System.out.println("확장자: " + fileExt);
|
||||
System.out.println("파일 크기: " + fileSize + " bytes");
|
||||
System.out.println("==========================================");
|
||||
|
||||
// 파일 확장자에 따른 문서 타입 결정
|
||||
@@ -2448,7 +2476,7 @@ public class PartMngController {
|
||||
if("STP".equals(fileExt) || "STEP".equals(fileExt)) {
|
||||
docType = "3D_CAD";
|
||||
docTypeName = "3D CAD 첨부파일";
|
||||
} else if("DWG".equals(fileExt)) {
|
||||
} else if("DWG".equals(fileExt) || "DXF".equals(fileExt)) {
|
||||
docType = "2D_DRAWING_CAD";
|
||||
docTypeName = "2D(Drawing) CAD 첨부파일";
|
||||
} else if("PDF".equals(fileExt)) {
|
||||
|
||||
@@ -3197,4 +3197,12 @@ SELECT option_objid::VARCHAR AS CODE
|
||||
|
||||
ORDER BY CODE_ID
|
||||
</select>
|
||||
|
||||
<!-- 사용자 권한 체크 -->
|
||||
<select id="checkUserAuthority" parameterType="map" resultType="int">
|
||||
SELECT COUNT(*)
|
||||
FROM AUTHORITY_SUB_USER
|
||||
WHERE USER_ID = #{userId}
|
||||
AND MASTER_OBJID::varchar = #{masterObjid}
|
||||
</select>
|
||||
</mapper>
|
||||
@@ -3157,40 +3157,50 @@ public class PartMngService extends BaseService {
|
||||
// 시도할 인코딩 목록 (Windows Excel CSV 기본 인코딩 우선)
|
||||
String[] encodings = {"CP949", "UTF-8", "EUC-KR", "MS949"};
|
||||
|
||||
String bestEncoding = "UTF-8"; // 기본값
|
||||
int minReplacementChars = Integer.MAX_VALUE;
|
||||
|
||||
for (String encoding : encodings) {
|
||||
try (FileInputStream fis = new FileInputStream(file);
|
||||
InputStreamReader isr = new InputStreamReader(fis, encoding);
|
||||
BufferedReader br = new BufferedReader(isr)) {
|
||||
|
||||
// 처음 몇 줄을 읽어서 깨진 문자 여부 확인
|
||||
// 처음 몇 줄을 읽어서 깨진 문자 개수 확인
|
||||
String line;
|
||||
int lineCount = 0;
|
||||
boolean hasBrokenChar = false;
|
||||
int replacementCharCount = 0;
|
||||
|
||||
while ((line = br.readLine()) != null && lineCount < 10) {
|
||||
// 깨진 문자 검사 (<28> 또는 replacement character)
|
||||
if (line.contains("\uFFFD") || line.contains("?")) {
|
||||
hasBrokenChar = true;
|
||||
break;
|
||||
// replacement character (\uFFFD) 개수 세기
|
||||
for (int i = 0; i < line.length(); i++) {
|
||||
if (line.charAt(i) == '\uFFFD') {
|
||||
replacementCharCount++;
|
||||
}
|
||||
}
|
||||
lineCount++;
|
||||
}
|
||||
|
||||
// 깨진 문자가 없으면 이 인코딩이 올바른 것으로 판단
|
||||
if (!hasBrokenChar && lineCount > 0) {
|
||||
System.out.println("CSV 인코딩 감지 성공: " + encoding);
|
||||
// 깨진 문자가 없으면 바로 이 인코딩 사용
|
||||
if (replacementCharCount == 0 && lineCount > 0) {
|
||||
System.out.println("CSV 인코딩 감지 성공: " + encoding + " (깨진 문자 없음)");
|
||||
return encoding;
|
||||
}
|
||||
|
||||
// 깨진 문자가 가장 적은 인코딩 기억
|
||||
if (replacementCharCount < minReplacementChars) {
|
||||
minReplacementChars = replacementCharCount;
|
||||
bestEncoding = encoding;
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
// 이 인코딩으로 읽기 실패 시 다음 인코딩 시도
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// 모든 시도 실패 시 기본값 UTF-8 반환
|
||||
System.out.println("CSV 인코딩 감지 실패, 기본값 UTF-8 사용");
|
||||
return "UTF-8";
|
||||
// 가장 적은 깨진 문자를 가진 인코딩 사용
|
||||
System.out.println("CSV 인코딩 감지 완료: " + bestEncoding + " (replacement chars: " + minReplacementChars + ")");
|
||||
return bestEncoding;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3334,23 +3344,38 @@ public class PartMngService extends BaseService {
|
||||
|
||||
// PART_TYPE 코드 조회
|
||||
String partTypeCode = "";
|
||||
if(!StringUtils.isBlank(partType) && rowIndex > 2) {
|
||||
Map sqlParamMap = new HashMap();
|
||||
sqlParamMap.put("CODE_NAME", partType);
|
||||
String partNoForCheck = CommonUtils.checkNull(partNo);
|
||||
sqlParamMap.put("partNo", partNoForCheck);
|
||||
Map partTypeMap = sqlSession.selectOne("partMng.parttypeInfo", sqlParamMap);
|
||||
if(null != partTypeMap && !StringUtils.isBlank((String)partTypeMap.get("code_id"))){
|
||||
partTypeCode = (String)partTypeMap.get("code_id");
|
||||
} else {
|
||||
noteMsg += "부품유형 확인:" + partType + ";";
|
||||
if(!StringUtils.isBlank(partType)) {
|
||||
// CSV 영문 범주명을 한글로 변환 (Unassigned→조립품, Buy→구매품, Make→부품)
|
||||
String partTypeForQuery = partType.trim();
|
||||
String partTypeUpper = partTypeForQuery.toUpperCase();
|
||||
|
||||
if("UNASSIGNED".equals(partTypeUpper)) {
|
||||
partTypeForQuery = "조립품";
|
||||
} else if("BUY".equals(partTypeUpper)) {
|
||||
partTypeForQuery = "구매품";
|
||||
} else if("MAKE".equals(partTypeUpper)) {
|
||||
partTypeForQuery = "부품";
|
||||
}
|
||||
} else if(!StringUtils.isBlank(partType) && rowIndex <= 2) {
|
||||
Map sqlParamMap = new HashMap();
|
||||
sqlParamMap.put("CODE_NAME", partType);
|
||||
Map partTypeMap = sqlSession.selectOne("partMng.parttypeInfo", sqlParamMap);
|
||||
if(null != partTypeMap && !StringUtils.isBlank((String)partTypeMap.get("code_id"))){
|
||||
partTypeCode = (String)partTypeMap.get("code_id");
|
||||
|
||||
// 변환된 값으로 DB 조회 (기존 방식)
|
||||
if(rowIndex > 2) {
|
||||
Map sqlParamMap = new HashMap();
|
||||
sqlParamMap.put("CODE_NAME", partTypeForQuery);
|
||||
String partNoForCheck = CommonUtils.checkNull(partNo);
|
||||
sqlParamMap.put("partNo", partNoForCheck);
|
||||
Map partTypeMap = sqlSession.selectOne("partMng.parttypeInfo", sqlParamMap);
|
||||
if(null != partTypeMap && !StringUtils.isBlank((String)partTypeMap.get("code_id"))){
|
||||
partTypeCode = (String)partTypeMap.get("code_id");
|
||||
} else {
|
||||
noteMsg += "부품유형 확인:" + partType + ";";
|
||||
}
|
||||
} else {
|
||||
Map sqlParamMap = new HashMap();
|
||||
sqlParamMap.put("CODE_NAME", partTypeForQuery);
|
||||
Map partTypeMap = sqlSession.selectOne("partMng.parttypeInfo", sqlParamMap);
|
||||
if(null != partTypeMap && !StringUtils.isBlank((String)partTypeMap.get("code_id"))){
|
||||
partTypeCode = (String)partTypeMap.get("code_id");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user