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