### feat: 재검 여부 필터 추가 및 그리드 개선

- **재검 여부 필터 추가**
  - `검색 조건`에 재검 여부(`재검(Y)`, `미재검(N)`) 선택 기능 추가.
  - 재검 여부에 따른 데이터 필터링 로직 구현:
    - JSP: 검색 영역에 재검 여부 체크박스 추가.
    - JS: 검색 조건(`schReinspYn`)에 재검 여부 값 추가 및 다운로드 URL에 포함되도록 설정.
    - MyBatis: 쿼리에 재검 여부 필터 추가.

- **그리드 컬럼 및 데이터 처리 개선**
  - 결과 그리드에 `재검 여부` 열 추가:
    - JSP 및 그리드 설정에 관련 컬럼 반영.
    - MyBatis 또는 데이터 처리 단계에서 `재검 여부` 값 처리 및 가공 로직 구현.
  - 일련번호 계산 로직 단순화:
    - 기존 페이징 정보 활용 대신 로우 키만 활용하도록 변경.

- **서비스 및 내부 로직 변경**
  - 데이터 처리 단계에서 `재검 여부` 설정:
    - `ServiceImpl`: 일수(`daycnt`) 값에 `*` 포함 여부로 재검 여부 결정 후 저장.
  - VO 및 Mapper 수정:
    - `CarFfnlgTrgtVO`, `CarFfnlgTrgtExcelVO`: 재검 여부(`reinspYn`) 필드 추가.
    - DB: `tb_car_ffnlg_trgt` 테이블에 `REINSP_YN` 칼럼 추가, 마이그레이션 SQL 작성.

- **불필요한 페이징 관련 코드 제거**
  - 조회 페이징용 전역 변수 및 관련 UI 제거:
    - `perPageSelect`, `currentPage`, `totalPages` 등 페이징 UI 요소 삭제.
  - JS 및 컨트롤러에서 페이징 관련 전역 로직 제거 및 단순화.

- **기타 개선**
  - 검색 초기화 버튼에 재검 여부 관련 로직 추가.
  - 검색 조건 정리(`SEARCH_COND`) 및 관련 주석 추가.
  - DEBUG 로그 추가: `재검 여부` 설정 및 출력 내역 기록.
main
박성영 4 days ago
parent 9a67cf6e14
commit 7051953c82

@ -13,6 +13,7 @@ create table tb_car_ffnlg_trgt
CAR_USG varchar(100) null comment '자동차 용도',
INSP_END_YMD varchar(10) null comment '검사 종료 일자',
DAYCNT varchar(5) null comment '일수',
REINSP_YN varchar(1) null comment '재검 여부',
FFNLG_AMT varchar(10) null comment '과태료 금액',
LAST_REG_YMD varchar(11) null comment '최종 등록 일자',
ADDR varchar(600) null comment '주소',
@ -21,6 +22,7 @@ create table tb_car_ffnlg_trgt
TASK_PRCS_STTS_CD varchar(2) null comment '업무 처리 상태 코드',
TASK_PRCS_YMD varchar(10) null comment '업무 처리 일자',
RMRK varchar(4000) null comment '비고',
RMRK_DTL text null comment '비고 상세',
CAR_BASS_MATTER_INQIRE_ID varchar(20) null comment '자동차 기본 사항 조회 ID',
CAR_LEDGER_FRMBK_ID varchar(20) null comment '자동차 등록 원부 갑 ID',
CAR_BSC_MTTR_INQ_FLNM varchar(75) null comment '자동차 기본 사항 조회 성명',
@ -34,8 +36,7 @@ create table tb_car_ffnlg_trgt
RGTR varchar(11) null comment '등록자',
DEL_YN char not null comment '삭제 여부',
DEL_DT datetime null comment '삭제 일시',
DLTR varchar(11) null comment '삭제자',
RMRK_DTL text null comment '비고 상세'
DLTR varchar(11) null comment '삭제자'
)
comment '자동차 과태료 대상';

@ -96,9 +96,6 @@ public class CarFfnlgTrgtController {
// 2. totalCount 설정
paramVO.setTotalCount(totalCount);
// 3. 페이징 활성화
paramVO.setPagingYn("Y");
// 목록 조회
List<CarFfnlgTrgtVO> list = service.selectList(paramVO);

@ -62,6 +62,10 @@ public class CarFfnlgTrgtExcelVO {
@ExcelColumn(headerName = "일수", headerWidth = 10, align = ExcelColumn.Align.RIGHT)
private Long daycnt;
/** 재검여부 */
@ExcelColumn(headerName = "재검여부", headerWidth = 12, align = ExcelColumn.Align.CENTER)
private String reinspYn;
/** 과태료금액 */
@ExcelColumn(headerName = "과태료금액", headerWidth = 15, align = ExcelColumn.Align.RIGHT)
private Long ffnlgAmt;

@ -35,6 +35,7 @@ public class CarFfnlgTrgtVO extends PagingVO {
private String carUsg; // 자동차 용도
private String inspEndYmd; // 검사 종료 일자
private String daycnt; // 일수
private String reinspYn; // 재검 여부 (Y/N)
private String ffnlgAmt; // 과태료 금액
private String lastRegYmd; // 최종 등록 일자
private String addr; // 주소
@ -75,6 +76,7 @@ public class CarFfnlgTrgtVO extends PagingVO {
private String schVhclno; // 검색 차량번호
private String schOwnrNm; // 검색 소유자명
private List<String> schTaskPrcsSttsCd; // 검색 업무 처리 상태 코드 (다중 선택 가능)
private List<String> schReinspYn; // 검색 재검 여부 (다중 선택 가능)
private String schInspYmdStart; // 검색 시작 검사 일자
private String schInspYmdEnd; // 검색 종료 검사 일자
private String schFfnlgTrgtSeCd; // 검색 과태료 대상 구분 코드

@ -610,7 +610,14 @@ public class CarFfnlgTrgtServiceImpl extends EgovAbstractServiceImpl implements
// 과태료 금액 숫자만 추출 (예: "30만원" -> "300000")
ffnlgAmt = extractNumericAmount(ffnlgAmt);
log.info("[DEBUG_LOG] 과태료 변환 후: [{}]", ffnlgAmt);
// 재검여부 설정 (일수에 '*'가 있으면 Y, 없으면 N)
String reinspYn = "N";
if (daycnt != null && daycnt.contains("*")) {
reinspYn = "Y";
}
log.info("[DEBUG_LOG] 재검여부(reinspYn): [{}] (일수: {})", reinspYn, daycnt);
// VO 설정
vo.setInspstnCd(inspstnCd);
vo.setInspYmd(inspYmd);
@ -622,6 +629,7 @@ public class CarFfnlgTrgtServiceImpl extends EgovAbstractServiceImpl implements
vo.setCarUsg(carUsg);
vo.setInspEndYmd(inspEndYmd);
vo.setDaycnt(daycnt);
vo.setReinspYn(reinspYn);
vo.setFfnlgAmt(ffnlgAmt);
vo.setLastRegYmd(lastRegYmd);
vo.setAddr(addr);

@ -30,6 +30,12 @@
<if test='schInspYmdEnd != null and schInspYmdEnd != ""'>
AND t.INSP_YMD &lt;= #{schInspYmdEnd}
</if>
<if test='schReinspYn != null and schReinspYn.size() > 0'>
AND t.REINSP_YN IN
<foreach collection="schReinspYn" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</if>
</sql>
<!-- 과태료 대상 목록 총 개수 조회 -->
@ -62,6 +68,7 @@
t.CAR_USG AS carUsg,
t.INSP_END_YMD AS inspEndYmd,
t.DAYCNT AS daycnt,
t.REINSP_YN AS reinspYn,
t.FFNLG_AMT AS ffnlgAmt,
t.LAST_REG_YMD AS lastRegYmd,
t.ADDR AS addr,
@ -118,6 +125,7 @@
t.CAR_USG AS carUsg,
t.INSP_END_YMD AS inspEndYmd,
t.DAYCNT AS daycnt,
t.REINSP_YN AS reinspYn,
t.FFNLG_AMT AS ffnlgAmt,
t.LAST_REG_YMD AS lastRegYmd,
t.ADDR AS addr,
@ -170,6 +178,7 @@
t.CAR_USG AS carUsg,
t.INSP_END_YMD AS inspEndYmd,
t.DAYCNT AS daycnt,
t.REINSP_YN AS reinspYn,
t.FFNLG_AMT AS ffnlgAmt,
t.LAST_REG_YMD AS lastRegYmd,
t.ADDR AS addr,
@ -214,6 +223,7 @@
CAR_USG,
INSP_END_YMD,
DAYCNT,
REINSP_YN,
FFNLG_AMT,
LAST_REG_YMD,
ADDR,
@ -247,6 +257,7 @@
#{carUsg},
#{inspEndYmd},
#{daycnt},
#{reinspYn},
#{ffnlgAmt},
#{lastRegYmd},
#{addr},

@ -41,6 +41,12 @@
<li>
<input type="text" id="schOwnrNm" name="schOwnrNm" class="input" style="width: 150px;" maxlength="75" autocomplete="off"/>
</li>
</ul>
<ul class="rig2">
<li><button type="button" id="search_btn" class="newbtnss bg1">검색</button></li>
<li><button type="button" id="reset_btn" class="newbtnss bg5" style="margin-left: 5px;">초기화</button></li>
</ul>
<ul class="lef2">
<li class="th">처리상태</li>
<li>
<c:forEach var="code" items="${taskPrcsSttsCdList}">
@ -50,10 +56,15 @@
</label>
</c:forEach>
</li>
</ul>
<ul class="rig2">
<li><button type="button" id="search_btn" class="newbtnss bg1">검색</button></li>
<li><button type="button" id="reset_btn" class="newbtnss bg5" style="margin-left: 5px;">초기화</button></li>
<li class="th">재검여부</li>
<li>
<label style="margin-right: 10px; cursor: pointer;">
<input type="checkbox" name="schReinspYn" value="Y"/> 재검(Y)
</label>
<label style="margin-right: 10px; cursor: pointer;">
<input type="checkbox" name="schReinspYn" value="N"/> 미재검(N)
</label>
</li>
</ul>
</div>
<div class="gs_booking">
@ -70,12 +81,6 @@
<button type="button" id="btn_save" class="newbtn bg4">저장</button>
<span id="totalCount" class="total-count" style="padding-left: 25px;padding-right: 25px;">총 0건</span>
<select id="perPageSelect" class="input" style="width: 112px; ">
<option value="15">페이지당 15</option>
<option value="50">페이지당 50</option>
<option value="100">페이지당 100</option>
</select>
<span class="page_number"><span id="currentPage"></span><span class="bar">/</span><span id="totalPages"></span> Pages</span>
</li>
</ul>
<div class="containers">
@ -113,13 +118,6 @@
// 그리드 조회 시 사용된 마지막 검색조건 저장
var LAST_GRID_SEARCH_COND = {};
// 페이징 정보를 저장할 전역 변수
var GRID_PAGINATION_INFO = {
totalCount: 0,
page: 0,
perPage: 0
};
// 검색정보 설정
var setSearchCond = function() {
var schRcptYmdStart = $.trim(nvl($("#schRcptYmdStart").val(), ""));
@ -135,6 +133,11 @@
schTaskPrcsSttsCd.push($(this).val());
});
var schReinspYn = [];
$("input[name='schReinspYn']:checked").each(function() {
schReinspYn.push($(this).val());
});
SEARCH_COND.schRcptYmdStart = schRcptYmdStart;
SEARCH_COND.schRcptYmdEnd = schRcptYmdEnd;
SEARCH_COND.schInspYmdStart = schInspYmdStart;
@ -142,6 +145,7 @@
SEARCH_COND.schVhclno = schVhclno;
SEARCH_COND.schOwnrNm = schOwnrNm;
SEARCH_COND.schTaskPrcsSttsCd = schTaskPrcsSttsCd;
SEARCH_COND.schReinspYn = schReinspYn;
};
// 다운로드 URL 생성 (현재 검색조건을 쿼리스트링으로 부여)
@ -161,6 +165,11 @@
params.push('schTaskPrcsSttsCd=' + encodeURIComponent(val));
});
}
if (SEARCH_COND.schReinspYn && SEARCH_COND.schReinspYn.length > 0) {
SEARCH_COND.schReinspYn.forEach(function(val) {
params.push('schReinspYn=' + encodeURIComponent(val));
});
}
return baseUrl + (params.length ? ('?' + params.join('&')) : '');
};
@ -183,7 +192,8 @@
schInspYmdEnd: '검사일자 종료',
schVhclno: '차량번호',
schOwnrNm: '소유자명',
schTaskPrcsSttsCd: '처리상태'
schTaskPrcsSttsCd: '처리상태',
schReinspYn: '재검여부'
};
// 날짜 포맷 변환 함수 (YYYYMMDD -> YYYY-MM-DD)
@ -207,6 +217,22 @@
return textArray.join(', ');
};
// 재검여부 -> 텍스트 변환
var getReinspYnText = function(codeArray) {
if (!codeArray || codeArray.length === 0) return '전체';
var textArray = [];
codeArray.forEach(function(code) {
if (code === 'Y') {
textArray.push('재검(Y)');
} else if (code === 'N') {
textArray.push('미재검(N)');
} else {
textArray.push(code);
}
});
return textArray.join(', ');
};
// 값 포맷팅 함수
var formatValue = function(field, value) {
if (field.indexOf('Ymd') > -1) {
@ -215,6 +241,9 @@
if (field === 'schTaskPrcsSttsCd') {
return getTaskPrcsSttsCdText(value);
}
if (field === 'schReinspYn') {
return getReinspYnText(value);
}
if (!value || (Array.isArray(value) && value.length === 0)) {
return '(공백)';
}
@ -224,14 +253,14 @@
// 달라진 조건 찾기
var differences = [];
var searchFields = ['schRcptYmdStart', 'schRcptYmdEnd', 'schInspYmdStart', 'schInspYmdEnd',
'schVhclno', 'schOwnrNm', 'schTaskPrcsSttsCd'];
'schVhclno', 'schOwnrNm', 'schTaskPrcsSttsCd', 'schReinspYn'];
searchFields.forEach(function(field) {
var currentValue = SEARCH_COND[field];
var lastValue = LAST_GRID_SEARCH_COND[field];
// 배열 비교 (처리상태)
if (field === 'schTaskPrcsSttsCd') {
// 배열 비교 (처리상태, 재검여부)
if (field === 'schTaskPrcsSttsCd' || field === 'schReinspYn') {
currentValue = currentValue || [];
lastValue = lastValue || [];
@ -306,9 +335,6 @@
// 데이터 소스 설정
var dataSource = this.createDataSource();
// 현재 선택된 perPage 값 가져오기
var perPage = parseInt($('#perPageSelect').val() || 15, 10);
// 그리드 설정 객체 생성
var gridConfig = new XitTuiGridConfig();
@ -321,10 +347,9 @@
gridConfig.setOptUseClientSort(false);
// 페이징 옵션 설정
gridConfig.setOptPageOptions({
useClient: false,
perPage: perPage
});
//gridConfig.setOptPageOptions({
// useClient: true
//});
gridConfig.setOptColumnOptions({ //컬럼고정 옵션
frozenCount: 7 //고정컬럼 갯수
@ -350,11 +375,7 @@
width: 60,
sortable: false,
formatter: function(e) {
var totalCount = GRID_PAGINATION_INFO.totalCount;
var page = GRID_PAGINATION_INFO.page;
var perPage = GRID_PAGINATION_INFO.perPage;
var rowIndex = e.row.rowKey;
return totalCount - (page - 1) * perPage - rowIndex;
return e.row.rowKey+1;
}
},
{ header: '접수일자', name: 'rcptYmd', align: 'center', width: 100,
@ -383,6 +404,7 @@
}
},
{ header: '일수', name: 'daycnt', align: 'right', width: 60 },
{ header: '재검여부', name: 'reinspYn', align: 'center', width: 80 },
{ header: '과태료금액', name: 'ffnlgAmt', align: 'right', width: 100,
formatter: function(e) {
return e.value ? parseInt(e.value).toLocaleString() + '원' : '';
@ -541,8 +563,6 @@
initialRequest: false,
serializer: function(params) {
setSearchCond();
SEARCH_COND.perPage = params.perPage;
SEARCH_COND.page = params.page;
return $.param(SEARCH_COND);
}
};
@ -572,15 +592,10 @@
this.instance.on('successResponse', function(ev) {
var responseObj = JSON.parse(ev.xhr.response);
if(responseObj){
$("#currentPage").text(responseObj.data.pagination.page);
$("#totalPages").text(responseObj.data.pagination.totalPages);
var totalCount = responseObj.data.pagination.totalCount;
$("#totalCount").text('총 ' + totalCount.toLocaleString() + '건');
// 페이징 정보를 전역 변수에 저장
GRID_PAGINATION_INFO.totalCount = responseObj.data.pagination.totalCount;
GRID_PAGINATION_INFO.page = responseObj.data.pagination.page;
GRID_PAGINATION_INFO.perPage = responseObj.data.pagination.perPage;
if( responseObj.data && responseObj.data.contents ){
var totalCount = responseObj.data.contents.length;
$("#totalCount").text('총 ' + totalCount.toLocaleString() + '건');
}
}
// 선택된 행 초기화
@ -676,7 +691,6 @@
},
error: function(xhr, status, error) {
console.error("저장 실패:", error);
alert("저장 중 오류가 발생했습니다.");
}
});
}
@ -715,6 +729,7 @@
$("#schOwnrNm").val("");
// 체크박스 모두 해제
$("input[name='schTaskPrcsSttsCd']").prop('checked', false);
$("input[name='schReinspYn']").prop('checked', false);
self.grid.reload();
});
@ -766,7 +781,7 @@
// 검색 조건 파라미터 추가
setSearchCond();
$.each(SEARCH_COND, function(key, value) {
if (key === 'schTaskPrcsSttsCd') {
if (key === 'schTaskPrcsSttsCd' || key === 'schReinspYn') {
// 배열인 경우 각각 추가
if (value && value.length > 0) {
value.forEach(function(val) {

Loading…
Cancel
Save