단속 > 단속 등록&열람: 기존 MariaDB DDL 제거 및 ibmsdb 디렉토리로 DDL 이동, 불법행위정보 등록 팝업 JSP 및 관련 JavaScript 추가

dev
박성영 4 months ago
parent 5d8d5655b3
commit c0967a0a30

@ -0,0 +1,17 @@
create table tb_pstn_idx
(
PSTN_IDX_NO varchar(2) not null comment '위치 지수 번호'
primary key,
BLDG_ANX_LAND_BGNG_PRC decimal null comment '건물 부속 토지 시작 가격',
BLDG_ANX_LAND_END_PRC decimal null comment '건물 부속 토지 종료 가격',
PSTN_IDX decimal(10, 2) null comment '위치 지수',
REG_DT datetime null comment '등록 일시',
RGTR varchar(11) null comment '등록자',
MDFCN_DT datetime null comment '수정 일시',
MDFR varchar(11) null comment '수정자',
DEL_YN char not null comment '삭제 여부',
DEL_DT datetime null comment '삭제 일시',
DLTR varchar(11) null comment '삭제자'
)
comment '위치 지수';

@ -0,0 +1,19 @@
create table tb_strct_idx
(
STRCT_IDX_CD varchar(3) not null comment '구조 지수 코드'
primary key,
STRCT_NM varchar(100) null comment '구조 명',
STRCT_IDX decimal(10, 2) null comment '구조 지수',
REG_DT datetime null comment '등록 일시',
RGTR varchar(11) null comment '등록자',
MDFCN_DT datetime null comment '수정 일시',
MDFR varchar(11) null comment '수정자',
DEL_YN char not null comment '삭제 여부',
DEL_DT datetime null comment '삭제 일시',
DLTR varchar(11) null comment '삭제자',
RDVLRT_CN_YR_CNT decimal(2) null comment '잔가율 내용 연도 수',
LAST_YR_RDVLRT decimal(4, 2) null comment '최종 연도 잔가율',
DPRT decimal(4, 4) null comment '감가상각률'
)
comment '구조 지수';

@ -0,0 +1,18 @@
create table tb_usg_idx
(
USG_IDX_CD varchar(5) not null comment '용도 지수 코드'
primary key,
USG_NM varchar(300) null comment '용도 명',
USG_IDX decimal(10, 2) null comment '용도 지수',
MAIN_USG_NM varchar(100) null comment '주요 용도 명',
LWR_USG_NM varchar(100) null comment '하위 용도 명',
REG_DT datetime null comment '등록 일시',
RGTR varchar(11) null comment '등록자',
MDFCN_DT datetime null comment '수정 일시',
MDFR varchar(11) null comment '수정자',
DEL_YN char not null comment '삭제 여부',
DEL_DT datetime null comment '삭제 일시',
DLTR varchar(11) null comment '삭제자'
)
comment '용도 지수';

@ -0,0 +1,18 @@
create table tb_vltn_lwrg
(
VLTN_LWRG_CD varchar(3) not null comment '위반 법규 코드'
primary key,
VLTN_LWRG_NM varchar(100) null comment '위반 법규 명',
VLTN_LAW varchar(20) null comment '위반 법',
REG_DT datetime null comment '등록 일시',
RGTR varchar(11) null comment '등록자',
MDFCN_DT datetime null comment '수정 일시',
MDFR varchar(11) null comment '수정자',
DEL_YN char not null comment '삭제 여부',
DEL_DT datetime null comment '삭제 일시',
DLTR varchar(11) null comment '삭제자',
CRC_LAW varchar(20) null comment '시정 법',
IMPLT_LAW varchar(20) null comment '이행 법'
)
comment '위반 법규';

@ -77,6 +77,7 @@ public class XssRequestWrapper extends HttpServletRequestWrapper {
// 일반 텍스트인 경우 escape 메서드 사용
//return xssUtil.escape(value);
// TODO : 임시 해제!! 추후 보안을 위해 다시 적용해야함!!
return value;
}
}

@ -18,13 +18,13 @@
a.ACT_TYPE_CD,
act.CD_NM AS ACT_TYPE_CD_NM,
a.VLTN_LWRG_CD_1,
vltn1.CD_NM AS VLTN_LWRG_CD_1_NM,
vltn1.VLTN_LWRG_NM AS VLTN_LWRG_CD_1_NM,
a.VLTN_LWRG_CD_2,
vltn2.CD_NM AS VLTN_LWRG_CD_2_NM,
vltn2.VLTN_LWRG_NM AS VLTN_LWRG_CD_2_NM,
a.STRCT_IDX_CD,
strct.CD_NM AS STRCT_IDX_CD_NM,
strct.STRCT_NM AS STRCT_IDX_CD_NM,
a.USG_IDX_CD,
usg.CD_NM AS USG_IDX_CD_NM,
usg.USG_NM AS USG_IDX_CD_NM,
a.HGT,
a.WDTH,
a.VRTC,
@ -44,10 +44,10 @@
FROM tb_act_info a
LEFT JOIN tb_cd_detail sgg ON sgg.CD_GROUP_ID = 'ORG_CD' AND sgg.CD_ID = a.SGG_CD
LEFT JOIN tb_cd_detail act ON act.CD_GROUP_ID = 'ACT_TYPE_CD' AND act.CD_ID = a.ACT_TYPE_CD
LEFT JOIN tb_cd_detail vltn1 ON vltn1.CD_GROUP_ID = 'VLTN_LWRG_CD' AND vltn1.CD_ID = a.VLTN_LWRG_CD_1
LEFT JOIN tb_cd_detail vltn2 ON vltn2.CD_GROUP_ID = 'VLTN_LWRG_CD' AND vltn2.CD_ID = a.VLTN_LWRG_CD_2
LEFT JOIN tb_cd_detail strct ON strct.CD_GROUP_ID = 'STRCT_IDX_CD' AND strct.CD_ID = a.STRCT_IDX_CD
LEFT JOIN tb_cd_detail usg ON usg.CD_GROUP_ID = 'USG_IDX_CD' AND usg.CD_ID = a.USG_IDX_CD
LEFT JOIN tb_vltn_lwrg vltn1 ON vltn1.VLTN_LWRG_CD = a.VLTN_LWRG_CD_1 AND vltn1.DEL_YN = 'N'
LEFT JOIN tb_vltn_lwrg vltn2 ON vltn2.VLTN_LWRG_CD = a.VLTN_LWRG_CD_2 AND vltn2.DEL_YN = 'N'
LEFT JOIN tb_strct_idx strct ON strct.STRCT_IDX_CD = a.STRCT_IDX_CD AND strct.DEL_YN = 'N'
LEFT JOIN tb_usg_idx usg ON usg.USG_IDX_CD = a.USG_IDX_CD AND usg.DEL_YN = 'N'
LEFT JOIN tb_user regUser ON regUser.USER_ID = a.RGTR
LEFT JOIN tb_user modUser ON modUser.USER_ID = a.MDFR
WHERE a.DEL_YN = 'N'
@ -143,13 +143,13 @@
a.ACT_TYPE_CD,
act.CD_NM AS ACT_TYPE_CD_NM,
a.VLTN_LWRG_CD_1,
vltn1.CD_NM AS VLTN_LWRG_CD_1_NM,
vltn1.VLTN_LWRG_NM AS VLTN_LWRG_CD_1_NM,
a.VLTN_LWRG_CD_2,
vltn2.CD_NM AS VLTN_LWRG_CD_2_NM,
vltn2.VLTN_LWRG_NM AS VLTN_LWRG_CD_2_NM,
a.STRCT_IDX_CD,
strct.CD_NM AS STRCT_IDX_CD_NM,
strct.STRCT_NM AS STRCT_IDX_CD_NM,
a.USG_IDX_CD,
usg.CD_NM AS USG_IDX_CD_NM,
usg.USG_NM AS USG_IDX_CD_NM,
a.HGT,
a.WDTH,
a.VRTC,
@ -167,12 +167,12 @@
a.DEL_DT,
a.DLTR
FROM tb_act_info a
LEFT JOIN tb_cd_detail sgg ON sgg.CD_GROUP_ID = 'ORG_CD' AND sgg.CD_ID = a.SGG_CD AND
LEFT JOIN tb_cd_detail sgg ON sgg.CD_GROUP_ID = 'ORG_CD' AND sgg.CD_ID = a.SGG_CD
LEFT JOIN tb_cd_detail act ON act.CD_GROUP_ID = 'ACT_TYPE_CD' AND act.CD_ID = a.ACT_TYPE_CD
LEFT JOIN tb_cd_detail vltn1 ON vltn1.CD_GROUP_ID = 'VLTN_LWRG_CD' AND vltn1.CD_ID = a.VLTN_LWRG_CD_1
LEFT JOIN tb_cd_detail vltn2 ON vltn2.CD_GROUP_ID = 'VLTN_LWRG_CD' AND vltn2.CD_ID = a.VLTN_LWRG_CD_2
LEFT JOIN tb_cd_detail strct ON strct.CD_GROUP_ID = 'STRCT_IDX_CD' AND strct.CD_ID = a.STRCT_IDX_CD
LEFT JOIN tb_cd_detail usg ON usg.CD_GROUP_ID = 'USG_IDX_CD' AND usg.CD_ID = a.USG_IDX_CD AND
LEFT JOIN tb_vltn_lwrg vltn1 ON vltn1.VLTN_LWRG_CD = a.VLTN_LWRG_CD_1 AND vltn1.DEL_YN = 'N'
LEFT JOIN tb_vltn_lwrg vltn2 ON vltn2.VLTN_LWRG_CD = a.VLTN_LWRG_CD_2 AND vltn2.DEL_YN = 'N'
LEFT JOIN tb_strct_idx strct ON strct.STRCT_IDX_CD = a.STRCT_IDX_CD AND strct.DEL_YN = 'N'
LEFT JOIN tb_usg_idx usg ON usg.USG_IDX_CD = a.USG_IDX_CD AND usg.DEL_YN = 'N'
LEFT JOIN tb_user regUser ON regUser.USER_ID = a.RGTR
LEFT JOIN tb_user modUser ON modUser.USER_ID = a.MDFR
WHERE a.ACT_INFO_ID = #{actInfoId}

@ -0,0 +1,279 @@
<%@ 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" %>
<!-- 불법행위정보 등록 팝업 -->
<div class="popup_wrap">
<div class="popup_inner">
<div class="popup_tit">
<h2 class="tit" id="popupTitle">
<c:choose>
<c:when test="${mode eq 'update'}">불법행위정보 수정</c:when>
<c:otherwise>불법행위정보 등록</c:otherwise>
</c:choose>
</h2>
<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="${data.pstnInfoId}" />
<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="actBgngYmd" name="actBgngYmd" class="input calender datepicker" maxlength="8" style="width: 120px;" autocomplete="off" validation-check="required" value="${data.actBgngYmd}"/>
</td>
<th class="th"><span class="required">*</span> 행위유형</th>
<td>
<select id="actTypeCd" name="actTypeCd" class="input" style="width: 180px;" validation-check="required">
<option value="">선택하세요</option>
<c:forEach var="code" items="${actTypeCdList}">
<option value="${code.cdId}" <c:if test="${data.actTypeCd eq code.cdId}">selected</c:if>>${code.cdNm}</option>
</c:forEach>
</select>
</td>
</tr>
<tr>
<th class="th">위반법규1</th>
<td>
<select id="vltnLwrgCd1" name="vltnLwrgCd1" class="input" style="width: 180px;">
<option value="">선택하세요</option>
<c:forEach var="code" items="${vltnLwrgCdList}">
<option value="${code.cdId}" <c:if test="${data.vltnLwrgCd1 eq code.cdId}">selected</c:if>>${code.cdNm}</option>
</c:forEach>
</select>
</td>
<th class="th">위반법규2</th>
<td>
<select id="vltnLwrgCd2" name="vltnLwrgCd2" class="input" style="width: 180px;">
<option value="">선택하세요</option>
<c:forEach var="code" items="${vltnLwrgCdList}">
<option value="${code.cdId}" <c:if test="${data.vltnLwrgCd2 eq code.cdId}">selected</c:if>>${code.cdNm}</option>
</c:forEach>
</select>
</td>
</tr>
<tr>
<th class="th">구조지수</th>
<td>
<select id="strctIdxCd" name="strctIdxCd" class="input" style="width: 180px;">
<option value="">선택하세요</option>
<c:forEach var="code" items="${strctIdxCdList}">
<option value="${code.cdId}" <c:if test="${data.strctIdxCd eq code.cdId}">selected</c:if>>${code.cdNm}</option>
</c:forEach>
</select>
</td>
<th class="th">용도지수</th>
<td>
<select id="usgIdxCd" name="usgIdxCd" class="input" style="width: 180px;">
<option value="">선택하세요</option>
<c:forEach var="code" items="${usgIdxCdList}">
<option value="${code.cdId}" <c:if test="${data.usgIdxCd eq code.cdId}">selected</c:if>>${code.cdNm}</option>
</c:forEach>
</select>
</td>
</tr>
<tr>
<th class="th">높이(m)</th>
<td>
<input type="text" id="hgt" name="hgt" class="input" style="width: 120px;" maxlength="10" placeholder="예) 10.50" validation-check="number" value="${data.hgt}"/>
</td>
<th class="th">가로(m)</th>
<td>
<input type="text" id="wdth" name="wdth" class="input" style="width: 120px;" maxlength="10" placeholder="예) 5.25" validation-check="number" value="${data.wdth}"/>
</td>
</tr>
<tr>
<th class="th">세로(m)</th>
<td>
<input type="text" id="vrtc" name="vrtc" class="input" style="width: 120px;" maxlength="10" placeholder="예) 8.75" validation-check="number" value="${data.vrtc}"/>
</td>
<th class="th">면적(㎡)</th>
<td>
<input type="text" id="area" name="area" class="input" style="width: 120px;" maxlength="10" placeholder="예) 45.94" validation-check="number" value="${data.area}"/>
</td>
</tr>
<tr>
<th class="th">비고</th>
<td colspan="3">
<textarea id="rmrk" name="rmrk" class="textarea" rows="3" maxlength="1000" style="height: 80px;">${data.rmrk}</textarea>
</td>
</tr>
</table>
</form>
</div>
</div>
<div class="popup_foot">
<button type="button" id="btnSave" class="newbtns bg1">저장</button>
<button type="button" id="btnClose" class="newbtns bg2 modalclose">닫기</button>
</div>
</div>
</div>
<script type="text/javascript">
/**
* 불법행위정보 등록/수정 팝업 JavaScript
* 중요한 로직 주석: mode가 C(등록)인지 U(수정)인지에 따라 다른 처리를 한다.
*/
$(document).ready(function() {
var mode = $('#mode').val();
// 달력 초기화
$('.datepicker').datepicker({
container: '.popup_inner',
dateFormat: 'yymmdd',
changeMonth: true,
changeYear: true,
showMonthAfterYear: true,
yearRange: '1900:2100',
monthNames: ['1월','2월','3월','4월','5월','6월','7월','8월','9월','10월','11월','12월'],
monthNamesShort: ['1월','2월','3월','4월','5월','6월','7월','8월','9월','10월','11월','12월'],
dayNames: ['일','월','화','수','목','금','토'],
dayNamesShort: ['일','월','화','수','목','금','토'],
dayNamesMin: ['일','월','화','수','목','금','토']
});
// 저장 버튼 클릭 이벤트
$('#btnSave').on('click', function() {
saveActInfo();
});
// 닫기 버튼 클릭 이벤트
$('#btnClose, #btnCloseTop').on('click', function() {
if (confirm('작업을 취소하시겠습니까?')) {
window.close();
}
});
console.log('불법행위정보 팝업이 초기화되었습니다. 모드:', mode);
});
/**
* 불법행위정보 저장 함수
* 중요한 로직 주석: validation 체크 후 mode에 따라 등록/수정 API를 호출한다.
*/
function saveActInfo() {
// 입력값 검증
if (!validateForm()) {
return;
}
var mode = $('#mode').val();
var formData = $('#actInfoForm').serialize();
// 세션에서 사용자 정보 가져오기 (등록자/수정자)
<c:choose>
<c:when test="${mode eq 'update'}">
formData += '&mdfr=' + encodeURIComponent('${sessionScope.loginVO.userId}');
</c:when>
<c:otherwise>
formData += '&rgtr=' + encodeURIComponent('${sessionScope.loginVO.userId}');
formData += '&sggCd=' + encodeURIComponent('${sessionScope.loginVO.sggCd}');
</c:otherwise>
</c:choose>
var url = (mode === 'update') ?
'<c:url value="/crdn/crndRegistAndView/crdnActInfo/update.ajax"/>' :
'<c:url value="/crdn/crndRegistAndView/crdnActInfo/insert.ajax"/>';
var actionText = (mode === 'update') ? '수정' : '등록';
if (!confirm('불법행위정보를 ' + actionText + '하시겠습니까?')) {
return;
}
$.ajax({
url: url,
type: 'POST',
data: formData,
success: function(response) {
if (response && response.success) {
alert('불법행위정보가 성공적으로 ' + actionText + '되었습니다.');
// 부모창의 그리드 새로고침
if (window.opener && window.opener.CrdnDetailView && window.opener.CrdnDetailView.grids.actInfo) {
window.opener.CrdnDetailView.grids.actInfo.search();
}
window.close();
} else {
alert(response.message || actionText + ' 중 오류가 발생했습니다.');
}
},
error: function(xhr, status, error) {
console.error('불법행위정보 ' + actionText + ' 오류:', error);
alert(actionText + ' 중 시스템 오류가 발생했습니다.');
}
});
}
/**
* 폼 입력값 검증 함수
* 중요한 로직 주석: 필수 입력 필드와 숫자 형식 검증을 수행한다.
*/
function validateForm() {
// 필수 입력 검증
var actBgngYmd = $('#actBgngYmd').val().trim();
var actTypeCd = $('#actTypeCd').val().trim();
if (!actBgngYmd) {
alert('행위시작일자를 입력해 주세요.');
$('#actBgngYmd').focus();
return false;
}
if (!actTypeCd) {
alert('행위유형을 선택해 주세요.');
$('#actTypeCd').focus();
return false;
}
// 숫자 필드 검증
var numberFields = ['hgt', 'wdth', 'vrtc', 'area'];
for (var i = 0; i < numberFields.length; i++) {
var fieldId = numberFields[i];
var value = $('#' + fieldId).val().trim();
if (value && !isValidNumber(value)) {
alert(getFieldLabel(fieldId) + ' 값이 올바르지 않습니다. 숫자만 입력해 주세요.');
$('#' + fieldId).focus();
return false;
}
}
return true;
}
/**
* 숫자 유효성 검증
*/
function isValidNumber(value) {
return /^\d+(\.\d+)?$/.test(value);
}
/**
* 필드 레이블 반환
*/
function getFieldLabel(fieldId) {
var labels = {
'hgt': '높이',
'wdth': '가로',
'vrtc': '세로',
'area': '면적'
};
return labels[fieldId] || fieldId;
}
</script>

@ -135,6 +135,10 @@
<div class="box_column">
<ul class="box_title">
<li class="tit">3. 불법행위 정보</li>
<li class="rig">
<button type="button" id="actInfoRegistBtn" class="newbtn bg2-1">불법행위 추가</button>
<button type="button" id="actInfoDeleteBtn" class="newbtn bg2" style="margin-left: 5px;">삭제</button>
</li>
</ul>
<div class="containers">
<div id="grid3"></div>
@ -533,6 +537,68 @@
$('#exmnr').val(exmnrNames);
}
};
// 중요로직: 불법행위 정보 등록 버튼 클릭 이벤트
$('#actInfoRegistBtn').on('click', function() {
var crdnYr = $('#crdnYr').val();
var crdnNo = $('#crdnNo').val();
if (!crdnYr || !crdnNo) {
alert('단속 기본정보가 없습니다.');
return;
}
var url = '<c:url value="/crdn/crndRegistAndView/crdnActInfo/crdnActInfoRegistPopup.do"/>' + '?crdnYr=' + encodeURIComponent(crdnYr) + '&crdnNo=' + encodeURIComponent(crdnNo) + '&mode=C';
var w = 1200, h = 600;
var left = Math.max(0, (screen.width - w) / 2);
var top = Math.max(0, (screen.height - h) / 2);
window.open(url, 'actInfoPopup', 'width=' + w + ',height=' + h + ',left=' + left + ',top=' + top + ',resizable=yes,scrollbars=yes');
});
// 중요로직: 불법행위 정보 삭제 버튼 클릭 이벤트
$('#actInfoDeleteBtn').on('click', function() {
if (!window.CrdnDetailView.grids.actInfo || !window.CrdnDetailView.grids.actInfo.grid.instance) {
alert('불법행위 정보 그리드가 초기화되지 않았습니다.');
return;
}
var checkedRows = window.CrdnDetailView.grids.actInfo.grid.instance.getCheckedRows();
if (checkedRows.length === 0) {
alert('삭제할 항목을 선택해 주세요.');
return;
}
if (!confirm('선택된 ' + checkedRows.length + '건의 불법행위 정보를 삭제하시겠습니까?')) {
return;
}
var deleteIds = checkedRows.map(function(row) {
return row.actInfoId;
});
// 중요로직: 서버에 삭제 요청
$.ajax({
url: '<c:url value="/crdn/crndRegistAndView/crdnActInfo/delete.ajax"/>',
type: 'POST',
data: {
actInfoIds: deleteIds
},
traditional: true, // 배열 전송을 위한 설정
success: function(response) {
if (response && response.success) {
alert('불법행위 정보가 성공적으로 삭제되었습니다.');
// 그리드 새로고침
if (window.CrdnDetailView.grids.actInfo) {
window.CrdnDetailView.grids.actInfo.search();
}
} else {
alert(response.message || '삭제 중 오류가 발생했습니다.');
}
},
error: function(xhr, status, error) {
console.error('불법행위 정보 삭제 오류:', error);
alert('삭제 중 시스템 오류가 발생했습니다.');
}
});
});
console.log('단속 상세보기 통합 모듈이 초기화되었습니다.');
}

Loading…
Cancel
Save