단속 > 단속 등록&열람: 소유자 관리 및 단속 팝업 기능 개선, 세션 기반 데이터 처리 적용, 팝업 UI 최적화, JavaScript 모듈 구조화, MyBatis 매퍼 수정 및 소스코드 주석 추가

dev
박성영 4 months ago
parent 65cdbc61b7
commit f7e5fad02f

@ -1,6 +1,7 @@
package go.kr.project.crdn.crndRegistAndView.crdnOwnrInfo.controller;
import egovframework.util.ApiResponseUtil;
import egovframework.util.SessionUtil;
import go.kr.project.crdn.crndRegistAndView.crdnOwnrInfo.model.CrdnOwnrInfoVO;
import go.kr.project.crdn.crndRegistAndView.crdnOwnrInfo.service.CrdnOwnrInfoService;
import io.swagger.v3.oas.annotations.Operation;
@ -66,15 +67,9 @@ public class CrdnOwnrInfoController {
@RequestParam String crdnYr,
@RequestParam String crdnNo,
@RequestParam String pstnInfoId,
@RequestParam String ownrId,
HttpSession session) {
try {
// 중요로직: 세션에서 사용자 ID 가져오기 (등록자 정보)
String rgtr = "SYSTEM"; // 기본값
// TODO: 실제로는 세션에서 사용자 정보를 가져와야 함
// Object loginUser = session.getAttribute("loginUser");
// if (loginUser != null) { rgtr = ((LoginVO)loginUser).getUserId(); }
@RequestParam String ownrId) {
String rgtr = SessionUtil.getUserId(); // 기본값
// 중요로직: 중복 검증 먼저 수행
if (service.checkDuplicateOwnr(crdnYr, crdnNo, ownrId)) {
@ -101,10 +96,5 @@ public class CrdnOwnrInfoController {
} else {
return ApiResponseUtil.error("소유자 정보 저장에 실패했습니다.");
}
} catch (Exception e) {
log.error("소유자 정보 저장 중 오류 발생: {}", e.getMessage(), e);
return ApiResponseUtil.error(e.getMessage());
}
}
}

@ -1,6 +1,7 @@
package go.kr.project.crdn.crndRegistAndView.crdnOwnrInfo.service.impl;
import egovframework.exception.MessageException;
import egovframework.util.SessionUtil;
import go.kr.project.crdn.crndRegistAndView.crdnOwnrInfo.mapper.CrdnOwnrInfoMapper;
import go.kr.project.crdn.crndRegistAndView.crdnOwnrInfo.model.CrdnOwnrInfoVO;
import go.kr.project.crdn.crndRegistAndView.crdnOwnrInfo.service.CrdnOwnrInfoService;
@ -106,9 +107,8 @@ public class CrdnOwnrInfoServiceImpl extends EgovAbstractServiceImpl implements
.delYn("N")
.build();
// 중요로직: SGG_CD는 단속 정보에서 가져와야 하지만 우선 기본값 설정
// TODO: 실제로는 단속 정보에서 SGG_CD를 조회해서 설정해야 함
vo.setSggCd("11"); // 임시 기본값
// 중요로직: SessionUtil에서 조직 코드를 가져와서 SGG_CD 설정
vo.setSggCd(SessionUtil.getSessionVO().getUser().getOrgCd());
return mapper.insertOwnrInfo(vo);
}

@ -133,7 +133,7 @@ public class CrdnRegistAndViewController {
try {
log.debug("단속 팝업 화면 요청 - 모드: {}, 단속연도: {}, 단속번호: {}", mode, crdnYr, crdnNo);
ModelAndView mav = new ModelAndView("crdn/crndRegistAndView/crdnRegistPopup" + TilesConstants.POPUP);
ModelAndView mav = new ModelAndView("crdn/crndRegistAndView/main/crdnRegistPopup" + TilesConstants.POPUP);
mav.addObject("mode", mode);
// 수정/조회 모드인 경우 기존 데이터 조회

@ -47,7 +47,6 @@
o.TELNO,
o.EML
FROM tb_ownr o
LEFT JOIN tb_cd_detail sgg ON sgg.CD_GROUP_ID = 'ORG_CD' AND sgg.CD_ID = o.SGG_CD AND sgg.USE_YN = 'Y'
LEFT JOIN tb_cd_detail ownrSe ON ownrSe.CD_GROUP_ID = 'OWNR_SE_CD' AND ownrSe.CD_ID = o.OWNR_SE_CD AND ownrSe.USE_YN = 'Y'
LEFT JOIN tb_user regUser ON regUser.USER_ID = o.RGTR
@ -84,7 +83,8 @@
/* OwnrSelectMapper.selectOwnrListTotalCount : 소유자 총 개수 조회 */
SELECT COUNT(*)
FROM tb_ownr o
WHERE o.DEL_YN = 'N'
WHERE NOT EXISTS (SELECT 1 FROM tb_ownr_info oi WHERE oi.OWNR_ID = o.OWNR_ID AND oi.DEL_YN = 'N')
AND o.DEL_YN = 'N'
<if test='flnm != null and flnm != ""'>
AND o.FLNM LIKE CONCAT('%', #{flnm}, '%')
</if>

@ -122,7 +122,7 @@
width: 60,
sortable: false,
formatter: function(e) {
return e.row.rowKey + 1;
return XitReverseRowNumberRenderer.format(ExmnrPopPopup.grid.instance.getData().length, e);
}
},
{

@ -123,34 +123,55 @@
</div>
</div>
<script>
(function($) {
'use strict';
<script type="text/javascript">
/**
* 단속 등록/수정 팝업 관리 모듈
* 단속 정보의 등록, 수정, 삭제 기능을 제공합니다.
*/
(function($) {
'use strict';
var CrdnPopup = {
// 자식 팝업창 참조 저장 배열
childPopups: [],
/**
* 단속 팝업 관리 네임스페이스
*/
var CrdnPopup = {
/**
* 자식 팝업창 참조 저장 배열
*/
childPopups: [],
init: function() {
this.initCodeSelect();
this.setFormData();
this.bindEvents();
},
/**
* 모듈 초기화
*/
init: function() {
this.initCodeSelect();
this.setFormData();
this.bindEvents();
},
initCodeSelect: function() {
commonCodeSelectAjax('RGN_SE_CD', 'rgnSeCd', '선택하세요', "${data.rgnSeCd == null ? '1':data.rgnSeCd}", {sortColumn:"SORT_ORDR"});
commonCodeSelectAjax('DSCL_MTHD_CD', 'dsclMthdCd', '선택하세요', "${data.dsclMthdCd}", {sortColumn:"CD_NM"});
},
/**
* 코드 선택박스 초기화
*/
initCodeSelect: function() {
commonCodeSelectAjax('RGN_SE_CD', 'rgnSeCd', '선택하세요', "${data.rgnSeCd == null ? '1':data.rgnSeCd}", {sortColumn:"SORT_ORDR"});
commonCodeSelectAjax('DSCL_MTHD_CD', 'dsclMthdCd', '선택하세요', "${data.dsclMthdCd}", {sortColumn:"CD_NM"});
},
setFormData: function() {
var mode = $("#mode").val();
if (mode === 'U' || mode === 'V') {
$("#relevyYn").val('${data.relevyYn}');
$("#agrvtnLevyTrgtYn").val('${data.agrvtnLevyTrgtYn}');
}
},
/**
* 폼 데이터 설정
*/
setFormData: function() {
var mode = $("#mode").val();
if (mode === 'U' || mode === 'V') {
$("#relevyYn").val('${data.relevyYn}');
$("#agrvtnLevyTrgtYn").val('${data.agrvtnLevyTrgtYn}');
}
},
bindEvents: function() {
/**
* 이벤트 바인딩
*/
bindEvents: function() {
var self = this;
$("#btnSave").on('click', function() {
@ -179,6 +200,10 @@
},
/**
* 팝업 취소 처리
* 자식 팝업창들을 닫고 현재 창을 닫습니다.
*/
cancel: function() {
// 공통 함수를 사용하여 자식 팝업창들을 닫고 현재 창 닫기
this.childPopups = closeChildPopupsAndSelf(this.childPopups);
@ -201,6 +226,10 @@
}
},
/**
* 단속 정보 저장
* 폼 유효성 검증 후 단속 정보를 저장합니다.
*/
save: function() {
if (!this.validate()) return;
@ -226,6 +255,10 @@
});
},
/**
* 단속 정보 삭제
* 사용자 확인 후 단속 정보를 삭제합니다.
*/
delete: function() {
if (!confirm('정말 삭제하시겠습니까?')) return;

@ -140,7 +140,6 @@
if( responseObj ){
totalCount = responseObj.data.contents.length;
}
console.log(totalCount);
var $pstnInfoRegistBtn = $('#pstnInfoRegistBtn');
if (totalCount >= 1) {
@ -194,7 +193,11 @@
popUrl += params;
var popTitle = "위치정보 수정";
var popOption = "width=1000px, height=700px, resizable=yes, scrollbars=yes, location=no, top=50px, left=100px";
// 중요로직: 위치정보 추가 버튼 팝업 크기와 동일하게 설정 (width=1200, height=500)
var w = 1200, h = 500;
var left = Math.max(0, (screen.width - w) / 2);
var top = Math.max(0, (screen.height - h) / 2);
var popOption = "width=" + w + ",height=" + h + ",left=" + left + ",top=" + top + ",resizable=yes,scrollbars=yes";
window.open(popUrl, popTitle, popOption);
}
},
@ -228,10 +231,7 @@
// DOM 준비 완료 시 초기화
$(document).ready(function() {
// 메인 모듈이 로드될 때까지 약간의 지연
setTimeout(function() {
CrdnDetailViewPstn.init();
}, 100);
CrdnDetailViewPstn.init();
});
// 전역 네임스페이스에 모듈 노출

@ -70,89 +70,190 @@
(function(window, $) {
'use strict';
// 중요로직: 소유자 선택 그리드 관리 객체
var ownrSelectGrid = {
instance: null,
// 그리드 초기화
init: function() {
var gridConfig = new XitTuiGridConfig();
// 데이터 소스 설정
var dataSource = {
api: {
readData: {
url: '<c:url value="/crdn/crndRegistAndView/ownrSelect/list.ajax"/>',
method: 'POST',
contentType: 'application/x-www-form-urlencoded',
processData: true
/**
* 소유자 선택 팝업 관리 네임스페이스
*/
var OwnrSelectPopup = {
/**
* 그리드 관련 객체
*/
grid: {
/**
* 그리드 인스턴스
*/
instance: null,
/**
* 그리드 설정 초기화
* @returns {Object} 그리드 설정 객체
*/
initConfig: function() {
// 데이터 소스 설정
var dataSource = this.createDataSource();
// 그리드 설정 객체 생성
var gridConfig = new XitTuiGridConfig();
// 기본 설정
gridConfig.setOptDataSource(dataSource); // 데이터소스 연결
gridConfig.setOptGridId('ownrSelectGrid'); // 그리드를 출력할 Element ID
gridConfig.setOptGridHeight(350); // 그리드 높이(단위: px)
gridConfig.setOptRowHeight(30); // 그리드 행 높이(단위: px)
gridConfig.setOptRowHeaderType('checkbox'); // 행 첫번째 셀 타입(checkbox: 체크박스)
gridConfig.setOptUseClientSort(true); // 클라이언트 사이드 정렬
gridConfig.setOptColumns(this.getGridColumns());
return gridConfig;
},
/**
* 그리드 컬럼 정의
* @returns {Array} 그리드 컬럼 배열
*/
getGridColumns: function() {
return [
{ header: '소유자ID', name: 'ownrId', align: 'center', width: 100, hidden: true },
{ header: '성명', name: 'flnm', align: 'center', width: 120, sortable: true },
{ header: '주민등록번호', name: 'rrno', align: 'center', width: 150 },
{ header: '소유자구분', name: 'ownrSeCdNm', align: 'center', width: 100 },
{ header: '전화번호', name: 'telno', align: 'center', width: 120 },
{ header: '이메일', name: 'eml', align: 'left', width: 200 },
{ header: '지번전체주소', name: 'lotnoWholAddr', align: 'left', width: 300 },
{ header: '도로명전체주소', name: 'roadNmWholAddr', align: 'left', width: 300 },
{ header: '우편번호', name: 'zip', align: 'center', width: 80 },
{ header: '비고', name: 'rmrk', align: 'left', width: 200 },
{ header: '등록일시', name: 'regDt', align: 'center', width: 150,
formatter: function (e) {
return e.value ? moment(e.value).format('YYYY-MM-DD HH:mm') : '';
}
}
},
initialRequest: true,
serializer: function(params) {
// 기본 파라미터 (페이지 정보 등)
var defaultParams = $.param(params);
// 검색 조건 추가
var searchParams = $.param({
flnm: $('#searchFlnm').val() || '',
rrno: $('#searchRrno').val() || '',
telno: $('#searchTelno').val() || '',
eml: $('#searchEml').val() || ''
});
return defaultParams + '&' + searchParams;
}
};
// 기본 설정
gridConfig.setOptDataSource(dataSource);
gridConfig.setOptGridId('ownrSelectGrid');
gridConfig.setOptGridHeight(350);
gridConfig.setOptRowHeight(30);
gridConfig.setOptRowHeaderType('checkbox');
gridConfig.setOptUseClientSort(true);
// 컬럼 설정 - TB_OWNR 테이블의 주요 컬럼들
gridConfig.setOptColumns([
{ header: '소유자ID', name: 'ownrId', align: 'center', width: 100, hidden: true },
{ header: '성명', name: 'flnm', align: 'center', width: 120, sortable: true },
{ header: '주민등록번호', name: 'rrno', align: 'center', width: 150 },
{ header: '소유자구분', name: 'ownrSeCdNm', align: 'center', width: 100 },
{ header: '전화번호', name: 'telno', align: 'center', width: 120 },
{ header: '이메일', name: 'eml', align: 'left', width: 200 },
{ header: '지번전체주소', name: 'lotnoWholAddr', align: 'left', width: 300 },
{ header: '도로명전체주소', name: 'roadNmWholAddr', align: 'left', width: 300 },
{ header: '우편번호', name: 'zip', align: 'center', width: 80 },
{ header: '비고', name: 'rmrk', align: 'left', width: 200 },
{ header: '등록일시', name: 'regDt', align: 'center', width: 150,
formatter: function (e) {
return e.value ? moment(e.value).format('YYYY-MM-DD HH:mm') : '';
];
},
/**
* 데이터 소스 생성
* @returns {Object} 데이터 소스 설정 객체
*/
createDataSource: function() {
return {
api: {
readData: {
url: '<c:url value="/crdn/crndRegistAndView/ownrSelect/list.ajax"/>',
method: 'POST',
contentType: 'application/x-www-form-urlencoded',
processData: true
}
},
initialRequest: true, // 초기 데이터 요청 여부
serializer: function(params) {
// 기본 파라미터 (페이지 정보 등)
var defaultParams = $.param(params);
// 검색 조건 추가
var searchParams = $.param({
flnm: $('#searchFlnm').val() || '',
rrno: $('#searchRrno').val() || '',
telno: $('#searchTelno').val() || '',
eml: $('#searchEml').val() || ''
});
return defaultParams + '&' + searchParams;
}
}
]);
this.instance = gridConfig.instance(tui.Grid);
tui.Grid.applyTheme('striped');
};
},
/**
* 그리드 인스턴스 생성
*/
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;
// 행 더블클릭 시 선택
this.instance.on('dblclick', function(ev) {
var rowData = self.instance.getRow(ev.rowKey);
if (rowData) {
OwnrSelectPopup.selectOwners([rowData]);
}
});
},
/**
* 체크된 행들 가져오기
*/
getCheckedRows: function() {
return this.instance ? this.instance.getCheckedRows() : [];
}
},
/**
* 모듈 초기화
*/
init: function() {
// 그리드 생성
this.grid.create();
this.bindEvents();
},
// 그리드 이벤트 바인딩
/**
* 이벤트 바인딩
*/
bindEvents: function() {
var self = this;
// 행 더블클릭 시 선택
this.instance.on('dblclick', function(ev) {
var rowData = self.instance.getRow(ev.rowKey);
if (rowData) {
self.selectOwners([rowData]);
// 검색 버튼 클릭 이벤트
$('#searchBtn').on('click', function() {
self.search();
});
// 초기화 버튼 클릭 이벤트
$('#resetBtn').on('click', function() {
$('#searchForm')[0].reset();
self.search();
});
// 선택 버튼 클릭 이벤트
$('#selectBtn').on('click', function() {
var checkedRows = self.grid.getCheckedRows();
if (checkedRows.length === 0) {
alert('선택할 소유자를 체크해주세요.');
return;
}
self.selectOwners(checkedRows);
});
// 닫기 버튼 클릭 이벤트
$('#closeBtn, #btnCloseTop').on('click', function(e) {
e.preventDefault();
window.close();
});
// Enter 키로 검색
$('#searchForm input').on('keypress', function(e) {
if (e.which === 13) {
e.preventDefault();
$('#searchBtn').click();
}
});
},
// 검색
/**
* 검색 함수
*/
search: function() {
if (this.instance) {
this.instance.readData();
if (this.grid.instance) {
this.grid.instance.readData();
}
},
@ -269,45 +370,14 @@
}
};
// DOM 준비 완료 시 초기화
$(document).ready(function() {
// 중요로직: 소유자 선택 그리드 초기화
ownrSelectGrid.init();
// 검색 버튼 클릭 이벤트
$('#searchBtn').on('click', function() {
ownrSelectGrid.search();
});
// 초기화 버튼 클릭 이벤트
$('#resetBtn').on('click', function() {
$('#searchForm')[0].reset();
ownrSelectGrid.search();
});
// 선택 버튼 클릭 이벤트
$('#selectBtn').on('click', function() {
var checkedRows = ownrSelectGrid.getCheckedRows();
if (checkedRows.length === 0) {
alert('선택할 소유자를 체크해주세요.');
return;
}
ownrSelectGrid.selectOwners(checkedRows);
});
// 닫기 버튼 클릭 이벤트
$('#closeBtn, #btnCloseTop').on('click', function(e) {
e.preventDefault();
window.close();
});
// Enter 키로 검색
$('#searchForm input').on('keypress', function(e) {
if (e.which === 13) {
e.preventDefault();
$('#searchBtn').click();
}
});
OwnrSelectPopup.init();
});
// 전역 네임스페이스에 모듈 노출
window.OwnrSelectPopup = OwnrSelectPopup;
})(window, jQuery);
</script>
Loading…
Cancel
Save