Files
wace_plm/WebContent/WEB-INF/view/partMng/structurePopupLeft.jsp
2025-10-27 12:09:22 +09:00

472 lines
12 KiB
Plaintext

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="com.pms.common.utils.*"%>
<%@ page import="java.util.*" %>
<%@include file= "/init.jsp" %>
<!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;
height: 15px;
}
#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>
<script>
var _tabulGrid;
var selectedRowData = null;
$(function(){
if('${param.readonly}' == 'readonly'){
$("#structureName2").hide();
}
$("#btnExcel").click(function() {
fn_excel();
});
// Tabulator 초기화
fn_initGrid();
});
// 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
});
// 나머지 컬럼 추가
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>';
}
},
{
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;
}
});
// 파일 아이콘 클릭 이벤트 (동적으로 생성된 요소)
$(document).on('click', '.File', function(e) {
e.preventDefault();
var popup_width = 800;
var popup_height = 335;
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);
});
}
// 수량 저장
function fn_saveQty(leftObjId, qty, leftQtyParObjId){
$.ajax({
url: "/partMng/structureQtySave.do",
method: 'post',
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('저장 중 오류가 발생했습니다.');
}
});
}
// Part 상세 팝업
function openPartMngPopup(objId, lastPartObjid, childObjid, BOM_LAST_PART_OBJID){
var popup_width = 800;
var popup_height = 500;
var hiddenForm = document.hiddenForm;
var url = "/partMng/partMngFormPopUp.do";
if("" != objId){
url = "/partMng/partMngDetailPopUp.do?ACTION_TYPE=work";
}
var target = "partMngPopUp";
fn_centerPopup(popup_width, popup_height, url, target);
hiddenForm.action = url;
hiddenForm.OBJID.value = fnc_checkNull(BOM_LAST_PART_OBJID, objId);
if('working' == '${param.actionType}')
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.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">
<form name="hiddenForm" id="hiddenForm" method="post">
<input type="hidden" name="OBJID" id="OBJID">
<input type="hidden" name="LAST_PART_OBJID" id="LAST_PART_OBJID">
<input type="hidden" name="CHILD_OBJID" id="CHILD_OBJID">
</form>
<form name="form1" action="" method="post" onsubmit="return false;">
<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="" />
<!-- 필터 값을 저장하기 위한 hidden 필드 (top frame에서 값 전달) -->
<input type="hidden" id="filterPartNo" />
<input type="hidden" id="filterPartName" />
<div id="structureTableWrap1">
<div id="structureName">
<span style="font-weight: bold; color: #333;">
<c:choose>
<c:when test="${not empty info.PART_NO}">
${info.PART_NO}
</c:when>
<c:otherwise>
(${info.CUSTOMER_NAME}_${info.CUSTOMER_PROJECT_NAME}_${info.UNIT_NAME})_${info.REVISION}
</c:otherwise>
</c:choose>
</span>
<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>