품질관리_고객CS관리

This commit is contained in:
2025-12-09 11:53:57 +09:00
parent d3e2ffa662
commit a4a066390d
11 changed files with 1378 additions and 274 deletions

View File

@@ -0,0 +1,347 @@
<%@ 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>