Merge remote-tracking branch 'origin/main'

This commit is contained in:
2025-10-24 17:49:22 +09:00
13 changed files with 697 additions and 531 deletions

View File

@@ -3210,12 +3210,15 @@ SELECT T1.LEV, T1.BOM_REPORT_OBJID, T1.ROOT_PART_NO, T1.PATH, T1.LEAF, T2.*
,P.OUT_DIAMETER
,P.IN_DIAMETER
,P.LENGTH
,P.SOURCING_CODE
,(SELECT COUNT(1) FROM ATTACH_FILE_INFO F WHERE P.OBJID = F.TARGET_OBJID <!--AND STATUS = 'Active'--> AND F.DOC_TYPE IN ('3D_CAD')) AS CU01_CNT
,(SELECT COUNT(1) FROM ATTACH_FILE_INFO F WHERE P.OBJID = F.TARGET_OBJID <!--AND STATUS = 'Active'--> AND F.DOC_TYPE IN ('2D_DRAWING_CAD')) AS CU02_CNT
,(SELECT COUNT(1) FROM ATTACH_FILE_INFO F WHERE P.OBJID = F.TARGET_OBJID <!--AND STATUS = 'Active'--> AND F.DOC_TYPE IN ('2D_PDF_CAD')) AS CU03_CNT
,V.LEV
,P.SOURCING_CODE
,P.HEAT_TREATMENT_HARDNESS
,P.HEAT_TREATMENT_METHOD
,P.SURFACE_TREATMENT
,(SELECT COUNT(1) FROM ATTACH_FILE_INFO F WHERE P.OBJID = F.TARGET_OBJID <!--AND STATUS = 'Active'--> AND F.DOC_TYPE IN ('3D_CAD')) AS CU01_CNT
,(SELECT COUNT(1) FROM ATTACH_FILE_INFO F WHERE P.OBJID = F.TARGET_OBJID <!--AND STATUS = 'Active'--> AND F.DOC_TYPE IN ('2D_DRAWING_CAD')) AS CU02_CNT
,(SELECT COUNT(1) FROM ATTACH_FILE_INFO F WHERE P.OBJID = F.TARGET_OBJID <!--AND STATUS = 'Active'--> AND F.DOC_TYPE IN ('2D_PDF_CAD')) AS CU03_CNT
,V.LEV
,(SELECT OBJID FROM VIEW_BOM VT WHERE V.BOM_REPORT_OBJID = VT.BOM_REPORT_OBJID AND VT.LEV = 1 ORDER BY SEQ LIMIT 1) AS ROOT_OBJID
,(SELECT OBJID FROM VIEW_BOM VT WHERE V.BOM_REPORT_OBJID = VT.BOM_REPORT_OBJID AND VT.LEV = 1 ORDER BY SEQ LIMIT 1) AS SUB_ROOT_OBJID
,( SELECT

View File

@@ -26,14 +26,14 @@ userMenuList = (ArrayList)request.getAttribute("userMenuList");
}
*/
.menu_off{
color:#fff !important; padding: 2px 3px; font-size:9px; background-color:#89b4fa; border-radius:2px;
display: inline-block; min-width: 40px; text-align: center; margin: 0px;
color:#fff !important; padding: 4px 8px; font-size:11px; background-color:#89b4fa; border-radius:3px;
display: inline-block; min-width: 55px; text-align: center; margin: 0px;
transition: all 0.3s ease; text-decoration: none !important; border: none;
cursor: pointer;
}
.menu_on{
color:#fff !important; padding: 2px 3px; font-size:9px; background-color:#5e9cff; border-radius:2px;
display: inline-block; min-width: 40px; text-align: center; margin: 0px;
color:#fff !important; padding: 4px 8px; font-size:11px; background-color:#5e9cff; border-radius:3px;
display: inline-block; min-width: 55px; text-align: center; margin: 0px;
transition: all 0.3s ease; text-decoration: none !important; border: none;
cursor: pointer;
}
@@ -392,7 +392,7 @@ function fn_setApprovalCnt(){
if("2".equals(lev)){
%>
<a href="#" class="menu menu_off" menuObjId="<%=menuObjid%>" style="background-color: #1e40af; color: #fff; padding: 3px 6px; font-size: 10px; border-radius: 3px; text-decoration: none; display: inline-block; min-width: 50px; text-align: center; margin-right: 4px;"><%=menuKorName%></a>
<a href="#" class="menu menu_off" menuObjId="<%=menuObjid%>" style="background-color: #1e40af; color: #fff; padding: 4px 8px; font-size: 11px; border-radius: 3px; text-decoration: none; display: inline-block; min-width: 55px; text-align: center; margin-right: 5px;"><%=menuKorName%></a>
<%
}
}

View File

@@ -463,7 +463,7 @@ function fn_openSetBomCopy(product_code){
* 구조등록 팝업
*/
function fn_openSetStructure(objId){
window.open("/partMng/setStructurePopupMainFS.do?objId="+objId, "", "width=1880, height=900, resizable=no");
window.open("/partMng/setStructurePopupMainFS.do?objId="+objId, "", "width=1880, height=900, resizable=yes");
}
/**
* 배포사유 입력 팝업

View File

@@ -10,33 +10,31 @@
<script>
$(function(){
if(isCreateBom()){
visibleChangeTalbe(false);
}
$('.select2').select2();
//0001055 - - 고객요청
//0001056 - - 자체설변
$('#CHANGE_TYPE option').not($('#CHANGE_TYPE').find('[value=""],[value=0001055],[value=0001056]')).remove();
//0001610 - - 파트삭제 test
//0001611 - - 파트추가
//0001626 - - 파트추가 real
//0001637 - - 파트삭제
//$('#CHANGE_OPTION option').not($('#CHANGE_OPTION').find('[value=""],[value=0001610],[value=0001611]')).remove(); //test
$('#CHANGE_OPTION option').not($('#CHANGE_OPTION').find('[value=""],[value=0001626],[value=0001637],[value=0001790]')).remove();
$('.select2').select2();
//Part 연결
$("#moveLeft").click(function(){
var rightPartArr = $(".partChks:checked", parent.frames['rightFrame'].document);
// Tabulator에서 선택된 행 데이터 가져오기
var leftPartNoObj = $("input[name=checkedPartNo]:checked", parent.frames['leftFrame'].document);
var leftPartChildObjId = leftPartNoObj.val();
var leftPartNo = $("input[name=checkedPartNo]:checked", parent.frames['leftFrame'].document).attr("data-PART_NO");
var leftPartNoQty = $("input[name=checkedPartNo]:checked", parent.frames['leftFrame'].document).attr("data-PART_NO_QTY");
var leftParentObjId = $("input[name=checkedPartNo]:checked", parent.frames['leftFrame'].document).attr("data-OBJID");
var leftPartLastObjId = $("input[name=checkedPartNo]:checked", parent.frames['leftFrame'].document).attr("data-LAST_PART_OBJID");
var leftQtyParObjId = $("input[name=checkedPartNo]:checked", parent.frames['leftFrame'].document).attr("data-PART_OBJID");
if(leftPartNoObj.length === 0){
// Tabulator 방식: 라디오가 선택되지 않았을 수 있으므로 체크
var leftPartChildObjId = null;
var leftPartNo = null;
var leftPartNoQty = null;
var leftParentObjId = null;
var leftPartLastObjId = null;
var leftQtyParObjId = null;
} else {
var leftPartChildObjId = leftPartNoObj.val();
var leftPartNo = leftPartNoObj.attr("data-PART_NO");
var leftPartNoQty = leftPartNoObj.attr("data-PART_NO_QTY");
var leftParentObjId = leftPartNoObj.attr("data-OBJID");
var leftPartLastObjId = leftPartNoObj.attr("data-LAST_PART_OBJID");
var leftQtyParObjId = leftPartNoObj.attr("data-PART_OBJID");
}
//같은 Part를 연결한건지 체크
var isSamePart = false;
@@ -89,19 +87,6 @@ $(function(){
}
}
if(!fnc_validate2('form1')){
return;
}
//0001611 - - 파트추가
//0001610 - - 파트삭제
if(!isCreateBom() && '0001626' != $('#CHANGE_OPTION').val()){
alert('설변사유는 파트추가만 가능합니다.');
$('#CHANGE_OPTION').val('0001626');
$('.select2').select2();
return;
}
fn_relatePartInfo(leftPartNoObj.val(), rightCheckedArr, leftPartNoQty, leftPartLastObjId, leftPartChildObjId, leftQtyParObjId);
});
//end of Part 연결
@@ -115,23 +100,6 @@ $(function(){
var leftParentObjId = $("input[name=checkedPartNo]:checked", parent.frames['leftFrame'].document).attr("data-PARENT_OBJID");
var leftPartLastObjId = $("input[name=checkedPartNo]:checked", parent.frames['leftFrame'].document).attr("data-LAST_PART_OBJID");
/* alert('leftPartNo ->'+leftPartNo+".");
alert('leftParentObjId ->'+leftParentObjId+".");
alert('leftParentPartNo ->'+leftParentPartNo+"."); */
if(!fnc_validate2('form1')){
return;
}
//0001611 - - 파트추가
//0001610 - - 파트삭제
if(!isCreateBom() && '0001637' != $('#CHANGE_OPTION').val()){
alert('설변사유는 파트삭제만 가능합니다.');
$('#CHANGE_OPTION').val('0001637');
$('.select2').select2();
return;
}
fn_deletePartRelateInfo(leftPartNoObj.val(), leftPartLastObjId, leftParentPartNo, leftParentObjId, leftPartChildObjId);
});
//end of 연결된 part 삭제
@@ -152,10 +120,6 @@ $(function(){
//alert("leftPartObjid::"+leftPartObjid);
var leftPartBomQtyObjId = $("input[name=checkedPartNo]:checked", parent.frames['leftFrame'].document).attr("data-OBJID");
if(!fnc_validate2('form1')){
return;
}
if(0 == leftPartNoList.length){
alert("선택된 파트가 없습니다.");
return false;
@@ -177,10 +141,6 @@ $(function(){
});
function isCreateBom(){
return '${info.STATUS}' == 'create';
}
//1레벨에 같은 Part No가 등록되어있는지 확인.
function fn_checkSameTopPartNo(rightCheckedArr){
var result = false;
@@ -204,11 +164,6 @@ function fn_checkSameTopPartNo(rightCheckedArr){
}
//end of 1레벨에 같은 Part No가 등록되어있는지 확인.
function resetChange(){
$('#CHANGE_TYPE').val();
$('#CHANGE_OPTION').val();
}
//구조 연결 해제
function fn_deletePartRelateInfo(leftObjId, leftPartLastObjId, leftParentPartNo, leftParentObjId, leftPartChildObjId){
if(leftObjId == null){
@@ -219,12 +174,10 @@ function fn_deletePartRelateInfo(leftObjId, leftPartLastObjId, leftParentPartNo,
if(!confirm("연결 해제하시겠습니까?")) return;
$.ajax({
//url: "/partMng/deletePartRelateInfo.do",
url: "/partMng/deleteStatusPartRelateInfo.do", //231211 위에서 변경
url: "/partMng/deleteStatusPartRelateInfo.do",
method: 'post',
data: {"OBJID":$("#objId").val(), "leftObjId":leftObjId, "partObjId":leftPartLastObjId, "BOM_REPORT_OBJID":$("#objId").val()
, "leftPartChildObjId":leftPartChildObjId, "leftParentPartNo":leftParentPartNo, "leftParentObjId":leftParentObjId,
"CHANGE_TYPE":$('#CHANGE_TYPE').val(), "CHANGE_OPTION":$('#CHANGE_OPTION').val() },
, "leftPartChildObjId":leftPartChildObjId, "leftParentPartNo":leftParentPartNo, "leftParentObjId":leftParentObjId},
dataType: 'json',
success: function(data) {
if(data.result){
@@ -258,8 +211,7 @@ function fn_relatePartInfo(leftObjId, rightCheckedArr, leftPartNoQty, leftPartLa
url: "/partMng/relatePartInfo.do",
method: 'post',
data: {"leftObjId":leftObjId,"leftPartNoQty":leftPartNoQty, "OBJID":$("#objId").val(), "rightCheckedArr":rightCheckedArr, "partObjId":leftPartLastObjId, "BOM_REPORT_OBJID":$("#objId").val(),
"leftPartChildObjId":leftPartChildObjId, "leftQtyParObjId":leftQtyParObjId,
"CHANGE_TYPE":$('#CHANGE_TYPE').val(), "CHANGE_OPTION":$('#CHANGE_OPTION').val()},
"leftPartChildObjId":leftPartChildObjId, "leftQtyParObjId":leftQtyParObjId},
dataType: 'json',
async:false,
success: function(data) {
@@ -289,22 +241,13 @@ function fn_relatePartInfo(leftObjId, rightCheckedArr, leftPartNoQty, leftPartLa
}
//end of 구조 연결
function visibleChangeTalbe(visible){
if(visible){
$("#changeTable").show();
}else{
$("#changeTable").hide();
}
$('#CHANGE_TYPE,#CHANGE_OPTION').attr('required', visible);
}
//구조 연결 변경
function fn_changeRelatePartInfo(objId,rightObjId,leftObjId,leftPartNoQty,leftPartChildObjId,leftPartObjid,rightPartNo,rightPartRev){
$.ajax({
url: "/partMng/changeRelatePartInfo.do",
method: 'post',
data: {"rightObjId":rightObjId, "OBJID":objId,"BOM_REPORT_OBJID":$("#objId").val(),"CHANGE_TYPE":$('#CHANGE_TYPE').val(),
"CHANGE_OPTION":$('#CHANGE_OPTION').val(), "leftObjId":leftObjId,"leftPartNoQty":leftPartNoQty,"leftPartChildObjId":leftPartChildObjId,
data: {"rightObjId":rightObjId, "OBJID":objId,"BOM_REPORT_OBJID":$("#objId").val(),
"leftObjId":leftObjId,"leftPartNoQty":leftPartNoQty,"leftPartChildObjId":leftPartChildObjId,
"leftPartObjid":leftPartObjid, "rightPartNo":rightPartNo, "rightPartRev":rightPartRev},
dataType: 'json',
async:false,
@@ -329,42 +272,8 @@ function fn_changeRelatePartInfo(objId,rightObjId,leftObjId,leftPartNoQty,leftPa
<body class="backcolor" style="border:border:1px solid #ccc;">
<form name="form1" id="form1" action="" method="post">
<input type="hidden" name="objId" id="objId" value="${param.objId}" />
<!--
<br><br><br><br><br>
<br><br><br><br><br><br><br>
-->
<table class="pmsPopupForm" id="changeTable">
<colgroup>
<!--
<col width="15%">
-->
<col width="*">
</colgroup>
<tr>
<td class="input_title" >
<label for="">설변구분</label>
</td>
</tr>
<tr>
<td class="input_sub_title" colspan="">
<select name="CHANGE_TYPE" id="CHANGE_TYPE" class="select2" type="select" required reqTitle="설변구분"><option value="">선택</option>${code_map.CHANGE_TYPE}</select>
</td>
</tr>
<tr>
<td class="input_title">
<label for="">설변사유</label>
</td>
</tr>
<tr>
<td class="input_sub_title">
<select name="CHANGE_OPTION" id="CHANGE_OPTION" class="select2" type="select" required reqTitle="설변사유"><option value="">선택</option>${code_map.CHANGE_OPTION}</select>
</td>
</tr>
</table>
<br>
<div id="structurePopupBtnW" style="padding-top:0px;">
<div id="structurePopupBtnW" style="padding-top:20px;">
<input type="button" value="변경" class="plm_btns" id="moveChange">
<br>
<input type="button" value="<<" class="plm_btns" id="moveLeft" style="margin-left:0px;">

View File

@@ -1,7 +1,7 @@
<%
java.util.Map map = (java.util.HashMap)request.getAttribute("info");
%>
<frameset rows="6%, 88%, 6%;" border="0" noresize>
<frameset rows="100px, *, 50px" border="0" noresize>
<frame src="/partMng/structureHeaderPopup.do">
<frame src="/partMng/structureBottomPopupFS.do?objId=<%=com.pms.common.utils.CommonUtils.checkNull(map.get("OBJID"))%>">
<frame src="/partMng/structureBtnAreaPopup.do">

View File

@@ -2,30 +2,13 @@
<%@ page import="com.pms.common.utils.*"%>
<%@ page import="java.util.*" %>
<%@include file= "/init.jsp" %>
<%
ArrayList TREELIST = new ArrayList();
TREELIST = (ArrayList)request.getAttribute("tree");
int z = 0;
int Maxlevel = 0;
//int[] levelarr;
int[] levelarr = new int[TREELIST.size()];
//if(TREELIST != null){
//levelarr = new int[TREELIST.size()];
for(int i=0; i< TREELIST.size(); i++){
HashMap treemap = (HashMap)TREELIST.get(i);
int level = Integer.parseInt(CommonUtils.checkNull(treemap.get("LEVEL")));
// System.out.println("level : "+level);
levelarr[i] = level;
}
if(null != TREELIST && 0 < TREELIST.size()){
HashMap MaxlevelMap = (HashMap)TREELIST.get(0);
Maxlevel = Integer.parseInt(CommonUtils.checkNull(MaxlevelMap.get("MAX_LEVEL")));
}
//}
%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title><%=Constants.SYSTEM_NAME%></title>
<link href="/css/tabulator/tabulator.min.css" rel="stylesheet">
<script type="text/javascript" src="/js/tabulator.min.js"></script>
<style>
::-webkit-scrollbar {
width: 10px;
@@ -33,172 +16,358 @@ int[] levelarr = new int[TREELIST.size()];
}
#structureTableWrap1 {
top: 56px;
width: 99%;
}
#structureName {
margin-bottom: 10px;
font-weight: bold;
}
#structureName2 {
margin-bottom: 10px;
font-size: 12px;
color: #666;
}
/* Tabulator 커스텀 스타일 */
.tabulator-row.level-1 { background-color: #fde9d9 !important; }
.tabulator-row.level-2 { background-color: #daeef3 !important; }
.tabulator-row.level-3 { background-color: #e4dfec !important; }
.tabulator-row.level-4 { background-color: #ebf1de !important; }
.tabulator-row.level-5 { background-color: #f2f2f2 !important; }
.tabulator-row.level-6 { background-color: #f2dcdb !important; }
.tabulator-row.level-7 { background-color: #eeece1 !important; }
.tabulator-row.level-8 { background-color: #dce6f1 !important; }
.tabulator-row.level-9 { background-color: #FFFFEB !important; }
.tabulator-row.level-10 { background-color: #ffffff !important; }
.file_icon, .file_empty_icon {
display: inline-block;
width: 20px;
height: 20px;
line-height: 20px;
text-align: center;
cursor: pointer;
font-size: 16px;
}
.file_icon {
color: #4CAF50;
}
.file_icon::before {
content: '📄';
}
.file_empty_icon {
color: #ccc;
}
.file_empty_icon::before {
content: '○';
}
</style>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title><%=Constants.SYSTEM_NAME%></title>
<script>
var _tabulGrid;
var selectedRowData = null;
$(function(){
if('${param.readonly}' == 'readonly'){
$("#structureName2").hide();
}
$(".qty").keyup(function(e){
var key = e.keyCode;
if(key == 13){
var leftObjId = $(this).attr("data-CHILD_OBJID");
var leftQtyParObjId = $(this).attr("data-PART_OBJID");
var leftPartLastObjId = $(this).attr("data-LAST_PART_OBJID");
var leftPartNo = $(this).attr("data-PART_NO");
var qty = $(this).val();
/* var isNumeric = $.isNumeric(qty);
if(!isNumeric){
Swal.fire("숫자만 입력 가능합니다. 수량을 1개로 조정합니다.");
$(this).val(1);
fn_saveQty(leftObjId, 1);
return;
} */
fn_saveQty(leftObjId, qty, leftPartNo, leftQtyParObjId, leftPartLastObjId);
}
});
$("#btnExcel").click(function() {
fn_excel();
});
//첨부팝업
$(".File").click(function(){
var popup_width = 800;
var popup_height = 335;
// Tabulator 초기화
fn_initGrid();
});
var objId = $(this).attr("data-OBJID");
var docType =$(this).attr("data-docType");
var docTypeName = $(this).attr("data-docTypeName");
var params = "?targetObjId="+objId+"&docType="+docType+"&docTypeName="+docTypeName;
var url = "/projectConcept/FileRegistPopup.do"+params;
fn_centerPopup(popup_width, popup_height, url);
// Tabulator 그리드 초기화
function fn_initGrid() {
var maxLevel = ${empty MAXLEV ? 1 : MAXLEV};
// 컬럼 정의
var columns = [
{
headerHozAlign: 'center',
hozAlign: 'center',
width: 60,
title: '선택',
field: 'RADIO',
formatter: function(cell) {
var rowData = cell.getData();
return '<input type="radio" name="checkedPartNo" value="' + rowData.CHILD_OBJID + '" ' +
'data-OBJID="' + rowData.OBJID + '" ' +
'data-PART_NO="' + rowData.PART_NO + '" ' +
'data-PARENT_PART_NO="' + rowData.PARENT_PART_NO + '" ' +
'data-PART_NO_QTY="' + rowData.LAST_PART_OBJID + '" ' +
'data-PARENT_PARTS="' + rowData.PARENT_PARTS + '" ' +
'data-LAST_PART_OBJID="' + rowData.LAST_PART_OBJID + '" ' +
'data-PARENT_OBJID="' + rowData.PARENT_OBJID + '" ' +
'data-PART_OBJID="' + rowData.PART_OBJID + '" ' +
'data-BOM_LAST_PART_OBJID="' + rowData.BOM_LAST_PART_OBJID + '">';
},
cellClick: function(e, cell) {
var radio = $(e.target);
if(radio.is(':radio')) {
selectedRowData = cell.getData();
// 다른 라디오 버튼 해제
$('input[name=checkedPartNo]').not(radio).prop('checked', false);
}
}
},
{
headerHozAlign: 'center',
hozAlign: 'center',
width: 100,
title: '시스템상태',
field: 'STATUS'
}
];
// 수준 컬럼 그룹 (헤더는 하나, 서브 컬럼은 여러개)
var levelColumns = [];
for(var i = 1; i <= maxLevel; i++) {
levelColumns.push({
headerHozAlign: 'center',
hozAlign: 'center',
width: 30,
title: i,
field: 'LEVEL_' + i,
formatter: function(cell) {
return cell.getValue() === '*' ? '*' : '';
}
});
}
columns.push({
title: '수준',
headerHozAlign: 'center',
columns: levelColumns
});
$(".seq").keyup(function(e){
var key = e.keyCode;
if(key == 13){
var leftObjId = $(this).attr("data-CHILD_OBJID");
var leftPartNo = $(this).attr("data-PART_NO");
var seq = $(this).val();
var partNo = $(this).attr("data-PART_NO");
var isNumeric = $.isNumeric(seq);
if(!isNumeric){
Swal.fire("숫자만 입력 가능합니다.");
$(this).val(1);
fn_saveSeq(leftObjId, 1,partNo);
return;
// 나머지 컬럼 추가
columns.push(
{
headerHozAlign: 'center',
hozAlign: 'left',
width: 150,
title: '품번',
field: 'PART_NO',
formatter: function(cell) {
var rowData = cell.getData();
return '<a href="#" onclick="openPartMngPopup(\'' +
rowData.PART_OBJID + '\',\'' +
rowData.LAST_PART_OBJID + '\',\'' +
rowData.CHILD_OBJID + '\',\'' +
rowData.BOM_LAST_PART_OBJID + '\');">' +
rowData.PART_NO + '</a>';
}
fn_saveSeq(leftObjId, seq,partNo);
},
{
headerHozAlign: 'center',
hozAlign: 'left',
width: 200,
title: '품명',
field: 'PART_NAME'
},
{
headerHozAlign: 'center',
hozAlign: 'center',
width: 60,
title: '수량',
field: 'QTY_TEMP',
editor: function(cell, onRendered, success, cancel) {
var rowData = cell.getData();
if(rowData.STATUS === 'adding') {
var input = $('<input type="text" style="width:100%; text-align:center;" maxlength="3"/>');
input.val(cell.getValue() || '0');
input.on('keydown', function(e) {
if(e.keyCode === 13) {
success(input.val());
} else if(e.keyCode === 27) {
cancel();
}
});
input.on('blur', function() {
success(input.val());
});
return input[0];
}
return false;
},
cellEdited: function(cell) {
var rowData = cell.getData();
fn_saveQty(rowData.CHILD_OBJID, cell.getValue(), rowData.PART_OBJID);
}
},
{
headerHozAlign: 'center',
hozAlign: 'center',
width: 100,
title: '항목 수량',
field: 'QTY'
},
{
headerHozAlign: 'center',
hozAlign: 'center',
width: 60,
title: '3D',
field: 'CU01_CNT',
formatter: function(cell) {
var rowData = cell.getData();
var isEmpty = cell.getValue() == 0;
return '<a href="#" class="File file_' + (isEmpty ? 'empty_' : '') + 'icon" ' +
'data-OBJID="' + rowData.LAST_PART_OBJID + '" ' +
'data-docType="3D_CAD" ' +
'data-docTypeName="3D CAD 첨부파일"></a>';
}
},
{
headerHozAlign: 'center',
hozAlign: 'center',
width: 60,
title: '2D',
field: 'CU02_CNT',
formatter: function(cell) {
var rowData = cell.getData();
var isEmpty = cell.getValue() == 0;
return '<a href="#" class="File file_' + (isEmpty ? 'empty_' : '') + 'icon" ' +
'data-OBJID="' + rowData.LAST_PART_OBJID + '" ' +
'data-docType="2D_DRAWING_CAD" ' +
'data-docTypeName="2D(Drawing) CAD 첨부파일"></a>';
}
},
{
headerHozAlign: 'center',
hozAlign: 'center',
width: 60,
title: 'PDF',
field: 'CU03_CNT',
formatter: function(cell) {
var rowData = cell.getData();
var isEmpty = cell.getValue() == 0;
return '<a href="#" class="File file_' + (isEmpty ? 'empty_' : '') + 'icon" ' +
'data-OBJID="' + rowData.LAST_PART_OBJID + '" ' +
'data-docType="2D_PDF_CAD" ' +
'data-docTypeName="2D(PDF) CAD 첨부파일"></a>';
}
},
{
headerHozAlign: 'center',
hozAlign: 'left',
width: 100,
title: '재료',
field: 'MATERIAL'
},
{
headerHozAlign: 'center',
hozAlign: 'left',
width: 120,
title: '열처리경도',
field: 'HEAT_TREATMENT_HARDNESS'
},
{
headerHozAlign: 'center',
hozAlign: 'left',
width: 120,
title: '열처리방법',
field: 'HEAT_TREATMENT_METHOD'
},
{
headerHozAlign: 'center',
hozAlign: 'left',
width: 120,
title: '표면처리',
field: 'SURFACE_TREATMENT'
},
{
headerHozAlign: 'center',
hozAlign: 'left',
width: 120,
title: '공급업체',
field: 'MAKER'
},
{
headerHozAlign: 'center',
hozAlign: 'center',
width: 120,
title: '범주 이름',
field: 'PART_TYPE_TITLE'
}
);
_tabulGrid = new Tabulator("#structureGrid", {
layout: "fitColumns",
height: "650px",
pagination: false,
columns: columns,
rowFormatter: function(row) {
var data = row.getData();
$(row.getElement()).addClass('level-' + data.LEVEL);
},
ajaxURL: "/partMng/getStructureTreeJson.do",
ajaxParams: {
objId: "${info.OBJID}"
},
ajaxResponse: function(url, params, response) {
// 서버 응답 데이터 가공
var processedData = [];
if(response && response.length > 0) {
var maxLevel = response[0].MAX_LEVEL || 1;
response.forEach(function(item) {
// Level 표시를 위한 동적 필드 생성
for(var i = 1; i <= maxLevel; i++) {
item['LEVEL_' + i] = (item.LEVEL == i) ? '*' : '';
}
processedData.push(item);
});
}
return processedData;
}
});
/*
$(".qty").blur(function(){
// 파일 아이콘 클릭 이벤트 (동적으로 생성된 요소)
$(document).on('click', '.File', function(e) {
e.preventDefault();
var popup_width = 800;
var popup_height = 335;
var objId = $(this).attr("data-OBJID");
var qty = $(this).val();
fn_saveQty(objId, qty);
var docType = $(this).attr("data-docType");
var docTypeName = $(this).attr("data-docTypeName");
var params = "?targetObjId=" + objId + "&docType=" + docType + "&docTypeName=" + docTypeName;
var url = "/projectConcept/FileRegistPopup.do" + params;
fn_centerPopup(popup_width, popup_height, url);
});
*/
$(document).ready(function(){
$(".dataTr").each(function(i){
var lev = $(this).attr("data-LEVEL");
if(lev == 1){
$(this).css("background-color", "#fde9d9");
}else if(lev == 2){
$(this).css("background-color", "#daeef3");
}else if(lev == 3){
$(this).css("background-color", "#e4dfec");
}else if(lev == 4){
$(this).css("background-color", "#ebf1de");
}else if(lev == 5){
$(this).css("background-color", "#f2f2f2");
}else if(lev == 6){
$(this).css("background-color", "#f2dcdb");
}else if(lev == 7){
$(this).css("background-color", "#eeece1");
}else if(lev == 8){
$(this).css("background-color", "#dce6f1");
}else if(lev == 9){
$(this).css("background-color", "#FFFFEB");
}else if(lev == 10){
$(this).css("background-color", "#ffffff");
}
});
});
});
}
function fn_saveQty(leftObjId,qty, leftQtyParObjId){
// 수량 저장
function fn_saveQty(leftObjId, qty, leftQtyParObjId){
$.ajax({
url: "/partMng/structureQtySave.do",
method: 'post',
//data: {"CHILD_OBJID":leftObjId,"QTY":qty}, //231211 아래로 변경(설변)
data: {"BOM_REPORT_OBJID":"${info.OBJID}","CHILD_OBJID":leftObjId,"QTY_TEMP":qty, "OBJID":leftQtyParObjId},
data: {
"BOM_REPORT_OBJID": "${info.OBJID}",
"CHILD_OBJID": leftObjId,
"QTY_TEMP": qty,
"OBJID": leftQtyParObjId
},
dataType: 'json',
success: function(data) {
if(data.result){
Swal.fire('저장하였습니다.');
_tabulGrid.replaceData(); // 그리드 새로고침
}
}
, error: function(jqxhr, status, error){
Swal.fire(jqxhr.statusText + ", " + status + ", " + error);
Swal.fire(jqxhr.status);
Swal.fire(jqxhr.responseText);
},
error: function(jqxhr, status, error){
Swal.fire('저장 중 오류가 발생했습니다.');
}
});
}
function fn_saveSeq(leftObjId,seq,partNo){
var foucs = "seq_"+partNo;
$.ajax({
url: "/partMng/structureSeqSave.do",
method: 'post',
data: {"BOM_REPORT_OBJID":"${info.OBJID}","CHILD_OBJID":leftObjId,"SEQ":seq},
dataType: 'json',
async : false,
success: function(data) {
Swal.fire('변경되었습니다');
var url = window.location.href;
url = url + "&foucs="+foucs;
location.href = url;
//Swal.fire("#"+seq+"_"+partNo);
//$("#"+seq+"_"+partNo).focus();
//parent.frames['leftFrame'].reload();
}
, error: function(jqxhr, status, error){
Swal.fire(jqxhr.statusText + ", " + status + ", " + error);
Swal.fire(jqxhr.status);
Swal.fire(jqxhr.responseText);
}
});
}
// Part 상세 팝업
function openPartMngPopup(objId, lastPartObjid, childObjid, BOM_LAST_PART_OBJID){
var popup_width = 800;
var popup_height = 500;
var popup_height = 500;
var hiddenForm = document.hiddenForm;
var url = "/partMng/partMngFormPopUp.do";
@@ -213,20 +382,54 @@ function openPartMngPopup(objId, lastPartObjid, childObjid, BOM_LAST_PART_OBJID)
hiddenForm.action = url;
hiddenForm.OBJID.value = fnc_checkNull(BOM_LAST_PART_OBJID, objId);
if('working' == '${param.actionType}')
hiddenForm.OBJID.value = lastPartObjid; //231211 최신 파트로 조회
hiddenForm.OBJID.value = lastPartObjid;
hiddenForm.LAST_PART_OBJID.value = lastPartObjid;
hiddenForm.CHILD_OBJID.value = childObjid;
hiddenForm.target = target;
hiddenForm.submit();
}
// Excel 다운로드
function fn_excel() {
document.form1.actionType.value = "excel";
var form = document.form1;
form.action="/partMng/structurePopupLeft.do";
form.action = "/partMng/structurePopupLeft.do";
form.submit();
}
// 선택된 행 데이터 가져오기 (Center 프레임에서 사용)
function getSelectedRowData() {
return selectedRowData;
}
// 필터 적용 함수
function fn_applyFilter() {
var partNo = $("#filterPartNo").val().trim();
var partName = $("#filterPartName").val().trim();
// 빈 값이 아닌 필터만 추가
var filters = [];
if(partNo) {
filters.push({field: "PART_NO", type: "like", value: partNo});
}
if(partName) {
filters.push({field: "PART_NAME", type: "like", value: partName});
}
// 필터가 있으면 적용, 없으면 전체 표시
if(filters.length > 0) {
_tabulGrid.setFilter(filters);
} else {
_tabulGrid.clearFilter();
}
}
// 필터 초기화 함수
function fn_resetFilter() {
$("#filterPartNo").val("");
$("#filterPartName").val("");
_tabulGrid.clearFilter();
}
</script>
</head>
<body class="backcolor">
@@ -240,134 +443,20 @@ function fn_excel() {
<input type="hidden" name="objid" id="objid" value="${info.OBJID}" />
<input type="hidden" name="objId" id="objId" value="${info.OBJID}" />
<input type="hidden" name="actionType" value="" />
<div id="structureTableWrap1" style="width: 99%;">
<div id="structureName">(${info.CUSTOMER_NAME}_${info.CUSTOMER_PROJECT_NAME}_${info.UNIT_NAME})_${info.REV}<input type="button" value="Excel Download" class="plm_btns structure_btn" id="btnExcel" style="float:right;"></div>
<div id="structureName2"><font size="2px">※수량 변경 후, 엔터치시면 저장됩니다.(신규 추가 파트만 가능)</font></div>
<div class="plm_scroll_table" style="height:90%;overflow-y:scroll;">
<table id="structurePopupTableHead" class="plm_table">
<colgroup>
<% if(Maxlevel == 0){%>
<col width="25px" />
<%}else{%>
<col width="25px" />
<%}
for(int i=0; i< Maxlevel; i++){%>
<col width="25px" />
<%}%>
<col width="130px" />
<col width="160px" />
<col width="50px" />
<col width="30px" /> <!-- 3D -->
<col width="30px" /> <!-- 2D -->
<col width="30px" /> <!-- 2D PDF -->
<col width="70px" /> <!-- Material -->
<col width="190px" /> <!-- SPEC. -->
<col width="90px" /> <!-- MAKER. -->
<col width="70px" /> <!-- Revision -->
<col width="75px" /> <!-- EO no -->
<col width="75px" /> <!-- EO Date -->
<col width="70px" /> <!-- 부품 유향 -->
<!-- <col width="15%" /> -->
</colgroup>
<tr class="plm_thead">
<td colspan="${MAXLEV + 1}">Level</td>
<td>품번</td>
<td>품명</td>
<td>수량</td>
<td>3D</td>
<td>2D</td>
<td>PDF</td>
<td>재질</td>
<td>사양(규격)</td>
<td>MAKER</td>
<td>Revision</td>
<td>EO No</td>
<td>EO Date</td>
<td>PART 구분</td>
<!-- <td>순번</td> -->
</tr>
</table>
<table id="structurePopupTable2" class="plm_table">
<colgroup>
<% if(Maxlevel == 0){%>
<col width="25px" />
<%}else{%>
<col width="25px" />
<%}
for(int i=0; i< Maxlevel; i++){%>
<col width="25px" />
<%}%>
<col width="130px" />
<col width="160px" />
<col width="50px" />
<col width="30px" /> <!-- 3D -->
<col width="30px" /> <!-- 2D -->
<col width="30px" /> <!-- 2D PDF -->
<col width="70px" /> <!-- Material -->
<col width="190px" /> <!-- SPEC. -->
<col width="90px" /> <!-- MAKER. -->
<col width="70px" /> <!-- Revision -->
<col width="75px" /> <!-- EO no -->
<col width="75px" /> <!-- EO Date -->
<col width="70px" /> <!-- 부품 유향 -->
<!-- <col width="15%" /> -->
</colgroup>
<c:choose>
<c:when test="${!empty tree}">
<c:forEach var="item" items="${tree}" varStatus="status">
<tr class="dataTr" data-LEVEL="${item.LEVEL}">
<td><input type="radio" name="checkedPartNo" value="${item.CHILD_OBJID}" data-OBJID="${item.OBJID}" data-PART_NO="${item.PART_NO}"
data-PARENT_PART_NO="${item.PARENT_PART_NO}" data-PART_NO_QTY="${item.LAST_PART_OBJID}"
data-PARENT_PARTS="${item.PARENT_PARTS}" data-LAST_PART_OBJID="${item.LAST_PART_OBJID}"
data-PARENT_OBJID="${item.PARENT_OBJID}" data-PART_OBJID="${item.PART_OBJID}"
data-BOM_LAST_PART_OBJID="${item.BOM_LAST_PART_OBJID}"
>
</td>
<%
for(int i=0; i< Maxlevel; i++){
if(levelarr[z] == (i+1)){%>
<td>*</td>
<% }else{ %>
<td> </td>
<% }
}
z++;
%>
<td style="text-align:left !important;" id="lpadpartno"><pre><a href="#" onclick="openPartMngPopup('${item.PART_OBJID}','${item.LAST_PART_OBJID}','${item.CHILD_OBJID}','${item.BOM_LAST_PART_OBJID}');">${item.PART_NO}</a></pre></td>
<td class="align_l">${item.PART_NAME}</td>
<c:if test="${item.STATUS ne 'adding'}">
<td class="align_c">${item.QTY_TEMP}</td>
</c:if>
<c:if test="${item.STATUS eq 'adding'}">
<td class="align_c"><input type="text" name="qty_${item.PART_NO}" id="qty_${item.PART_NO}" class="qty" style="width:40px; text-align:center;" maxlength="3" value="${empty item.QTY_TEMP?'0':item.QTY_TEMP}" data-CHILD_OBJID="${item.CHILD_OBJID}" data-PART_NO="${item.PART_NO}" data-PARENT_PART_NO="${item.PARENT_PART_NO}" ></td>
</c:if>
<td><a href="#" class="File file_${item.CU01_CNT eq 0?'empty_':''}icon" data-OBJID="${item.LAST_PART_OBJID}" data-docType="3D_CAD" data-docTypeName="3D CAD 첨부파일"></a></td>
<td><a href="#" class="File file_${item.CU02_CNT eq 0?'empty_':''}icon" data-OBJID="${item.LAST_PART_OBJID}" data-docType="2D_DRAWING_CAD" data-docTypeName="2D(Drawing) CAD 첨부파일"></a></td>
<td><a href="#" class="File file_${item.CU03_CNT eq 0?'empty_':''}icon" data-OBJID="${item.LAST_PART_OBJID}" data-docType="2D_PDF_CAD" data-docTypeName="2D(PDF) CAD 첨부파일"></a></td>
<td title="${item.MATERIAL}" class="align_l" style="text-align: left; padding-left: 10px;">${item.MATERIAL}</td><!-- 재질 -->
<td title="${item.SPEC}" class="align_l" style="text-align: left; padding-left: 10px;">${item.SPEC}</td><!-- SPEC -->
<td title="${item.MAKER}" class="align_l" style="text-align: left; padding-left: 10px;">${item.MAKER}</td><!-- SPEC -->
<td title="${item.REVISION}" class="align_l" style="text-align: left; padding-left: 10px;">${item.REVISION}</td><!-- REVISION -->
<td title="${item.EO_NO}" class="align_c">${item.EO_NO}</td><!-- REVISION -->
<td title="${item.EO_DATE}" class="align_c">${item.EO_DATE}</td><!-- REVISION -->
<td title="${item.PART_TYPE_TITLE}" class="align_c">${item.PART_TYPE_TITLE}</td><!-- SIZE -->
</tr>
</c:forEach>
</c:when>
<c:otherwise>
<tr>
<td colspan="5" align="center">등록된 구조정보가 없습니다.</td>
</tr>
</c:otherwise>
</c:choose>
</table>
</div>
</div>
<!-- 필터 값을 저장하기 위한 hidden 필드 (top frame에서 값 전달) -->
<input type="hidden" id="filterPartNo" />
<input type="hidden" id="filterPartName" />
<div id="structureTableWrap1">
<div id="structureName">
(${info.CUSTOMER_NAME}_${info.CUSTOMER_PROJECT_NAME}_${info.UNIT_NAME})_${info.REV}
<input type="button" value="Excel Download" class="plm_btns structure_btn" id="btnExcel" style="float:right;">
</div>
<div id="structureName2">
<font size="2px">※수량 변경 후, 엔터치시면 저장됩니다.(신규 추가 파트만 가능)</font>
</div>
<div id="structureGrid"></div>
</div>
</form>
</body>
</html>
</html>

View File

@@ -8,6 +8,8 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title><%=Constants.SYSTEM_NAME%></title>
<link href="/css/tabulator/tabulator.min.css" rel="stylesheet">
<script type="text/javascript" src="/js/tabulator.min.js"></script>
<style>
::-webkit-scrollbar {
width: 10px;
@@ -15,6 +17,31 @@
#structureTableWrap2 .structure_btn {
top: 25px;
}
/* Tabulator 커스텀 스타일 */
.tabulator {
border: 1px solid #ddd;
}
.tabulator .tabulator-header {
background-color: #f0f0f0;
border-bottom: 2px solid #ddd;
}
.tabulator .tabulator-header .tabulator-col {
background-color: #f0f0f0;
border-right: 1px solid #ddd;
}
.tabulator .tabulator-tableHolder .tabulator-table {
background-color: #fff;
}
.tabulator .tabulator-row {
border-bottom: 1px solid #eee;
}
.tabulator .tabulator-row:hover {
background-color: #f5f5f5;
}
.tabulator .tabulator-cell {
padding: 8px;
border-right: 1px solid #eee;
}
</style>
<script>
$(function(){
@@ -72,47 +99,84 @@ $(function(){
fnc_productUPGNEWList("","${resultMap.PRODUCT_MGMT_SPEC}","search_product_mgmt_upg", "");
$('.select2').select2();
// Tabulator 초기화
fn_initRightGrid();
});
function fn_searchPart(){
$("#structurePopupTable2").empty();
var _rightGrid;
function fn_initRightGrid(){
var columns = [
{
formatter: "rowSelection",
titleFormatter: "rowSelection",
headerHozAlign: 'center',
hozAlign: 'center',
width: 50,
headerSort: false,
cellClick: function(e, cell){
e.stopPropagation();
}
},
{
headerHozAlign: 'center',
hozAlign: 'left',
width: 150,
title: '품번',
field: 'PART_NO',
formatter: function(cell) {
var rowData = cell.getData();
return '<a href="#" onclick="openPartMngPopup(\'' + rowData.OBJID + '\');">' + rowData.PART_NO + '</a>';
}
},
{
headerHozAlign: 'center',
hozAlign: 'left',
width: 180,
title: '품명',
field: 'PART_NAME'
},
{
headerHozAlign: 'center',
hozAlign: 'left',
width: 200,
title: '규격',
field: 'SPEC'
},
{
headerHozAlign: 'center',
hozAlign: 'left',
width: 120,
title: 'MAKER',
field: 'MAKER'
}
];
_rightGrid = new Tabulator("#rightPartGrid", {
layout: "fitColumns",
height: "600px",
pagination: false,
columns: columns,
placeholder: "조회된 부품이 없습니다.",
data: []
});
}
function fn_searchPart(){
$.ajax({
url: "/partMng/getPartMngList_ajax.do",
method: 'post',
data: $("#form1").serialize(),
dataType: 'json',
success: function(data) {
var trHtml = "";
trHtml += " <colgroup>";
trHtml += " <col width='5%' />";
trHtml += " <col width='30%' />";
trHtml += " <col width='30%' />";
trHtml += " <col width='45%' />";
trHtml += " <col width='15%' />";
trHtml += " </colgroup>";
if(data.length > 0){
$.each(data, function(i){
trHtml += " <tr>";
//trHtml += " <input type=\"checkbox\" name=\"partChks\" class=\"partChks\" value=\""+data[i].OBJID+"\" data-PART_TYPE='"+data[i].PART_TYPE+"' data-PART_NO='"+data[i].PART_NO+"' ></td>";
trHtml += " <td><input type=\"checkbox\" name=\"partChks\" class=\"partChks\" value=\""+data[i].OBJID+"\" data-PART_TYPE='"+data[i].PART_TYPE+"' data-PART_NO='"+data[i].PART_NO+"' data-PART_REV='"+data[i].REVISION+"'></td>";
trHtml += " <td class='align_l' title='"+data[i].PART_NO+"'><a href='#' onclick=\"openPartMngPopup('"+data[i].OBJID+"');\">"+data[i].PART_NO+"</a></td>";
trHtml += " <td class='align_l' title='"+data[i].PART_NAME+"'>"+data[i].PART_NAME+"</td>";
trHtml += " <td class='align_l' title='"+data[i].SPEC+"'>"+data[i].SPEC+"</td>";
trHtml += " <td class='align_l' title='"+data[i].MAKER+"'>"+data[i].MAKER+"</td>";
trHtml += " </tr>";
});
}else{
trHtml += " <tr>";
trHtml += " <td colspan=\"5\" align=\"center\">조회된 Part가 없습니다.</td>";
trHtml += " </tr>";
// Tabulator에 데이터 설정
if(_rightGrid){
_rightGrid.setData(data);
}
$("#structurePopupTable2").append(trHtml);
},
error: function(jqxhr, status, error){
Swal.fire('조회 중 오류가 발생했습니다.');
}
});
}
@@ -152,80 +216,40 @@ function openPartMngPopup(objId){
<input type="hidden" name="searchTargetStatus" id="searchTargetStatus" value="${info.STATUS}">
<div id="structureName2"></div>
<div id="structureTableWrap2" style="">
<div class="searchIdName">
<!-- 검색 필터 영역 -->
<div id="plmSearchZon">
<table>
<!-- <tr>
<td class="input_title"><label for="">기종명</label></td>
<td class="input_sub_title" >
<select name="search_product_mgmt_objid" id="search_product_mgmt_objid" class="select2"></select>
</td>
<td class="input_title"><label for="">UPG No</label></td>
<td>
<select name="search_product_mgmt_upg" id="search_product_mgmt_upg" title="UPG" required type="select" class="select2"></select>
</td>
</tr> -->
<tr>
<td class="input_title"><label for="">품번</label></td>
<td class="input_sub_title" style="width:150px;">
<input type="text" name="search_part_no" id="search_part_no" value="" style="width:90%">
<td><label for="search_part_no">품번</label></td>
<td>
<input type="text" name="search_part_no" id="search_part_no" value="">
</td>
<td class="label"><label for="search_part_name">품명</label></td>
<td>
<input type="text" name="search_part_name" id="search_part_name" value="">
</td>
<td class="input_title"><label for="">품명</label></td>
<td>
<input type="text" name="search_part_name" id="search_part_name" value="" style="width:80%">
</td>
<td class="input_sub_title" style="float:right">
</td>
</tr>
<tr>
<td class="input_title"><label for="">규격</label></td>
<td class="input_sub_title" style="width:150px;">
<input type="text" name="search_spec" id="search_spec" value="" style="width:90%">
<td><label for="search_spec">규격</label></td>
<td>
<input type="text" name="search_spec" id="search_spec" value="">
</td>
<td class="label"><label for="search_maker">MAKER</label></td>
<td>
<input type="text" name="search_maker" id="search_maker" value="">
</td>
<td>
<input type="button" value="조회" class="plm_btns" id="btnSearch">
</td>
<td class="input_title"><label for="">MAKER</label></td>
<td>
<input type="text" name="search_maker" id="search_maker" value="" style="width:80%">
</td>
<td class="input_sub_title" style="float:right">
<input type="button" value="조회" class="plm_btns structure_btn" id="btnSearch" >
</td>
</tr>
</table>
</table>
</div>
<div class="plm_table_wrap">
<div style="overflow-y:scroll;">
<table id="structurePopupTableHead" class="plm_table">
<colgroup>
<col width="5%" />
<col width="30%" />
<col width="30%" />
<col width="45%" />
<col width="15%" />
</colgroup>
<tr class="plm_thead">
<td><input type="checkbox" name="" value="" id="allChk" class="checkBox"></td>
<td>품번</td>
<td>품명</td>
<td>규격</td>
<td>MAKER</td>
</tr>
</table>
</div>
<div class="plm_scroll_table" style="height:100%;">
<table id="structurePopupTable2" class="plm_table">
<colgroup>
<col width="5%" />
<col width="30%" />
<col width="30%" />
<col width="40%" />
<col width="20%" />
</colgroup>
<tr class="partListTr">
<td colspan="5" align="center">조회된 부품이 없습니다.</td>
</tr>
</table>
</div>
<div id="rightPartGrid"></div>
</div>
</div>
</form>

View File

@@ -6,15 +6,115 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title><%=Constants.SYSTEM_NAME%></title>
<title><%=Constants.SYSTEM_NAME%></title>
<style>
body, html {
margin: 0;
padding: 0;
overflow: visible;
height: auto;
}
.plm_menu_name {
margin: 5px 15px 0 15px !important;
}
.plm_menu_name h2 {
margin: 5px 0 !important;
padding: 5px 0;
}
#plmSearchZon {
margin-bottom: 0 !important;
padding-bottom: 5px !important;
overflow: visible !important;
position: relative;
z-index: 1000;
}
.select2-container {
z-index: 9999 !important;
}
.select2-dropdown {
z-index: 9999 !important;
}
</style>
<script>
$(document).ready(function(){
// 엔터키 이벤트 바인딩
$("#filterPartNo, #filterPartName, #filterVersion").on('keypress', function(e){
if(e.keyCode == 13 || e.which == 13){
e.preventDefault();
fn_applyFilter();
}
});
});
// 필터 적용 함수
function fn_applyFilter() {
var partNo = $("#filterPartNo").val().trim();
var partName = $("#filterPartName").val().trim();
try {
// 프레임 구조: parent(headerFs) -> parent(main) -> frames[1](bottomFs) -> frames[0](leftFrame)
var leftFrame = parent.parent.frames[1].frames['leftFrame'];
if(leftFrame && leftFrame.fn_applyFilter) {
leftFrame.$("#filterPartNo").val(partNo);
leftFrame.$("#filterPartName").val(partName);
leftFrame.fn_applyFilter();
} else {
console.error("leftFrame not found or fn_applyFilter not available");
}
} catch(e) {
console.error("Error accessing leftFrame:", e);
alert("필터를 적용할 수 없습니다. 프레임 구조를 확인해주세요.");
}
}
// 필터 초기화 함수
function fn_resetFilter() {
$("#filterPartNo").val("");
$("#filterPartName").val("");
try {
// 프레임 구조: parent(headerFs) -> parent(main) -> frames[1](bottomFs) -> frames[0](leftFrame)
var leftFrame = parent.parent.frames[1].frames['leftFrame'];
if(leftFrame && leftFrame.fn_resetFilter) {
leftFrame.fn_resetFilter();
}
} catch(e) {
console.error("Error accessing leftFrame:", e);
}
}
</script>
</head>
<body class="backcolor">
<form name="form1" action="" method="post">
<form name="form1" id="form1" action="" method="post">
<div class="plm_menu_name">
<h2>
<span>구조등록</span>
<span>E-BOM 확인/수정</span>
</h2>
</div>
<!-- 검색 필터 영역 -->
<div id="plmSearchZon">
<table>
<tr>
<td class="label"><label for="filterPartNo">품번</label></td>
<td>
<input type="text" id="filterPartNo" name="filterPartNo">
</td>
<td class="label"><label for="filterPartName">품명</label></td>
<td>
<input type="text" id="filterPartName" name="filterPartName">
</td>
<td>
<button type="button" class="plm_btns" onclick="fn_applyFilter()">검색</button>
<button type="button" class="plm_btns" onclick="fn_resetFilter()">초기화</button>
</td>
</tr>
</table>
</div>
</form>
</body>
</html>

View File

@@ -296,6 +296,7 @@ div.plm_menu_name h2 span,
.input_title {
background: var(--label-bg);
color: var(--text-primary);
border-left: 1px solid var(--border-color);
border-right: 1px solid var(--border-color);
font-weight: 500;
position: relative;
@@ -644,7 +645,7 @@ div.plm_menu_name h2 span,
border-collapse: collapse;
background: var(--surface);
text-align: center;
font-size: 14px;
font-size: 13px;
}
.plm_table .plm_thead {
@@ -658,7 +659,7 @@ div.plm_menu_name h2 span,
border-right: 1px solid var(--border-color);
padding: 14px 12px;
font-weight: 600;
font-size: 14px;
font-size: 13px;
}
.plm_table .plm_thead td:last-child {
@@ -671,6 +672,7 @@ div.plm_menu_name h2 span,
border-right: 1px solid var(--border-color);
padding: 12px;
vertical-align: middle;
font-size: 13px;
}
.plm_table td:last-child {

View File

@@ -3,7 +3,7 @@
}
.ui-jqgrid .ui-jqgrid-view,.ui-jqgrid .ui-paging-info, .ui-jqgrid .ui-pg-table,
.ui-jqgrid .ui-pg-selbox {
font-size: 14px;
font-size: 13px;
}
.ui-jqgrid .ui-jqgrid-titlebar{
height: 40px;
@@ -19,11 +19,12 @@
}
.ui-jqgrid .ui-widget-header{
border-bottom:1px solid #D3D3D3;
border-bottom:1px solid #e0e0e0;
background: #f5f5f5;
}
.ui-jqgrid .ui-search-toolbar input[type="text"]{
font-size: 12px;
font-size: 13px;
border: 1px solid #CCCCCC;
border-radius: 4px;
}
@@ -41,17 +42,21 @@
/*** Column headers ******/
.ui-jqgrid .ui-jqgrid-hdiv {
/*background: #F9F9F9;*/
border: 1px solid #D3D3D3;
background: #f5f5f5;
border: 1px solid #e0e0e0;
line-height: 15px;
/*height: 45px;*/
font-weight: bold;
color: #777777;
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
color: #666666;
text-shadow: none;
font-size: 13px;
}
.ui-jqgrid .ui-jqgrid-htable th {
height: auto;
background: #f5f5f5 !important;
border-bottom: 1px solid #e0e0e0 !important;
color: #666666 !important;
}
.ui-jqgrid .ui-jqgrid-htable th div {
@@ -71,6 +76,7 @@
border-bottom: 1px solid #DDDDDD;
border-right:none;
padding:8px;
font-size: 13px;
}
@@ -160,5 +166,5 @@
font-weight: bold;
display: none;
border-width: 2px !important;
font-size:11px;
font-size:13px;
}

View File

@@ -24,8 +24,9 @@ echo ""
# 2단계: 도커 중지 및 삭제
echo -e "${YELLOW}[2/3] 기존 도커 컨테이너 중지 및 삭제 중...${NC}"
docker-compose -f docker-compose.dev.yml down 2>&1 | grep -v "level=warning"
if [ $? -ne 0 ]; then
docker-compose -f docker-compose.dev.yml down 2>&1 | grep -v "level=warning" || true
# PIPESTATUS[0]로 docker-compose의 실제 종료 코드 확인
if [ ${PIPESTATUS[0]} -ne 0 ]; then
echo -e "${RED}✗ 도커 중지 실패!${NC}"
exit 1
fi
@@ -34,14 +35,14 @@ echo ""
# 3단계: 도커 이미지 재빌드 및 시작
echo -e "${YELLOW}[3/3] 도커 이미지 재빌드 및 시작 중...${NC}"
docker-compose -f docker-compose.dev.yml build --no-cache 2>&1 | grep -v "level=warning" | tail -5
if [ $? -ne 0 ]; then
docker-compose -f docker-compose.dev.yml build --no-cache 2>&1 | grep -v "level=warning" | tail -5 || true
if [ ${PIPESTATUS[0]} -ne 0 ]; then
echo -e "${RED}✗ 도커 빌드 실패!${NC}"
exit 1
fi
docker-compose -f docker-compose.dev.yml up -d 2>&1 | grep -v "level=warning"
if [ $? -ne 0 ]; then
docker-compose -f docker-compose.dev.yml up -d 2>&1 | grep -v "level=warning" || true
if [ ${PIPESTATUS[0]} -ne 0 ]; then
echo -e "${RED}✗ 도커 시작 실패!${NC}"
exit 1
fi

View File

@@ -875,6 +875,14 @@ public class PartMngController {
@RequestMapping("/partMng/structureHeaderPopup.do")
public String structureHeaderPopup(HttpServletRequest request, @RequestParam Map<String, Object> paramMap){
Map code_map = new HashMap();
try {
// 제품구분 (PART_TYPE)
code_map.put("product_cd", commonService.bizMakeOptionList("0000001", CommonUtils.nullToEmpty((String)paramMap.get("product")),"common.getCodeselect"));
} catch (Exception e) {
e.printStackTrace();
}
request.setAttribute("code_map", code_map);
return "/partMng/structurePopupTop";
}
@@ -928,6 +936,27 @@ public class PartMngController {
return "/partMng/structurePopupLeft"+("excel".equals(actionType) ? "Excel" : "");
}
/**
* 구조등록 좌측 프레임 JSON 데이터
* @param request
* @param paramMap
* @return
*/
@RequestMapping("/partMng/getStructureTreeJson.do")
@ResponseBody
public List<Map> getStructureTreeJson(HttpServletRequest request, @RequestParam Map<String, Object> paramMap){
List bomTreeList = null;
try{
Map info = partMngService.getBOMStructureStandardInfo(request,paramMap);
bomTreeList = partMngService.getBOMPartTreeList(info);
}catch(Exception e){
e.printStackTrace();
}
return bomTreeList != null ? bomTreeList : new ArrayList<Map>();
}
@RequestMapping("/partMng/structurePopupCenter.do")
public String structurePopupCenter(HttpServletRequest request, @RequestParam Map<String, Object> paramMap){

View File

@@ -3278,12 +3278,15 @@ SELECT T1.LEV, T1.BOM_REPORT_OBJID, T1.ROOT_PART_NO, T1.PATH, T1.LEAF, T2.*
,P.OUT_DIAMETER
,P.IN_DIAMETER
,P.LENGTH
,P.SOURCING_CODE
,(SELECT COUNT(1) FROM ATTACH_FILE_INFO F WHERE P.OBJID = F.TARGET_OBJID <!--AND STATUS = 'Active'--> AND F.DOC_TYPE IN ('3D_CAD')) AS CU01_CNT
,(SELECT COUNT(1) FROM ATTACH_FILE_INFO F WHERE P.OBJID = F.TARGET_OBJID <!--AND STATUS = 'Active'--> AND F.DOC_TYPE IN ('2D_DRAWING_CAD')) AS CU02_CNT
,(SELECT COUNT(1) FROM ATTACH_FILE_INFO F WHERE P.OBJID = F.TARGET_OBJID <!--AND STATUS = 'Active'--> AND F.DOC_TYPE IN ('2D_PDF_CAD')) AS CU03_CNT
,V.LEV
,P.SOURCING_CODE
,P.HEAT_TREATMENT_HARDNESS
,P.HEAT_TREATMENT_METHOD
,P.SURFACE_TREATMENT
,(SELECT COUNT(1) FROM ATTACH_FILE_INFO F WHERE P.OBJID = F.TARGET_OBJID <!--AND STATUS = 'Active'--> AND F.DOC_TYPE IN ('3D_CAD')) AS CU01_CNT
,(SELECT COUNT(1) FROM ATTACH_FILE_INFO F WHERE P.OBJID = F.TARGET_OBJID <!--AND STATUS = 'Active'--> AND F.DOC_TYPE IN ('2D_DRAWING_CAD')) AS CU02_CNT
,(SELECT COUNT(1) FROM ATTACH_FILE_INFO F WHERE P.OBJID = F.TARGET_OBJID <!--AND STATUS = 'Active'--> AND F.DOC_TYPE IN ('2D_PDF_CAD')) AS CU03_CNT
,V.LEV
,(SELECT OBJID FROM VIEW_BOM VT WHERE V.BOM_REPORT_OBJID = VT.BOM_REPORT_OBJID AND VT.LEV = 1 ORDER BY SEQ LIMIT 1) AS ROOT_OBJID
,(SELECT OBJID FROM VIEW_BOM VT WHERE V.BOM_REPORT_OBJID = VT.BOM_REPORT_OBJID AND VT.LEV = 1 ORDER BY SEQ LIMIT 1) AS SUB_ROOT_OBJID
,( SELECT