Merge branch 'dev' of http://211.119.124.110:3000/xit-app/IBMS_NEW.git into dev
commit
be5bed3ef7
@ -0,0 +1,56 @@
|
||||
package go.kr.project.crdn.crndRegistAndView.crdnActInfo.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import go.kr.project.common.model.PagingVO;
|
||||
import lombok.*;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 조치정보 VO
|
||||
* 중요한 로직 주석: tb_actn_info 테이블과 매핑되며, 불법행위정보에 대한 조치 내역을 관리한다.
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class CrdnActnInfoVO extends PagingVO {
|
||||
|
||||
// ============ 테이블 컬럼 ============
|
||||
private String actnInfoId; // 조치 정보 ID (PK)
|
||||
private String sggCd; // 시군구 코드
|
||||
private String crdnYr; // 단속 연도
|
||||
private String crdnNo; // 단속 번호
|
||||
private String actInfoId; // 행위 정보 ID (FK - tb_act_info)
|
||||
private String actnYmd; // 조치 일자 (YYYYMMDD)
|
||||
private BigDecimal actnArea; // 조치 면적
|
||||
private String actnRmrk; // 조치 비고
|
||||
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul")
|
||||
private LocalDateTime regDt; // 등록 일시
|
||||
private String rgtr; // 등록자
|
||||
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul")
|
||||
private LocalDateTime mdfcnDt; // 수정 일시
|
||||
private String mdfr; // 수정자
|
||||
|
||||
private String delYn; // 삭제 여부
|
||||
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul")
|
||||
private LocalDateTime delDt; // 삭제 일시
|
||||
private String dltr; // 삭제자
|
||||
|
||||
// ============ 조회용 추가 필드 ============
|
||||
private int rownum; // 행 번호 (목록 조회용)
|
||||
|
||||
// ============ 검색 조건 필드 ============
|
||||
private String searchActInfoId; // 검색용 행위정보 ID
|
||||
private String searchStartYmd; // 검색 시작일자
|
||||
private String searchEndYmd; // 검색 종료일자
|
||||
}
|
||||
@ -0,0 +1,728 @@
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
|
||||
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
|
||||
<%@ taglib prefix="dateUtil" uri="http://egovframework.go.kr/functions/date-util" %>
|
||||
|
||||
<!-- 파일 업로드 관련 CSS -->
|
||||
<link rel="stylesheet" type="text/css" href="<c:url value='/resources/xit/xit-fileupload.css'/>" />
|
||||
|
||||
<!-- 조치정보 관리 팝업 -->
|
||||
<div class="popup_wrap">
|
||||
<div class="popup_inner">
|
||||
<div class="popup_tit">
|
||||
<h2 class="tit" id="popupTitle">조치정보 관리</h2>
|
||||
<a href="#" class="pop-x-btn modalclose" id="btnCloseTop"></a>
|
||||
</div>
|
||||
|
||||
<!-- 탭 메뉴 -->
|
||||
<div class="tab-container">
|
||||
<ul class="tab-menu">
|
||||
<li id="tab-act" class="tab-item" data-tab="act">
|
||||
<a href="#" class="tab-link">1. 불법행위정보</a>
|
||||
</li>
|
||||
<li id="tab-actn" class="tab-item active" data-tab="actn">
|
||||
<a href="#" class="tab-link">2. 조치정보</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="popup_con">
|
||||
<!-- 조치정보 탭 컨텐츠 -->
|
||||
<div id="tab-content-actn" class="tab-content active">
|
||||
<!-- 조치정보 그리드 영역 -->
|
||||
<div class="box_column">
|
||||
<ul class="box_title">
|
||||
<li class="tit">조치 정보</li>
|
||||
</ul>
|
||||
<div class="containers">
|
||||
<div id="actnInfoGrid"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 조치정보 입력 폼 -->
|
||||
<div class="box_column mt-20">
|
||||
<ul class="box_title">
|
||||
<li class="tit">조치정보 상세</li>
|
||||
</ul>
|
||||
<div class="containers">
|
||||
<form id="actnInfoForm" name="actnInfoForm">
|
||||
<input type="hidden" id="mode" name="mode" value="${mode}" />
|
||||
<input type="hidden" id="pstnInfoId" name="pstnInfoId" value="${pstnInfoId}" />
|
||||
<input type="hidden" id="actInfoId" name="actInfoId" value="${actInfoId}" />
|
||||
<input type="hidden" id="actnInfoId" name="actnInfoId" value="" />
|
||||
<input type="hidden" id="crdnYr" name="crdnYr" value="${crdnYr}" />
|
||||
<input type="hidden" id="crdnNo" name="crdnNo" value="${crdnNo}" />
|
||||
<input type="hidden" id="actnMode" name="actnMode" value="C" />
|
||||
|
||||
<div class="forms_table_non">
|
||||
<table>
|
||||
<colgroup>
|
||||
<col style="width: 18%;" />
|
||||
<col style="width: 32%;" />
|
||||
<col style="width: 18%;" />
|
||||
<col style="width: 32%;" />
|
||||
</colgroup>
|
||||
<tr>
|
||||
<th class="th"><span class="required">*</span> 조치일자</th>
|
||||
<td>
|
||||
<input type="text" id="actnYmd" name="actnYmd" class="input calender datepicker" maxlength="10" style="width: 120px;" autocomplete="off" validation-check="required date" />
|
||||
</td>
|
||||
<th class="th"><span class="required">*</span> 조치면적(㎡)</th>
|
||||
<td>
|
||||
<input type="text" id="actnArea" name="actnArea" class="input decimalMask" style="width: 120px;" maxlength="12" placeholder="예) 45.94" validation-check="required" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="th">조치비고</th>
|
||||
<td colspan="3">
|
||||
<textarea id="actnRmrk" name="actnRmrk" class="textarea" rows="3" maxlength="1000" style="height: 80px;"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="th">조치사진</th>
|
||||
<td colspan="3">
|
||||
<!-- 조치사진 업로드 영역 -->
|
||||
<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개, 각 10MB 이하의 이미지 파일만 업로드 가능합니다.</span>
|
||||
</div>
|
||||
<div class="photo-preview-container" id="actnPhotoPreviewContainer">
|
||||
<!-- 기존 조치사진들이 여기에 표시됩니다 -->
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="forms_foot">
|
||||
<div class="btn_group">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="popup_foot">
|
||||
<button type="button" id="btnSaveActn" class="newbtns bg1">조치정보 저장</button>
|
||||
<button type="button" id="btnDeleteActn" class="newbtns bg6">조치정보 삭제</button>
|
||||
<button type="button" id="btnClearActn" class="newbtns bg2-1">신규</button>
|
||||
<button type="button" id="btnClose" class="newbtns bg2 modalclose">닫기</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
(function(window, $) {
|
||||
'use strict';
|
||||
|
||||
var CrdnActnInfoRegistPopup = {
|
||||
|
||||
actInfoId: '${actInfoId}',
|
||||
crdnYr: '${crdnYr}',
|
||||
crdnNo: '${crdnNo}',
|
||||
pstnInfoId: '${pstnInfoId}',
|
||||
actnInfoIdSelect: null,
|
||||
|
||||
|
||||
grid: {
|
||||
|
||||
instance: null,
|
||||
|
||||
|
||||
initConfig: function() {
|
||||
|
||||
var dataSource = this.createDataSource();
|
||||
|
||||
|
||||
var gridConfig = new XitTuiGridConfig();
|
||||
|
||||
|
||||
gridConfig.setOptDataSource(dataSource);
|
||||
gridConfig.setOptGridId('actnInfoGrid');
|
||||
gridConfig.setOptGridHeight(150);
|
||||
gridConfig.setOptRowHeight(30);
|
||||
gridConfig.setOptUseClientSort(true);
|
||||
gridConfig.setOptRowHeaderType('');
|
||||
gridConfig.setOptColumns(this.getGridColumns());
|
||||
|
||||
return gridConfig;
|
||||
},
|
||||
|
||||
|
||||
getGridColumns: function() {
|
||||
return [
|
||||
{
|
||||
header: '조치정보ID',
|
||||
name: 'actnInfoId',
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
header: '순번',
|
||||
name: 'rownum',
|
||||
width: 60,
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
header: '조치일자',
|
||||
name: 'actnYmd',
|
||||
width: 100,
|
||||
align: 'center',
|
||||
formatter: function(e) {
|
||||
return e.value ? moment(e.value).format('YYYY-MM-DD') : '';
|
||||
}
|
||||
},
|
||||
{
|
||||
header: '조치면적(㎡)',
|
||||
name: 'actnArea',
|
||||
width: 100,
|
||||
align: 'right',
|
||||
formatter: function(e) {
|
||||
return e.value ? parseFloat(e.value).toLocaleString() : '-';
|
||||
}
|
||||
},
|
||||
{
|
||||
header: '조치비고',
|
||||
name: 'actnRmrk',
|
||||
minWidth: 200,
|
||||
},
|
||||
{
|
||||
header: '수정일시',
|
||||
name: 'mdfcnDt',
|
||||
width: 130,
|
||||
align: 'center',
|
||||
}
|
||||
];
|
||||
},
|
||||
|
||||
|
||||
createDataSource: function() {
|
||||
return {
|
||||
api: {
|
||||
readData: {
|
||||
url: '<c:url value="/crdn/crndRegistAndView/crdnActInfo/actnInfoList.ajax"/>',
|
||||
method: 'POST',
|
||||
contentType: 'application/x-www-form-urlencoded',
|
||||
processData: true
|
||||
}
|
||||
},
|
||||
initialRequest: false,
|
||||
serializer: function(params) {
|
||||
var defaultParams = $.param(params);
|
||||
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 = CrdnActnInfoRegistPopup;
|
||||
|
||||
this.instance.on('successResponse', function(ev) {
|
||||
var responseObj = JSON.parse(ev.xhr.response);
|
||||
var totalCount = 0;
|
||||
if (responseObj && responseObj.data && responseObj.data.contents) {
|
||||
totalCount = responseObj.data.contents.length;
|
||||
$('#actnTotalCount').text('총 ' + totalCount + '건');
|
||||
}
|
||||
});
|
||||
|
||||
this.instance.on('onGridUpdated', function() {
|
||||
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 (self.actnInfoIdSelect === row.actnInfoId) {
|
||||
rowKey = row.rowKey
|
||||
console.log(self.actnInfoIdSelect, rowKey, row.rowKey, row.actnInfoId)
|
||||
}
|
||||
});
|
||||
if(rowKey != null){
|
||||
self.grid.instance.focus(rowKey, firstVisibleColumn.name, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.instance.on('focusChange', function(ev) {
|
||||
console.log(ev);
|
||||
if (ev.rowKey !== null) {
|
||||
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) {
|
||||
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();
|
||||
},
|
||||
|
||||
|
||||
eventBindEvents: function() {
|
||||
var self = this;
|
||||
|
||||
|
||||
$('#actnYmd').datepicker({
|
||||
container: '.popup_inner',
|
||||
language: "kr"
|
||||
});
|
||||
|
||||
|
||||
$('.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();
|
||||
});
|
||||
},
|
||||
|
||||
switchTab: function(tabType) {
|
||||
var self = this;
|
||||
if (tabType === 'act') {
|
||||
|
||||
var url = '<c:url value="/crdn/crndRegistAndView/crdnActInfo/crdnActInfoRegistPopup.do"/>?mode=U' +
|
||||
'&actInfoId=' + encodeURIComponent(self.actInfoId) +
|
||||
'&pstnInfoId=' + encodeURIComponent(self.pstnInfoId) +
|
||||
'&crdnYr=' + encodeURIComponent(self.crdnYr) +
|
||||
'&crdnNo=' + encodeURIComponent(self.crdnNo);
|
||||
var newWindow = openPopup(url, 1200, 700, 'actInfoPopup');
|
||||
if (newWindow) {
|
||||
window.close();
|
||||
} else {
|
||||
alert('팝업이 차단되었습니다. 팝업 차단을 해제해주세요.');
|
||||
}
|
||||
|
||||
} 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();
|
||||
}
|
||||
},
|
||||
|
||||
loadActnInfoToForm: function(rowData) {
|
||||
if (!rowData) return;
|
||||
|
||||
|
||||
$('#actnInfoId').val(rowData.actnInfoId || '');
|
||||
|
||||
|
||||
$('#actnYmd').val(moment(rowData.actnYmd).format('YYYY-MM-DD') || '');
|
||||
|
||||
|
||||
$('#actnArea').val(rowData.actnArea || '');
|
||||
|
||||
|
||||
$('#actnRmrk').val(rowData.actnRmrk || '');
|
||||
|
||||
|
||||
$('#actnMode').val('U');
|
||||
|
||||
|
||||
this.loadActnPhotos(rowData.actnInfoId);
|
||||
|
||||
console.log('조치정보 폼 로드 완료:', rowData);
|
||||
},
|
||||
|
||||
|
||||
loadActnPhotos: function(actnInfoId) {
|
||||
var self = this;
|
||||
|
||||
if (!actnInfoId) {
|
||||
$('#actnPhotoPreviewContainer').empty();
|
||||
return;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: '<c:url value="/crdn/crndRegistAndView/crdnActInfo/selectActnPhotos.ajax"/>',
|
||||
type: 'GET',
|
||||
data: { actnInfoId: actnInfoId },
|
||||
success: function(response) {
|
||||
$('#actnPhotoPreviewContainer').empty();
|
||||
|
||||
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="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="CrdnActnInfoRegistPopup.deleteExistingPhoto(\'' + photo.actInfoId + '\', \'' + photo.crdnPhotoSn + '\', \'2\')">삭제</button>' +
|
||||
' </div>' +
|
||||
'</div>';
|
||||
$('#actnPhotoPreviewContainer').append(previewHtml);
|
||||
});
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
alert('조치사진 조회 중 오류가 발생했습니다.');
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
saveActnInfo: function() {
|
||||
var self = this;
|
||||
|
||||
|
||||
if (!validateFormByAttributes('actnInfoForm')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var actnInfoId = $('#actnInfoId').val().trim();
|
||||
var actInfoId = this.actInfoId;
|
||||
var mode = actnInfoId ? 'U' : 'C';
|
||||
|
||||
|
||||
var formData = new FormData();
|
||||
formData.append('mode', mode);
|
||||
|
||||
$('#actnInfoForm').find('input, select, textarea').each(function() {
|
||||
var $this = $(this);
|
||||
var name = $this.attr('name');
|
||||
var value = $this.val();
|
||||
|
||||
if (name && value && $this.attr('type') !== 'file') {
|
||||
formData.append(name, value);
|
||||
}
|
||||
});
|
||||
|
||||
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',
|
||||
data: formData,
|
||||
processData: false,
|
||||
contentType: false,
|
||||
success: function(response) {
|
||||
if (response && response.success) {
|
||||
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 || '조치정보 저장에 실패했습니다.');
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
alert('조치정보 저장 중 오류가 발생했습니다.');
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
deleteActnInfo: function() {
|
||||
var actnInfoId = $('#actnInfoId').val().trim();
|
||||
|
||||
if (!actnInfoId) {
|
||||
alert('삭제할 조치정보를 선택해주세요.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!confirm('선택한 조치정보를 삭제하시겠습니까?\n관련된 조치사진도 함께 삭제됩니다.')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
|
||||
$.ajax({
|
||||
url: '<c:url value="/crdn/crndRegistAndView/crdnActInfo/deleteActnInfo.ajax"/>',
|
||||
type: 'POST',
|
||||
data: {
|
||||
actnInfoIds: actnInfoId,
|
||||
mode: 'D'
|
||||
},
|
||||
success: function(response) {
|
||||
if (response && response.success) {
|
||||
alert('조치정보가 삭제되었습니다.');
|
||||
self.actnInfoIdSelect = null;
|
||||
self.grid.instance.readData();
|
||||
self.clearActnForm();
|
||||
} else {
|
||||
alert(response.message || '조치정보 삭제에 실패했습니다.');
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
alert('조치정보 삭제 중 오류가 발생했습니다.');
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
clearActnForm: function() {
|
||||
var self = this;
|
||||
|
||||
$('#actnInfoId').val('');
|
||||
$('#actnYmd').val('');
|
||||
$('#actnArea').val('');
|
||||
$('#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 = [];
|
||||
|
||||
console.log('조치정보 폼 초기화 완료');
|
||||
},
|
||||
|
||||
|
||||
handleFileSelect: function(files, photoType) {
|
||||
if (!files || files.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var containerSelector = '#actnPhotoPreviewContainer';
|
||||
var selectedFilesArray = this.actnSelectedFiles;
|
||||
var photoTypeName = '조치';
|
||||
|
||||
|
||||
var existingPhotos = $(containerSelector + ' .photo-preview-item.existing-photo').length;
|
||||
var newFiles = selectedFilesArray.length + files.length;
|
||||
|
||||
if (existingPhotos + newFiles > 10) {
|
||||
alert('최대 10개의 ' + photoTypeName + ' 사진만 업로드할 수 있습니다.');
|
||||
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);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
validateFile: function(file) {
|
||||
|
||||
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();
|
||||
|
||||
if (allowedExtensions.indexOf(fileExtension) === -1) {
|
||||
alert('지원되지 않는 파일 형식입니다. (jpg, jpeg, png, gif만 가능)');
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
|
||||
createPhotoPreview: function(file, photoType) {
|
||||
var reader = new FileReader();
|
||||
var containerSelector = '#actnPhotoPreviewContainer';
|
||||
var photoTypeName = '조치';
|
||||
|
||||
reader.onload = function(e) {
|
||||
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">[' + photoTypeName + ']</div>' +
|
||||
' <button type="button" class="delete-photo-btn" onclick="CrdnActnInfoRegistPopup.deleteNewPhoto(this, \'' + photoType + '\')">삭제</button>' +
|
||||
' </div>' +
|
||||
'</div>';
|
||||
|
||||
$(containerSelector).append(previewHtml);
|
||||
};
|
||||
|
||||
reader.readAsDataURL(file);
|
||||
},
|
||||
|
||||
|
||||
deleteNewPhoto: function(button, photoType) {
|
||||
var $item = $(button).closest('.photo-preview-item');
|
||||
var fileName = $item.data('file-name');
|
||||
var selectedFilesArray = this.actnSelectedFiles;
|
||||
|
||||
|
||||
for (var i = 0; i < selectedFilesArray.length; i++) {
|
||||
if (selectedFilesArray[i].name === fileName) {
|
||||
selectedFilesArray.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$item.remove();
|
||||
},
|
||||
|
||||
|
||||
deleteExistingPhoto: function(actInfoId, crdnPhotoSn, photoType) {
|
||||
var photoTypeName = photoType === '1' ? '단속' : '조치';
|
||||
|
||||
if (!confirm('선택한 ' + photoTypeName + ' 사진을 삭제하시겠습니까?')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: '<c:url value="/crdn/crndRegistAndView/crdnActInfo/deletePhoto.ajax"/>',
|
||||
type: 'POST',
|
||||
data: {
|
||||
actInfoId: actInfoId,
|
||||
crdnPhotoSn: crdnPhotoSn
|
||||
},
|
||||
success: function(response) {
|
||||
if (response && response.success) {
|
||||
// 화면에서 해당 사진 제거
|
||||
$('[data-act-info-id="' + actInfoId + '"][data-photo-sn="' + crdnPhotoSn + '"][data-photo-type="' + photoType + '"]').remove();
|
||||
} else {
|
||||
alert(response.message || '사진 삭제에 실패했습니다.');
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
closePopup: function() {
|
||||
|
||||
if (window.opener && !window.opener.closed) {
|
||||
if (typeof window.opener.CrdnDetailViewActInfo.search === 'function') {
|
||||
window.opener.CrdnDetailViewActInfo.search();
|
||||
}
|
||||
window.opener.focus();
|
||||
}
|
||||
window.close();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
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');
|
||||
}
|
||||
|
||||
|
||||
$(document).ready(function() {
|
||||
CrdnActnInfoRegistPopup.init();
|
||||
});
|
||||
|
||||
|
||||
window.CrdnActnInfoRegistPopup = CrdnActnInfoRegistPopup;
|
||||
|
||||
})(window, jQuery);
|
||||
</script>
|
||||
Loading…
Reference in New Issue