불법행위 정보 - 조치에 대한 로직 재구성 진행 중...

dev
박성영 3 months ago
parent 3f743ac3d6
commit 12a267c30a

@ -575,7 +575,7 @@ public class CrdnActInfoController {
@ApiResponse(responseCode = "200", description = "삭제 성공"),
@ApiResponse(responseCode = "500", description = "서버 오류")
})
@PostMapping("/actnInfoDelete.ajax")
@PostMapping("/deleteActnInfo.ajax")
public ResponseEntity<?> actnInfoDeleteAjax(@RequestParam List<String> actnInfoIds) {
log.debug("조치정보 삭제 요청: {}", actnInfoIds);

@ -120,39 +120,31 @@
</div>
<script type="text/javascript">
/**
* 조치정보 관리 팝업 JavaScript
* 중요한 로직 주석: crdnActInfoRegistPopup.jsp와 동일한 구조, levyPrvntcPopup.jsp의 탭 패턴 적용
*/
var crdnActnInfoRegistPopup = {
// 기본 정보
(function(window, $) {
'use strict';
var CrdnActnInfoRegistPopup = {
actInfoId: '${actInfoId}',
crdnYr: '${crdnYr}',
crdnNo: '${crdnNo}',
pstnInfoId: '${pstnInfoId}',
actnInfoIdSelect: null,
/**
* 그리드 관련 객체
*/
grid: {
/**
* 그리드 인스턴스
*/
instance: null,
/**
* 그리드 설정 초기화
* @returns {Object} 그리드 설정 객체
*/
initConfig: function() {
// 데이터 소스 설정
var dataSource = this.createDataSource();
// 그리드 설정 객체 생성
var gridConfig = new XitTuiGridConfig();
// 기본 설정
gridConfig.setOptDataSource(dataSource);
gridConfig.setOptGridId('actnInfoGrid');
gridConfig.setOptGridHeight(150);
@ -164,10 +156,7 @@
return gridConfig;
},
/**
* 그리드 컬럼 정의
* @returns {Array} 그리드 컬럼 배열
*/
getGridColumns: function() {
return [
{
@ -213,12 +202,8 @@
];
},
/**
* 데이터 소스 생성
* @returns {Object} 데이터 소스 설정 객체
*/
createDataSource: function() {
var self = crdnActnInfoRegistPopup;
return {
api: {
readData: {
@ -231,32 +216,28 @@
initialRequest: false,
serializer: function(params) {
var defaultParams = $.param(params);
var extra = $.param({ actInfoId: self.actInfoId });
var extra = $.param({ actInfoId: CrdnActnInfoRegistPopup.actInfoId });
return defaultParams + '&' + extra;
}
};
},
/**
* 그리드 인스턴스 생성
*/
create: function() {
var gridConfig = this.initConfig();
var Grid = tui.Grid;
this.instance = gridConfig.instance(Grid);
// 그리드 테마 설정
Grid.applyTheme('striped');
this.gridBindEvents();
},
/**
* 그리드 이벤트 바인딩
*/
gridBindEvents: function() {
var self = this;
var self = CrdnActnInfoRegistPopup;
this.instance.on('successResponse', function(ev) {
var responseObj = JSON.parse(ev.xhr.response);
@ -268,96 +249,101 @@
});
this.instance.on('onGridUpdated', function() {
const firstVisibleColumn = self.instance.getColumns().find(column => !column.hidden);
var allRows = self.instance.getData();
const firstVisibleColumn = self.grid.instance.getColumns().find(column => !column.hidden);
var allRows = self.grid.instance.getData();
var rowKey = null;
if (allRows && allRows.length > 0) {
allRows.forEach(function(row) {
if( crdnActnInfoRegistPopup.actnInfoIdSelect === null ){
rowKey = allRows[0].rowKey;
crdnActnInfoRegistPopup.actnInfoIdSelect = row.actnInfoId;
}else if (crdnActnInfoRegistPopup.actnInfoIdSelect === row.actnInfoId) {
if (self.actnInfoIdSelect === row.actnInfoId) {
rowKey = row.rowKey
console.log(self.actnInfoIdSelect, rowKey, row.rowKey, row.actnInfoId)
}
// 2. 행 전체 선택 (파란색 배경)
self.instance.setSelectionRange({
start: [rowKey, 0],
end: [rowKey, self.instance.getColumns().length - 1]
});
// 2. 첫 번째 보이는 컬럼으로 포커스 이동 및 스크롤
self.instance.focus(rowKey, firstVisibleColumn.name, true);
});
if(rowKey != null){
self.grid.instance.focus(rowKey, firstVisibleColumn.name, true);
}
}
});
this.instance.on('focusChange', function(ev) {
console.log(ev);
if (ev.rowKey !== null) {
crdnActnInfoRegistPopup.actnInfoIdSelect = ev.actnInfoId;
var rowData = self.grid.instance.getRow(ev.rowKey);
self.actnInfoIdSelect = rowData.actnInfoId;
self.loadActnInfoToForm(rowData);
}
// validation 에러 스타일과 메시지 제거
$('#actnInfoForm').find('.is-invalid').removeClass('is-invalid');
$('#actnInfoForm').find('.is-invalid-custom').removeClass('is-invalid-custom');
$('#actnInfoForm').find('.error-message').remove();
});
this.instance.on('click', function(ev) {
if (ev.rowKey !== null) {
crdnActnInfoRegistPopup.actnInfoIdSelect = ev.actnInfoId;
var rowData = self.grid.instance.getRow(ev.rowKey);
//self.actnInfoIdSelect = rowData.actnInfoId;
//self.loadActnInfoToForm(rowData);
}
// validation 에러 스타일과 메시지 제거
$('#actnInfoForm').find('.is-invalid').removeClass('is-invalid');
$('#actnInfoForm').find('.is-invalid-custom').removeClass('is-invalid-custom');
$('#actnInfoForm').find('.error-message').remove();
});
}
},
// 선택된 조치사진 파일들
actnSelectedFiles: [],
/**
* 초기화
*/
init: function() {
this.grid.create();
this.eventBindEvents();
this.loadActnInfoList();
},
/**
* 이벤트 초기화 (crdnActInfoRegistPopup.jsp 패턴과 동일)
*/
eventBindEvents: function() {
var self = this;
// 달력 초기화
$('#actnYmd').datepicker({
container: '.popup_inner',
language: "kr"
});
// 탭 전환 이벤트 (levyPrvntcPopup.jsp 패턴 적용)
$('.tab-link').on('click', function(e) {
e.preventDefault();
self.switchTab($(this).parent().data('tab'));
});
// 조치정보 저장 버튼
$('#btnSaveActn').on('click', function() {
self.saveActnInfo();
});
// 조치정보 삭제 버튼
$('#btnDeleteActn').on('click', function() {
self.deleteActnInfo();
});
// 입력 초기화 버튼
$('#btnClearActn').on('click', function() {
self.actnInfoIdSelect = null;
self.grid.instance.readData();
self.clearActnForm();
});
// 조치사진 파일 선택 이벤트
$('#actnPhotoFiles').on('change', function(e) {
self.handleFileSelect(e.target.files, '2');
});
// 팝업 닫기
$('#btnClose, #btnCloseTop').on('click', function() {
self.closePopup();
});
@ -380,15 +366,13 @@
}
} else if (tabType === 'actn') {
// 조치정보 탭은 현재 페이지 (활성화 상태 유지)
$('.tab-item').removeClass('active');
$('.tab-item[data-tab="' + tabType + '"]').addClass('active');
}
},
/**
* 조치정보 목록 조회
*/
loadActnInfoList: function() {
if (this.grid.instance) {
this.grid.instance.readData();
@ -398,30 +382,28 @@
loadActnInfoToForm: function(rowData) {
if (!rowData) return;
// 조치정보 ID 설정 (숨겨진 필드)
$('#actnInfoId').val(rowData.actnInfoId || '');
// 조치 일자 설정
$('#actnYmd').val(moment(rowData.actnYmd).format('YYYY-MM-DD') || '');
// 조치 면적 설정 (소수점 2자리까지 표시)
$('#actnArea').val(rowData.actnArea || '');
// 조치 비고 설정
$('#actnRmrk').val(rowData.actnRmrk || '');
// 폼 모드를 수정으로 설정
$('#actnMode').val('U');
// 기존 조치사진 로드
this.loadActnPhotos(rowData.actnInfoId);
console.log('조치정보 폼 로드 완료:', rowData);
},
/**
* 조치사진 목록 로드 (crdnActInfoRegistPopup.jsp의 loadActnPhotos 패턴)
*/
loadActnPhotos: function(actnInfoId) {
var self = this;
@ -440,15 +422,15 @@
if (response && response.data && response.data.length > 0) {
$.each(response.data, function(index, photo) {
var previewHtml =
'<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-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.actnInfoId + '\', \'' + 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 class="photo-type">[조치]</div>' +
' <button type="button" class="delete-photo-btn" onclick="CrdnActnInfoRegistPopup.deleteExistingPhoto(\'' + photo.actInfoId + '\', \'' + photo.crdnPhotoSn + '\', \'2\')">삭제</button>' +
' </div>' +
'</div>';
$('#actnPhotoPreviewContainer').append(previewHtml);
@ -461,25 +443,23 @@
});
},
/**
* 조치정보 저장 (crdnActInfoRegistPopup.jsp의 saveActnInfo 패턴)
*/
saveActnInfo: function() {
var self = this;
// 중요로직: validateFormByAttributes를 사용하여 모든 validation-check 속성 검증
if (!validateFormByAttributes('actnInfoForm')) {
return;
}
var actnInfoId = $('#actnInfoId').val().trim();
var actInfoId = this.actInfoId; // 부모 행위정보 ID
var mode = actnInfoId ? 'U' : 'C'; // 조치정보 ID가 있으면 수정, 없으면 신규
var actInfoId = this.actInfoId;
var mode = actnInfoId ? 'U' : 'C';
// FormData 생성 (파일 업로드를 위해)
var formData = new FormData();
formData.append('mode', mode);
// 폼의 모든 입력값을 FormData에 추가
$('#actnInfoForm').find('input, select, textarea').each(function() {
var $this = $(this);
var name = $this.attr('name');
@ -490,14 +470,12 @@
}
});
// 새로 선택한 조치사진 파일들 추가
if (this.actnSelectedFiles && this.actnSelectedFiles.length > 0) {
for (var i = 0; i < this.actnSelectedFiles.length; i++) {
formData.append('actnPhotoFiles', this.actnSelectedFiles[i]);
}
}
// 저장 요청
$.ajax({
url: '<c:url value="/crdn/crndRegistAndView/crdnActInfo/saveActnInfo.ajax"/>',
type: 'POST',
@ -506,11 +484,15 @@
contentType: false,
success: function(response) {
if (response && response.success) {
// 그리드 새로고침
if (self.grid.instance) {
alert(response.message);
if( mode === "C" ){
self.actnInfoIdSelect = null;
self.grid.instance.readData();
self.clearActnForm();
}else{
self.grid.instance.readData();
self.loadActnInfoToForm(response.data);
}
} else {
alert(response.message || '조치정보 저장에 실패했습니다.');
}
@ -521,9 +503,7 @@
});
},
/**
* 조치정보 삭제 (crdnActInfoRegistPopup.jsp의 deleteActnInfo 패턴)
*/
deleteActnInfo: function() {
var actnInfoId = $('#actnInfoId').val().trim();
@ -542,21 +522,15 @@
url: '<c:url value="/crdn/crndRegistAndView/crdnActInfo/deleteActnInfo.ajax"/>',
type: 'POST',
data: {
actnInfoId: actnInfoId,
actnInfoIds: actnInfoId,
mode: 'D'
},
success: function(response) {
if (response && response.success) {
alert('조치정보가 삭제되었습니다.');
// 폼 초기화
self.actnInfoIdSelect = null;
self.grid.instance.readData();
self.clearActnForm();
// 그리드 새로고침
if (self.grid.instance) {
self.grid.instance.readData();
}
} else {
alert(response.message || '조치정보 삭제에 실패했습니다.');
}
@ -567,9 +541,7 @@
});
},
/**
* 조치정보 폼 초기화 (crdnActInfoRegistPopup.jsp의 clearActnForm 패턴)
*/
clearActnForm: function() {
var self = this;
@ -579,19 +551,20 @@
$('#actnRmrk').val('');
$('#actnMode').val('C');
// 조치사진 초기화
// validation 에러 스타일과 메시지 제거
$('#actnInfoForm').find('.is-invalid').removeClass('is-invalid');
$('#actnInfoForm').find('.is-invalid-custom').removeClass('is-invalid-custom');
$('#actnInfoForm').find('.error-message').remove();
$('#actnPhotoPreviewContainer').empty();
$('#actnPhotoFiles').val('');
this.actnSelectedFiles = [];
self.grid.instance.readData();
console.log('조치정보 폼 초기화 완료');
},
/**
* 파일 선택 처리 (crdnActInfoRegistPopup.jsp의 handleFileSelect 패턴)
*/
handleFileSelect: function(files, photoType) {
if (!files || files.length === 0) {
return;
@ -601,7 +574,7 @@
var selectedFilesArray = this.actnSelectedFiles;
var photoTypeName = '조치';
// 파일 개수 제한 체크 (각 종류별로 10개까지)
var existingPhotos = $(containerSelector + ' .photo-preview-item.existing-photo').length;
var newFiles = selectedFilesArray.length + files.length;
@ -610,41 +583,39 @@
return;
}
// 각 파일에 대해 검증 및 미리보기 생성
for (var i = 0; i < files.length; i++) {
var file = files[i];
// 파일 유효성 검증
if (!this.validateFile(file)) {
continue;
}
// 해당 종류의 선택된 파일 목록에 추가
selectedFilesArray.push(file);
// 미리보기 생성
this.createPhotoPreview(file, photoType);
}
},
/**
* 파일 유효성 검증 (crdnActInfoRegistPopup.jsp의 validateFile 패턴)
*/
validateFile: function(file) {
// 파일 크기 체크 (10MB)
var maxSize = 10 * 1024 * 1024;
if (file.size > maxSize) {
alert(file.name + ' 파일이 10MB를 초과합니다.');
return false;
}
// 이미지 파일인지 체크
if (!file.type.startsWith('image/')) {
alert(file.name + ' 은(는) 이미지 파일이 아닙니다.');
return false;
}
// 허용된 확장자 체크
var allowedExtensions = ['jpg', 'jpeg', 'png', 'gif'];
var fileName = file.name.toLowerCase();
var fileExtension = fileName.split('.').pop();
@ -657,9 +628,7 @@
return true;
},
/**
* 사진 미리보기 생성 (crdnActInfoRegistPopup.jsp의 createPhotoPreview 패턴)
*/
createPhotoPreview: function(file, photoType) {
var reader = new FileReader();
var containerSelector = '#actnPhotoPreviewContainer';
@ -674,7 +643,7 @@
' <div class="photo-info">' +
' <div class="photo-name" title="' + file.name + '">' + file.name + '</div>' +
' <div class="photo-type">[' + photoTypeName + ']</div>' +
' <button type="button" class="delete-photo-btn" onclick="crdnActnInfoRegistPopup.deleteNewPhoto(this, \'' + photoType + '\')">삭제</button>' +
' <button type="button" class="delete-photo-btn" onclick="CrdnActnInfoRegistPopup.deleteNewPhoto(this, \'' + photoType + '\')">삭제</button>' +
' </div>' +
'</div>';
@ -684,15 +653,13 @@
reader.readAsDataURL(file);
},
/**
* 새로 선택한 파일 삭제 (crdnActInfoRegistPopup.jsp의 deleteNewPhoto 패턴)
*/
deleteNewPhoto: function(button, photoType) {
var $item = $(button).closest('.photo-preview-item');
var fileName = $item.data('file-name');
var selectedFilesArray = this.actnSelectedFiles;
// selectedFiles 배열에서 파일 제거
for (var i = 0; i < selectedFilesArray.length; i++) {
if (selectedFilesArray[i].name === fileName) {
selectedFilesArray.splice(i, 1);
@ -700,45 +667,39 @@
}
}
// 화면에서 제거
$item.remove();
},
/**
* 기존 조치사진 삭제 (crdnActInfoRegistPopup.jsp의 deleteExistingActnPhoto 패턴)
*/
deleteExistingActnPhoto: function(actnInfoId, crdnPhotoSn) {
if (!confirm('선택한 조치사진을 삭제하시겠습니까?')) {
deleteExistingPhoto: function(actInfoId, crdnPhotoSn, photoType) {
var photoTypeName = photoType === '1' ? '단속' : '조치';
if (!confirm('선택한 ' + photoTypeName + ' 사진을 삭제하시겠습니까?')) {
return;
}
$.ajax({
url: '<c:url value="/crdn/crndRegistAndView/crdnActInfo/deleteActnPhoto.ajax"/>',
url: '<c:url value="/crdn/crndRegistAndView/crdnActInfo/deletePhoto.ajax"/>',
type: 'POST',
data: {
actnInfoId: actnInfoId,
actInfoId: actInfoId,
crdnPhotoSn: crdnPhotoSn
},
success: function(response) {
if (response && response.success) {
// 화면에서 해당 사진 제거
$('[data-actn-info-id="' + actnInfoId + '"][data-photo-sn="' + crdnPhotoSn + '"][data-photo-type="2"]').remove();
alert('조치사진이 삭제되었습니다.');
$('[data-act-info-id="' + actInfoId + '"][data-photo-sn="' + crdnPhotoSn + '"][data-photo-type="' + photoType + '"]').remove();
} else {
alert(response.message || '조치사진 삭제에 실패했습니다.');
alert(response.message || '사진 삭제에 실패했습니다.');
}
},
error: function() {
alert('조치사진 삭제 중 오류가 발생했습니다.');
}
});
},
/**
* 팝업 닫기
*/
closePopup: function() {
// 부모 팝업에 변경 사항 알림
if (window.opener && !window.opener.closed) {
if (typeof window.opener.CrdnDetailViewActInfo.search === 'function') {
window.opener.CrdnDetailViewActInfo.search();
@ -749,17 +710,19 @@
}
};
/**
* 원본 사진 보기 (기존 DB 사진)
* 중요한 로직 주석: 등록된 사진을 photoView 페이지에서 원본 크기로 표시하고 다운로드 버튼을 제공한다.
*/
function viewOriginalPhoto(actnInfoId, actInfoId, crdnPhotoSn, crdnPhotoSeCd) {
var url = '<c:url value="/crdn/crndRegistAndView/crdnActInfo/photoView.do"/>?actnInfoId=' + actnInfoId + '&actInfoId=' + actInfoId + '&crdnPhotoSn=' + crdnPhotoSn + '&crdnPhotoSeCd=' + crdnPhotoSeCd ;
openPopup(url, 1000, 700, '_blank');
}
// DOM 준비 완료 시 초기화
$(document).ready(function() {
crdnActnInfoRegistPopup.init();
CrdnActnInfoRegistPopup.init();
});
</script>
window.CrdnActnInfoRegistPopup = CrdnActnInfoRegistPopup;
})(window, jQuery);
</script>

Loading…
Cancel
Save