From b94a38b3599f4a6b6d19b1d85105981fc3aadd76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EC=84=B1=EC=98=81?= Date: Tue, 28 Oct 2025 16:32:22 +0900 Subject: [PATCH] =?UTF-8?q?=EB=8B=A8=EC=86=8D=EC=9D=98=20=EC=9D=B4?= =?UTF-8?q?=ED=96=89=EC=9D=B4=EB=A0=A5=20=ED=8C=9D=EC=97=85=20=EB=B0=8F=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CrdnImpltTaskHistoryController.java | 93 +++++++++ .../mapper/CrdnImpltTaskHistoryMapper.java | 19 ++ .../main/model/CrdnImpltTrprInfoVO.java | 3 + .../service/CrdnImpltTaskHistoryService.java | 45 +++++ .../impl/CrdnImpltTaskHistoryServiceImpl.java | 67 +++++++ .../main/CrdnImpltTaskHistoryMapper_maria.xml | 101 ++++++++++ .../impltTaskHistoryPopup.jsp | 178 ++++++++++++++++++ .../crdn/crndRegistAndView/main/list.jsp | 33 +++- src/main/webapp/resources/xit/xit-popup.css | 92 +++++++++ 9 files changed, 627 insertions(+), 4 deletions(-) create mode 100644 src/main/java/go/kr/project/crdn/crndRegistAndView/main/controller/CrdnImpltTaskHistoryController.java create mode 100644 src/main/java/go/kr/project/crdn/crndRegistAndView/main/mapper/CrdnImpltTaskHistoryMapper.java create mode 100644 src/main/java/go/kr/project/crdn/crndRegistAndView/main/service/CrdnImpltTaskHistoryService.java create mode 100644 src/main/java/go/kr/project/crdn/crndRegistAndView/main/service/impl/CrdnImpltTaskHistoryServiceImpl.java create mode 100644 src/main/resources/mybatis/mapper/crdn/crndRegistAndView/main/CrdnImpltTaskHistoryMapper_maria.xml create mode 100644 src/main/webapp/WEB-INF/views/crdn/crndRegistAndView/main/crdnImpltTaskHistory/impltTaskHistoryPopup.jsp diff --git a/src/main/java/go/kr/project/crdn/crndRegistAndView/main/controller/CrdnImpltTaskHistoryController.java b/src/main/java/go/kr/project/crdn/crndRegistAndView/main/controller/CrdnImpltTaskHistoryController.java new file mode 100644 index 0000000..50d9402 --- /dev/null +++ b/src/main/java/go/kr/project/crdn/crndRegistAndView/main/controller/CrdnImpltTaskHistoryController.java @@ -0,0 +1,93 @@ +package go.kr.project.crdn.crndRegistAndView.main.controller; + +import egovframework.constant.TilesConstants; +import go.kr.project.crdn.crndRegistAndView.main.model.CrdnImpltTaskVO; +import go.kr.project.crdn.crndRegistAndView.main.model.CrdnImpltTrprInfoVO; +import go.kr.project.crdn.crndRegistAndView.main.service.CrdnImpltTaskHistoryService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.servlet.ModelAndView; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * packageName : go.kr.project.crdn.crndRegistAndView.main.controller + * fileName : CrdnImpltTaskHistoryController + * author : 시스템 관리자 + * date : 2025-01-28 + * description : 이행정보 이력 조회 관련 요청을 처리하는 컨트롤러 + * 중요한 로직 주석: 이행정보 이력 팝업 화면 제공 + * =========================================================== + * DATE AUTHOR NOTE + * ----------------------------------------------------------- + * 2025-01-28 시스템 관리자 최초 생성 + */ +@Controller +@RequestMapping("/crdn/crndRegistAndView/crdnImpltTaskHistory") +@RequiredArgsConstructor +@Slf4j +@Tag(name = "이행정보 이력 조회", description = "이행정보 이력 조회 관련 API") +public class CrdnImpltTaskHistoryController { + + private final CrdnImpltTaskHistoryService crdnImpltTaskHistoryService; + + /** + * 이행정보 이력 팝업 화면을 제공합니다. + * + * @param crdnYr 단속 연도 + * @param crdnNo 단속 번호 + * @return 이행정보 이력 팝업 화면 + */ + @GetMapping("/impltTaskHistoryPopup.do") + @Operation(summary = "이행정보 이력 팝업", description = "이행정보 이력 팝업 화면을 제공합니다.") + public ModelAndView impltTaskHistoryPopup( + @Parameter(description = "단속 연도") @RequestParam String crdnYr, + @Parameter(description = "단속 번호") @RequestParam String crdnNo) { + + log.debug("이행정보 이력 팝업 요청 - 단속연도: {}, 단속번호: {}", crdnYr, crdnNo); + + ModelAndView mav = new ModelAndView("crdn/crndRegistAndView/main/crdnImpltTaskHistory/impltTaskHistoryPopup" + TilesConstants.POPUP); + + // 기본 파라미터 설정 + mav.addObject("crdnYr", crdnYr); + mav.addObject("crdnNo", crdnNo); + + CrdnImpltTaskVO paramVO = new CrdnImpltTaskVO(); + paramVO.setCrdnYr(crdnYr); + paramVO.setCrdnNo(crdnNo); + + // 단속 기본 정보 조회 (이력이 없어도 주소 정보를 표시하기 위해) + CrdnImpltTaskVO crdnBasicInfo = crdnImpltTaskHistoryService.selectCrdnBasicInfo(paramVO); + mav.addObject("crdnBasicInfo", crdnBasicInfo); + + // 이행정보 이력 목록 조회 (코드 테이블 기준으로 LEFT OUTER JOIN하여 모든 구분 표시) + // 중요로직: 쿼리에서 이미 모든 이행업무구분 코드를 포함하여 반환하므로, 데이터가 없는 경우 impltInfoId가 NULL + List impltInfoHistoryList = crdnImpltTaskHistoryService.selectImpltInfoHistoryList(paramVO); + mav.addObject("impltInfoHistoryList", impltInfoHistoryList); + + // 각 이행정보별로 대상자 목록을 조회하여 Map에 저장 + Map> impltTrprInfoMap = new HashMap<>(); + for (CrdnImpltTaskVO impltInfo : impltInfoHistoryList) { + // impltInfoId가 null이면 데이터가 없는 것이므로 스킵 + if (impltInfo.getImpltInfoId() != null) { + CrdnImpltTrprInfoVO trprParam = new CrdnImpltTrprInfoVO(); + trprParam.setSchImpltInfoId(impltInfo.getImpltInfoId()); + List trprList = crdnImpltTaskHistoryService.selectImpltTrprInfoHistoryList(trprParam); + impltTrprInfoMap.put(impltInfo.getImpltInfoId(), trprList); + } + } + mav.addObject("impltTrprInfoMap", impltTrprInfoMap); + + return mav; + } + +} diff --git a/src/main/java/go/kr/project/crdn/crndRegistAndView/main/mapper/CrdnImpltTaskHistoryMapper.java b/src/main/java/go/kr/project/crdn/crndRegistAndView/main/mapper/CrdnImpltTaskHistoryMapper.java new file mode 100644 index 0000000..fd272bf --- /dev/null +++ b/src/main/java/go/kr/project/crdn/crndRegistAndView/main/mapper/CrdnImpltTaskHistoryMapper.java @@ -0,0 +1,19 @@ +package go.kr.project.crdn.crndRegistAndView.main.mapper; + +import go.kr.project.crdn.crndRegistAndView.main.model.CrdnImpltTaskVO; +import go.kr.project.crdn.crndRegistAndView.main.model.CrdnImpltTrprInfoVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +@Mapper +public interface CrdnImpltTaskHistoryMapper { + + CrdnImpltTaskVO selectCrdnBasicInfo(CrdnImpltTaskVO vo); + + List selectImpltInfoHistoryList(CrdnImpltTaskVO vo); + + List selectImpltTrprInfoHistoryList(CrdnImpltTrprInfoVO vo); + +} \ No newline at end of file diff --git a/src/main/java/go/kr/project/crdn/crndRegistAndView/main/model/CrdnImpltTrprInfoVO.java b/src/main/java/go/kr/project/crdn/crndRegistAndView/main/model/CrdnImpltTrprInfoVO.java index ac7da08..04498e7 100644 --- a/src/main/java/go/kr/project/crdn/crndRegistAndView/main/model/CrdnImpltTrprInfoVO.java +++ b/src/main/java/go/kr/project/crdn/crndRegistAndView/main/model/CrdnImpltTrprInfoVO.java @@ -105,6 +105,9 @@ public class CrdnImpltTrprInfoVO { private String lotnoMno; private String lotnoSno; + // ==================== 추가 필드 (검색) ==================== + private String schImpltInfoId; + // ==================== TUI 그리드용 속성 ==================== /** * TUI Grid 행 속성 (예: 체크박스, 클래스명) diff --git a/src/main/java/go/kr/project/crdn/crndRegistAndView/main/service/CrdnImpltTaskHistoryService.java b/src/main/java/go/kr/project/crdn/crndRegistAndView/main/service/CrdnImpltTaskHistoryService.java new file mode 100644 index 0000000..82e67aa --- /dev/null +++ b/src/main/java/go/kr/project/crdn/crndRegistAndView/main/service/CrdnImpltTaskHistoryService.java @@ -0,0 +1,45 @@ +package go.kr.project.crdn.crndRegistAndView.main.service; + +import go.kr.project.crdn.crndRegistAndView.main.model.CrdnImpltTaskVO; +import go.kr.project.crdn.crndRegistAndView.main.model.CrdnImpltTrprInfoVO; + +import java.util.List; + +/** + * packageName : go.kr.project.crdn.crndRegistAndView.main.service + * fileName : CrdnImpltTaskHistoryService + * author : 시스템 관리자 + * date : 2025-01-28 + * description : 이행정보 이력 조회 서비스 인터페이스 + * =========================================================== + * DATE AUTHOR NOTE + * ----------------------------------------------------------- + * 2025-01-28 시스템 관리자 최초 생성 + */ +public interface CrdnImpltTaskHistoryService { + + /** + * 단속 기본 정보 및 위치 정보를 조회합니다. + * + * @param vo 조회 조건 (단속연도, 단속번호) + * @return 단속 기본 정보 + */ + CrdnImpltTaskVO selectCrdnBasicInfo(CrdnImpltTaskVO vo); + + /** + * 이행정보 이력 목록을 조회합니다. + * + * @param vo 조회 조건 (단속연도, 단속번호) + * @return 이행정보 이력 목록 + */ + List selectImpltInfoHistoryList(CrdnImpltTaskVO vo); + + /** + * 이행 대상자 정보 목록을 조회합니다. + * + * @param vo 조회 조건 (이행정보ID) + * @return 이행 대상자 정보 목록 + */ + List selectImpltTrprInfoHistoryList(CrdnImpltTrprInfoVO vo); + +} diff --git a/src/main/java/go/kr/project/crdn/crndRegistAndView/main/service/impl/CrdnImpltTaskHistoryServiceImpl.java b/src/main/java/go/kr/project/crdn/crndRegistAndView/main/service/impl/CrdnImpltTaskHistoryServiceImpl.java new file mode 100644 index 0000000..eca74e3 --- /dev/null +++ b/src/main/java/go/kr/project/crdn/crndRegistAndView/main/service/impl/CrdnImpltTaskHistoryServiceImpl.java @@ -0,0 +1,67 @@ +package go.kr.project.crdn.crndRegistAndView.main.service.impl; + +import go.kr.project.crdn.crndRegistAndView.main.mapper.CrdnImpltTaskHistoryMapper; +import go.kr.project.crdn.crndRegistAndView.main.model.CrdnImpltTaskVO; +import go.kr.project.crdn.crndRegistAndView.main.model.CrdnImpltTrprInfoVO; +import go.kr.project.crdn.crndRegistAndView.main.service.CrdnImpltTaskHistoryService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * packageName : go.kr.project.crdn.crndRegistAndView.main.service.impl + * fileName : CrdnImpltTaskHistoryServiceImpl + * author : 시스템 관리자 + * date : 2025-01-28 + * description : 이행정보 이력 조회 서비스 구현체 + * =========================================================== + * DATE AUTHOR NOTE + * ----------------------------------------------------------- + * 2025-01-28 시스템 관리자 최초 생성 + */ +@Service +@RequiredArgsConstructor +@Slf4j +public class CrdnImpltTaskHistoryServiceImpl implements CrdnImpltTaskHistoryService { + + private final CrdnImpltTaskHistoryMapper mapper; + + /** + * 단속 기본 정보 및 위치 정보를 조회합니다. + * + * @param vo 조회 조건 (단속연도, 단속번호) + * @return 단속 기본 정보 + */ + @Override + public CrdnImpltTaskVO selectCrdnBasicInfo(CrdnImpltTaskVO vo) { + log.debug("단속 기본 정보 조회 - 단속연도: {}, 단속번호: {}", vo.getCrdnYr(), vo.getCrdnNo()); + return mapper.selectCrdnBasicInfo(vo); + } + + /** + * 이행정보 이력 목록을 조회합니다. + * + * @param vo 조회 조건 (단속연도, 단속번호) + * @return 이행정보 이력 목록 + */ + @Override + public List selectImpltInfoHistoryList(CrdnImpltTaskVO vo) { + log.debug("이행정보 이력 목록 조회 - 단속연도: {}, 단속번호: {}", vo.getCrdnYr(), vo.getCrdnNo()); + return mapper.selectImpltInfoHistoryList(vo); + } + + /** + * 이행 대상자 정보 목록을 조회합니다. + * + * @param vo 조회 조건 (이행정보ID) + * @return 이행 대상자 정보 목록 + */ + @Override + public List selectImpltTrprInfoHistoryList(CrdnImpltTrprInfoVO vo) { + log.debug("이행 대상자 정보 목록 조회 - 이행정보ID: {}", vo.getSchImpltInfoId()); + return mapper.selectImpltTrprInfoHistoryList(vo); + } + +} diff --git a/src/main/resources/mybatis/mapper/crdn/crndRegistAndView/main/CrdnImpltTaskHistoryMapper_maria.xml b/src/main/resources/mybatis/mapper/crdn/crndRegistAndView/main/CrdnImpltTaskHistoryMapper_maria.xml new file mode 100644 index 0000000..cd66a49 --- /dev/null +++ b/src/main/resources/mybatis/mapper/crdn/crndRegistAndView/main/CrdnImpltTaskHistoryMapper_maria.xml @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/views/crdn/crndRegistAndView/main/crdnImpltTaskHistory/impltTaskHistoryPopup.jsp b/src/main/webapp/WEB-INF/views/crdn/crndRegistAndView/main/crdnImpltTaskHistory/impltTaskHistoryPopup.jsp new file mode 100644 index 0000000..77add65 --- /dev/null +++ b/src/main/webapp/WEB-INF/views/crdn/crndRegistAndView/main/crdnImpltTaskHistory/impltTaskHistoryPopup.jsp @@ -0,0 +1,178 @@ +<%@ 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" %> + + + + + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/views/crdn/crndRegistAndView/main/list.jsp b/src/main/webapp/WEB-INF/views/crdn/crndRegistAndView/main/list.jsp index e1c6a92..53caf8a 100644 --- a/src/main/webapp/WEB-INF/views/crdn/crndRegistAndView/main/list.jsp +++ b/src/main/webapp/WEB-INF/views/crdn/crndRegistAndView/main/list.jsp @@ -363,6 +363,15 @@ return e.value; } }, + { + header: '이행정보 이력', + name: 'impltTaskHistoryBtn', + width: 120, + align: 'center', + formatter: function(value) { + return '이행이력'; + } + }, { header: '처분사전 일자', name: 'dspsBfhdBgngYmd', align: 'center', width: 120, formatter: function (e) { return e.value ? moment(e.value).format('YYYY-MM-DD') : ''; @@ -478,6 +487,13 @@ if (ev.rowKey !== undefined && ev.rowKey !== null) { CrdnRegistAndViewList.selectedRow = self.instance.getRow(ev.rowKey); } + if (ev.columnName === 'impltTaskHistoryBtn') { + var rowKey = ev.rowKey; + var rowData = self.instance.getRow(rowKey); + if (rowData) { + CrdnRegistAndViewList.openImpltTaskHistoryPopup(rowData.crdnYr, rowData.crdnNo); + } + } }); // 행 더블클릭 이벤트 - detailView 페이지를 새 탭으로 열기 @@ -574,6 +590,19 @@ }); }, + /** + * 이행정보 이력 팝업을 엽니다. + * + * @param crdnYr 단속 연도 + * @param crdnNo 단속 번호 + */ + openImpltTaskHistoryPopup: function(crdnYr, crdnNo) { + var url = '?crdnYr=' + + encodeURIComponent(crdnYr) + '&crdnNo=' + + encodeURIComponent(crdnNo); + openPopup(url, 1000, 800, 'impltTaskHistoryPopup'); + }, + /** * 조치처리상태를 확인하고 미조치(코드 1)인 경우에만 콜백 함수를 실행합니다. * 중요로직: 팝업 호출 전 미조치(코드 1) 여부를 확인하는 공통 함수 @@ -602,10 +631,6 @@ } else { alert('조치처리상태 확인에 실패했습니다.'); } - }, - error: function( xhr, status, error ) { - console.error( error ); - alert('조치처리상태 확인 중 오류가 발생했습니다.'); } }); }, diff --git a/src/main/webapp/resources/xit/xit-popup.css b/src/main/webapp/resources/xit/xit-popup.css index 8a917f3..bcefced 100644 --- a/src/main/webapp/resources/xit/xit-popup.css +++ b/src/main/webapp/resources/xit/xit-popup.css @@ -301,4 +301,96 @@ .tab-content.active { display: block; +} + +/* 이행정보 이력 팝업 스타일 */ +.history-list { + margin-top: 20px; +} + +.history-item { + margin-bottom: 30px; + padding: 20px; + border: 1px solid #ddd; + border-radius: 5px; + background-color: #f9f9f9; +} + +.history-item h3 { + margin: 0 0 15px 0; + padding-bottom: 10px; + border-bottom: 2px solid #4a90e2; + color: #333; +} + +.history-empty-message { + padding: 20px; + text-align: center; + color: #999; + font-style: italic; + background-color: #fafafa; + border-radius: 3px; +} + +.history-detail { + margin-bottom: 15px; +} + +.detail-table { + width: 100%; + border-collapse: collapse; +} + +.detail-table th { + width: 150px; + padding: 8px; + background-color: #f0f0f0; + border: 1px solid #ddd; + text-align: left; +} + +.detail-table td { + padding: 8px; + border: 1px solid #ddd; +} + +.target-person-list h4 { + margin: 15px 0 10px 0; + color: #555; + font-size: 14px; + font-weight: bold; +} + +.target-person-empty { + padding: 10px 20px; + color: #999; + font-style: italic; +} + +.target-person-list ul { + list-style: none; + padding: 0; + margin: 0; +} + +.target-person-item { + padding: 10px 20px; + border-left: 3px solid #4a90e2; + margin-bottom: 8px; + background-color: #fff; +} + +.target-person-type { + color: #666; + margin-left: 10px; +} + +.target-person-detail { + margin-top: 5px; + color: #666; + font-size: 13px; +} + +.text-left { + text-align: left; } \ No newline at end of file