1984 lines
58 KiB
Plaintext
1984 lines
58 KiB
Plaintext
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
|
|
<%@ page import="com.pms.common.utils.*"%>
|
|
<%@ page import="java.util.*"%>
|
|
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
|
|
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
|
|
<%@include file="/init.jsp"%>
|
|
<%
|
|
PersonBean person = (PersonBean) session.getAttribute(Constants.PERSON_BEAN);
|
|
String userId = CommonUtils.checkNull(person.getUserId());
|
|
%>
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
<title><%=Constants.SYSTEM_NAME%></title>
|
|
<style>
|
|
.fileListscrollTbody td {
|
|
font-size: 11px !important;
|
|
}
|
|
|
|
/* 컴팩트한 첨부파일 영역 디자인 - 높이 최적화 */
|
|
.file_upload_main_table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
table-layout: fixed;
|
|
}
|
|
|
|
.file_upload_main_table td {
|
|
width: 50%;
|
|
vertical-align: top;
|
|
padding: 8px; /* 패딩을 줄여서 더 컴팩트하게 */
|
|
}
|
|
|
|
/* 각 첨부파일 섹션의 전체 컨테이너 - 높이 최적화 */
|
|
.file_section_container {
|
|
border: 1px solid #ddd; /* 테두리를 얇게 해서 더 깔끔하게 */
|
|
border-radius: 6px;
|
|
background: #f8f9fa;
|
|
overflow: hidden;
|
|
height: 200px; /* 전체 높이를 200px로 제한 */
|
|
}
|
|
|
|
/* 섹션 제목 영역 - 높이 줄임 */
|
|
.file_section_header {
|
|
background: #6c757d;
|
|
color: white;
|
|
text-align: center;
|
|
padding: 8px; /* 패딩을 줄여서 헤더 높이 감소 */
|
|
font-weight: bold;
|
|
font-size: 13px; /* 폰트 크기도 약간 줄임 */
|
|
margin: 0;
|
|
}
|
|
|
|
/* 드래그 앤 드롭 영역의 컨테이너 - 패딩 줄임 */
|
|
.drag_drop_container {
|
|
padding: 12px; /* 패딩을 대폭 줄임 */
|
|
background: white;
|
|
}
|
|
|
|
/* 실제 드래그 앤 드롭 영역 - 높이 대폭 감소 */
|
|
.drag_drop_zone {
|
|
border: 2px dashed #ccc;
|
|
border-radius: 6px;
|
|
padding: 15px 10px; /* 패딩을 줄여서 높이 감소 */
|
|
text-align: center;
|
|
background: #fafafa;
|
|
cursor: pointer;
|
|
transition: all 0.3s ease;
|
|
min-height: 40px; /* 최소 높이를 40px로 대폭 줄임 */
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
align-items: center;
|
|
}
|
|
|
|
.drag_drop_zone:hover,
|
|
.drag_drop_zone.dragover {
|
|
border-color: #28a745;
|
|
background: #f8fff8;
|
|
color: #28a745;
|
|
}
|
|
|
|
/* 드래그 앤 드롭 텍스트 스타일 - 크기 줄임 */
|
|
.drag_drop_text {
|
|
font-size: 13px; /* 폰트 크기 줄임 */
|
|
font-weight: bold;
|
|
color: #666;
|
|
margin-bottom: 4px; /* 마진 줄임 */
|
|
}
|
|
|
|
.drag_drop_hint {
|
|
font-size: 10px; /* 힌트 텍스트 크기 더욱 줄임 */
|
|
color: #999;
|
|
}
|
|
|
|
/* 파일 목록 영역 */
|
|
.file_list_section {
|
|
background: white;
|
|
border-top: 1px solid #ddd;
|
|
flex: 1; /* 남은 공간을 모두 차지하도록 설정 */
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.file_list_header {
|
|
background: #e9ecef;
|
|
padding: 6px; /* 패딩을 줄여서 헤더 높이 감소 */
|
|
font-weight: bold;
|
|
text-align: center;
|
|
border-bottom: 1px solid #ddd;
|
|
font-size: 12px; /* 폰트 크기 줄임 */
|
|
}
|
|
|
|
/* 파일 목록 컨테이너 - 높이 최적화 */
|
|
.file_list_content {
|
|
max-height: 80px; /* 최대 높이를 80px로 줄임 */
|
|
overflow-y: auto;
|
|
min-height: 50px; /* 최소 높이도 줄임 */
|
|
flex: 1; /* 남은 공간을 모두 사용 */
|
|
}
|
|
|
|
.file_list_content table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
}
|
|
|
|
.file_list_content td {
|
|
padding: 6px 8px; /* 패딩을 줄여서 행 높이 감소 */
|
|
border-bottom: 1px solid #f0f0f0;
|
|
font-size: 11px; /* 폰트 크기 줄임 */
|
|
line-height: 1.2; /* 줄 간격 줄임 */
|
|
}
|
|
|
|
.file_list_content tr:hover {
|
|
background: #f8f9fa;
|
|
}
|
|
|
|
/* 파일 링크 스타일 */
|
|
.file_link {
|
|
color: #007bff;
|
|
text-decoration: none;
|
|
display: inline-block;
|
|
max-width: 150px; /* 최대 너비를 줄임 */
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.file_link:hover {
|
|
text-decoration: underline;
|
|
color: #0056b3;
|
|
}
|
|
|
|
/* 파일 삭제 버튼 */
|
|
.delete_btn {
|
|
width: 14px; /* 크기를 줄임 */
|
|
height: 14px;
|
|
background: #dc3545;
|
|
border-radius: 50%;
|
|
cursor: pointer;
|
|
margin-left: 6px; /* 마진 줄임 */
|
|
display: inline-block;
|
|
position: relative;
|
|
vertical-align: middle;
|
|
transition: background 0.2s ease;
|
|
}
|
|
|
|
.delete_btn:hover {
|
|
background: #c82333;
|
|
}
|
|
|
|
/* X 표시 구현 */
|
|
.delete_btn:before,
|
|
.delete_btn:after {
|
|
content: '';
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
width: 6px; /* 크기 줄임 */
|
|
height: 1px;
|
|
background: white;
|
|
transform: translate(-50%, -50%) rotate(45deg);
|
|
}
|
|
|
|
.delete_btn:after {
|
|
transform: translate(-50%, -50%) rotate(-45deg);
|
|
}
|
|
|
|
/* 빈 파일 목록 메시지 */
|
|
.empty_file_message {
|
|
text-align: center;
|
|
color: #999;
|
|
padding: 15px 10px; /* 패딩 줄임 */
|
|
font-style: italic;
|
|
font-size: 11px; /* 폰트 크기 줄임 */
|
|
}
|
|
|
|
/* 스크롤바 스타일 - 더 얇게 */
|
|
.file_list_content::-webkit-scrollbar {
|
|
width: 4px; /* 스크롤바 너비 줄임 */
|
|
}
|
|
|
|
.file_list_content::-webkit-scrollbar-track {
|
|
background: #f1f1f1;
|
|
border-radius: 2px;
|
|
}
|
|
|
|
.file_list_content::-webkit-scrollbar-thumb {
|
|
background: #c1c1c1;
|
|
border-radius: 2px;
|
|
}
|
|
|
|
.file_list_content::-webkit-scrollbar-thumb:hover {
|
|
background: #a8a8a8;
|
|
}
|
|
|
|
/* ======================================= */
|
|
/* 이미지와 동일한 간단한 파일첨부 영역 스타일 */
|
|
/* ======================================= */
|
|
|
|
/* 파일 섹션 헤더 셀 - 회색 배경으로 TD 영역에 꽉참 */
|
|
.file_section_header_cell {
|
|
background: #6c757d !important;
|
|
color: white !important;
|
|
text-align: center !important;
|
|
font-weight: bold !important;
|
|
font-size: 13px !important;
|
|
vertical-align: middle !important;
|
|
padding: 10px !important;
|
|
}
|
|
|
|
/* 드래그 앤 드롭 셀 */
|
|
.file_drag_drop_cell {
|
|
padding: 8px !important;
|
|
vertical-align: middle !important;
|
|
}
|
|
|
|
/* 간단한 드래그 앤 드롭 영역 */
|
|
.drag_drop_zone_simple {
|
|
border: 2px dashed #ccc;
|
|
border-radius: 6px;
|
|
padding: 20px 10px;
|
|
text-align: center;
|
|
background: #fafafa;
|
|
cursor: pointer;
|
|
transition: all 0.3s ease;
|
|
height: 60px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.drag_drop_zone_simple:hover,
|
|
.drag_drop_zone_simple.dragover {
|
|
border-color: #28a745;
|
|
background: #f8fff8;
|
|
color: #28a745;
|
|
}
|
|
|
|
.drag_drop_zone_simple .drag_drop_text {
|
|
font-size: 12px;
|
|
font-weight: bold;
|
|
color: #666;
|
|
}
|
|
|
|
/* 파일 목록 셀 */
|
|
.file_list_cell {
|
|
padding: 8px !important;
|
|
vertical-align: middle !important;
|
|
}
|
|
|
|
/* 간단한 파일 목록 내용 */
|
|
.file_list_content_simple {
|
|
max-height: 80px;
|
|
overflow-y: auto;
|
|
border: 1px solid #ddd;
|
|
border-radius: 4px;
|
|
background: white;
|
|
}
|
|
|
|
.file_list_content_simple table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
}
|
|
|
|
.file_list_content_simple td {
|
|
padding: 6px 10px;
|
|
border-bottom: 1px solid #f0f0f0;
|
|
font-size: 11px;
|
|
line-height: 1.2;
|
|
}
|
|
|
|
.file_list_content_simple tr:hover {
|
|
background: #f8f9fa;
|
|
}
|
|
|
|
.file_list_content_simple tr:last-child td {
|
|
border-bottom: none;
|
|
}
|
|
|
|
/* 파일 링크 스타일 */
|
|
.file_list_content_simple .file_link {
|
|
color: #007bff;
|
|
text-decoration: none;
|
|
display: inline-block;
|
|
max-width: 200px;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.file_list_content_simple .file_link:hover {
|
|
text-decoration: underline;
|
|
color: #0056b3;
|
|
}
|
|
|
|
/* 삭제 버튼 */
|
|
.file_list_content_simple .delete_btn {
|
|
width: 14px;
|
|
height: 14px;
|
|
background: #dc3545;
|
|
border-radius: 50%;
|
|
cursor: pointer;
|
|
margin-left: 6px;
|
|
display: inline-block;
|
|
position: relative;
|
|
vertical-align: middle;
|
|
transition: background 0.2s ease;
|
|
}
|
|
|
|
.file_list_content_simple .delete_btn:hover {
|
|
background: #c82333;
|
|
}
|
|
|
|
/* X 표시 구현 */
|
|
.file_list_content_simple .delete_btn:before,
|
|
.file_list_content_simple .delete_btn:after {
|
|
content: '';
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
width: 6px;
|
|
height: 1px;
|
|
background: white;
|
|
transform: translate(-50%, -50%) rotate(45deg);
|
|
}
|
|
|
|
.file_list_content_simple .delete_btn:after {
|
|
transform: translate(-50%, -50%) rotate(-45deg);
|
|
}
|
|
|
|
/* 빈 파일 목록 메시지 */
|
|
.file_list_content_simple .empty_file_message {
|
|
text-align: center;
|
|
color: #999;
|
|
padding: 15px 10px;
|
|
font-style: italic;
|
|
font-size: 11px;
|
|
}
|
|
|
|
/* 스크롤바 스타일 */
|
|
.file_list_content_simple::-webkit-scrollbar {
|
|
width: 4px;
|
|
}
|
|
|
|
.file_list_content_simple::-webkit-scrollbar-track {
|
|
background: #f1f1f1;
|
|
border-radius: 2px;
|
|
}
|
|
|
|
.file_list_content_simple::-webkit-scrollbar-thumb {
|
|
background: #c1c1c1;
|
|
border-radius: 2px;
|
|
}
|
|
|
|
.file_list_content_simple::-webkit-scrollbar-thumb:hover {
|
|
background: #a8a8a8;
|
|
}
|
|
|
|
/* ======================================= */
|
|
/* 견적이력관리 전용 스타일 */
|
|
/* ======================================= */
|
|
|
|
/* 견적 관리 테이블 스타일 */
|
|
#quoteManagementTable {
|
|
border-collapse: collapse;
|
|
width: 100%;
|
|
}
|
|
|
|
#quoteManagementTable td {
|
|
border: 1px solid #ddd;
|
|
padding: 8px;
|
|
vertical-align: middle;
|
|
}
|
|
|
|
#quoteManagementTable .quote_input,
|
|
#quoteManagementTable .quote_select {
|
|
width: 100%;
|
|
border: 1px solid #ccc;
|
|
padding: 4px;
|
|
font-size: 12px;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
/* 견적서 첨부파일 드롭존 */
|
|
.quote_dropzone {
|
|
border: 2px dashed #ccc;
|
|
border-radius: 4px;
|
|
padding: 8px;
|
|
text-align: center;
|
|
background: #fafafa;
|
|
cursor: pointer;
|
|
transition: all 0.3s ease;
|
|
min-height: 30px;
|
|
font-size: 11px;
|
|
color: #666;
|
|
}
|
|
|
|
.quote_dropzone:hover,
|
|
.quote_dropzone.dragover {
|
|
border-color: #28a745;
|
|
background: #f8fff8;
|
|
color: #28a745;
|
|
}
|
|
|
|
.quote_file_list {
|
|
max-height: 50px;
|
|
overflow-y: auto;
|
|
border: 1px solid #ddd;
|
|
background: white;
|
|
margin-top: 4px;
|
|
}
|
|
|
|
.quote_file_item {
|
|
padding: 4px 6px;
|
|
border-bottom: 1px solid #f0f0f0;
|
|
font-size: 10px;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
|
|
.quote_file_item:last-child {
|
|
border-bottom: none;
|
|
}
|
|
|
|
.quote_file_link {
|
|
color: #007bff;
|
|
text-decoration: none;
|
|
flex: 1;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.quote_file_link:hover {
|
|
text-decoration: underline;
|
|
}
|
|
|
|
.quote_delete_btn {
|
|
width: 14px;
|
|
height: 14px;
|
|
background: #dc3545;
|
|
border-radius: 50%;
|
|
cursor: pointer;
|
|
position: relative;
|
|
transition: background 0.2s ease;
|
|
margin-left: 4px;
|
|
}
|
|
|
|
.quote_delete_btn:hover {
|
|
background: #c82333;
|
|
}
|
|
|
|
.quote_delete_btn:before,
|
|
.quote_delete_btn:after {
|
|
content: '';
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
width: 6px;
|
|
height: 1px;
|
|
background: white;
|
|
transform: translate(-50%, -50%) rotate(45deg);
|
|
}
|
|
|
|
.quote_delete_btn:after {
|
|
transform: translate(-50%, -50%) rotate(-45deg);
|
|
}
|
|
</style>
|
|
|
|
<script type="text/javascript">
|
|
|
|
// ===================================================================
|
|
// 1. 전역 변수 선언부 - 페이지 전체에서 사용되는 변수들
|
|
// ===================================================================
|
|
|
|
// 견적 관리 관련 전역 변수
|
|
var quoteRowCounter = ${empty detailList ? 0 : detailList.size()}; // JSTL로 기존 데이터 개수 초기화
|
|
var currencyTypeOptions = ''; // 통화 옵션 HTML 문자열 저장용
|
|
|
|
// ===================================================================
|
|
// 2. 공통 유틸리티 함수들 - 없을 경우를 대비한 안전한 함수 정의
|
|
// ===================================================================
|
|
|
|
// 숫자에 천단위 콤마 추가 함수
|
|
if (typeof addComma !== 'function') {
|
|
function addComma(data) {
|
|
if (!data) return '';
|
|
return data.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
}
|
|
}
|
|
|
|
// null 체크 함수
|
|
if (typeof fnc_checkNull !== 'function') {
|
|
function fnc_checkNull(value) {
|
|
if (value === null || value === undefined || value === 'null' || value === 'undefined') {
|
|
return '';
|
|
}
|
|
return value;
|
|
}
|
|
}
|
|
|
|
// 고유 ID 생성 함수
|
|
if (typeof fnc_createObjId !== 'function') {
|
|
function fnc_createObjId() {
|
|
return 'OBJ_' + new Date().getTime() + '_' + Math.random().toString(36).substr(2, 9);
|
|
}
|
|
}
|
|
|
|
// ===================================================================
|
|
// 3. 메인 초기화 함수 - 페이지 로드 시 실행되는 모든 초기화 작업
|
|
// ===================================================================
|
|
|
|
$(function() {
|
|
|
|
$("#form1 input[type='text'], #form1 select , input[type='number']").prop("disabled", true);
|
|
// -----------------------------------------------------------
|
|
// 3-1. 통화 옵션 초기화 (견적 관리에서 사용)
|
|
// -----------------------------------------------------------
|
|
currencyTypeOptions =
|
|
'<option value="">선택</option>' +
|
|
'<option value="KRW">원화(KRW)</option>' +
|
|
'<option value="USD">달러(USD)</option>' +
|
|
'<option value="EUR">유로(EUR)</option>' +
|
|
'<option value="JPY">엔화(JPY)</option>' +
|
|
'<option value="CNY">위안화(CNY)</option>';
|
|
|
|
// -----------------------------------------------------------
|
|
// 3-2. 기본 폼 요소 초기화 및 계산 로직
|
|
// -----------------------------------------------------------
|
|
|
|
// 견적금액과 설비대수 변경 시 수주가 자동계산
|
|
$("#quote_amount_1st, #quote_amount_2nd, #quote_amount_3rd, #facility_qty").on("keyup change", function() {
|
|
calculateOrderAmount();
|
|
});
|
|
|
|
// 계약구분에 따른 화면 표시/숨김 처리
|
|
if("${info.CATEGORY_CD}" == '0000170' || "${info.CATEGORY_CD}" == '0000171'){
|
|
$(".DIRECT").show();
|
|
$(".SELECT").hide();
|
|
} else {
|
|
$(".DIRECT").hide();
|
|
$(".SELECT").show();
|
|
}
|
|
|
|
// 계약 결과가 완료된 경우 필드 비활성화
|
|
if("${info.CONTRACT_RESULT}" == "0000964"){
|
|
$("#category_cd,#area_cd,#target_project_no,#customer_objid,#product,#contract_result,#overhaul_order").prop("disabled","disabled");
|
|
$("#mechanical_type,#facility_qty,#target_project_no_direct").prop("readonly", true);
|
|
}
|
|
|
|
// 수정 모드에서는 저장 버튼 제거
|
|
if ("${actionType}" == "U") {
|
|
$("#btnSave").remove();
|
|
}
|
|
|
|
// 인증여부 초기값 설정
|
|
$("#certification_status").val("${info.CERTIFICATION_STATUS}");
|
|
|
|
// -----------------------------------------------------------
|
|
// 3-3. 입력 필드 포맷팅 및 플러그인 초기화
|
|
// -----------------------------------------------------------
|
|
|
|
// 숫자만 입력 가능한 필드에 콤마 자동 추가
|
|
$("input:text[numberOnly]").on("keyup", function() {
|
|
$(this).val(addComma($(this).val().replace(/[^0-9]/g, "")));
|
|
});
|
|
|
|
// Select2 플러그인 적용
|
|
$('.select2').select2();
|
|
|
|
// 날짜 선택기 초기화
|
|
_fnc_datepick();
|
|
|
|
// -----------------------------------------------------------
|
|
// 3-4. 첨부파일 드롭존 초기화 (기본 파일 첨부 영역)
|
|
// -----------------------------------------------------------
|
|
|
|
// 3개의 기본 파일 첨부 영역 초기화 (입수자료, 제출자료, 공유자료)
|
|
fnc_setFileDropZone2("contractMgmt01DropZone", "${objId}", "contractMgmt01", "contractMgmt01", "fileAreaDraw", false);
|
|
fnc_setFileDropZone2("contractMgmt02DropZone", "${objId}", "contractMgmt02", "contractMgmt02", "fileAreaDraw", false);
|
|
fnc_setFileDropZone2("contractMgmt03DropZone", "${objId}", "contractMgmt03", "contractMgmt03", "fileAreaDraw", false);
|
|
|
|
// 초기 파일 목록 로드
|
|
fileAreaDraw();
|
|
|
|
// -----------------------------------------------------------
|
|
// 3-5. 기존 버튼 이벤트 바인딩 (호환성 유지)
|
|
// -----------------------------------------------------------
|
|
|
|
// 기본 파일 업로드 버튼들
|
|
$("#btnUpload").click(function() {
|
|
var files = $("#file1")[0].files;
|
|
if (files.length > 0) {
|
|
fnc_fileMultiUpload(files, null, "${objId}", "contractMgmt01", "contractMgmt01", null, "fileAreaDraw");
|
|
$("#file1").val("");
|
|
} else {
|
|
Swal.fire("선택된 File이 없습니다.");
|
|
}
|
|
});
|
|
|
|
$("#btnUpload1").click(function() {
|
|
var files = $("#file2")[0].files;
|
|
if (files.length > 0) {
|
|
fnc_fileMultiUpload(files, null, "${objId}", "contractMgmt02", "contractMgmt02", null, "fileAreaDraw");
|
|
$("#file2").val("");
|
|
} else {
|
|
Swal.fire("선택된 File이 없습니다.");
|
|
}
|
|
});
|
|
|
|
$("#btnUpload2").click(function() {
|
|
var files = $("#file3")[0].files;
|
|
if (files.length > 0) {
|
|
fnc_fileMultiUpload(files, null, "${objId}", "contractMgmt03", "contractMgmt03", null, "fileAreaDraw");
|
|
$("#file3").val("");
|
|
} else {
|
|
Swal.fire("선택된 File이 없습니다.");
|
|
}
|
|
});
|
|
|
|
// 메인 버튼들
|
|
$("#btnSave").click(function() { fn_save(); });
|
|
$("#btnClose").click(function() { self.close(); });
|
|
|
|
// 파일 상세보기 버튼
|
|
$(".File").click(function() {
|
|
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 + "&callbackFnc=file_check";
|
|
var url = "/common/FileRegistPopup.do" + params;
|
|
fn_centerPopup(popup_width, popup_height, url);
|
|
});
|
|
|
|
// -----------------------------------------------------------
|
|
// 3-6. 제품군-제품코드 연동 기능
|
|
// -----------------------------------------------------------
|
|
|
|
// 제품군 선택 변경 시 제품코드 목록 업데이트
|
|
$("#product").change(function() {
|
|
var selectedProductCode = $(this).val();
|
|
|
|
console.log("제품군 변경됨:", selectedProductCode);
|
|
|
|
if (selectedProductCode && selectedProductCode !== "") {
|
|
// common.js의 fnc_getCodeListAppend 함수 사용하여 제품코드 목록 로드
|
|
fnc_getCodeListAppend(selectedProductCode, "product_code", "");
|
|
$("#product_code").select2(); // select2 재적용
|
|
console.log("제품코드 목록 로드 완료 for 제품군:", selectedProductCode);
|
|
} else {
|
|
// 제품군이 선택되지 않은 경우 제품코드 초기화
|
|
$("#product_code").empty();
|
|
$("#product_code").append('<option value="">선택</option>');
|
|
$("#product_code").select2();
|
|
console.log("제품코드 목록 초기화");
|
|
}
|
|
});
|
|
|
|
// 계약구분 변경 시 화면 전환
|
|
$("#category_cd").change(function(){
|
|
if($(this).val() == '0000170' || $(this).val() == '0000171'){
|
|
$(".DIRECT").show();
|
|
$(".SELECT").hide();
|
|
$("#target_project_no_direct").attr('required', 'required');
|
|
$("#overhaul_order").attr('required', 'required');
|
|
} else {
|
|
$(".DIRECT").hide();
|
|
$(".SELECT").show();
|
|
$("#target_project_no_direct").removeAttr('required');
|
|
$("#overhaul_order").removeAttr('required');
|
|
}
|
|
});
|
|
|
|
// -----------------------------------------------------------
|
|
// 3-7. 저장된 제품 정보 복원 (수정 모드용)
|
|
// -----------------------------------------------------------
|
|
|
|
var savedProductCode = "${info.PRODUCT}"; // 저장된 제품군 코드
|
|
var savedProductCodeValue = "${info.PRODUCT_CODE}"; // 저장된 제품코드 값
|
|
|
|
console.log("저장된 제품 정보 확인:");
|
|
console.log("- 제품군:", savedProductCode);
|
|
console.log("- 제품코드:", savedProductCodeValue);
|
|
|
|
// 저장된 제품 정보가 있는 경우 복원
|
|
if (savedProductCode && savedProductCode !== "" && savedProductCode !== "null") {
|
|
console.log("저장된 제품 정보 복원 시작");
|
|
|
|
// 제품군 값 설정
|
|
$("#product").val(savedProductCode);
|
|
|
|
if ($("#product").hasClass('select2-hidden-accessible')) {
|
|
$("#product").trigger('change.select2');
|
|
}
|
|
|
|
console.log("제품군 값 복원 완료:", savedProductCode);
|
|
|
|
// 제품코드 목록 로드 및 값 설정
|
|
if (savedProductCodeValue && savedProductCodeValue !== "" && savedProductCodeValue !== "null") {
|
|
fnc_getCodeListAppend(savedProductCode, "product_code", savedProductCodeValue);
|
|
console.log("제품코드 목록 로드 및 값 복원 완료:", savedProductCodeValue);
|
|
} else {
|
|
fnc_getCodeListAppend(savedProductCode, "product_code", "");
|
|
console.log("제품코드 목록만 로드 완료 (선택값 없음)");
|
|
}
|
|
|
|
$("#product_code").select2(); // select2 재적용
|
|
console.log("제품 정보 복원 작업 완료");
|
|
} else {
|
|
console.log("저장된 제품 정보 없음 - 신규 등록 모드");
|
|
}
|
|
|
|
// -----------------------------------------------------------
|
|
// 3-8. 견적이력관리 기능 초기화
|
|
// -----------------------------------------------------------
|
|
|
|
// 전체 선택/해제 체크박스 이벤트
|
|
$("#allQuoteCheck").change(function() {
|
|
$("input[name='quote_check']").prop('checked', $(this).prop('checked'));
|
|
});
|
|
|
|
// 견적 행 추가/삭제 버튼 이벤트
|
|
$("#btnAddQuoteRow").click(function() {
|
|
addNewQuoteRow();
|
|
});
|
|
|
|
$("#btnDeleteQuoteRow").click(function() {
|
|
deleteSelectedQuoteRows();
|
|
});
|
|
|
|
// -----------------------------------------------------------
|
|
// 3-9. 기존 견적 데이터 초기화 (JSTL로 렌더링된 행들 처리)
|
|
// -----------------------------------------------------------
|
|
|
|
// 페이지 로드 후 기존 견적 데이터의 이벤트 바인딩 및 파일 로드
|
|
setTimeout(function() {
|
|
initializeExistingQuoteRows();
|
|
}, 500); // 다른 초기화가 완료된 후 실행
|
|
|
|
});
|
|
|
|
// ===================================================================
|
|
// 4. 기본 비즈니스 로직 함수들
|
|
// ===================================================================
|
|
|
|
// -----------------------------------------------------------
|
|
// 4-1. 수주가 자동계산 함수
|
|
// -----------------------------------------------------------
|
|
function calculateOrderAmount() {
|
|
var quoteAmount1st = parseFloat($("#quote_amount_1st").val()) || 0;
|
|
var quoteAmount2nd = parseFloat($("#quote_amount_2nd").val()) || 0;
|
|
var quoteAmount3rd = parseFloat($("#quote_amount_3rd").val()) || 0;
|
|
var facilityQty = parseFloat($("#facility_qty").val()) || 0;
|
|
|
|
// 견적금액 중 최신값(3차 > 2차 > 1차) 선택
|
|
var latestQuoteAmount = 0;
|
|
if (quoteAmount3rd > 0) {
|
|
latestQuoteAmount = quoteAmount3rd;
|
|
} else if (quoteAmount2nd > 0) {
|
|
latestQuoteAmount = quoteAmount2nd;
|
|
} else if (quoteAmount1st > 0) {
|
|
latestQuoteAmount = quoteAmount1st;
|
|
}
|
|
|
|
// 수주가 = 최신 견적금액 * 설비대수
|
|
var orderAmount = latestQuoteAmount * facilityQty;
|
|
|
|
if (orderAmount > 0) {
|
|
$("#contract_price").val(addComma(orderAmount.toFixed(0)));
|
|
} else {
|
|
$("#contract_price").val("");
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------
|
|
// 4-2. 날짜 선택기 초기화 함수
|
|
// -----------------------------------------------------------
|
|
function _fnc_datepick() {
|
|
var $dateinput = $("input.date_icon");
|
|
for (var i = 0; i < $dateinput.length; i++) {
|
|
$dateinput.eq(i).attr("size", "10");
|
|
$dateinput.eq(i).datepicker({
|
|
changeMonth : true,
|
|
changeYear : true
|
|
});
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------
|
|
// 4-3. 저장 함수 (메인 비즈니스 로직)
|
|
// -----------------------------------------------------------
|
|
function fn_save() {
|
|
try {
|
|
if (fnc_valitate("form1")) {
|
|
var message = "수정";
|
|
if ("${actionType}" == 'regist') {
|
|
message = "등록";
|
|
}
|
|
if (confirm(message + "하시겠습니까?")) {
|
|
// 견적 데이터 수집
|
|
var quoteData = collectQuoteData();
|
|
|
|
// 기본 폼 데이터와 견적 데이터를 함께 전송
|
|
var formData = $("#form1").serialize();
|
|
if (quoteData.length > 0) {
|
|
formData += ""eData=" + encodeURIComponent(JSON.stringify(quoteData));
|
|
}
|
|
|
|
$.ajax({
|
|
url : "/contractMgmt/saveContractMgmtInfo.do",
|
|
type : "POST",
|
|
data : formData,
|
|
dataType : "json",
|
|
success : function(data) {
|
|
try {
|
|
alert(data.msg || "저장이 완료되었습니다.");
|
|
if (opener && typeof opener.fn_search === 'function') {
|
|
opener.fn_search();
|
|
}
|
|
self.close();
|
|
} catch(e) {
|
|
console.error('저장 후 처리 실패:', e);
|
|
alert("저장은 완료되었지만 화면 갱신 중 오류가 발생했습니다.");
|
|
}
|
|
},
|
|
error : function(jqxhr, status, error) {
|
|
console.error("저장 실패:", error);
|
|
alert("저장 중 오류가 발생했습니다. 다시 시도해주세요.");
|
|
}
|
|
});
|
|
}
|
|
}
|
|
} catch(e) {
|
|
console.error('저장 함수 실행 실패:', e);
|
|
alert("저장 중 예기치 않은 오류가 발생했습니다.");
|
|
}
|
|
}
|
|
|
|
// ===================================================================
|
|
// 5. 파일 관리 함수들 (기본 첨부파일용)
|
|
// ===================================================================
|
|
|
|
// -----------------------------------------------------------
|
|
// 5-1. 개선된 드래그 앤 드롭 기능
|
|
// -----------------------------------------------------------
|
|
function fnc_setFileDropZone2(divId, targetObjId, docType, docTypeName, callbackFnc, onlyOne, preProcessor, url, okExt) {
|
|
try {
|
|
var obj = $("#" + divId);
|
|
|
|
if (obj.length === 0) {
|
|
console.warn('드롭존 요소를 찾을 수 없습니다:', divId);
|
|
return;
|
|
}
|
|
|
|
// 드래그 앤 드롭 이벤트 처리
|
|
obj.on('dragenter', function(e) {
|
|
e.stopPropagation();
|
|
e.preventDefault();
|
|
$(this).addClass('dragover');
|
|
});
|
|
|
|
obj.on('dragleave', function(e) {
|
|
e.stopPropagation();
|
|
e.preventDefault();
|
|
$(this).removeClass('dragover');
|
|
});
|
|
|
|
obj.on('dragover', function(e) {
|
|
e.stopPropagation();
|
|
e.preventDefault();
|
|
});
|
|
|
|
obj.on('drop', function(e) {
|
|
try {
|
|
e.preventDefault();
|
|
$(this).removeClass('dragover');
|
|
|
|
var files = e.originalEvent.dataTransfer.files;
|
|
if (files.length < 1) return;
|
|
|
|
if (onlyOne && files.length > 1) {
|
|
if (typeof Swal !== 'undefined') {
|
|
Swal.fire("1개의 파일만 등록 가능합니다.");
|
|
} else {
|
|
alert("1개의 파일만 등록 가능합니다.");
|
|
}
|
|
return;
|
|
}
|
|
|
|
// 드롭된 파일 즉시 업로드 처리
|
|
processFileUpload(files, targetObjId, docType, docTypeName, callbackFnc, url, okExt);
|
|
} catch(e) {
|
|
console.error('파일 드롭 처리 실패:', e);
|
|
}
|
|
});
|
|
|
|
// 클릭 이벤트 처리 - 자동 업로드 기능 추가
|
|
obj.on('click', function() {
|
|
try {
|
|
// 숨겨진 파일 입력 요소 생성
|
|
var input = $('<input type="file" multiple style="display:none;" accept="*/*">');
|
|
|
|
// 파일 선택 시 자동 업로드 처리
|
|
input.on('change', function() {
|
|
try {
|
|
var files = this.files;
|
|
if (files.length > 0) {
|
|
// 선택된 파일을 즉시 업로드 처리
|
|
processFileUpload(files, targetObjId, docType, docTypeName, callbackFnc, url, okExt);
|
|
}
|
|
// 사용 후 요소 제거
|
|
$(this).remove();
|
|
} catch(e) {
|
|
console.error('파일 선택 처리 실패:', e);
|
|
$(this).remove();
|
|
}
|
|
});
|
|
|
|
// DOM에 추가하고 클릭 트리거
|
|
$('body').append(input);
|
|
input.click();
|
|
} catch(e) {
|
|
console.error('파일 선택 대화상자 열기 실패:', e);
|
|
}
|
|
});
|
|
} catch(e) {
|
|
console.error('드롭존 초기화 실패:', e);
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------
|
|
// 5-2. 파일 업로드 처리 통합 함수
|
|
// -----------------------------------------------------------
|
|
function processFileUpload(files, targetObjId, docType, docTypeName, callbackFnc, url, okExt) {
|
|
try {
|
|
// 기본 URL 설정
|
|
if (!url) url = "/common/fileUploadProc.do";
|
|
|
|
// 파일 검증 및 업로드 실행
|
|
fnc_fileMultiUpload1(files, null, targetObjId, docType, docTypeName, url, callbackFnc, okExt);
|
|
} catch(e) {
|
|
console.error('파일 업로드 처리 실패:', e);
|
|
if (typeof Swal !== 'undefined') {
|
|
Swal.fire("파일 처리 중 오류가 발생했습니다.");
|
|
} else {
|
|
alert("파일 처리 중 오류가 발생했습니다.");
|
|
}
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------
|
|
// 5-3. 파일 검증 및 업로드 실행 함수
|
|
// -----------------------------------------------------------
|
|
function fnc_fileMultiUpload1(files, obj, targetObjId, docType, docTypeName, uploadUrl, callbackFnc, okExt) {
|
|
try {
|
|
// 파일 검증 단계
|
|
if (!validateFiles(files, okExt)) {
|
|
return; // 검증 실패 시 업로드 중단
|
|
}
|
|
|
|
// 업로드 확인 메시지
|
|
if (confirm(files.length + "개의 파일을 업로드 하시겠습니까?")) {
|
|
executeFileUpload(files, targetObjId, docType, docTypeName, uploadUrl, callbackFnc);
|
|
}
|
|
} catch(e) {
|
|
console.error('파일 업로드 함수 실행 실패:', e);
|
|
if (typeof Swal !== 'undefined') {
|
|
Swal.fire("파일 업로드 중 예기치 않은 오류가 발생했습니다.");
|
|
} else {
|
|
alert("파일 업로드 중 예기치 않은 오류가 발생했습니다.");
|
|
}
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------
|
|
// 5-4. 파일 검증 함수
|
|
// -----------------------------------------------------------
|
|
function validateFiles(files, okExt) {
|
|
try {
|
|
if (!files || files.length === 0) {
|
|
return false;
|
|
}
|
|
|
|
// 허용된 확장자 검증
|
|
if (okExt != null && okExt !== "") {
|
|
for (var i = 0; i < files.length; i++) {
|
|
var fileName = files[i].name;
|
|
var ext = fileName.substring(fileName.lastIndexOf(".") + 1).toUpperCase() + ",";
|
|
if ((okExt.toUpperCase() + ",").indexOf(ext) < 0) {
|
|
if (typeof Swal !== 'undefined') {
|
|
Swal.fire("허용되지 않은 확장자입니다.\n업로드 가능 확장자 : " + okExt);
|
|
} else {
|
|
alert("허용되지 않은 확장자입니다.\n업로드 가능 확장자 : " + okExt);
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
} else {
|
|
// 위험한 확장자 차단
|
|
var dangerousExt = "JSP,BAT,EXE,PHP,JS,SQL";
|
|
for (var i = 0; i < files.length; i++) {
|
|
var fileName = files[i].name;
|
|
var ext = fileName.substring(fileName.lastIndexOf(".") + 1).toUpperCase();
|
|
if (dangerousExt.toUpperCase().indexOf(ext) >= 0) {
|
|
if (typeof Swal !== 'undefined') {
|
|
Swal.fire("보안상 허용되지 않은 확장자입니다: " + ext);
|
|
} else {
|
|
alert("보안상 허용되지 않은 확장자입니다: " + ext);
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 파일명 특수문자 검증
|
|
for (var i = 0; i < files.length; i++) {
|
|
var fileName = files[i].name;
|
|
var pattern = /[#%&*+[\]]/;
|
|
if (pattern.test(fileName)) {
|
|
if (typeof Swal !== 'undefined') {
|
|
Swal.fire("파일명에 허용되지 않은 특수문자가 포함되어 있습니다(#,%,&,*,+,[,]).");
|
|
} else {
|
|
alert("파일명에 허용되지 않은 특수문자가 포함되어 있습니다(#,%,&,*,+,[,]).");
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true; // 모든 검증 통과
|
|
} catch(e) {
|
|
console.error('파일 검증 실패:', e);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------
|
|
// 5-5. 실제 파일 업로드 실행 함수
|
|
// -----------------------------------------------------------
|
|
function executeFileUpload(files, targetObjId, docType, docTypeName, uploadUrl, callbackFnc) {
|
|
try {
|
|
// 업로드 URL 기본값 설정
|
|
uploadUrl = fnc_checkNull(uploadUrl);
|
|
if (uploadUrl == "") uploadUrl = "/common/fileUploadProc.do";
|
|
|
|
// FormData 생성 및 파일 추가
|
|
var data = new FormData();
|
|
for (var i = 0; i < files.length; i++) {
|
|
data.append('file', files[i]);
|
|
}
|
|
|
|
// 업로드 메타데이터 추가
|
|
data.append("targetObjId", targetObjId);
|
|
data.append("docType", docType);
|
|
data.append("docTypeName", docTypeName);
|
|
|
|
// Ajax 업로드 실행
|
|
$.ajax({
|
|
url : uploadUrl,
|
|
method : 'post',
|
|
data : data,
|
|
dataType : 'text',
|
|
processData : false,
|
|
contentType : false,
|
|
beforeSend : function() {
|
|
console.log("파일 업로드 시작...");
|
|
},
|
|
success : function(res) {
|
|
try {
|
|
// 업로드 성공 시 콜백 함수 실행
|
|
if (fnc_checkNull(callbackFnc) != "") {
|
|
if (typeof window[callbackFnc] === 'function') {
|
|
window[callbackFnc]();
|
|
} else {
|
|
eval(callbackFnc + "();");
|
|
}
|
|
}
|
|
console.log("파일 업로드 완료");
|
|
} catch(e) {
|
|
console.error('업로드 후 콜백 실행 실패:', e);
|
|
}
|
|
},
|
|
error : function(jqxhr, status, error) {
|
|
console.error("업로드 실패:", error);
|
|
if (typeof Swal !== 'undefined') {
|
|
Swal.fire("업로드 중 오류가 발생했습니다: " + error);
|
|
} else {
|
|
alert("업로드 중 오류가 발생했습니다: " + error);
|
|
}
|
|
}
|
|
});
|
|
} catch(e) {
|
|
console.error('파일 업로드 함수 실행 실패:', e);
|
|
if (typeof Swal !== 'undefined') {
|
|
Swal.fire("파일 업로드 중 예기치 않은 오류가 발생했습니다.");
|
|
} else {
|
|
alert("파일 업로드 중 예기치 않은 오류가 발생했습니다.");
|
|
}
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------
|
|
// 5-6. 파일 영역 다시 그리기 및 콜백 함수들
|
|
// -----------------------------------------------------------
|
|
|
|
// 기본 파일 영역 다시 그리기
|
|
function fileAreaDraw() {
|
|
fn_fileCallback("contractMgmt01", "contractMgmt01");
|
|
fn_fileCallback("contractMgmt02", "contractMgmt02");
|
|
fn_fileCallback("contractMgmt03", "contractMgmt03");
|
|
}
|
|
|
|
// 파일 목록 콜백 함수 - 간단한 UI에 최적화
|
|
function fn_fileCallback(areaId, fileType) {
|
|
try {
|
|
$.ajax({
|
|
url : "/common/getFileList.do",
|
|
type : "POST",
|
|
data : {
|
|
"targetObjId" : "${objId}",
|
|
"docType" : fileType
|
|
},
|
|
dataType : "json",
|
|
async : false,
|
|
success : function(data) {
|
|
try {
|
|
var fileArea = $("#" + areaId + "FileArea");
|
|
if (fileArea.length === 0) {
|
|
console.warn('파일 영역을 찾을 수 없습니다:', areaId + "FileArea");
|
|
return;
|
|
}
|
|
|
|
fileArea.empty();
|
|
|
|
if (data && data.length > 0) {
|
|
var appendText = "";
|
|
$.each(data, function(i) {
|
|
appendText += "<tr>";
|
|
appendText += " <td>";
|
|
// 파일명 표시
|
|
var displayName = data[i].REAL_FILE_NAME || '파일명 없음';
|
|
if (displayName.length > 25) {
|
|
displayName = displayName.substring(0, 22) + "...";
|
|
}
|
|
appendText += " <a href='javascript:fnc_downloadFile(\"" + data[i].OBJID + "\")' class='file_link' title='" + (data[i].REAL_FILE_NAME || '') + "'>";
|
|
appendText += " " + displayName;
|
|
appendText += " </a>";
|
|
// 권한에 따른 삭제 버튼 표시
|
|
<c:if test="${param.actionType eq 'regist' or info.WRITER eq connectUserId or 'plm_admin' eq connectUserId}">
|
|
appendText += " <a href='javascript:fileDelete(\"" + data[i].OBJID + "\",\"" + areaId + "\")'>";
|
|
appendText += " <div class='delete_btn' title='파일 삭제'></div>";
|
|
appendText += " </a>";
|
|
</c:if>
|
|
appendText += " </td>";
|
|
appendText += "</tr>";
|
|
});
|
|
fileArea.append(appendText);
|
|
} else {
|
|
// 빈 목록 메시지
|
|
fileArea.append("<tr><td class='empty_file_message'>등록된 파일이 없습니다</td></tr>");
|
|
}
|
|
} catch(e) {
|
|
console.error('파일 목록 표시 실패:', e);
|
|
}
|
|
},
|
|
error : function(jqxhr, status, error) {
|
|
console.error("파일 목록 로드 실패:", error);
|
|
}
|
|
});
|
|
} catch(e) {
|
|
console.error('파일 콜백 함수 실행 실패:', e);
|
|
}
|
|
}
|
|
|
|
// 파일 삭제 함수
|
|
function fileDelete(fileObjId, areaId) {
|
|
try {
|
|
if (!fileObjId || !areaId) {
|
|
console.error('파일 삭제에 필요한 정보가 없습니다.');
|
|
return;
|
|
}
|
|
|
|
if (confirm("파일을 삭제하시겠습니까?")) {
|
|
$.ajax({
|
|
url : "/common/deleteFileInfo.do",
|
|
type : "POST",
|
|
data : { "objId" : fileObjId },
|
|
dataType : "json",
|
|
async : true,
|
|
success : function(data) {
|
|
try {
|
|
fileAreaDraw(); // 삭제 후 목록 새로고침
|
|
} catch(e) {
|
|
console.error('파일 삭제 후 목록 새로고침 실패:', e);
|
|
}
|
|
},
|
|
error : function(jqxhr, status, error) {
|
|
console.error("파일 삭제 실패:", error);
|
|
if (typeof Swal !== 'undefined') {
|
|
Swal.fire("파일 삭제 중 오류가 발생했습니다.");
|
|
} else {
|
|
alert("파일 삭제 중 오류가 발생했습니다.");
|
|
}
|
|
}
|
|
});
|
|
}
|
|
} catch(e) {
|
|
console.error('파일 삭제 함수 실행 실패:', e);
|
|
}
|
|
}
|
|
|
|
// 파일 체크 함수
|
|
function file_check(doctype, filesize) {
|
|
try {
|
|
var element = $("#" + doctype);
|
|
if (element.length === 0) {
|
|
console.warn('파일 체크 대상 요소를 찾을 수 없습니다:', doctype);
|
|
return;
|
|
}
|
|
|
|
if (filesize > 0) {
|
|
element.removeClass("file_icon file_empty_icon");
|
|
element.addClass("file_icon");
|
|
} else {
|
|
element.removeClass("file_icon file_empty_icon");
|
|
element.addClass("file_empty_icon");
|
|
}
|
|
} catch(e) {
|
|
console.error('파일 체크 함수 실행 실패:', e);
|
|
}
|
|
}
|
|
|
|
// ===================================================================
|
|
// 6. 견적이력관리 전용 함수들 - JSTL 적용 버전 (일괄삭제 기능 포함)
|
|
// ===================================================================
|
|
|
|
// -----------------------------------------------------------
|
|
// 6-1. 기존 견적 행들의 초기화 (JSTL로 렌더링된 행들 처리)
|
|
// -----------------------------------------------------------
|
|
function initializeExistingQuoteRows() {
|
|
console.log("기존 견적 행 초기화 시작...");
|
|
|
|
// JSTL로 렌더링된 모든 견적 행에 대해 초기화 작업 수행
|
|
$('#quoteTableBody tr.quote-row').each(function() {
|
|
var row = $(this);
|
|
var objId = row.data('objid');
|
|
|
|
if (objId) {
|
|
console.log("견적 행 초기화 - objId:", objId);
|
|
|
|
// Select2 적용
|
|
try {
|
|
row.find('.select2').select2();
|
|
} catch(e) {
|
|
console.warn('Select2 적용 실패:', e);
|
|
}
|
|
|
|
// 숫자 전용 입력 필드 설정
|
|
row.find('input[numberOnly]').on("keyup change", function() {
|
|
$(this).val(addComma($(this).val().replace(/[^0-9]/g, "")));
|
|
});
|
|
|
|
// 첨부파일 드롭존 초기화
|
|
try {
|
|
initQuoteFileDropZone(objId);
|
|
} catch(e) {
|
|
console.error('드롭존 초기화 실패:', e);
|
|
}
|
|
|
|
// 개별 체크박스 이벤트
|
|
row.find('input[name="quote_check"]').change(function() {
|
|
updateAllQuoteCheckStatus();
|
|
});
|
|
|
|
// 기존 파일 목록 로드
|
|
setTimeout(function() {
|
|
fn_quoteFileCallback("quoteFileList_" + objId, "QUOTE_DOCUMENT", objId);
|
|
}, 200);
|
|
}
|
|
});
|
|
|
|
console.log("기존 견적 행 초기화 완료");
|
|
}
|
|
|
|
// -----------------------------------------------------------
|
|
// 6-2. 새로운 견적 행 추가
|
|
// -----------------------------------------------------------
|
|
function addNewQuoteRow() {
|
|
quoteRowCounter++;
|
|
|
|
var newObjId = fnc_createObjId();
|
|
var today = new Date().toISOString().split('T')[0];
|
|
|
|
console.log("새로운 견적 행 추가 - objId:", newObjId);
|
|
|
|
// "데이터 없음" 행 제거
|
|
$('#noQuoteDataRow').remove();
|
|
|
|
var newRowHTML =
|
|
'<tr class="quote-row" data-objid="' + newObjId + '" data-is-new="true">' +
|
|
' <td style="text-align:center;">' +
|
|
' <input type="checkbox" name="quote_check" class="quote_row_checkbox">' +
|
|
' </td>' +
|
|
' <td>' +
|
|
' <input type="text" name="quote_sequence" class="quote_input" placeholder="차수" readonly value="' + quoteRowCounter + '">' +
|
|
' </td>' +
|
|
' <td>' +
|
|
' <select name="currency_type" class="quote_select select2" required>' +
|
|
currencyTypeOptions +
|
|
' </select>' +
|
|
' </td>' +
|
|
' <td>' +
|
|
' <input type="text" name="quote_amount" class="quote_input" placeholder="견적금액" numberOnly>' +
|
|
' </td>' +
|
|
' <td>' +
|
|
' <input type="date" name="quote_submit_date" class="quote_input" value="' + today + '">' +
|
|
' </td>' +
|
|
' <td>' +
|
|
' <div class="quote_file_container">' +
|
|
' <div id="quoteDropZone_' + newObjId + '" class="quote_dropzone" data-objid="' + newObjId + '">' +
|
|
' 견적서 첨부 (클릭 또는 드래그앤드롭)' +
|
|
' </div>' +
|
|
' <div id="quoteFileList_' + newObjId + '" class="quote_file_list" style="display:none;">' +
|
|
' </div>' +
|
|
' </div>' +
|
|
' <input type="hidden" name="quote_objid" value="' + newObjId + '">' +
|
|
' </td>' +
|
|
'</tr>';
|
|
|
|
// 테이블에 새 행 추가
|
|
$('#quoteTableBody').append(newRowHTML);
|
|
|
|
// 새로 추가된 행에 이벤트 바인딩
|
|
var newRow = $('#quoteTableBody tr:last');
|
|
|
|
// Select2 적용
|
|
try {
|
|
newRow.find('.select2').select2();
|
|
} catch(e) {
|
|
console.warn('Select2 적용 실패:', e);
|
|
}
|
|
|
|
// 숫자 전용 입력 필드 설정
|
|
newRow.find('input[numberOnly]').on("keyup change", function() {
|
|
$(this).val(addComma($(this).val().replace(/[^0-9]/g, "")));
|
|
});
|
|
|
|
// 첨부파일 드롭존 초기화 - 중요: 새로 추가된 행에서도 작동하도록
|
|
try {
|
|
initQuoteFileDropZone(newObjId);
|
|
} catch(e) {
|
|
console.error('드롭존 초기화 실패:', e);
|
|
}
|
|
|
|
// 개별 체크박스 이벤트
|
|
newRow.find('input[name="quote_check"]').change(function() {
|
|
updateAllQuoteCheckStatus();
|
|
});
|
|
|
|
console.log("견적 행 추가 완료:", newObjId);
|
|
}
|
|
|
|
// -----------------------------------------------------------
|
|
// 6-3. 선택된 견적 행 일괄 삭제 (배열 처리 방식으로 수정)
|
|
// -----------------------------------------------------------
|
|
function deleteSelectedQuoteRows() {
|
|
var checkedRows = $('input[name="quote_check"]:checked');
|
|
|
|
if (checkedRows.length === 0) {
|
|
Swal.fire({
|
|
icon: 'warning',
|
|
title: '선택 확인',
|
|
text: '삭제할 견적 정보를 선택해주세요.'
|
|
});
|
|
return;
|
|
}
|
|
|
|
// 삭제 확인 대화상자
|
|
Swal.fire({
|
|
title: '삭제 확인',
|
|
text: checkedRows.length + '개의 견적 정보를 삭제하시겠습니까?',
|
|
icon: 'question',
|
|
showCancelButton: true,
|
|
confirmButtonText: '삭제',
|
|
cancelButtonText: '취소',
|
|
confirmButtonColor: '#d33'
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
// 삭제 대상 objId 배열 수집
|
|
var targetObjIdList = [];
|
|
var newRowsToDelete = []; // 신규 추가된 행들 (DB에 없는 행)
|
|
|
|
checkedRows.each(function() {
|
|
var row = $(this).closest('tr');
|
|
var objId = row.data('objid');
|
|
var isNew = row.data('is-new');
|
|
|
|
if (objId) {
|
|
if (isNew) {
|
|
// 신규 추가된 행 (DB에 저장되지 않은 행)
|
|
newRowsToDelete.push(row);
|
|
} else {
|
|
// 기존 데이터 (DB에서 삭제 필요)
|
|
targetObjIdList.push(objId);
|
|
}
|
|
}
|
|
});
|
|
|
|
console.log("삭제 대상 - DB 저장된 견적:", targetObjIdList);
|
|
console.log("삭제 대상 - 신규 견적:", newRowsToDelete.length + "개");
|
|
|
|
// 1. 먼저 신규 추가된 행들을 화면에서 제거
|
|
$(newRowsToDelete).each(function() {
|
|
$(this).remove();
|
|
});
|
|
|
|
// 2. DB에 저장된 견적이 있는 경우 서버에 일괄 삭제 요청
|
|
if (targetObjIdList.length > 0) {
|
|
deleteQuotesFromServer(targetObjIdList, checkedRows);
|
|
} else {
|
|
// DB 삭제할 항목이 없는 경우 화면 갱신만 처리
|
|
updateQuoteTableAfterDelete();
|
|
showDeleteSuccessMessage(checkedRows.length);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// -----------------------------------------------------------
|
|
// 6-4. 서버에서 견적 데이터 일괄 삭제 (새로 추가된 함수)
|
|
// -----------------------------------------------------------
|
|
function deleteQuotesFromServer(targetObjIdList, originalCheckedRows) {
|
|
console.log("서버 일괄 삭제 요청:", targetObjIdList);
|
|
$.ajax({
|
|
url: "/contractMgmt/deleteQuoteInfoMultiple.do", // 새로운 일괄 삭제 URL
|
|
type: "POST",
|
|
data: {
|
|
"checkArr": targetObjIdList.join(",") // 배열을 콤마로 구분된 문자열로 변환
|
|
},
|
|
dataType: "json",
|
|
async: false,
|
|
success: function(data) {
|
|
try {
|
|
console.log("견적 일괄 삭제 응답:", data);
|
|
|
|
if (data.result) {
|
|
// 삭제 성공 시 화면에서 해당 행들 제거
|
|
originalCheckedRows.each(function() {
|
|
var row = $(this).closest('tr');
|
|
var objId = row.data('objid');
|
|
var isNew = row.data('is-new');
|
|
|
|
// DB에 저장된 항목만 제거 (신규 항목은 이미 제거됨)
|
|
if (objId && !isNew && targetObjIdList.includes(objId)) {
|
|
row.remove();
|
|
}
|
|
});
|
|
|
|
updateQuoteTableAfterDelete();
|
|
showDeleteSuccessMessage(originalCheckedRows.length);
|
|
|
|
} else {
|
|
Swal.fire({
|
|
icon: 'error',
|
|
title: '삭제 실패',
|
|
text: data.msg || '견적 삭제 중 오류가 발생했습니다.'
|
|
});
|
|
}
|
|
} catch(e) {
|
|
console.error('삭제 응답 처리 실패:', e);
|
|
Swal.fire({
|
|
icon: 'error',
|
|
title: '처리 오류',
|
|
text: '삭제 응답 처리 중 오류가 발생했습니다.'
|
|
});
|
|
}
|
|
},
|
|
error: function(jqxhr, status, error) {
|
|
console.error("견적 일괄 삭제 실패:", error);
|
|
Swal.fire({
|
|
icon: 'error',
|
|
title: '서버 오류',
|
|
text: '서버 통신 중 오류가 발생했습니다: ' + error
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
// -----------------------------------------------------------
|
|
// 6-5. 삭제 후 테이블 상태 업데이트
|
|
// -----------------------------------------------------------
|
|
function updateQuoteTableAfterDelete() {
|
|
// 모든 행이 삭제된 경우 "데이터 없음" 메시지 표시
|
|
if ($('#quoteTableBody tr.quote-row').length === 0) {
|
|
$('#quoteTableBody').html(
|
|
'<tr id="noQuoteDataRow">' +
|
|
'<td colspan="6" style="text-align:center; color:#999; font-style:italic; padding:20px;">' +
|
|
'등록된 견적 정보가 없습니다' +
|
|
'</td>' +
|
|
'</tr>'
|
|
);
|
|
}
|
|
|
|
// 전체 선택 체크박스 상태 업데이트
|
|
updateAllQuoteCheckStatus();
|
|
}
|
|
|
|
// -----------------------------------------------------------
|
|
// 6-6. 삭제 성공 메시지 표시
|
|
// -----------------------------------------------------------
|
|
function showDeleteSuccessMessage(deletedCount) {
|
|
Swal.fire({
|
|
icon: 'success',
|
|
title: '삭제 완료',
|
|
text: deletedCount + '개의 견적 정보가 성공적으로 삭제되었습니다.',
|
|
timer: 1500,
|
|
showConfirmButton: false
|
|
});
|
|
}
|
|
|
|
// -----------------------------------------------------------
|
|
// 6-7. 견적서 첨부파일 드롭존 초기화
|
|
// -----------------------------------------------------------
|
|
function initQuoteFileDropZone(objId) {
|
|
var dropZone = $("#quoteDropZone_" + objId);
|
|
|
|
if (dropZone.length === 0) {
|
|
console.warn('드롭존을 찾을 수 없습니다:', "quoteDropZone_" + objId);
|
|
return;
|
|
}
|
|
|
|
console.log("견적서 드롭존 초기화 시작 - objId:", objId);
|
|
|
|
// 기존 이벤트 제거 (중복 바인딩 방지)
|
|
dropZone.off('dragenter dragleave dragover drop click');
|
|
|
|
// 드래그 앤 드롭 이벤트 처리
|
|
dropZone.on('dragenter', function(e) {
|
|
e.stopPropagation();
|
|
e.preventDefault();
|
|
$(this).addClass('dragover');
|
|
});
|
|
|
|
dropZone.on('dragleave', function(e) {
|
|
e.stopPropagation();
|
|
e.preventDefault();
|
|
$(this).removeClass('dragover');
|
|
});
|
|
|
|
dropZone.on('dragover', function(e) {
|
|
e.stopPropagation();
|
|
e.preventDefault();
|
|
});
|
|
|
|
dropZone.on('drop', function(e) {
|
|
try {
|
|
e.preventDefault();
|
|
$(this).removeClass('dragover');
|
|
|
|
var files = e.originalEvent.dataTransfer.files;
|
|
if (files.length > 0) {
|
|
uploadQuoteFiles(files, objId);
|
|
}
|
|
} catch(e) {
|
|
console.error('견적서 파일 드롭 처리 실패:', e);
|
|
}
|
|
});
|
|
|
|
// 클릭 이벤트 처리
|
|
dropZone.on('click', function() {
|
|
try {
|
|
var input = $('<input type="file" multiple style="display:none;" accept="*/*">');
|
|
|
|
input.on('change', function() {
|
|
var files = this.files;
|
|
if (files.length > 0) {
|
|
uploadQuoteFiles(files, objId);
|
|
}
|
|
$(this).remove();
|
|
});
|
|
|
|
$('body').append(input);
|
|
input.click();
|
|
} catch(e) {
|
|
console.error('파일 선택 대화상자 열기 실패:', e);
|
|
}
|
|
});
|
|
|
|
console.log("견적서 드롭존 초기화 완료 - objId:", objId);
|
|
}
|
|
|
|
// -----------------------------------------------------------
|
|
// 6-8. 견적서 파일 업로드 함수
|
|
// -----------------------------------------------------------
|
|
function uploadQuoteFiles(files, objId) {
|
|
if (!files || files.length === 0) return;
|
|
|
|
console.log("견적서 파일 업로드 시작 - objId:", objId, "파일 수:", files.length);
|
|
|
|
// 기본 파일 검증
|
|
for (var i = 0; i < files.length; i++) {
|
|
var fileName = files[i].name;
|
|
var ext = fileName.substring(fileName.lastIndexOf(".") + 1).toUpperCase();
|
|
var dangerousExt = ["JSP", "BAT", "EXE", "PHP", "JS", "SQL"];
|
|
|
|
if (dangerousExt.indexOf(ext) >= 0) {
|
|
if (typeof Swal !== 'undefined') {
|
|
Swal.fire("보안상 허용되지 않은 확장자입니다: " + ext);
|
|
} else {
|
|
alert("보안상 허용되지 않은 확장자입니다: " + ext);
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
// 업로드 처리
|
|
try {
|
|
var data = new FormData();
|
|
for (var i = 0; i < files.length; i++) {
|
|
data.append('file', files[i]);
|
|
}
|
|
|
|
data.append("targetObjId", objId);
|
|
data.append("docType", "QUOTE_DOCUMENT");
|
|
data.append("docTypeName", "견적서");
|
|
|
|
$.ajax({
|
|
url: "/common/fileUploadProc.do",
|
|
method: 'post',
|
|
data: data,
|
|
dataType: 'text',
|
|
processData: false,
|
|
contentType: false,
|
|
success: function(res) {
|
|
try {
|
|
console.log("견적서 파일 업로드 완료 - objId:", objId);
|
|
fn_quoteFileCallback("quoteFileList_" + objId, "QUOTE_DOCUMENT", objId);
|
|
} catch(e) {
|
|
console.error('업로드 후 콜백 실행 실패:', e);
|
|
}
|
|
},
|
|
error: function(jqxhr, status, error) {
|
|
console.error("견적서 파일 업로드 실패:", error);
|
|
if (typeof Swal !== 'undefined') {
|
|
Swal.fire("업로드 중 오류가 발생했습니다: " + error);
|
|
} else {
|
|
alert("업로드 중 오류가 발생했습니다: " + error);
|
|
}
|
|
}
|
|
});
|
|
} catch(e) {
|
|
console.error('견적서 파일 업로드 실패:', e);
|
|
alert('파일 업로드 중 오류가 발생했습니다.');
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------
|
|
// 6-9. 견적서 파일 목록 콜백 함수
|
|
// -----------------------------------------------------------
|
|
function fn_quoteFileCallback(areaId, fileType, targetObjId) {
|
|
console.log("견적서 파일 목록 로드 시작 - areaId:", areaId, "targetObjId:", targetObjId);
|
|
|
|
$.ajax({
|
|
url: "/common/getFileList.do",
|
|
type: "POST",
|
|
data: {
|
|
"targetObjId": targetObjId,
|
|
"docType": fileType
|
|
},
|
|
dataType: "json",
|
|
success: function(data) {
|
|
try {
|
|
var fileArea = $("#" + areaId);
|
|
if (fileArea.length === 0) {
|
|
console.warn('파일 영역을 찾을 수 없습니다:', areaId);
|
|
return;
|
|
}
|
|
|
|
fileArea.empty();
|
|
|
|
console.log("견적서 파일 목록 응답:", data);
|
|
|
|
if (data && data.length > 0) {
|
|
fileArea.show();
|
|
$.each(data, function(i, file) {
|
|
var fileItem = $('<div class="quote_file_item"></div>');
|
|
|
|
var fileName = file.REAL_FILE_NAME;
|
|
if (fileName.length > 20) {
|
|
fileName = fileName.substring(0, 17) + "...";
|
|
}
|
|
|
|
var fileLink = $('<a href="javascript:fnc_downloadFile(\'' + file.OBJID + '\')" class="quote_file_link" title="' + file.REAL_FILE_NAME + '">' + fileName + '</a>');
|
|
var deleteBtn = $('<div class="quote_delete_btn" onclick="deleteQuoteFile(\'' + file.OBJID + '\', \'' + targetObjId + '\')" title="파일 삭제"></div>');
|
|
|
|
fileItem.append(fileLink);
|
|
fileItem.append(deleteBtn);
|
|
fileArea.append(fileItem);
|
|
});
|
|
|
|
console.log("견적서 파일 목록 표시 완료 - " + data.length + "개 파일");
|
|
} else {
|
|
fileArea.hide();
|
|
console.log("견적서 파일 목록 없음");
|
|
}
|
|
} catch(e) {
|
|
console.error('견적서 파일 목록 처리 실패:', e);
|
|
}
|
|
},
|
|
error: function(jqxhr, status, error) {
|
|
console.error("견적서 파일 목록 로드 실패:", error);
|
|
}
|
|
});
|
|
}
|
|
|
|
// -----------------------------------------------------------
|
|
// 6-10. 견적서 파일 삭제
|
|
// -----------------------------------------------------------
|
|
function deleteQuoteFile(fileObjId, parentObjId) {
|
|
if (confirm("파일을 삭제하시겠습니까?")) {
|
|
$.ajax({
|
|
url: "/common/deleteFileInfo.do",
|
|
type: "POST",
|
|
data: { "objId": fileObjId },
|
|
dataType: "json",
|
|
success: function(data) {
|
|
fn_quoteFileCallback("quoteFileList_" + parentObjId, "QUOTE_DOCUMENT", parentObjId);
|
|
},
|
|
error: function(jqxhr, status, error) {
|
|
console.error("파일 삭제 실패:", error);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------
|
|
// 6-11. 기타 견적 관리 함수들
|
|
// -----------------------------------------------------------
|
|
|
|
// 기존 개별 삭제 함수 (유지 - 필요시 사용)
|
|
function deleteQuoteFromServer(objId) {
|
|
if (!objId) {
|
|
console.warn('삭제할 견적 objId가 없습니다.');
|
|
return;
|
|
}
|
|
|
|
console.log("개별 견적 데이터 삭제 요청:", objId);
|
|
|
|
$.ajax({
|
|
url: "/contractMgmt/deleteQuoteInfo.do", // 기존 개별 삭제 URL
|
|
type: "POST",
|
|
data: { "objId": objId },
|
|
dataType: "json",
|
|
success: function(data) {
|
|
if (data.result) {
|
|
console.log("견적 정보 삭제 완료:", objId);
|
|
} else {
|
|
console.error("견적 정보 삭제 실패:", data.msg);
|
|
}
|
|
},
|
|
error: function(jqxhr, status, error) {
|
|
console.error("견적 정보 삭제 실패:", error);
|
|
}
|
|
});
|
|
}
|
|
|
|
// 전체 선택 체크박스 상태 업데이트
|
|
function updateAllQuoteCheckStatus() {
|
|
try {
|
|
var totalCheckboxes = $('input[name="quote_check"]').length;
|
|
var checkedCheckboxes = $('input[name="quote_check"]:checked').length;
|
|
|
|
if (totalCheckboxes === 0) {
|
|
$("#allQuoteCheck").prop('checked', false);
|
|
} else if (checkedCheckboxes === totalCheckboxes) {
|
|
$("#allQuoteCheck").prop('checked', true);
|
|
} else {
|
|
$("#allQuoteCheck").prop('checked', false);
|
|
}
|
|
} catch(e) {
|
|
console.error('체크박스 상태 업데이트 실패:', e);
|
|
}
|
|
}
|
|
|
|
// 견적 데이터 수집 (저장 시 사용)
|
|
function collectQuoteData() {
|
|
var quoteData = [];
|
|
|
|
try {
|
|
$('#quoteTableBody tr.quote-row').each(function() {
|
|
var row = $(this);
|
|
var objId = row.data('objid');
|
|
var isNew = row.data('is-new');
|
|
|
|
if (!objId) {
|
|
console.warn('견적 행에 objId가 없습니다.');
|
|
return true; // continue
|
|
}
|
|
|
|
var sequence = row.find('input[name="quote_sequence"]').val() || '';
|
|
var currencyType = row.find('select[name="currency_type"]').val() || '';
|
|
var amount = row.find('input[name="quote_amount"]').val() || '';
|
|
var submitDate = row.find('input[name="quote_submit_date"]').val() || '';
|
|
var originalObjId = row.find('input[name="quote_original_objid"]').val() || '';
|
|
|
|
// 금액에서 콤마 제거
|
|
if (amount) {
|
|
amount = amount.replace(/,/g, '');
|
|
}
|
|
|
|
var data = {
|
|
objId: objId,
|
|
originalObjId: originalObjId,
|
|
sequence: sequence,
|
|
currencyType: currencyType,
|
|
amount: amount,
|
|
submitDate: submitDate,
|
|
isNew: isNew
|
|
};
|
|
|
|
quoteData.push(data);
|
|
});
|
|
} catch(e) {
|
|
console.error('견적 데이터 수집 실패:', e);
|
|
}
|
|
|
|
console.log("수집된 견적 데이터:", quoteData);
|
|
return quoteData;
|
|
}
|
|
|
|
// ===================================================================
|
|
// 7. 기타 유틸리티 함수들
|
|
// ===================================================================
|
|
|
|
// 숫자 전용 입력 처리
|
|
function fnc_numberOnly(obj) {
|
|
$("#" + obj.attr("id")).val(addComma(obj.val().replace(/[^0-9]/g, "")));
|
|
}
|
|
|
|
// 로딩 관련 함수들
|
|
function _startLoading1(loadingMsg) {
|
|
$(".loader_back").hide();
|
|
$(".loader").show();
|
|
}
|
|
|
|
function _endLoading1() {
|
|
$(".loader").hide();
|
|
$(".loader_back").show();
|
|
}
|
|
|
|
// 파일 콜백 함수 (레거시)
|
|
function fnc_fileMultiUpload1_Callback(files) {
|
|
for (var i = 0; i < files.length; i++)
|
|
console.log(files[i].file_nm + " - " + files[i].file_size);
|
|
}
|
|
</script>
|
|
</head>
|
|
<body>
|
|
<form name="form1" id="form1" action="" method="post">
|
|
<input type="hidden" name="objId" id="objId" value="${objId}">
|
|
<input type="hidden" name="option" id="option">
|
|
<input type="hidden" name="actionType" id="actionType" value="${actionType}">
|
|
|
|
<section class="business_popup_min_width">
|
|
|
|
|
|
<div id="EntirePopupFormWrap">
|
|
<div class="form_popup_title">
|
|
<span>사양상세</span>
|
|
</div>
|
|
<table class="">
|
|
<tr>
|
|
<td>
|
|
<table class="pmsPopuptable">
|
|
<colgroup>
|
|
<col width="16.66%" />
|
|
<col width="16.66%" />
|
|
<col width="16.66%" />
|
|
<col width="16.66%" />
|
|
<col width="16.66%" />
|
|
<col width="16.66%" />
|
|
</colgroup>
|
|
<tr>
|
|
<td class="input_title"><label for="">재질</label></td>
|
|
<td class="input_title"><label for="">압력(BAR)</label></td>
|
|
<td class="input_title"><label for="">온도(℃)</label></td>
|
|
<td class="input_title"><label for="">용량(LITER)</label></td>
|
|
<td class="input_title"><label for="">I.D(mm)</label></td>
|
|
<td class="input_title"><label for="">I.L(mm)</label></td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<input type="text" name="material" id="material" reqTitle="재질" value="${info.MATERIAL}" placeholder="직접 입력" />
|
|
</td>
|
|
<td>
|
|
<input type="number" step="0.01" name="pressure_bar" id="pressure_bar" reqTitle="압력(BAR)" value="${info.PRESSURE_BAR}" placeholder="숫자 입력" />
|
|
</td>
|
|
<td>
|
|
<input type="number" step="0.01" name="temperature_celsius" id="temperature_celsius" reqTitle="온도(℃)" value="${info.TEMPERATURE_CELSIUS}" placeholder="숫자 입력" />
|
|
</td>
|
|
<td>
|
|
<input type="number" step="0.01" name="capacity_liter" id="capacity_liter" reqTitle="용량(LITER)" value="${info.CAPACITY_LITER}" placeholder="숫자 입력" />
|
|
</td>
|
|
<td>
|
|
<input type="text" name="idmm" id="idmm" reqTitle="idmm" value="${info.IDMM}" placeholder="입력" />
|
|
</td>
|
|
<td>
|
|
<input type="text" name="ilmm" id="ilmm" reqTitle="ilmm" value="${info.ILMM}" placeholder="입력" />
|
|
</td>
|
|
|
|
</tr>
|
|
<tr>
|
|
<td class="input_title"><label for="">Closure type</label></td>
|
|
<td class="input_title"><label for="">기타(소모품)</label></td>
|
|
<td class="input_title"><label for="">전압</label></td>
|
|
<td class="input_title"><label for="">인증여부</label></td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<input type="text" name="closure_type" id="closure_type" reqTitle="Closure Type" value="${info.CLOSURE_TYPE}" placeholder="직접 입력" />
|
|
</td>
|
|
<td>
|
|
<input type="text" name="consumables_etc" id="consumables_etc" reqTitle="기타(소모품)" value="${info.CONSUMABLES_ETC}" placeholder="직접 입력" />
|
|
</td>
|
|
<td>
|
|
<input type="text" name="voltage" id="voltage" reqTitle="전압" value="${info.VOLTAGE}" placeholder="직접 입력" />
|
|
</td>
|
|
<td>
|
|
|
|
<select name="certification_status" id="certification_status" required reqTitle="인증여부" type="select" class="select2">
|
|
<option value="">선택</option>
|
|
<option value="Y">필요</option>
|
|
<option value="N">불필요</option>
|
|
</select>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
|
|
|
|
<div class="btn_wrap">
|
|
<div class="plm_btn_wrap_center">
|
|
<%-- <c:choose>
|
|
<c:when test="${actionType eq 'regist'}">
|
|
<input type="button" value="저장" id="btnSave" class="plm_btns">
|
|
</c:when>
|
|
<c:otherwise>
|
|
<input type="button" value="수정" id="btnSave" class="plm_btns">
|
|
</c:otherwise>
|
|
</c:choose> --%>
|
|
<input type="button" value="닫기" id="btnClose" class="plm_btns">
|
|
</div>
|
|
</div>
|
|
|
|
</section>
|
|
</form>
|
|
</body>
|
|
</html> |