|
|
|
|
@ -20,15 +20,15 @@
|
|
|
|
|
<a href="#" class="pop-x-btn modalclose" id="btnCloseTop"></a>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="popup_con">
|
|
|
|
|
<div class="forms_table_non">
|
|
|
|
|
<!-- 중요로직: 단속연도/번호는 부모창에서 전달받아 그대로 저장에 사용 -->
|
|
|
|
|
<form id="actInfoForm" name="actInfoForm">
|
|
|
|
|
<input type="hidden" id="mode" name="mode" value="${mode}" />
|
|
|
|
|
<input type="hidden" id="actInfoId" name="actInfoId" value="${data.actInfoId}" />
|
|
|
|
|
<input type="hidden" id="crdnYr" name="crdnYr" value="${crdnYr}" />
|
|
|
|
|
<input type="hidden" id="crdnNo" name="crdnNo" value="${crdnNo}" />
|
|
|
|
|
<input type="hidden" id="pstnInfoId" name="pstnInfoId" value="${pstnInfoId}" />
|
|
|
|
|
|
|
|
|
|
<!-- 중요로직: 단속연도/번호는 부모창에서 전달받아 그대로 저장에 사용 -->
|
|
|
|
|
<form id="actInfoForm" name="actInfoForm">
|
|
|
|
|
<input type="hidden" id="mode" name="mode" value="${mode}" />
|
|
|
|
|
<input type="hidden" id="actInfoId" name="actInfoId" value="${data.actInfoId}" />
|
|
|
|
|
<input type="hidden" id="crdnYr" name="crdnYr" value="${crdnYr}" />
|
|
|
|
|
<input type="hidden" id="crdnNo" name="crdnNo" value="${crdnNo}" />
|
|
|
|
|
<input type="hidden" id="pstnInfoId" name="pstnInfoId" value="${pstnInfoId}" />
|
|
|
|
|
|
|
|
|
|
<div class="forms_table_non">
|
|
|
|
|
<table>
|
|
|
|
|
<colgroup>
|
|
|
|
|
<col style="width: 18%;" />
|
|
|
|
|
@ -74,21 +74,21 @@
|
|
|
|
|
<tr>
|
|
|
|
|
<th class="th"><span class="required">*</span> 가로(m)</th>
|
|
|
|
|
<td>
|
|
|
|
|
<input type="text" id="wdth" name="wdth" class="input decimalMask" style="width: 120px;" maxlength="10" placeholder="예) 5.25" validation-check="required number" value="${data.wdth}"/>
|
|
|
|
|
<input type="text" id="wdth" name="wdth" class="input decimalMask" style="width: 120px;" maxlength="10" placeholder="예) 5.25" validation-check="required" value="${data.wdth}"/>
|
|
|
|
|
</td>
|
|
|
|
|
<th class="th"><span class="required">*</span> 세로(m)</th>
|
|
|
|
|
<td>
|
|
|
|
|
<input type="text" id="vrtc" name="vrtc" class="input decimalMask" style="width: 120px;" maxlength="10" placeholder="예) 8.75" validation-check="required number" value="${data.vrtc}"/>
|
|
|
|
|
<input type="text" id="vrtc" name="vrtc" class="input decimalMask" style="width: 120px;" maxlength="10" placeholder="예) 8.75" validation-check="required" value="${data.vrtc}"/>
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
<tr>
|
|
|
|
|
<th class="th"><span class="required">*</span> 면적(㎡)</th>
|
|
|
|
|
<td>
|
|
|
|
|
<input type="text" id="area" name="area" class="input decimalMask" style="width: 120px;" maxlength="12" placeholder="예) 45.94" validation-check="required number" value="${data.area}"/>
|
|
|
|
|
<input type="text" id="area" name="area" class="input decimalMask" style="width: 120px;" maxlength="12" placeholder="예) 45.94" validation-check="required" value="${data.area}"/>
|
|
|
|
|
</td>
|
|
|
|
|
<th class="th">높이(m)</th>
|
|
|
|
|
<td>
|
|
|
|
|
<input type="text" id="hgt" name="hgt" class="input decimalMask" style="width: 120px;" maxlength="10" placeholder="예) 10.50" validation-check="number" value="${data.hgt}"/>
|
|
|
|
|
<input type="text" id="hgt" name="hgt" class="input decimalMask" style="width: 120px;" maxlength="10" placeholder="예) 10.50" value="${data.hgt}"/>
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
<tr>
|
|
|
|
|
@ -98,33 +98,97 @@
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
<tr>
|
|
|
|
|
<th class="th">행위 사진</th>
|
|
|
|
|
<th class="th">단속 사진</th>
|
|
|
|
|
<td colspan="3">
|
|
|
|
|
<!-- 중요한 로직 주석: 파일 업로드와 미리보기 기능을 제공한다 -->
|
|
|
|
|
<div class="file-upload-section">
|
|
|
|
|
<!-- 중요한 로직 주석: 단속 사진 업로드와 미리보기 기능 (CRDN_PHOTO_SE_CD = 1) -->
|
|
|
|
|
<div class="file-upload-section" data-photo-type="1">
|
|
|
|
|
<div class="file-upload-controls">
|
|
|
|
|
<label for="photoFiles" class="file-upload-btn smallb-2">
|
|
|
|
|
<span>사진 선택</span>
|
|
|
|
|
<input type="file" id="photoFiles" name="photoFiles" accept="image/*" multiple style="display: none;">
|
|
|
|
|
<label for="crdnPhotoFiles" class="file-upload-btn smallb-2">
|
|
|
|
|
<span>단속 사진 선택</span>
|
|
|
|
|
<input type="file" id="crdnPhotoFiles" name="crdnPhotoFiles" accept="image/*" multiple style="display: none;">
|
|
|
|
|
</label>
|
|
|
|
|
<input type="hidden" id="crdnPhotoSeCd" name="crdnPhotoSeCd" value="1"/>
|
|
|
|
|
<span class="file-info">최대 10개, 각 10MB 이하의 이미지 파일만 업로드 가능합니다.</span>
|
|
|
|
|
<span class="file-info">최대 10개, 각 20MB 이하의 이미지 파일만 업로드 가능합니다.</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="photo-preview-container" id="photoPreviewContainer">
|
|
|
|
|
<!-- 중요한 로직 주석: 수정 모드에서 기존 등록된 사진들을 표시한다 -->
|
|
|
|
|
<c:if test="${mode eq 'U' && not empty photoList}">
|
|
|
|
|
<c:forEach var="photo" items="${photoList}">
|
|
|
|
|
<div class="photo-preview-item existing-photo" data-act-info-id="${photo.actInfoId}" data-photo-sn="${photo.crdnPhotoSn}">
|
|
|
|
|
<div class="photo-thumbnail">
|
|
|
|
|
<img src="<c:url value='/crdn/crndRegistAndView/crdnActInfo/downloadPhoto.do'/>?actInfoId=${photo.actInfoId}&crdnPhotoSn=${photo.crdnPhotoSn}"
|
|
|
|
|
alt="${photo.orgnlPhotoNm}" onclick="viewOriginalPhoto('${photo.actInfoId}', '${photo.crdnPhotoSn}')">
|
|
|
|
|
<div class="photo-preview-container" id="crdnPhotoPreviewContainer">
|
|
|
|
|
<!-- 중요한 로직 주석: 수정 모드에서 기존 등록된 단속 사진들을 표시한다 -->
|
|
|
|
|
<c:if test="${mode eq 'U' && not empty crdnPhotoList}">
|
|
|
|
|
<c:forEach var="photo" items="${crdnPhotoList}">
|
|
|
|
|
<c:if test="${photo.crdnPhotoSeCd eq '1'}">
|
|
|
|
|
<div class="photo-preview-item existing-photo" data-act-info-id="${photo.actInfoId}" data-photo-sn="${photo.crdnPhotoSn}" data-photo-type="1">
|
|
|
|
|
<div class="photo-thumbnail">
|
|
|
|
|
<img src="<c:url value='/crdn/crndRegistAndView/crdnActInfo/downloadPhoto.do'/>?actInfoId=${photo.actInfoId}&crdnPhotoSn=${photo.crdnPhotoSn}"
|
|
|
|
|
alt="${photo.orgnlPhotoNm}" onclick="viewOriginalPhoto('${photo.actInfoId}', '${photo.crdnPhotoSn}', '${photo.crdnPhotoSeCd}')">
|
|
|
|
|
</div>
|
|
|
|
|
<div class="photo-info">
|
|
|
|
|
<div class="photo-name" title="${photo.orgnlPhotoNm}">${photo.orgnlPhotoNm}</div>
|
|
|
|
|
<div class="photo-type">[단속]</div>
|
|
|
|
|
<button type="button" class="delete-photo-btn" onclick="deleteExistingPhoto('${photo.actInfoId}', '${photo.crdnPhotoSn}', '1')">삭제</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="photo-info">
|
|
|
|
|
<div class="photo-name" title="${photo.orgnlPhotoNm}">${photo.orgnlPhotoNm}</div>
|
|
|
|
|
<div class="photo-type">[${photo.crdnPhotoSeCdNm}]</div>
|
|
|
|
|
<button type="button" class="delete-photo-btn" onclick="deleteExistingPhoto('${photo.actInfoId}', '${photo.crdnPhotoSn}')">삭제</button>
|
|
|
|
|
</c:if>
|
|
|
|
|
</c:forEach>
|
|
|
|
|
</c:if>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
</table>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div class="forms_table_non mt-20">
|
|
|
|
|
<table>
|
|
|
|
|
<colgroup>
|
|
|
|
|
<col style="width: 18%;" />
|
|
|
|
|
<col style="width: 32%;" />
|
|
|
|
|
<col style="width: 18%;" />
|
|
|
|
|
<col style="width: 32%;" />
|
|
|
|
|
</colgroup>
|
|
|
|
|
<tr>
|
|
|
|
|
<th class="th">조치일자</th>
|
|
|
|
|
<td>
|
|
|
|
|
<input type="text" id="actnYmd" name="actnYmd" class="input calender datepicker" maxlength="10" style="width: 120px;" autocomplete="off" value="${dateUtil:formatDateString(data.actnYmd)}"/>
|
|
|
|
|
</td>
|
|
|
|
|
<th class="th">조치 면적(㎡)</th>
|
|
|
|
|
<td>
|
|
|
|
|
<input type="text" id="actnArea" name="actnArea" class="input decimalMask" style="width: 120px;" maxlength="12" placeholder="예) 45.94" value="${data.actnArea}"/>
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
<tr>
|
|
|
|
|
<th class="th">비고</th>
|
|
|
|
|
<td colspan="3">
|
|
|
|
|
<textarea id="actnRmrk" name="actnRmrk" class="textarea" rows="3" maxlength="1000" style="height: 80px;">${data.rmrk}</textarea>
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
<tr>
|
|
|
|
|
<th class="th">조치 사진</th>
|
|
|
|
|
<td colspan="3">
|
|
|
|
|
<!-- 중요한 로직 주석: 조치 사진 업로드와 미리보기 기능 (CRDN_PHOTO_SE_CD = 2) -->
|
|
|
|
|
<div class="file-upload-section" data-photo-type="2">
|
|
|
|
|
<div class="file-upload-controls">
|
|
|
|
|
<label for="actnPhotoFiles" class="file-upload-btn smallb-2">
|
|
|
|
|
<span>조치 사진 선택</span>
|
|
|
|
|
<input type="file" id="actnPhotoFiles" name="actnPhotoFiles" accept="image/*" multiple style="display: none;">
|
|
|
|
|
</label>
|
|
|
|
|
<span class="file-info">최대 10개, 각 20MB 이하의 이미지 파일만 업로드 가능합니다.</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="photo-preview-container" id="actnPhotoPreviewContainer">
|
|
|
|
|
<!-- 중요한 로직 주석: 수정 모드에서 기존 등록된 조치 사진들을 표시한다 -->
|
|
|
|
|
<c:if test="${mode eq 'U' && not empty crdnPhotoList}">
|
|
|
|
|
<c:forEach var="photo" items="${crdnPhotoList}">
|
|
|
|
|
<c:if test="${photo.crdnPhotoSeCd eq '2'}">
|
|
|
|
|
<div class="photo-preview-item existing-photo" data-act-info-id="${photo.actInfoId}" data-photo-sn="${photo.crdnPhotoSn}" data-photo-type="2">
|
|
|
|
|
<div class="photo-thumbnail">
|
|
|
|
|
<img src="<c:url value='/crdn/crndRegistAndView/crdnActInfo/downloadPhoto.do'/>?actInfoId=${photo.actInfoId}&crdnPhotoSn=${photo.crdnPhotoSn}"
|
|
|
|
|
alt="${photo.orgnlPhotoNm}" onclick="viewOriginalPhoto('${photo.actInfoId}', '${photo.crdnPhotoSn}', '${photo.crdnPhotoSeCd}')">
|
|
|
|
|
</div>
|
|
|
|
|
<div class="photo-info">
|
|
|
|
|
<div class="photo-name" title="${photo.orgnlPhotoNm}">${photo.orgnlPhotoNm}</div>
|
|
|
|
|
<div class="photo-type">[조치]</div>
|
|
|
|
|
<button type="button" class="delete-photo-btn" onclick="deleteExistingPhoto('${photo.actInfoId}', '${photo.crdnPhotoSn}', '2')">삭제</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</c:if>
|
|
|
|
|
</c:forEach>
|
|
|
|
|
</c:if>
|
|
|
|
|
</div>
|
|
|
|
|
@ -132,8 +196,9 @@
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
</table>
|
|
|
|
|
</form>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</form>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="popup_foot">
|
|
|
|
|
<button type="button" id="btnSave" class="newbtns bg1">저장</button>
|
|
|
|
|
@ -489,10 +554,17 @@
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 중요한 로직 주석: 선택된 파일들을 FormData에 추가 (있는 경우에만)
|
|
|
|
|
if (selectedFiles && selectedFiles.length > 0) {
|
|
|
|
|
for (var i = 0; i < selectedFiles.length; i++) {
|
|
|
|
|
formData.append('photoFiles', selectedFiles[i]);
|
|
|
|
|
// 중요한 로직 주석: 선택된 단속 사진들을 FormData에 추가 (있는 경우에만)
|
|
|
|
|
if (crdnSelectedFiles && crdnSelectedFiles.length > 0) {
|
|
|
|
|
for (var i = 0; i < crdnSelectedFiles.length; i++) {
|
|
|
|
|
formData.append('crdnPhotoFiles', crdnSelectedFiles[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 중요한 로직 주석: 선택된 조치 사진들을 FormData에 추가 (있는 경우에만)
|
|
|
|
|
if (actnSelectedFiles && actnSelectedFiles.length > 0) {
|
|
|
|
|
for (var i = 0; i < actnSelectedFiles.length; i++) {
|
|
|
|
|
formData.append('actnPhotoFiles', actnSelectedFiles[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -531,79 +603,116 @@
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 전역 변수: 선택된 파일들을 보관
|
|
|
|
|
var selectedFiles = [];
|
|
|
|
|
// 전역 변수: 선택된 파일들을 사진 종류별로 보관
|
|
|
|
|
var crdnSelectedFiles = []; // 단속 사진 파일들
|
|
|
|
|
var actnSelectedFiles = []; // 조치 사진 파일들
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 파일 업로드 초기화
|
|
|
|
|
* 중요한 로직 주석: 파일 선택 이벤트와 드래그앤드롭 이벤트를 추가하고 파일 유효성 검증을 초기화한다.
|
|
|
|
|
* 중요한 로직 주석: 단속/조치 사진 각각의 파일 선택 이벤트와 드래그앤드롭 이벤트를 추가한다.
|
|
|
|
|
*/
|
|
|
|
|
function initFileUpload() {
|
|
|
|
|
var dropZone = $('#photoPreviewContainer');
|
|
|
|
|
// 단속 사진 영역
|
|
|
|
|
var crdnDropZone = $('#crdnPhotoPreviewContainer');
|
|
|
|
|
var actnDropZone = $('#actnPhotoPreviewContainer');
|
|
|
|
|
|
|
|
|
|
// 단속 사진 파일 선택 이벤트
|
|
|
|
|
$('#crdnPhotoFiles').on('change', function(e) {
|
|
|
|
|
handleFileSelect(e.target.files, '1');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 파일 선택 이벤트
|
|
|
|
|
$('#photoFiles').on('change', function(e) {
|
|
|
|
|
handleFileSelect(e.target.files);
|
|
|
|
|
// 조치 사진 파일 선택 이벤트
|
|
|
|
|
$('#actnPhotoFiles').on('change', function(e) {
|
|
|
|
|
handleFileSelect(e.target.files, '2');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 중요로직: 드래그앤드롭으로 파일 업로드 처리
|
|
|
|
|
dropZone.on('dragover', function(e) {
|
|
|
|
|
// 중요로직: 단속 사진 드래그앤드롭 처리
|
|
|
|
|
crdnDropZone.on('dragover', function(e) {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
dropZone.addClass('drag-over');
|
|
|
|
|
crdnDropZone.addClass('drag-over');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
dropZone.on('dragleave', function(e) {
|
|
|
|
|
crdnDropZone.on('dragleave', function(e) {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
dropZone.removeClass('drag-over');
|
|
|
|
|
crdnDropZone.removeClass('drag-over');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
dropZone.on('drop', function(e) {
|
|
|
|
|
crdnDropZone.on('drop', function(e) {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
dropZone.removeClass('drag-over');
|
|
|
|
|
crdnDropZone.removeClass('drag-over');
|
|
|
|
|
|
|
|
|
|
var files = e.originalEvent.dataTransfer.files;
|
|
|
|
|
if (files.length > 0) {
|
|
|
|
|
// 기존 파일 선택 로직 재사용
|
|
|
|
|
handleFileSelect(files);
|
|
|
|
|
handleFileSelect(files, '1'); // 단속 사진으로 처리
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 중요로직: 조치 사진 드래그앤드롭 처리
|
|
|
|
|
actnDropZone.on('dragover', function(e) {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
actnDropZone.addClass('drag-over');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
actnDropZone.on('dragleave', function(e) {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
actnDropZone.removeClass('drag-over');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
actnDropZone.on('drop', function(e) {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
actnDropZone.removeClass('drag-over');
|
|
|
|
|
|
|
|
|
|
var files = e.originalEvent.dataTransfer.files;
|
|
|
|
|
if (files.length > 0) {
|
|
|
|
|
handleFileSelect(files, '2'); // 조치 사진으로 처리
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 파일 선택 처리
|
|
|
|
|
* 중요한 로직 주석: 선택된 파일들을 검증하고 파일명만 표시한다. 미리보기는 하지 않는다.
|
|
|
|
|
* 중요한 로직 주석: 사진 종류별로 선택된 파일들을 검증하고 각자의 영역에 미리보기를 표시한다.
|
|
|
|
|
* @param {FileList} files - 선택된 파일 목록
|
|
|
|
|
* @param {string} photoType - 사진 종류 ('1': 단속, '2': 조치)
|
|
|
|
|
*/
|
|
|
|
|
function handleFileSelect(files) {
|
|
|
|
|
function handleFileSelect(files, photoType) {
|
|
|
|
|
if (!files || files.length === 0) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 파일 개수 제한 체크
|
|
|
|
|
var existingPhotos = $('.photo-preview-item.existing-photo').length;
|
|
|
|
|
var newFiles = selectedFiles.length + files.length;
|
|
|
|
|
|
|
|
|
|
var containerSelector = photoType === '1' ? '#crdnPhotoPreviewContainer' : '#actnPhotoPreviewContainer';
|
|
|
|
|
var selectedFilesArray = photoType === '1' ? crdnSelectedFiles : actnSelectedFiles;
|
|
|
|
|
var photoTypeName = photoType === '1' ? '단속' : '조치';
|
|
|
|
|
|
|
|
|
|
// 파일 개수 제한 체크 (각 종류별로 10개까지)
|
|
|
|
|
var existingPhotos = $(containerSelector + ' .photo-preview-item.existing-photo').length;
|
|
|
|
|
var newFiles = selectedFilesArray.length + files.length;
|
|
|
|
|
|
|
|
|
|
if (existingPhotos + newFiles > 10) {
|
|
|
|
|
alert('최대 10개의 사진만 업로드할 수 있습니다.');
|
|
|
|
|
alert('최대 10개의 ' + photoTypeName + ' 사진만 업로드할 수 있습니다.');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 각 파일에 대해 검증 및 파일명만 표시
|
|
|
|
|
// 각 파일에 대해 검증 및 미리보기 생성
|
|
|
|
|
for (var i = 0; i < files.length; i++) {
|
|
|
|
|
var file = files[i];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 파일 유효성 검증
|
|
|
|
|
if (!validateFile(file)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 선택된 파일 목록에 추가
|
|
|
|
|
selectedFiles.push(file);
|
|
|
|
|
|
|
|
|
|
// 미리보기 생성 (클릭 이벤트 없음)
|
|
|
|
|
createPhotoPreview(file);
|
|
|
|
|
|
|
|
|
|
// 해당 종류의 선택된 파일 목록에 추가
|
|
|
|
|
selectedFilesArray.push(file);
|
|
|
|
|
|
|
|
|
|
// 미리보기 생성
|
|
|
|
|
createPhotoPreview(file, photoType);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -615,7 +724,7 @@
|
|
|
|
|
// 파일 크기 체크 (10MB)
|
|
|
|
|
var maxSize = 10 * 1024 * 1024;
|
|
|
|
|
if (file.size > maxSize) {
|
|
|
|
|
alert(file.name + ' 파일이 10MB를 초과합니다.');
|
|
|
|
|
alert(file.name + ' 파일이 20MB를 초과합니다.');
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -639,40 +748,46 @@
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 사진 미리보기 생성 (클릭 이벤트 없음)
|
|
|
|
|
* 중요한 로직 주석: 선택된 파일을 읽어서 미리보기 이미지를 생성한다. 클릭 시 원본 이미지 팝업은 제공하지 않는다.
|
|
|
|
|
* 사진 미리보기 생성
|
|
|
|
|
* 중요한 로직 주석: 선택된 파일을 읽어서 해당 종류의 미리보기 영역에 이미지를 생성한다.
|
|
|
|
|
* @param {File} file - 미리보기를 생성할 파일
|
|
|
|
|
* @param {string} photoType - 사진 종류 ('1': 단속, '2': 조치)
|
|
|
|
|
*/
|
|
|
|
|
function createPhotoPreview(file) {
|
|
|
|
|
function createPhotoPreview(file, photoType) {
|
|
|
|
|
var reader = new FileReader();
|
|
|
|
|
|
|
|
|
|
var containerSelector = photoType === '1' ? '#crdnPhotoPreviewContainer' : '#actnPhotoPreviewContainer';
|
|
|
|
|
var photoTypeName = photoType === '1' ? '단속' : '조치';
|
|
|
|
|
|
|
|
|
|
reader.onload = function(e) {
|
|
|
|
|
var photoSeCd = $('#crdnPhotoSeCd').val();
|
|
|
|
|
var photoSeCdNm = photoSeCd === '1' ? '단속' : '조치';
|
|
|
|
|
|
|
|
|
|
var previewHtml =
|
|
|
|
|
'<div class="photo-preview-item new-photo" data-file-name="' + file.name + '">' +
|
|
|
|
|
var previewHtml =
|
|
|
|
|
'<div class="photo-preview-item new-photo" data-file-name="' + file.name + '" data-photo-type="' + photoType + '">' +
|
|
|
|
|
' <div class="photo-thumbnail">' +
|
|
|
|
|
' <img src="' + e.target.result + '" alt="' + file.name + '">' +
|
|
|
|
|
' </div>' +
|
|
|
|
|
' <div class="photo-info">' +
|
|
|
|
|
' <div class="photo-name" title="' + file.name + '">' + file.name + '</div>' +
|
|
|
|
|
' <div class="photo-type">[' + photoSeCdNm + ']</div>' +
|
|
|
|
|
' <button type="button" class="delete-photo-btn" onclick="deleteNewPhoto(this)">삭제</button>' +
|
|
|
|
|
' <div class="photo-type">[' + photoTypeName + ']</div>' +
|
|
|
|
|
' <button type="button" class="delete-photo-btn" onclick="deleteNewPhoto(this, \'' + photoType + '\')">삭제</button>' +
|
|
|
|
|
' </div>' +
|
|
|
|
|
'</div>';
|
|
|
|
|
|
|
|
|
|
$('#photoPreviewContainer').append(previewHtml);
|
|
|
|
|
|
|
|
|
|
$(containerSelector).append(previewHtml);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
reader.readAsDataURL(file);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 기존 사진 삭제
|
|
|
|
|
* 중요한 로직 주석: DB에 등록된 사진을 논리삭제하고 화면에서 제거한다.
|
|
|
|
|
* @param {string} actInfoId - 행위정보 ID
|
|
|
|
|
* @param {string} crdnPhotoSn - 단속사진 순번
|
|
|
|
|
* @param {string} photoType - 사진 종류 ('1': 단속, '2': 조치)
|
|
|
|
|
*/
|
|
|
|
|
function deleteExistingPhoto(actInfoId, crdnPhotoSn) {
|
|
|
|
|
if (!confirm('선택한 사진을 삭제하시겠습니까?')) {
|
|
|
|
|
function deleteExistingPhoto(actInfoId, crdnPhotoSn, photoType) {
|
|
|
|
|
var photoTypeName = photoType === '1' ? '단속' : '조치';
|
|
|
|
|
|
|
|
|
|
if (!confirm('선택한 ' + photoTypeName + ' 사진을 삭제하시겠습니까?')) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -686,7 +801,7 @@
|
|
|
|
|
success: function(response) {
|
|
|
|
|
if (response && response.success) {
|
|
|
|
|
// 화면에서 해당 사진 제거
|
|
|
|
|
$('[data-act-info-id="' + actInfoId + '"][data-photo-sn="' + crdnPhotoSn + '"]').remove();
|
|
|
|
|
$('[data-act-info-id="' + actInfoId + '"][data-photo-sn="' + crdnPhotoSn + '"][data-photo-type="' + photoType + '"]').remove();
|
|
|
|
|
} else {
|
|
|
|
|
alert(response.message || '사진 삭제에 실패했습니다.');
|
|
|
|
|
}
|
|
|
|
|
@ -696,20 +811,23 @@
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 새로 선택한 파일 삭제
|
|
|
|
|
* 중요한 로직 주석: 아직 저장되지 않은 파일을 목록에서 제거하고 selectedFiles 배열에서도 제거한다.
|
|
|
|
|
* 중요한 로직 주석: 아직 저장되지 않은 파일을 해당 종류의 목록에서 제거하고 selectedFiles 배열에서도 제거한다.
|
|
|
|
|
* @param {Element} button - 삭제 버튼 요소
|
|
|
|
|
* @param {string} photoType - 사진 종류 ('1': 단속, '2': 조치)
|
|
|
|
|
*/
|
|
|
|
|
function deleteNewPhoto(button) {
|
|
|
|
|
function deleteNewPhoto(button, photoType) {
|
|
|
|
|
var $item = $(button).closest('.photo-preview-item');
|
|
|
|
|
var fileName = $item.data('file-name');
|
|
|
|
|
|
|
|
|
|
// selectedFiles 배열에서 해당 파일 제거
|
|
|
|
|
for (var i = 0; i < selectedFiles.length; i++) {
|
|
|
|
|
if (selectedFiles[i].name === fileName) {
|
|
|
|
|
selectedFiles.splice(i, 1);
|
|
|
|
|
var selectedFilesArray = photoType === '1' ? crdnSelectedFiles : actnSelectedFiles;
|
|
|
|
|
|
|
|
|
|
// 해당 종류의 selectedFiles 배열에서 파일 제거
|
|
|
|
|
for (var i = 0; i < selectedFilesArray.length; i++) {
|
|
|
|
|
if (selectedFilesArray[i].name === fileName) {
|
|
|
|
|
selectedFilesArray.splice(i, 1);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 화면에서 제거
|
|
|
|
|
$item.remove();
|
|
|
|
|
}
|
|
|
|
|
@ -718,8 +836,8 @@
|
|
|
|
|
* 원본 사진 보기 (기존 DB 사진)
|
|
|
|
|
* 중요한 로직 주석: 등록된 사진을 photoView 페이지에서 원본 크기로 표시하고 다운로드 버튼을 제공한다.
|
|
|
|
|
*/
|
|
|
|
|
function viewOriginalPhoto(actInfoId, crdnPhotoSn) {
|
|
|
|
|
var url = '<c:url value="/crdn/crndRegistAndView/crdnActInfo/photoView.do"/>?actInfoId=' + actInfoId + '&crdnPhotoSn=' + crdnPhotoSn;
|
|
|
|
|
function viewOriginalPhoto(actInfoId, crdnPhotoSn, crdnPhotoSeCd) {
|
|
|
|
|
var url = '<c:url value="/crdn/crndRegistAndView/crdnActInfo/photoView.do"/>?actInfoId=' + actInfoId + '&crdnPhotoSn=' + crdnPhotoSn + '&crdnPhotoSeCd=' + crdnPhotoSeCd ;
|
|
|
|
|
openPopup(url, 1000, 700, '_blank');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|