Files
sam-kd/shutterbox/fetch_modal.php
hskwon aca1767eb9 초기 커밋: 5130 레거시 시스템
- URL 하드코딩 → .env APP_URL 기반 동적 URL로 변경
- DB 연결 하드코딩 → .env 기반으로 변경
- MySQL strict mode DATE 오류 수정
2025-12-10 20:14:31 +09:00

543 lines
30 KiB
PHP

<?php
require_once($_SERVER['DOCUMENT_ROOT'] . "/session.php");
$mode = isset($_POST['mode']) ? $_POST['mode'] : '';
$num = isset($_POST['num']) ? $_POST['num'] : '';
$tablename = isset($_POST['tablename']) ? $_POST['tablename'] : '';
require_once($_SERVER['DOCUMENT_ROOT'] . "/common.php"); // 초기파일 로드
require_once($_SERVER['DOCUMENT_ROOT'] . "/lib/mydb.php");
$pdo = db_connect();
// --- 변수 초기화 ---
$bending_components = '';
$registration_date = date('Y-m-d');
$author = isset($user_name) ? $user_name : '';
$num_display = $num;
if ( ($mode === 'modify' or $mode === 'copy' or $mode === 'view' ) && $num) {
try {
$sql = "SELECT * FROM {$DB}.$tablename WHERE num=? ";
$stmh = $pdo->prepare($sql);
$stmh->bindValue(1, $num, PDO::PARAM_INT);
$stmh->execute();
$row = $stmh->fetch(PDO::FETCH_ASSOC);
if ($row) {
include '_row.php';
}
if ($mode === 'copy') {
$registration_date = date('Y-m-d');
$num_display = ''; // 복사 모드에서는 번호 비움
$author = isset($user_name) ? $user_name : '';
}
} catch (PDOException $Exception) {
echo "오류: ".$Exception->getMessage();
exit;
}
} else {
include '_request.php';
$mode = 'insert';
$registration_date = date('Y-m-d');
$author = isset($user_name) ? $user_name : '';
}
$title_message = ($mode === 'view') ? "셔터박스 조회 (#{$num_display})" : '셔터박스 등록';
$title_message = ($mode === 'modify') ? "셔터박스 수정 (#{$num_display})" : $title_message ;
$title_message = ($mode === 'copy') ? '셔터박스 (데이터 복사)' : $title_message ;
// 기존에 저장된 값이 있는 경우 해당 값을 설정
$selected_exit_direction = isset($row['exit_direction']) ? $row['exit_direction'] : '양면 점검구';
$is_assembly_model = true;
?>
<link href="../css/bending.css?v=<?php echo time(); ?>" rel="stylesheet"> <!-- 절곡관련 (가이드레일,케이스,하단마감재) -->
<input type="hidden" id="update_log" name="update_log" value="<?= isset($update_log) ? htmlspecialchars($update_log, ENT_QUOTES, 'UTF-8') : '' ?>">
<input type="hidden" id="selected_exit_direction" name="selected_exit_direction" value="<?=$selected_exit_direction?>">
<input type="hidden" id="bending_components_data" name="bending_components" value="<?= htmlspecialchars($bending_components, ENT_QUOTES, 'UTF-8') ?>">
<input type="hidden" id="material_summary" name="material_summary" value="<?= isset($material_summary) ? htmlspecialchars($material_summary, ENT_QUOTES, 'UTF-8') : '' ?>">
<div class="container-fluid">
<div class="card justify-content-center">
<div class="card-header text-center" style="height: 45px;">
<div class="row" style="height: 40px;">
<div class="col-sm-10">
<div class="d-flex align-items-center justify-content-center">
<span class="text-center mx-5"><?= $mode ?></span>
<span class="text-center fs-6 me-5"> <?=$title_message?> </span>
<?php if($mode == 'view' ) { ?>
<button type="button" id="modifyBtn" data-num="<?=$num?>" class="btn btn-dark btn-sm mx-1"> <i class="bi bi-pencil-square"></i> 수정 </button>
<button id="copyBtn" data-num="<?=$num?>" class="btn btn-primary btn-sm mx-1" type="button"><i class="bi bi-copy"></i> 복사 </button>
<?php } ?>
<?php if($mode == 'insert' || $mode == 'modify' || $mode == 'copy' ) { ?>
<button type="button" id="saveBtn" class="btn btn-dark btn-sm mx-1"> <i class="bi bi-save"></i> 저장 </button>
<button type="button" class="btn btn-dark btn-sm mx-1 registImageBtn"> <i class="bi bi-list"></i> 결합형태 이미지 등록 </button>
<?php } ?>
<?php if( $mode == 'view' ) { ?>
<button type="button" id="deleteBtn" class="btn btn-danger btn-sm mx-1"> <i class="bi bi-trash"></i> 삭제 </button>
<?php } ?>
</div>
</div>
<div class="col-sm-2">
<div class="d-flex align-items-center justify-content-end">
<button type="button" class="btn btn-outline-dark btn-sm me-2 closeBtn"> &times; 닫기 </button>
</div>
</div>
</div>
</div>
<div class="card-body">
<div class="row">
<div class="col-sm-8">
<div class="d-flex justify-content-center" style="padding : 2px;">
<table class="table table-bordered table-sm" id="mainTable">
<tbody>
<tr>
<td class="text-center fw-bold w80px" style="width:80px!important;"> 등록일</td>
<td class="text-center" >
<input type="date" class="form-control viewmode " id="registration_date" name="registration_date" value="<?=$registration_date?>">
</td>
<td class="text-center fw-bold">작성자</td>
<td class="text-center" style="width:100px;">
<input class="form-control viewmode " id="author" name="author" value="<?=$author?>" autocomplete="off">
</td>
<td class="text-center" >
<div class="d-flex align-items-center justify-content-center">
<span class="text-center ms-1 me-1 text-primary fw-bold"> 가로(폭) </span>
<input type="text" class="form-control w50px text-primary ms-1 me-1 viewmode" id="box_width" name="box_width" value="<?= isset($box_width) ? htmlspecialchars($box_width, ENT_QUOTES, 'UTF-8') : '' ?>">
<span class="text-center ms-1 me-1"> x </span>
<span class="text-center ms-1 me-1 text-danger fw-bold"> 세로(높이) </span>
<input type="text" class="form-control w50px text-danger viewmode" id="box_height" name="box_height" value="<?= isset($box_height) ? htmlspecialchars($box_height, ENT_QUOTES, 'UTF-8') : '' ?>">
<span class="text-center ms-3 me-1 text-success fw-bold"> 전면밑 </span>
<input type="text" class="form-control w50px text-success viewmode inputVal" id="front_bottom_width" name="front_bottom_width" value="<?= isset($front_bottom_width) ? htmlspecialchars($front_bottom_width, ENT_QUOTES, 'UTF-8') : '' ?>">
<span class="text-center ms-2 me-1 text-danger fw-bold"> 레일폭 </span>
<input type="text" class="form-control w50px text-danger viewmode inputVal" id="rail_width" name="rail_width" value="<?= isset($rail_width) ? htmlspecialchars($rail_width, ENT_QUOTES, 'UTF-8') : '' ?>">
</div>
</td>
</tr>
<tr>
<td class="text-center " colspan="4" >
<div class="col text-center">
<label class="me-3">
<input type="radio" name="exit_direction" value="양면 점검구" <?php if($selected_exit_direction === '양면 점검구') echo 'checked'; ?>> 양면 점검구
</label>
<label class="me-3">
<input type="radio" name="exit_direction" value="밑면 점검구" <?php if($selected_exit_direction === '밑면 점검구') echo 'checked'; ?>> 밑면 점검구
</label>
<label>
<input type="radio" name="exit_direction" value="후면 점검구" <?php if($selected_exit_direction === '후면 점검구') echo 'checked'; ?>> 후면 점검구
</label>
</div>
</td>
<td class="text-center" colspan="1" >
<div class="d-flex align-items-center justify-content-center">
<span class="mx-2 fw-bold">품목 검색어</span>
<input type="text" class="form-control text-start viewmode" id="search_keyword" name="search_keyword" value="<?= isset($search_keyword) ? htmlspecialchars($search_keyword, ENT_QUOTES, 'UTF-8') : '' ?>" style="height: 30px;">
<span class="mx-2 fw-bold">비고</span>
<input type="text" class="form-control text-start viewmode" id="remark" name="remark" value="<?= isset($remark) ? htmlspecialchars($remark, ENT_QUOTES, 'UTF-8') : '' ?>" autocomplete="off" style="height: 30px;">
</div>
</td>
</tr>
<tr>
<td class="text-end" colspan="5">
<!-- 재질별 폭합 테이블 -->
<div id="materialSummaryArea" class="assembly-area" style="<?= !$is_assembly_model ? 'display:none;' : '' ?>">
<div class="d-flex justify-content-between align-items-center">
<small class="text-muted mx-1">※ 각 부품의 합계 </small>
<div class="table-responsive">
<table class="table table-bordered table-sm w-auto" id="materialSummaryTable">
<thead class="table-secondary">
<tr>
<th class="text-center" style="width: 50%;">재질</th>
<th class="text-center" style="width: 50%;">폭합계</th>
</tr>
</thead>
<tbody>
<!-- JavaScript로 동적으로 생성됨 -->
</tbody>
</table>
</div>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="col-sm-4" style="padding : 4px;">
<!-- 그리기 컨트롤 -->
<div class="d-flex align-items-center mb-2" style="width:260px;">
<?php if($mode!=='view') : ?>
<button id="openEditorBtn" type="button" class="btn btn-outline-dark btn-sm me-2 viewNoBtn">그리기</button>
<?php else: ?>
<div class="text-muted">
<i class="bi bi-info-circle"></i> 조회 모드, 그리기 기능 불가
</div>
<?php endif; ?>
</div>
<!-- 셔터박스용 이미지 표시 영역 (수정) -->
<div class="card mb-3">
<div class="card-body">
<div class="image-container mb-3">
<?php
// PHP: 셔터박스 JSON 파일 경로
$jsonFile = $_SERVER['DOCUMENT_ROOT'].'/shutterbox/shutterbox.json';
$imgUrl = '';
// 이미지 찾기 함수: 조건에 맞는 이미지 URL 리턴
function findImageByConditions($items, $conditions) {
foreach ($items as $item) {
$matched = true;
foreach ($conditions as $key => $value) {
if (empty($item[$key]) || $item[$key] !== $value) {
$matched = false;
break;
}
}
if ($matched && !empty($item['image'])) {
return $item['image'];
}
}
return '';
}
if ($mode === 'insert') {
// insert 모드: 기본 셔터박스 그림
switch ($selected_exit_direction) {
case '양면 점검구': $default = '../img/box/box_both.png'; break;
case '밑면 점검구': $default = '../img/box/box_bottom.png';break;
case '후면 점검구': $default = '../img/box/box_back.png'; break;
default: $default = '../img/box/box_both.png';
}
$imgUrl = $default;
} else {
// update 모드: JSON에서 검색
if (file_exists($jsonFile)) {
$shutterboxImages = json_decode(file_get_contents($jsonFile), true);
if (is_array($shutterboxImages)) {
// 우선순위 조건 배열
$searchCases = [
// 1순위: 키워드
!empty($row['search_keyword'])
? ['search_keyword' => $row['search_keyword']]
: null,
// 2순위: 모든 속성 일치
[
'box_width' => $row['box_width'],
'box_height' => $row['box_height'],
'front_bottom_width' => $row['front_bottom_width'],
'rail_width' => $row['rail_width'],
'exit_direction' => $row['exit_direction'],
],
];
// null 제거
$searchCases = array_filter($searchCases);
// 순차 검색
foreach ($searchCases as $case) {
$found = findImageByConditions($shutterboxImages, $case);
if ($found) {
$imgUrl = $found;
break;
}
}
}
}
}
?>
<?php if (!empty($imgUrl)): ?>
<img
id="targetImage"
src="<?= htmlspecialchars($imgUrl) ?>"
class="img-thumbnail img-fluid "
alt="편집할 이미지"
style="max-width:350px; cursor:pointer;"
>
<?php else: ?>
<img
id="targetImage"
src="../img/empty.png"
class="img-thumbnail img-fluid "
alt="이미지가 없습니다."
style="max-width:350px; cursor:pointer;"
>
<?php endif; ?>
<div class="paste-overlay" style="display: none;">
<i class="bi bi-clipboard-plus"></i>
<span>Ctrl+V로 이미지 붙여넣기</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row mb-2">
<div id="assemblyModelArea" class="assembly-area" style="<?= !$is_assembly_model ? 'display:none;' : '' ?>">
<div class="d-flex justify-content-between align-items-center mb-2">
<h5 class="mb-0">절곡 부품 조립</h5>
<div class="d-flex gap-2">
<button type="button" id="addPartBtn" class="btn btn-sm btn-info viewmode"><i class="bi bi-plus-lg"></i> 부품 추가</button>
<button type="button" id="removeAllPartBtn" class="btn btn-sm btn-danger viewmode"><i class="bi bi-minus-lg"></i> 전체 삭제</button>
</div>
</div>
<div class="d-flex justify-content-between align-items-center mb-2">
<div class="d-flex gap-2">
<button type="button" id="resetOrderBtn" class="btn btn-sm btn-outline-secondary viewmode"><i class="bi bi-arrow-clockwise"></i> 순서 초기화</button>
<button type="button" id="moveUpBtn" class="btn btn-sm btn-outline-primary viewmode"><i class="bi bi-arrow-up"></i> 위로</button>
<button type="button" id="moveDownBtn" class="btn btn-sm btn-outline-primary viewmode"><i class="bi bi-arrow-down"></i> 아래로</button>
</div>
<small class="text-muted">※ 순서변경은 위/아래 버튼을 사용하세요</small>
</div>
<div class="table-container d-flex">
<table class="table table-bordered" id="assemblyTable">
<tbody>
<!-- JavaScript로 동적으로 생성됨 -->
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<!-- 셔터박스 검색 Modal -->
<div id="shutterboxSearchModal" class="modal fade" tabindex="-1">
<div class="modal-dialog modal-fullscreen modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">셔터박스 조건 및 이미지 검색</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="row mb-3">
<div class="col-md-12">
<div class="d-flex flex-wrap gap-2 align-items-center mb-3" style="flex-wrap: wrap;">
<!-- 점검구 형태 라디오 버튼 -->
<div class="mx-2">
<div class="btn-group" role="group" aria-label="점검구 형태 선택">
<?php
$exit_direction_list = ['양면 점검구', '밑면 점검구', '후면 점검구'];
$selected_exit_direction = isset($_REQUEST['exit_direction_search']) ? $_REQUEST['exit_direction_search'] : '';
// 전체 옵션 추가
$all_checked = empty($selected_exit_direction) ? 'checked' : '';
echo '<input type="radio" class="btn-check" name="shutterbox_exit_direction_search" id="shutterbox_exit_direction_all" value="" ' . $all_checked . '>';
echo '<label class="btn btn-outline-secondary btn-sm" for="shutterbox_exit_direction_all">전체</label>';
foreach ($exit_direction_list as $item) {
$checked = ($selected_exit_direction === $item) ? 'checked' : '';
echo '<input type="radio" class="btn-check" name="shutterbox_exit_direction_search" id="shutterbox_exit_direction_' . htmlspecialchars($item, ENT_QUOTES, 'UTF-8') . '" value="' . htmlspecialchars($item, ENT_QUOTES, 'UTF-8') . '" ' . $checked . '>';
echo '<label class="btn btn-outline-primary btn-sm" for="shutterbox_exit_direction_' . htmlspecialchars($item, ENT_QUOTES, 'UTF-8') . '">' . htmlspecialchars($item, ENT_QUOTES, 'UTF-8') . '</label>';
}
?>
</div>
</div>
<!-- 검색어 입력 -->
<div class="input-group" style="width: auto; min-width: 200px;">
<input type="text" class="form-control text-start" id="shutterboxSearchInput" placeholder="품목검색어 입력" style="font-size: 0.9rem; height:35px!important;">
<button class="btn btn-primary" type="button" id="shutterboxSearchBtn" style="font-size: 0.9rem;"><i class="bi bi-search"></i> 검색</button>
</div>
<!-- 검색 조건 초기화 버튼 -->
<button class="btn btn-outline-secondary" type="button" id="resetShutterboxSearchBtn" style="font-size: 0.9rem;" ><i class="bi bi-arrow-clockwise"></i> 초기화</button>
</div>
</div>
</div>
<div class="table-responsive">
<table class="table table-hover table-bordered">
<thead class="table-secondary">
<tr>
<th style="width: 50px;" class="text-center">
<input class="form-check-input" type="checkbox" id="selectAllShutterboxItems">
</th>
<th style="width: 60px;" class="text-center">순서</th>
<th>점검구 형태</th>
<th>전면부 밑면치수</th>
<th>레일(폭)</th>
<th>품목검색어</th>
<th>이미지</th>
</tr>
</thead>
<tbody id="shutterboxSearchResults">
<!-- 검색 결과가 여기에 표시됩니다 -->
</tbody>
</table>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">취소</button>
<button type="button" class="btn btn-success" id="applyShutterboxSelectionBtn">선택 적용</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
// 셔터박스 검색 관련 JavaScript
$(document).ready(function() {
// 셔터박스 검색 버튼
$("#shutterboxSearchBtn").on("click", function() {
performShutterboxSearch();
});
// 라디오 버튼 변경 시 검색
$(document).on('change', 'input[name="shutterbox_exit_direction_search"]', function() {
performShutterboxSearch();
});
// 검색 조건 초기화
$("#resetShutterboxSearchBtn").on("click", function() {
// 라디오 버튼 초기화
$('#shutterboxSearchModal input[name="shutterbox_exit_direction_search"]').prop('checked', false);
$('#shutterbox_exit_direction_all').prop('checked', true);
// 검색어 초기화
$("#shutterboxSearchInput").val('');
performShutterboxSearch();
});
// 전체 선택 체크박스
$("#selectAllShutterboxItems").on("change", function() {
var isChecked = $(this).is(":checked");
$("#shutterboxSearchResults input[type='checkbox']").prop("checked", isChecked);
});
// 선택 적용 버튼
$("#applyShutterboxSelectionBtn").on("click", function() {
var selectedItems = [];
$("#shutterboxSearchResults input[type='checkbox']:checked").each(function() {
var row = $(this).closest("tr");
var itemData = {
exit_direction: row.find("td:eq(2)").text().trim(),
front_bottom_width: row.find("td:eq(3)").text().trim(),
rail_width: row.find("td:eq(4)").text().trim(),
search_keyword: row.find("td:eq(5)").text().trim()
};
selectedItems.push(itemData);
});
if (selectedItems.length > 0) {
// 선택된 아이템들을 적용
applySelectedShutterboxItems(selectedItems);
$("#shutterboxSearchModal").modal('hide');
} else {
alert("선택된 아이템이 없습니다.");
}
});
});
// 셔터박스 검색 함수
function performShutterboxSearch() {
var searchData = {
exit_direction: $('input[name="shutterbox_exit_direction_search"]:checked').val(),
searchKeyword: $("#shutterboxSearchInput").val()
};
$.ajax({
url: "search_shutterbox_json.php",
type: "GET",
data: searchData,
success: function(response) {
var tbody = $("#shutterboxSearchResults");
tbody.empty();
if (response && response.length > 0) {
response.forEach(function(item, index) {
var row = `
<tr>
<td class="text-center">
<input type="checkbox" class="form-check-input" value="${index}">
</td>
<td class="text-center">${index + 1}</td>
<td>${item.exit_direction || ''}</td>
<td>${item.front_bottom_width || ''}</td>
<td>${item.rail_width || ''}</td>
<td>${item.search_keyword || ''}</td>
<td class="text-center">
${item.image ? `<div class="image-zoom-container"><img src="${item.image}" alt="이미지" class="image-zoom" style="width:50px;height:50px;" data-src="${item.image}"></div>` : ''}
</td>
</tr>
`;
tbody.append(row);
});
} else {
tbody.append('<tr><td colspan="7" class="text-center">검색 결과가 없습니다.</td></tr>');
}
},
error: function(xhr, status, error) {
console.error("검색 오류:", error);
$("#shutterboxSearchResults").html('<tr><td colspan="7" class="text-center">검색 중 오류가 발생했습니다.</td></tr>');
}
});
}
// 선택된 셔터박스 아이템 적용 함수
function applySelectedShutterboxItems(selectedItems) {
console.log("선택된 셔터박스 아이템들:", selectedItems);
// 첫 번째 선택된 아이템의 정보를 폼에 적용
if (selectedItems.length > 0) {
var firstItem = selectedItems[0];
// 폼 필드에 값 설정
if (firstItem.front_bottom_width) {
$('#front_bottom_width').val(firstItem.front_bottom_width);
}
if (firstItem.rail_width) {
$('#rail_width').val(firstItem.rail_width);
}
if (firstItem.search_keyword) {
$('#search_keyword').val(firstItem.search_keyword);
}
if (firstItem.exit_direction) {
$('input[name="exit_direction"][value="' + firstItem.exit_direction + '"]').prop('checked', true);
}
// 변경사항 알림
Toastify({
text: '셔터박스 정보가 적용되었습니다.',
duration: 1500,
close: true,
gravity: 'top',
position: 'center',
style: { background: '#4fbe87' }
}).showToast();
}
}
// 이미지 확대 기능
$(document).on('click', '.image-zoom', function(e) {
e.stopPropagation();
var imageSrc = $(this).data('src');
if (imageSrc) {
openImageZoom(imageSrc);
}
});
function openImageZoom(imageSrc) {
document.getElementById('zoomedImage').src = imageSrc;
document.getElementById('imageZoomOverlay').style.display = 'flex';
document.body.style.overflow = 'hidden';
}
function closeImageZoom() {
document.getElementById('imageZoomOverlay').style.display = 'none';
document.body.style.overflow = 'auto';
}
// 모달 외부 클릭으로 닫기
document.getElementById('imageZoomOverlay').addEventListener('click', function(event) {
if (event.target === this) {
closeImageZoom();
}
});
</script>