Files
wace_plm/WebContent/WEB-INF/view/common/ImageRegistPopup.jsp
2025-12-09 11:53:57 +09:00

348 lines
9.2 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<%@ 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>
<style>
/* 이미지 미리보기 영역 */
.image-preview-container {
display: flex;
flex-wrap: wrap;
gap: 10px;
padding: 10px;
max-height: 300px;
overflow-y: auto;
border: 1px solid #ddd;
border-radius: 4px;
background: #f9f9f9;
}
.image-preview-item {
position: relative;
width: 120px;
height: 120px;
border: 1px solid #ccc;
border-radius: 4px;
overflow: hidden;
background: #fff;
}
.image-preview-item img {
width: 100%;
height: 100%;
object-fit: cover;
cursor: pointer;
}
.image-preview-item .delete-btn {
position: absolute;
top: 2px;
right: 2px;
width: 20px;
height: 20px;
background: rgba(255, 0, 0, 0.8);
color: white;
border: none;
border-radius: 50%;
cursor: pointer;
font-size: 12px;
line-height: 18px;
text-align: center;
}
.image-preview-item .delete-btn:hover {
background: rgba(255, 0, 0, 1);
}
.image-preview-item .file-name {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background: rgba(0,0,0,0.6);
color: white;
font-size: 10px;
padding: 2px 4px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.no-image-msg {
width: 100%;
text-align: center;
color: #999;
padding: 30px;
}
/* 드래그앤드롭 영역 */
.drop-zone {
border: 2px dashed #ccc;
border-radius: 8px;
padding: 20px;
text-align: center;
color: #666;
margin-bottom: 10px;
transition: all 0.3s;
}
.drop-zone.dragover {
border-color: #007bff;
background: #e8f4ff;
}
.drop-zone p {
margin: 0;
font-size: 14px;
}
</style>
</head>
<script>
var callbackFnc = "${param.callbackFnc}";
var _isChanged = false;
var _fileCnt = 0;
// 이미지 확장자 목록
var allowedExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'];
$(document).ready(function(){
$("#btn_close").click(function(){
openerCallback();
self.close(0);
});
// 드래그앤드롭 이벤트 설정
setupDropZone();
// 이미지 목록 조회
loadImageList();
// 파일 선택 시 확장자 검사
$("#imageFile").change(function(){
validateImageFiles(this.files);
});
// 업로드 버튼
$("#btnUpload").click(function(){
var files = $("#imageFile")[0].files;
if(files.length > 0){
if(validateImageFiles(files)){
uploadImages(files);
}
}else{
Swal.fire("선택된 이미지가 없습니다.");
}
});
});
// 드래그앤드롭 영역 설정
function setupDropZone(){
var dropZone = document.getElementById("imageDropZone");
dropZone.addEventListener("dragover", function(e){
e.preventDefault();
e.stopPropagation();
$(this).addClass("dragover");
});
dropZone.addEventListener("dragleave", function(e){
e.preventDefault();
e.stopPropagation();
$(this).removeClass("dragover");
});
dropZone.addEventListener("drop", function(e){
e.preventDefault();
e.stopPropagation();
$(this).removeClass("dragover");
var files = e.dataTransfer.files;
if(files.length > 0){
if(validateImageFiles(files)){
uploadImages(files);
}
}
});
}
// 이미지 파일 검증
function validateImageFiles(files){
for(var i = 0; i < files.length; i++){
var fileName = files[i].name;
var ext = fileName.split('.').pop().toLowerCase();
if(allowedExtensions.indexOf(ext) === -1){
Swal.fire({
icon: 'error',
title: '허용되지 않는 파일 형식',
text: '이미지 파일만 업로드 가능합니다.\n허용 확장자: ' + allowedExtensions.join(', ')
});
$("#imageFile").val("");
return false;
}
}
return true;
}
// 이미지 업로드 - 기존 fnc_fileMultiUpload 함수 사용
function uploadImages(files){
fnc_fileMultiUpload(files, null, "${param.targetObjId}", "${param.docType}", "${param.docTypeName}", null, "loadImageList", null, "");
}
// 이미지 목록 조회
function loadImageList(){
$.ajax({
url: "/common/getFileList.do",
type: "POST",
data: {
"targetObjId": "${param.targetObjId}",
"docType": "${param.docType}"
},
dataType: "json",
async: false,
success: function(data){
// 부모 창 새로고침
if(opener && typeof opener.fn_search == "function"){
opener.fn_search();
}
_fileCnt = data.length;
renderImageList(data);
openerCallback();
},
error: function(){
console.error("이미지 목록 조회 실패");
}
});
}
// 이미지 목록 렌더링
function renderImageList(data){
var container = $("#imagePreviewArea");
container.empty();
if(data.length == 0){
container.append('<div class="no-image-msg">등록된 이미지가 없습니다.</div>');
return;
}
$.each(data, function(i, file){
var ext = file.UPPER_FILE_EXT;
// 이미지 파일인 경우만 표시
if(allowedExtensions.indexOf(ext.toLowerCase()) > -1){
// objId 기반으로 이미지 표시 (viewImageByObjId.do 사용)
var imgSrc = "/common/viewImageByObjId.do?objId=" + file.OBJID;
var html = '<div class="image-preview-item">';
html += '<img src="' + imgSrc + '" onclick="viewImage(\'' + imgSrc + '\')" title="클릭하여 원본보기">';
// 삭제 권한 체크
if(file.WRITER == "${connectUserId}" || "${connectUserId}" == "plm_admin"){
html += '<button type="button" class="delete-btn" onclick="deleteImage(\'' + file.OBJID + '\', event)" title="삭제">×</button>';
}
html += '<div class="file-name" title="' + file.REAL_FILE_NAME + '">' + file.REAL_FILE_NAME + '</div>';
html += '</div>';
container.append(html);
}
});
// 이미지가 하나도 없는 경우
if(container.children().length == 0){
container.append('<div class="no-image-msg">등록된 이미지가 없습니다.</div>');
}
}
// 이미지 원본 보기 - 새 창에서 이미지 표시
function viewImage(imgUrl){
var img = new Image();
img.src = imgUrl;
// 이미지 크기에 맞게 팝업 열기
img.onload = function(){
var width = Math.min(img.width + 30, 1200);
var height = Math.min(img.height + 30, 800);
window.open(imgUrl, "ImageViewPopUp", "width=" + width + ",height=" + height + ",scrollbars=yes,resizable=yes");
};
// 이미지 로딩 실패시 기본 크기로 열기
img.onerror = function(){
window.open(imgUrl, "ImageViewPopUp", "width=800,height=600,scrollbars=yes,resizable=yes");
};
}
// 이미지 삭제
function deleteImage(fileObjId, event){
// 이벤트 전파 방지
if(event){
event.preventDefault();
event.stopPropagation();
}
if(confirm("이미지를 삭제하시겠습니까?")){
$.ajax({
url: "/common/deleteFileInfo.do",
type: "POST",
data: {"objId": fileObjId},
dataType: "json",
success: function(){
loadImageList();
// 부모 창 새로고침
if(opener && typeof opener.fn_search == "function"){
opener.fn_search();
}
},
error: function(){
alert("삭제 실패: 서버 통신 오류가 발생했습니다.");
}
});
}
}
// 부모 창 콜백
function openerCallback(){
if((fnc_isEmpty(callbackFnc) || callbackFnc == "fnc_tabulCallbackFnc") && opener && opener.fnc_tabulCallbackFnc){
opener.fnc_tabulCallbackFnc("${param.targetObjId}", "${param.docType}", "${param.columnField}", _fileCnt);
}else if(fnc_checkNull(callbackFnc) != "" && opener){
opener.eval(callbackFnc+"();");
}
}
</script>
<body>
<form name="form1" action="" method="post">
<input type="hidden" name="fileList" id="fileList" />
<section class="business_staff_popup_min_width">
<div class="plm_menu_name">
<h2>
<span>이미지 등록</span>
</h2>
</div>
<div id="businessPopupFormWrap">
<table class="pmsPopupForm">
<tr>
<td class="input_title align_c" style="width:80px;">이미지<br>업로드</td>
<td>
<!-- 드래그앤드롭 영역 -->
<div id="imageDropZone" class="drop-zone">
<p>📷 이미지 파일을 여기에 드래그하거나 아래에서 선택하세요</p>
<p style="font-size:11px; color:#999; margin-top:5px;">허용 확장자: jpg, jpeg, png, gif, bmp, webp</p>
</div>
<!-- 파일 선택 -->
<div style="margin-bottom: 10px;">
<input type="file" name="imageFile" id="imageFile" multiple accept="image/*">
<input type="button" id="btnUpload" value="업로드" class="plm_btns">
</div>
</td>
</tr>
<tr>
<td class="input_title align_c">이미지<br>목록</td>
<td>
<!-- 이미지 미리보기 영역 -->
<div id="imagePreviewArea" class="image-preview-container">
<div class="no-image-msg">등록된 이미지가 없습니다.</div>
</div>
</td>
</tr>
</table>
<div class="btn_wrap">
<div class="plm_btn_wrap_center">
<input type="button" value="닫기" id="btn_close" class="plm_btns">
</div>
</div>
</div>
</section>
</form>
</body>
</html>