Compare commits

...

6 Commits

@ -17,7 +17,7 @@ public class CommonContorller {
private final CommonService commonService;
/**
*
* , ,
*/
@GetMapping("/common/code/find.ajax")
public ResponseEntity<?> getCode(@ModelAttribute CommonDto.Request commonDto) {
@ -28,6 +28,7 @@ public class CommonContorller {
return ResponseEntity.ok(result);
}
/**
*
*/

@ -1,8 +1,7 @@
package go.kr.project.biz.common.dto;
import go.kr.project.domain.entity.CpBdong;
import go.kr.project.domain.entity.CpViolation;
import go.kr.project.vo.CpBdongVO;
import go.kr.project.vo.CpCancelAnswerVO;
import go.kr.project.vo.CpViolationVO;
import lombok.Builder;
import lombok.Getter;
@ -37,6 +36,7 @@ public class CommonDto {
public static class CodeResult {
private List<CpViolationVO> cpViolation;
private List<CpBdongVO> cpBdong;
private List<CpCancelAnswerVO> cpCancelAnswer;
}

@ -6,6 +6,7 @@ import go.kr.project.biz.common.dto.CommonDto;
import go.kr.project.domain.entity.CpBdong;
import go.kr.project.domain.entity.CpViolation;
import go.kr.project.vo.CpBdongVO;
import go.kr.project.vo.CpCancelAnswerVO;
import go.kr.project.vo.CpViolationVO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
@ -13,6 +14,7 @@ import org.springframework.stereotype.Repository;
import java.util.List;
import static go.kr.project.domain.entity.QCpBdong.cpBdong;
import static go.kr.project.domain.entity.QCpCancelAnswer.cpCancelAnswer;
import static go.kr.project.domain.entity.QCpViolation.cpViolation;
@Repository
@ -74,6 +76,27 @@ public class CommonRepository {
return result;
}
public List<CpCancelAnswerVO> findCancelAnswerCode(CommonDto.Request commonDto) {
commonDto.setSggCode("41590");
List<CpCancelAnswerVO> result = queryFactory
.select(
Projections.fields(
CpCancelAnswerVO.class,
cpCancelAnswer.id.caSggCode,
cpCancelAnswer.id.caCode,
cpCancelAnswer.caId,
cpCancelAnswer.caAnswerText,
cpCancelAnswer.caIsAnswer
)
)
.from(cpCancelAnswer)
.where(cpCancelAnswer.id.caSggCode.eq(commonDto.getSggCode()))
.fetch();
return result;
}

@ -7,4 +7,5 @@ import java.util.List;
public interface CommonService {
CommonDto.Response.CodeResult findCode(CommonDto.Request commonDto);
}

@ -24,11 +24,11 @@ public class CommonServiceImpl implements CommonService {
return CommonDto.Response.CodeResult.builder()
.cpViolation(commonRepository.findViolationCode(commonDto))
.cpBdong(commonRepository.findBdongCode())
.cpCancelAnswer(commonRepository.findCancelAnswerCode(commonDto))
.build();
}
}

@ -12,6 +12,10 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.util.List;
@Controller
@ -22,7 +26,6 @@ public class CautionController {
private final CautionService cautionService;
@GetMapping("/search/caution/caution.do")
public String cautionPageReturn() {
return "biz/search/caution" + TilesConstants.BASE;
}
@ -33,8 +36,27 @@ public class CautionController {
dto.setTotalCount(0);
dto.setPagingYn("N");
List<CautionDto.Response.cpMain> result = cautionService.selectAllSearch(dto);
List<?> result = cautionService.selectAllSearch(dto);
return ApiResponseUtil.successWithGrid(result, dto);
}
@GetMapping("/search/caution/caution-hwp-download.do")
public void downloadCautionHwp(@ModelAttribute CautionDto.Request.Search dto,
HttpServletResponse response) throws Exception {
byte[] fileBytes = cautionService.generateCautionStatsHwp(dto);
String fileName = "경고통계_" + LocalDate.now() + ".hwp";
String encodedFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.name())
.replaceAll("\\+", "%20");
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition",
"attachment; filename=\"" + encodedFileName + "\";");
response.setContentLength(fileBytes.length);
return ApiResponseUtil.successWithGrid(result,dto);
response.getOutputStream().write(fileBytes);
response.getOutputStream().flush();
}
}

@ -8,5 +8,14 @@ import java.util.List;
@Mapper
public interface CautionMapper {
List<CautionDto.Response.cpMain> selectAllSearch(CautionDto.Request.Search dto);
// List<CautionDto.Response.cpMain> selectAllSearch(CautionDto.Request.Search dto);
List<CautionDto.Response.YearStats> selectYearStats(CautionDto.Request.Search dto);
List<CautionDto.Response.DeviceStats> selectDeviceStats(CautionDto.Request.Search dto);
List<CautionDto.Response.TypeStats> selectTypeStats(CautionDto.Request.Search dto);
List<CautionDto.Response.DetailStats> selectDetailStats(CautionDto.Request.Search dto);
}

@ -4,6 +4,8 @@ import go.kr.project.system.common.model.PagingVO;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
public class CautionDto {
public static class Request {
@ -12,26 +14,10 @@ public class CautionDto {
public static class Search extends PagingVO {
private String searchCondition;
private String searchCondition1;
private String searchCondition2;
private String searchCondition3;
private String searchCondition4;
private String searchKeyword;
private String gridId;
private String searchStartDt;
private String searchEndDt;
private String searchCarno;
private String searchName;
private String searchJno;
private String searchUser;
private String searchTel;
private String searchBbsno;
private String searchPos;
private String searchAddr;
private String searchTime1;
private String searchTime2;
private String worker;
}
}
@ -63,11 +49,52 @@ public class CautionDto {
}
@Getter
@Setter
public static class Violation {
public static class YearStats {
private String year;
private String insCnt;
private String violCnt;
private String totalCnt;
}
private String vlCode;
@Getter
@Setter
public static class DeviceStats {
private String year;
private String cctvCnt;
private String smgCnt;
private String totalCnt;
}
@Getter
@Setter
public static class TypeStats {
private String vlId;
private String insCnt;
private String violCnt;
private String totalCnt;
}
@Getter
@Setter
public static class DetailStats {
private String year;
private String instructNormalCnt;
private String instructRegistCnt;
private String sajunNormalCnt;
private String sajunRegistCnt;
private String bugwaNormalCnt;
private String bugwaRegistCnt;
private String dokNormalCnt;
private String dokRegistCnt;
private String totalCnt;
}
}
@Getter
@Setter
public static class StatsForHwp {
private List<YearStats> yearList;
private List<DeviceStats> deviceList;
private List<TypeStats> typeList;
private List<DetailStats> detailList;
}
}
}

@ -6,5 +6,9 @@ import java.util.List;
public interface CautionService {
List<CautionDto.Response.cpMain> selectAllSearch(CautionDto.Request.Search dto);
List<?> selectAllSearch(CautionDto.Request.Search dto);
CautionDto.Response.StatsForHwp getStatsForHwp(CautionDto.Request.Search dto);
byte[] generateCautionStatsHwp(CautionDto.Request.Search dto) throws Exception;
}

@ -8,6 +8,7 @@ import lombok.extern.slf4j.Slf4j;
import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.List;
@Service
@ -18,13 +19,125 @@ public class CautionServiceImpl extends EgovAbstractServiceImpl implements Cauti
private final CautionMapper cautionMapper;
@Override
public List<CautionDto.Response.cpMain> selectAllSearch(CautionDto.Request.Search dto) {
public List<?> selectAllSearch(CautionDto.Request.Search dto) {
List<CautionDto.Response.cpMain> list = cautionMapper.selectAllSearch(dto);
String gridId = dto.getGridId();
log.info("selectAllSearch gridId = {}", gridId);
List<?> list;
if ("YEAR".equals(gridId)) {
list = cautionMapper.selectYearStats(dto);
} else if ("DEVICE".equals(gridId)) {
list = cautionMapper.selectDeviceStats(dto);
} else if ("TYPE".equals(gridId)) {
list = cautionMapper.selectTypeStats(dto);
} else if ("DETAIL".equals(gridId)) {
list = cautionMapper.selectDetailStats(dto);
} else {
list = Collections.emptyList();
}
log.info("gridId={}, resultSize={}", gridId, list.size());
return list;
}
@Override
public CautionDto.Response.StatsForHwp getStatsForHwp(CautionDto.Request.Search dto) {
if (dto.getSearchStartDt() != null) {
dto.setSearchStartDt(dto.getSearchStartDt().replaceAll("-", ""));
}
if (dto.getSearchEndDt() != null) {
dto.setSearchEndDt(dto.getSearchEndDt().replaceAll("-", ""));
}
CautionDto.Response.StatsForHwp stats = new CautionDto.Response.StatsForHwp();
stats.setYearList( cautionMapper.selectYearStats(dto));
stats.setDeviceList( cautionMapper.selectDeviceStats(dto));
stats.setTypeList( cautionMapper.selectTypeStats(dto));
stats.setDetailList( cautionMapper.selectDetailStats(dto));
return stats;
}
@Override
public byte[] generateCautionStatsHwp(CautionDto.Request.Search dto) throws Exception {
CautionDto.Response.StatsForHwp stats = getStatsForHwp(dto);
StringBuilder sb = new StringBuilder();
sb.append("[경고 통계]\n");
sb.append("조회기간: ")
.append(dto.getSearchStartDt())
.append(" ~ ")
.append(dto.getSearchEndDt())
.append("\n\n");
sb.append("1. 연도별 경고/과태료/전체\n");
if (stats.getYearList() != null) {
for (CautionDto.Response.YearStats y : stats.getYearList()) {
sb.append(y.getYear()).append("년 경고:")
.append(y.getInsCnt())
.append(" 과태료:")
.append(y.getViolCnt())
.append(" 합계:")
.append(y.getTotalCnt())
.append("\n");
}
}
sb.append("\n");
sb.append("2. 단속장비/안전신문고\n");
if (stats.getDeviceList() != null) {
for (CautionDto.Response.DeviceStats d : stats.getDeviceList()) {
sb.append(d.getYear()).append("년 자동단속기:")
.append(d.getCctvCnt())
.append(" 안전신문고:")
.append(d.getSmgCnt())
.append(" 합계:")
.append(d.getTotalCnt())
.append("\n");
}
}
sb.append("\n");
sb.append("3. 위반유형별 경고/과태료/합계\n");
if (stats.getTypeList() != null) {
for (CautionDto.Response.TypeStats t : stats.getTypeList()) {
sb.append(t.getVlId()).append(" 경고:")
.append(t.getInsCnt())
.append(" 과태료:")
.append(t.getViolCnt())
.append(" 합계:")
.append(t.getTotalCnt())
.append("\n");
}
}
sb.append("\n");
sb.append("4. 단계별(계도/사전/부과/독촉) 합계\n");
if (stats.getDetailList() != null) {
for (CautionDto.Response.DetailStats d : stats.getDetailList()) {
sb.append(d.getYear()).append("년 ")
.append("계도(일반/등기): ")
.append(d.getInstructNormalCnt()).append("/").append(d.getInstructRegistCnt())
.append(" 사전(일반/등기): ")
.append(d.getSajunNormalCnt()).append("/").append(d.getSajunRegistCnt())
.append(" 부과(일반/등기): ")
.append(d.getBugwaNormalCnt()).append("/").append(d.getBugwaRegistCnt())
.append(" 독촉(일반/등기): ")
.append(d.getDokNormalCnt()).append("/").append(d.getDokRegistCnt())
.append(" 합계: ")
.append(d.getTotalCnt())
.append("\n");
}
}
return sb.toString().getBytes(java.nio.charset.StandardCharsets.UTF_8);
}
}

@ -0,0 +1,17 @@
package go.kr.project.vo;
import lombok.*;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class CpCancelAnswerVO {
private String caSggCode;
private String caCode;
private String caId;
private String caIsAnswer;
private String caAnswerText;
}

@ -18,6 +18,8 @@ public interface EntityVoMapper {
CpCancelVO toCpCancelVO(CpCancel entity);
CpCancelAnswerVO toCpCancelAnswerVO(CpCancelAnswer entity);
CpGojiPrtVO toCpGojiPrtVO(CpGojiPrt entity);
CpGojiSendHistVO toCpGojiSendHistVO(CpGojiSendHist entity);

@ -4,123 +4,80 @@
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="go.kr.project.biz.search.caution.mapper.CautionMapper">
<select id="selectAllSearch"
parameterType="go.kr.project.biz.search.caution.model.CautionDto"
resultType="go.kr.project.biz.search.caution.model.CautionDto$Response$cpMain">
SELECT M.MM_INGB,
DATE_FORMAT(
STR_TO_DATE(CONCAT(M.MM_DATE, M.MM_TIME), '%Y%m%d%H%i%s'),
'%Y-%m-%d %H:%i:%s' ) AS mmDate,
M.MM_CARNO,
O.OM_JNO,
O.OM_NAME,
M.MM_KEUM2,
M.MM_IMAGEGB,
M.MM_IMAGECNT,
M.MM_CARCHECK,
M.MM_STATE,
DATE_FORMAT(A.AS_JSDATE, '%Y-%m-%d') AS AS_JSDATE,
A.AS_USER,
A.AS_JSNO,
A.AS_BBS_NO,
C.CC_CAUSE,
DATE_FORMAT(C.CC_DATE, '%Y-%m-%d') AS CC_DATE,
C.CC_ETC,
M.MM_CODE
FROM CP_MAIN M
LEFT OUTER JOIN CP_ANSWER A ON M.MM_CODE = AS_MMCODE
LEFT OUTER JOIN CP_CANCEL C ON M.MM_CODE=CC_MMCODE
LEFT OUTER JOIN CP_OWNER O ON M.MM_OMCODE=O.OM_CODE
<where>
<!-- 날짜 -->
<if test="searchStartDt != null and searchStartDt != ''">
AND M.MM_DATE &gt;= REPLACE(#{searchStartDt}, '-', '')
</if>
<if test="searchEndDt != null and searchEndDt != ''">
AND M.MM_DATE &lt;= REPLACE(#{searchEndDt}, '-', '')
</if>
<!-- 시간 -->
<if test="searchTime1 != null and searchTime1 != ''">
AND M.MM_TIME &gt;= REPLACE(#{searchTime1}, '-', '')
</if>
<if test="searchTime2 != null and searchTime2 != ''">
AND M.MM_TIME &lt;= REPLACE(#{searchTime2}, '-', '')
</if>
<!-- 위반내용 (searchCondition : code1~6) -->
<!-- <if test="searchCondition != null and searchCondition != ''">-->
<!-- &lt;!&ndash; 코드가없다. &ndash;&gt;-->
<!-- AND M.VL_CODE = #{searchCondition}-->
<!-- </if>-->
<select id="selectYearStats"
parameterType="go.kr.project.biz.search.caution.model.CautionDto$Request$Search"
resultType="go.kr.project.biz.search.caution.model.CautionDto$Response$YearStats">
<!-- 처리상태 (searchCondition1 : code1~22) -->
<if test="searchCondition1 != null and searchCondition1 != ''">
AND M.MM_STATE = #{searchCondition1}
</if>
<!-- 등록구분 -->
<if test="searchCondition2 != null and searchCondition2 != ''">
AND M.MM_DLGB = #{searchCondition2}
</if>
<!-- 자료출처 -->
<if test="searchCondition3 != null and searchCondition3 != ''">
AND M.MM_INGB = #{searchCondition3}
</if>
<!-- &lt;!&ndash; 법정동 &ndash;&gt;-->
<!-- <if test="searchCondition4 != null and searchCondition4 != ''">-->
<!-- AND M.MM_DONG = #{searchCondition4}-->
<!-- </if>-->
<!-- ===== 텍스트 입력 필드들 (값이 있으면 AND LIKE) ===== -->
<!-- 차량번호 -->
<if test="searchCarno != null and searchCarno != ''">
AND M.MM_CARNO LIKE CONCAT('%', #{searchCarno}, '%')
</if>
<!-- 소유자성명 -->
<if test="searchName != null and searchName != ''">
AND O.OM_NAME LIKE CONCAT('%', #{searchName}, '%')
</if>
<!-- 주민번호 -->
<if test="searchJno != null and searchJno != ''">
AND O.OM_JNO LIKE CONCAT('%', #{searchJno}, '%')
</if>
SELECT SUBSTR(mm_date,1,4) AS year,
CONCAT(COUNT(NULLIF(CASE WHEN mm_state = '83' THEN '0'
WHEN mm_state = '84' THEN '0'
ELSE '1' END, '1'))) AS insCnt,
CONCAT(COUNT(NULLIF(CASE WHEN mm_state = '83' THEN '0'
WHEN mm_state = '84' THEN '0'
ELSE '1' END, '0'))) AS violCnt,
CONCAT(COUNT(*)) AS totalCnt
FROM cp_main
WHERE mm_state IN ('21','31','42','51','52','53','54','55','71','72','73','74','75','83','84')
AND mm_date BETWEEN REPLACE(#{searchStartDt}, '-', '') AND REPLACE(#{searchEndDt}, '-', '')
GROUP BY SUBSTR(mm_date,1,4)
</select>
<!-- 신고자 -->
<if test="searchUser != null and searchUser != ''">
AND A.AS_USER LIKE CONCAT('%', #{searchUser}, '%')
</if>
<select id="selectDeviceStats"
parameterType="go.kr.project.biz.search.caution.model.CautionDto$Request$Search"
resultType="go.kr.project.biz.search.caution.model.CautionDto$Response$DeviceStats">
<!-- 신고자 전화번호 -->
<if test="searchTel != null and searchTel != ''">
AND A.AS_TEL LIKE CONCAT('%', #{searchTel}, '%')
</if>
SELECT SUBSTR(mm_date,1,4) AS year,
CONCAT(COUNT(NULLIF(CASE WHEN mm_dlgb = '0' THEN '0'
ELSE '1' END, '1'))) AS cctvCnt,
CONCAT(COUNT(NULLIF(CASE WHEN mm_dlgb = '0' THEN '0'
ELSE '1' END, '0'))) AS smgCnt,
CONCAT(COUNT(*)) AS totalCnt
FROM cp_main
WHERE 1 = 1
AND mm_date BETWEEN REPLACE(#{searchStartDt}, '-', '') AND REPLACE(#{searchEndDt}, '-', '')
GROUP BY SUBSTR(mm_date,1,4)
</select>
<select id="selectTypeStats"
parameterType="go.kr.project.biz.search.caution.model.CautionDto$Request$Search"
resultType="go.kr.project.biz.search.caution.model.CautionDto$Response$TypeStats">
<!-- 목록번호 -->
<if test="searchBbsno != null and searchBbsno != ''">
AND A.AS_BBS_NO LIKE CONCAT('%', #{searchBbsno}, '%')
</if>
SELECT vl_id,
CONCAT(COUNT(NULLIF(CASE WHEN mm_state = '83' THEN '0'
WHEN mm_state = '84' THEN '0'
ELSE '1' END, '1'))) AS insCnt,
CONCAT(COUNT(NULLIF(CASE WHEN mm_state = '83' THEN '0'
WHEN mm_state = '84' THEN '0'
ELSE '1' END, '0'))) AS violCnt,
CONCAT(COUNT(*)) AS totalCnt
FROM cp_main
LEFT OUTER JOIN cp_violation
ON mm_sggcode = vl_sggcode
AND mm_lawgb = vl_code
WHERE mm_state IN ('21','31','42','51','52','53','54','55','71','72','73','74','75','83','84')
AND mm_date BETWEEN REPLACE(#{searchStartDt}, '-', '') AND REPLACE(#{searchEndDt}, '-', '')
GROUP BY mm_lawgb, vl_id
</select>
<!-- &lt;!&ndash; 위반장소 &ndash;&gt;-->
<!-- <if test="searchPos != null and searchPos != ''">-->
<!-- AND M.MM_PLACE LIKE CONCAT('%', #{searchPos}, '%')-->
<!-- </if>-->
<select id="selectDetailStats"
parameterType="go.kr.project.biz.search.caution.model.CautionDto$Request$Search"
resultType="go.kr.project.biz.search.caution.model.CautionDto$Response$DetailStats">
<!-- 상세주소 (예: O.OM_ADDR) -->
<!-- <if test="searchAddr != null and searchAddr != ''">-->
<!-- AND O.OM_ADDR LIKE CONCAT('%', #{searchAddr}, '%')-->
<!-- </if>-->
</where>
ORDER BY AS_JSDATE DESC, AS_JSNO DESC
</select>
<select id="selectViolationList"
resultType="go.kr.project.biz.search.filtersearch.model.FilterSearchDto$Response$Violation">
SELECT
VL_CODE,
VL_ID
FROM CP_VIOLATION
SELECT SUBSTR(R.REG_YMD,1,4) AS year,
CONCAT(COUNT(CASE WHEN SUBSTR(R.JOB_CD,4,1) = '1' AND R.RECEV_DIV_CD = '0' THEN 1 END)) AS instructNormalCnt,
CONCAT(COUNT(CASE WHEN SUBSTR(R.JOB_CD,4,1) = '1' AND R.RECEV_DIV_CD = '1' THEN 1 END)) AS instructRegistCnt,
CONCAT(COUNT(CASE WHEN SUBSTR(R.JOB_CD,4,1) = '2' AND R.RECEV_DIV_CD = '0' THEN 1 END)) AS sajunNormalCnt,
CONCAT(COUNT(CASE WHEN SUBSTR(R.JOB_CD,4,1) = '2' AND R.RECEV_DIV_CD = '1' THEN 1 END)) AS sajunRegistCnt,
CONCAT(COUNT(CASE WHEN SUBSTR(R.JOB_CD,4,1) = '3' AND R.RECEV_DIV_CD = '0' THEN 1 END)) AS bugwaNormalCnt,
CONCAT(COUNT(CASE WHEN SUBSTR(R.JOB_CD,4,1) = '3' AND R.RECEV_DIV_CD = '1' THEN 1 END)) AS bugwaRegistCnt,
CONCAT(COUNT(CASE WHEN SUBSTR(R.JOB_CD,4,1) = '4' AND R.RECEV_DIV_CD = '0' THEN 1 END)) AS dokNormalCnt,
CONCAT(COUNT(CASE WHEN SUBSTR(R.JOB_CD,4,1) = '4' AND R.RECEV_DIV_CD = '1' THEN 1 END)) AS dokRegistCnt,
CONCAT(COUNT(*)) AS totalCnt
FROM epost_sender_detail D
LEFT OUTER JOIN epost_sender_reg R
ON D.CON_KEY = R.CON_KEY
WHERE R.REG_YMD BETWEEN REPLACE(#{searchStartDt}, '-', '') AND REPLACE(#{searchEndDt}, '-', '')
AND R.DELETE_AT &lt;&gt; 'Y'
GROUP BY SUBSTR(R.REG_YMD,1,4)
</select>
</mapper>

@ -0,0 +1,136 @@
<%--
Created by IntelliJ IDEA.
User: kurt
Date: 2025. 11. 28.
Time: 오후 1:46
To change this template use File | Settings | File Templates.
--%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<div id="destruction_doc_dialog" style="display:none;">
<div class="left">
<div class="form-grid">
<!-- 1줄 -->
<div class="form-row">
<div class="field-group">
<div class="lbl">처리사유</div>
<div class="fld">
<select name="cpCancelAnswer" id="cpCancelAnswer">
<option value=""></option>
</select>
</div>
</div>
<div class="field-group empty"></div>
</div>
<!-- 2줄 -->
<div class="form-row">
<div class="field-group">
<div class="lbl">처리일자</div>
<div class="fld">
<input type="text" id="desDate" name="desDate" class="input calender datepicker" />
</div>
</div>
<div class="field-group empty"></div>
</div>
<!-- 3줄 -->
<div class="form-row block">
<div class="field-group">
<div class="lbl">특기사항</div>
<div class="fld">
<input type="text" name="cpMain" data-field="mmDlgb" id="mmDlgb" value="">
</div>
</div>
</div>
</div>
</div>
<div class="disdoc-btn-area">
<button type="button" class="btn btn-light disdoc-btn" name="" id="dis-doc">미부과처리</button>
</div>
</div>
<script type="text/javascript">
let fnDesDocFn = {
init: () => {
},
updateDestructionDoc: () => {
$.ajax({
url: "",
type: "post",
contentType: 'application/json',
success: function(response) {
//다이얼로그 하이드
//네이게이팅 다음으로
//로컬스토리지 mmCodes에 해당 mmCode 제거
},
error: function(xhr, status, error) {
$("#result").text("서손처리 실패");
}
});
},
eventListener: () => {
$("#dis-doc").on("click", () => {
fnDesDocFn.updateDestructionDoc();
})
}
}
$(function () {
/* 다이얼로그 설정 */
$("#destruction_doc_dialog").dialog({
autoOpen: false,
modal: true,
resizable: true,
// width: "auto",
width: 1000,
maxHeight: 800,
show: { effect: "drop", direction: "left", duration: 200 },
hide: { effect: "drop", direction: "left", duration: 200 },
title: "서손처리",
open: function () {
}
});
/* 오늘날짜 기본세팅 */
$('#desDate').datepicker('setDate', new Date());
});
</script>

@ -26,8 +26,7 @@
<input type="hidden" id="mmCodes" />
<%-- 부모창에서 받아오는 리스크 커서 --%>
<input type="hidden" id="cursor" />
<%-- 개별총정보 상태값 --%>
<input type="hidden" id="infoState" value="init" />
<div class="page-indicator">
<span id="cursorCnt">0</span>of <span id="total">0</span>
@ -154,7 +153,9 @@
<div class="field-group">
<div class="lbl">법정동</div>
<div class="fld">
<input type="text" name="cpAnswer" data-field="asJsno" id="asJsno" value="" readonly>
<select name="cpMain" id="mmDdcode">
<option value=""></option>
</select>
</div>
</div>
</div>
@ -195,7 +196,7 @@
<div class="field-group full">
<div class="lbl">특기사항</div>
<div class="fld">
<textarea name="cpMain" data-field="mmSgcont" id="mmSgcont" value="" readonly></textarea>
<textarea name="cpMain" data-field="mmSgcont" id="mmSgcont" value="" ></textarea>
</div>
</div>
</div>
@ -205,13 +206,13 @@
<div class="field-group">
<div class="lbl">차량명</div>
<div class="fld">
<input type="text" data-field="" value="" readonly>
<input type="text" data-field="" value="" >
</div>
</div>
<div class="field-group">
<div class="lbl">차량색상</div>
<div class="fld">
<input type="text" data-field="" value="" readonly>
<input type="text" data-field="" value="" >
</div>
</div>
</div>
@ -221,7 +222,7 @@
<div class="field-group">
<div class="lbl">연료구분</div>
<div class="fld">
<input type="text" data-field="" value="" readonly>
<input type="text" data-field="" value="" >
</div>
</div>
<div class="field-group empty"></div>
@ -232,13 +233,13 @@
<div class="field-group">
<div class="lbl">소유주</div>
<div class="fld">
<input type="text" data-field="" value="" readonly>
<input type="text" data-field="" value="" >
</div>
</div>
<div class="field-group">
<div class="lbl">등록구분</div>
<div class="fld">
<input type="text" data-field="" value="" readonly>
<input type="text" data-field="" value="" >
</div>
</div>
</div>
@ -248,13 +249,13 @@
<div class="field-group">
<div class="lbl">주민번호</div>
<div class="fld">
<input type="text" data-field="" value="" readonly>
<input type="text" data-field="" value="" >
</div>
</div>
<div class="field-group">
<div class="lbl">우편번호</div>
<div class="fld">
<input type="text" data-field="" value="" readonly>
<input type="text" data-field="" value="" >
</div>
</div>
</div>
@ -264,7 +265,7 @@
<div class="field-group full">
<div class="lbl">주소</div>
<div class="fld">
<input type="text" data-field="" value="" readonly>
<input type="text" data-field="" value="" >
</div>
</div>
</div>
@ -274,13 +275,13 @@
<div class="field-group">
<div class="lbl">번지</div>
<div class="fld">
<input type="text" data-field="" value="" readonly>
<input type="text" data-field="" value="" >
</div>
</div>
<div class="field-group">
<div class="lbl">차대번호</div>
<div class="fld">
<input type="text" data-field="" value="" readonly>
<input type="text" data-field="" value="" >
</div>
</div>
</div>
@ -290,7 +291,7 @@
<div class="field-group">
<div class="lbl">도로코드</div>
<div class="fld">
<input type="text" data-field="" value="" readonly>
<input type="text" data-field="" value="" >
</div>
</div>
<div class="field-group empty"></div>
@ -317,12 +318,12 @@
<div id="btn-area">
<button type="button" class="btn btn-light" name="changeSt" id="non-target" value="81">미부과처리</button>
<button type="button" class="btn btn-light" name="changeSt" id="non-target" value="">계도처리</button>
<button type="button" class="btn btn-light" name="changeSt" id="non-target" value="">회수처리</button>
<button type="button" class="btn btn-light" name="changeSt" id="non-target" value="">자료복사</button>
<button type="button" class="btn btn-light" name="changeSt" id="guide" value="">계도처리</button>
<button type="button" class="btn btn-light" name="changeSt" id="return" value="">회수처리</button>
<button type="button" class="btn btn-light" name="changeSt" id="copy" value="">자료복사</button>
<button type="button" class="btn btn-light" id="delay">처리보류</button>
<button type="button" class="btn btn-light" id="delay">원본보기</button>
<button type="button" class="btn btn-light" id="infoReadReturn">되돌리기</button>
<button type="button" class="btn btn-light" id="init">되돌리기</button>
<button type="button" class="btn btn-light" id="lavyTarget">되돌리기</button>
<button type="button" class="btn btn-light" id="stateChange" hidden>처리상태 변경</button>
</div>
@ -337,9 +338,8 @@
</div>
</div>
<div id="photoEditSection" style="display:none;">
<jsp:include page="/WEB-INF/views/biz/totalInfo/totalInfo_photo_dialog.jsp" />
</div>
<jsp:include page="/WEB-INF/views/biz/totalInfo/totalInfo_photo_dialog.jsp" />
<jsp:include page="/WEB-INF/views/biz/dialog/destruction_doc_dialog.jsp" />
</div>
<!-- /Main body -->
@ -348,10 +348,7 @@
<script type="text/javascript">
window.INIT_POP_API = {
search: () => {
console.log("Total Info Search!!!!")
const { cursor, mmCodes } = JSON.parse(localStorage.getItem("TOTAL_INFO_STATE"));
$.ajax({
// PathVariable 형태로 url를 동적으로 쓰는방식이다.
// 해당 방식 이외에 그냥 쿼리스트링으로 넘기는 방법도 있다.
@ -359,10 +356,7 @@
type: "GET",
dataType: 'json',
success: function(response) {
console.log(response.data)
$("#mmIngb").val(response.data.cpMain.mmIngb);
$("#mmDlgb").val(response.data.cpMain.mmDlgb);
$("#mmLawgb").val(response.data.cpMain.mmLawgb);
@ -407,9 +401,6 @@
$("#cursorCnt").text(mmCodes.indexOf(cursor) + 1);
$("#total").text(mmCodes.length);
// total info 초기상태
$("#infoState").val("init").trigger("change");
},
error: function(xhr, status, error) {
$("#result").text("조회 실패");
@ -423,10 +414,31 @@
let fnBiz = {
init: () => {
// fnBiz.search();
fnBiz.setCode();
},
infoSave: () => {
setCode: () => {
$.ajax({
url: "/common/code/find.ajax",
type: "GET",
contentType: 'application/json',
success: function(response) {
console.log(response);
response.cpBdong.forEach((item) => {
$("#mmDdcode").append('<option value="' +item.bdCode+'">' +item.bdDongName+ '</option>')
});
response.cpCancelAnswer.forEach((item) => {
$("#cpCancelAnswer").append('<option value="' +item.caCode+'">' +item.caId+ '</option>')
})
},
error: function(xhr, status, error) {
$("#result").text("조회 실패");
}
});
},
initDataUpdate: () => {
const { cursor, mmCodes } = JSON.parse(localStorage.getItem("TOTAL_INFO_STATE"));
const payload = fnBiz.collectByDataField();
@ -466,32 +478,7 @@
});
},
btnSet: (infoState) => {
switch (infoState) {
case "init":
// $("#btn-area > button").prop("hidden", true);
// $("#infoEdit").prop("hidden", false);
// $("#infoDel").prop("hidden", false);
// $("#delay").prop("hidden", false);
// $("#buillPrint").prop("hidden", false);
// $("#stateChange").prop("hidden", false);
// $("#non-target").prop("hidden", false);
break;
case "edit":
// $("#btn-area > button").prop("hidden", true);
// $("#infoSave").prop("hidden", false);
// $("#infoReadReturn").prop("hidden", false);
break;
}
switch ($("#asState")) {
case "":
$("#destructionDocReReg").prop("hidden", false);
}
},
collectByDataField: () => {
const payload = {};
@ -534,40 +521,8 @@
INIT_POP_API.search();
});
/** 개별총정보 상태변경 트리거 */
$("#infoState").on("change", () => {
fnBiz.btnSet($("#infoState").val());
})
/** 개별총정보 수정모드 진입*/
$("#infoEdit").on("click", () => {
$("input").prop("readonly", false);
$("#infoState").val("edit").trigger("change");
})
/** 개별총정보 읽기모드 진입 */
$("#infoReadReturn").on("click", () => {
$("input").prop("readonly", true);
INIT_POP_API.search();
$("#infoState").val("init").trigger("change");
})
/** 정보수정 */
$("#infoSave").on("click", () => {
fnBiz.infoSave();
$("input").prop("readonly", true);
INIT_POP_API.search();
})
/** 상태값 변경 */
$("button[name='changeSt']").on("click", (e) => {
let flag = e.target.value;
fnBiz.changeState(e, flag);
})
/** 사진 더블클릭 → 원본 다이얼로그 */
$("#photoThumbs").on("dblclick", "img", function () {
const src = $(this).attr("src"); // 썸네일 경로
@ -576,6 +531,12 @@
$("#photoDialog").dialog("open");
});
$("#non-target").on("click", () => {
$("#destruction_doc_dialog").dialog("open");
})
}
}
@ -585,6 +546,8 @@
$("#tabs").tabs();
fnBiz.init();
INIT_POP_API.search();
fnBiz.eventListener();

@ -115,10 +115,10 @@
init: () => {
fnBiz.searchCode();
fnBiz.setCode();
},
searchCode: () => {
setCode: () => {
$.ajax({
url: "/common/code/find.ajax",
type: "GET",
@ -132,8 +132,6 @@
$(".state-tabs li").first().addClass("on").trigger("click");
},
error: function(xhr, status, error) {
$("#result").text("조회 실패");

@ -44,143 +44,98 @@
</ul>
</div>
</div>
<div class="gs_booking">
<div class="row">
<div class="col-sm-12">
<div class="box_column">
<div class="containers">
<!-- 상단 3개 그리드 -->
<div class="grid-row-top">
<!-- 1. 연도별 경고/과태료 합계 -->
<div class="grid-wrap">
<div class="grid-title">연도별 합계</div>
<div id="gridYear"></div>
</div>
<!-- 2. 연도별 단속수단 -->
<div class="grid-wrap">
<div class="grid-title">연도별 단속수단</div>
<div id="gridDevice"></div>
</div>
<!-- 3. 위반유형별 경고/과태료 -->
<div class="grid-wrap">
<div class="grid-title">위반유형별</div>
<div id="gridType"></div>
</div>
</div>
<!-- 하단 1개 그리드 -->
<div class="grid-row-bottom">
<div class="grid-wrap">
<div class="grid-title">상세 통계</div>
<div id="gridDetail"></div>
</div>
</div>
</div>
</div>
<div class="gs_booking">
<!-- 상단 3개 그리드 -->
<div class="row">
<div class="col-sm-4">
<div class="box_column">
<div class="containers">
<!-- 연도별 경고/과태료/전체 -->
<div id="gridYear" class="stat-grid-top"></div>
</div>
</div>
</div>
<style>
/* 전체 컨테이너 */
.gs_booking {
width: 100%;
}
/* 상단 3개 그리드 영역 */
.grid-row-top {
display: flex;
gap: 10px;
width: 100%;
height: 260px; /* 반드시 px 지정 */
margin-bottom: 10px;
}
/* 상단 개별 박스 */
.grid-row-top .grid-wrap {
flex: 1;
border: 1px solid #c0c0c0;
background: #fff;
display: flex;
flex-direction: column;
}
<div class="col-sm-4">
<div class="box_column">
<div class="containers">
<!-- 자동단속기/안전신문고/합계 -->
<div id="gridDevice" class="stat-grid-top"></div>
</div>
</div>
</div>
/* 하단 1개 그리드 영역 */
.grid-row-bottom {
width: 100%;
height: 260px;
margin-top: 10px;
}
<div class="col-sm-4">
<div class="box_column">
<div class="containers">
<!-- 위반유형별 경고/과태료/합계 -->
<div id="gridType" class="stat-grid-top"></div>
</div>
</div>
</div>
</div>
.grid-row-bottom .grid-wrap {
height: 100%;
border: 1px solid #c0c0c0;
background: #fff;
display: flex;
flex-direction: column;
<!-- 하단 1개 그리드 (상세 합계) -->
<div class="row stat-grid-bottom-row">
<div class="col-sm-12">
<div class="box_column">
<div class="containers">
<!-- 단계별(계도/사전/부과/독촉) 합계 -->
<div id="gridDetail" class="stat-grid-bottom"></div>
</div>
</div>
</div>
</div>
</div>
<style>
.stat-grid-top {
margin-bottom: 8px;
}
/* 그리드 타이틀 */
.grid-title {
flex: 0 0 30px;
line-height: 30px;
font-size: 12px;
font-weight: bold;
padding-left: 8px;
background: #f5f5f5;
border-bottom: 1px solid #ddd;
.stat-grid-bottom {
margin-top: 8px;
}
#gridYear,
#gridDevice,
#gridType,
#gridDetail {
flex: 1;
min-height: 0;
.stat-grid-row {
margin-top: 5px;
}
/* 버튼 우측 정렬 */
.btn-area-right {
margin-top: 10px;
text-align: right;
.stat-grid-bottom-row {
margin-top: 12px;
}
</style>
<script type="text/javascript">
let INIT_POPUP = null;
let SEARCH_COND = {};
let GRID_YEAR = null;
let GRID_DEVICE = null;
let GRID_TYPE = null;
let GRID_DETAIL = null;
// 검색조건 세팅
let setSearchCond = function () {
let searchCondition = $.trim(nvl($("#searchCondition").val(), ""));
let searchKeyword = $.trim(nvl($("#searchKeyword").val(), ""));
let searchUseYn = $.trim(nvl($("#searchUseYn").val(), ""));
let searchStartDt = $.trim(nvl($("#searchStartDt").val(), ""));
let searchEndDt = $.trim(nvl($("#searchEndDt").val(), ""));
SEARCH_COND.searchCondition = searchCondition;
SEARCH_COND.searchKeyword = searchKeyword;
SEARCH_COND.searchUseYn = searchUseYn;
SEARCH_COND.searchStartDt = searchStartDt;
SEARCH_COND.searchEndDt = searchEndDt;
let searchStartDt = $.trim(nvl($("#searchStartDt").val(), ""));
let searchEndDt = $.trim(nvl($("#searchEndDt").val(), ""));
SEARCH_COND = {}; // 항상 새로 만듦
SEARCH_COND.searchStartDt = searchStartDt;
SEARCH_COND.searchEndDt = searchEndDt;
};
const fnBiz = {
init: () => {
initGrid();
initGridYear();
initGridDevice();
initGridType();
initGridDetail();
},
eventListener: () => {
// 검색 버튼
// 검색 버튼
$('#search_btn').on('click', function () {
let startDate = $("#searchStartDt").val();
let endDate = $("#searchEndDt").val();
@ -202,114 +157,69 @@
}
}
$("#page").val(1);
GRID.readData(1);
});
// 검색어 엔터
$('#searchKeyword').on('keypress', function (e) {
if (e.which === 13) {
e.preventDefault();
$('#search_btn').trigger('click');
}
[GRID_YEAR, GRID_DEVICE, GRID_TYPE, GRID_DETAIL].forEach(grid => {
if (grid) {
grid.readData(1);
}
});
});
// perPage 변경 이벤트 추가
$('#perPageSelect').on('change', () => {
const pagination = TuiGrid.instance.getPagination();
if (!pagination) return;
const perPage = $('#perPageSelect').val();
[GRID_YEAR, GRID_DEVICE, GRID_TYPE, GRID_DETAIL].forEach(grid => {
if (!grid || !grid.getPagination) return;
pagination.setItemsPerPage($('#perPageSelect').val());
pagination.reset(TuiGrid.instance.getRowCount());
pagination.movePageTo(1);
const pagination = grid.getPagination();
if (!pagination) return;
pagination.setItemsPerPage(perPage);
pagination.reset(grid.getRowCount());
pagination.movePageTo(1);
});
});
// 상태 탭 클릭
$('.state-tabs li').on('click', function () {
$('.state-tabs li').removeClass('on');
$(this).addClass('on');
$('#btnHwp').on('click', function () {
setSearchCond();
if (!SEARCH_COND.searchStartDt || !SEARCH_COND.searchEndDt) {
alert("조회일자를 먼저 선택해 주세요.");
return;
}
const state = $(this).data('state') || '';
$('#tabState').val(state);
const queryString = $.param({
searchStartDt: SEARCH_COND.searchStartDt,
searchEndDt: SEARCH_COND.searchEndDt
});
SEARCH_COND = {};
GRID.readData(1);
const url = '<c:url value="/search/caution/caution-hwp-download.do"/>' + '?' + queryString;
window.open(url, '_blank');
});
}
};
/** tui-grid Set */
const initGrid = () => {
// 1. 연도별 합계
GRID_YEAR = new tui.Grid({
el: document.getElementById('gridYear'),
bodyHeight: '200',
rowHeaders: [],
scrollX: false,
scrollY: true,
columns: [
{ header: '구분', name: 'gbn', width: 80, align: 'center' },
{ header: '경고', name: 'warnCnt', width: 80, align: 'right' },
{ header: '과태료', name: 'fineCnt', width: 80, align: 'right' },
{ header: '전체', name: 'totalCnt', width: 80, align: 'right' }
],
data: []
});
// 2. 연도별 단속수단
GRID_DEVICE = new tui.Grid({
el: document.getElementById('gridDevice'),
bodyHeight: '200',
rowHeaders: [],
scrollX: false,
scrollY: true,
columns: [
{ header: '구분', name: 'gbn', width: 80, align: 'center' },
{ header: '자동단속기', name: 'autoCnt', width: 80, align: 'right' },
{ header: '안전신문고', name: 'safeCnt', width: 80, align: 'right' },
{ header: '합계', name: 'totalCnt', width: 80, align: 'right' }
],
data: []
});
const initGridYear = () => {
const perPage = parseInt($('#perPageSelect').val() || 10, 10);
// 3. 위반유형별
GRID_TYPE = new tui.Grid({
el: document.getElementById('gridType'),
bodyHeight: '200',
rowHeaders: [],
scrollX: false,
scrollY: true,
columns: [
{ header: '구분', name: 'gbn', width: 120, align: 'left' },
{ header: '경고', name: 'warnCnt', width: 80, align: 'right' },
{ header: '과태료', name: 'fineCnt', width: 80, align: 'right' },
{ header: '합계', name: 'totalCnt', width: 80, align: 'right' }
],
data: []
});
const gridColumns = [
{ header: '구분', name: 'year', width: 80, align: 'center' },
{ header: '경고', name: 'insCnt', width: 80, align: 'right' },
{ header: '과태료', name: 'violCnt', width: 80, align: 'right' },
{ header: '전체', name: 'totalCnt', width: 80, align: 'right' }
];
// 4. 상세 통계 (하단)
GRID_DETAIL = new tui.Grid({
el: document.getElementById('gridDetail'),
bodyHeight: '220',
rowHeaders: [],
scrollX: true,
scrollY: true,
columns: [
{ header: '구분', name: 'gbn', width: 80, align: 'center' },
{ header: '계도-일반', name: 'cdGen', width: 90, align: 'right' },
{ header: '계도-등기', name: 'cd5', width: 90, align: 'right' },
{ header: '사전-일반', name: 'sjGen', width: 90, align: 'right' },
{ header: '사전-등기', name: 'sj5', width: 90, align: 'right' },
{ header: '부과-일반', name: 'bgGen', width: 90, align: 'right' },
{ header: '부과-등기', name: 'bg5', width: 90, align: 'right' },
{ header: '독촉-일반', name: 'dcGen', width: 90, align: 'right' },
{ header: '독촉-등기', name: 'dc5', width: 90, align: 'right' },
{ header: '합계', name: 'totalCnt', width: 90, align: 'right' }
],
data: []
});
const gridOptions = {
el: 'gridYear',
rowHeaders: ['rowNum'],
columns: gridColumns,
noData: "자료가 없습니다.",
height: 100,
bodyHeight: 80,
pageOptions: {
useClient: true, // 통계는 클라이언트 페이징이 편함
perPage: perPage
}
};
const gridDatasource = {
api: {
@ -325,93 +235,184 @@
setSearchCond();
SEARCH_COND.perPage = params.perPage;
SEARCH_COND.page = params.page;
SEARCH_COND.gridId = 'YEAR';
return $.param(SEARCH_COND);
}
};
GRID_YEAR = TuiGrid.of(gridOptions, gridDatasource, (res) => {});
GRID_YEAR.readData(1);
};
const initGridDevice = () => {
const perPage = parseInt($('#perPageSelect').val() || 10, 10);
const gridColumns = [
{ header: '구분', name: 'year', width: 80, align: 'center' },
{ header: '자동단속기', name: 'cctvCnt', width: 100, align: 'right' },
{ header: '안전신문고', name: 'smgCnt', width: 100, align: 'right' },
{ header: '합계', name: 'totalCnt', width: 80, align: 'right' }
];
const gridOptions = {
el: 'grid',
rowHeaders: ['checkbox'],
el: 'gridDevice',
rowHeaders: ['rowNum'],
columns: gridColumns,
noData: "처리 할 초기자료가 없습니다.",
noData: "자료가 없습니다.",
height: 100,
bodyHeight: 80,
pageOptions: {
useClient: false,
useClient: true,
perPage: perPage
}
};
// 실제 GRID 생성
GRID = TuiGrid.of(gridOptions, gridDatasource, (res) => {
// 서버 응답 후 페이지 정보 세팅
const data = res.data || {};
if (data.pagination) {
$("#currentPage").text(data.pagination.page || '');
$("#totalPages").text(data.pagination.totalPages || '');
const gridDatasource = {
api: {
readData: {
url: '<c:url value="/search/caution/caution-select.ajax"/>',
method: 'POST',
contentType: 'application/x-www-form-urlencoded',
processData: true
}
},
initialRequest: true,
serializer: function (params) {
setSearchCond();
SEARCH_COND.perPage = params.perPage;
SEARCH_COND.page = params.page;
SEARCH_COND.gridId = 'DEVICE';
return $.param(SEARCH_COND);
}
};
GRID_DEVICE = TuiGrid.of(gridOptions, gridDatasource, (res) => {});
GRID_DEVICE.readData(1);
};
const initGridType = () => {
const perPage = parseInt($('#perPageSelect').val() || 10, 10);
const gridColumns = [
{ header: '위반유형', name: 'vlId', width: 120, align: 'left' },
{ header: '경고', name: 'insCnt', width: 80, align: 'right' },
{ header: '과태료', name: 'violCnt', width: 80, align: 'right' },
{ header: '합계', name: 'totalCnt', width: 80, align: 'right' }
];
const gridOptions = {
el: 'gridType',
rowHeaders: ['rowNum'],
columns: gridColumns,
noData: "자료가 없습니다.",
height: 100,
bodyHeight: 80,
pageOptions: {
useClient: true,
perPage: perPage
}
};
// 더블 클릭 이벤트
GRID.on("dblclick", (e) => {
var popUrl = '/minwon/init/init_popup.do';
var popTitle = "initPopup";
var popOption = "width=1400px, height=900px, resizable=yes, scrollbars=yes, location=no, top=100px, left=100px";
const gridDatasource = {
api: {
readData: {
url: '<c:url value="/search/caution/caution-select.ajax"/>',
method: 'POST',
contentType: 'application/x-www-form-urlencoded',
processData: true
}
},
initialRequest: true,
serializer: function (params) {
setSearchCond();
SEARCH_COND.perPage = params.perPage;
SEARCH_COND.page = params.page;
SEARCH_COND.gridId = 'TYPE';
// 1) localStorage에 저장
console.log(e)
return $.param(SEARCH_COND);
}
};
let cursor = e.instance.getValue(e.rowKey, 'mmCode');
let mmCodes = e.instance.getData().map(row => row.mmCode);
GRID_TYPE = TuiGrid.of(gridOptions, gridDatasource, (res) => {});
GRID_TYPE.readData(1);
};
console.log(cursor);
const initGridDetail = () => {
const perPage = parseInt($('#perPageSelect').val() || 10, 10);
const gridColumns = [
{ header: '구분', name: 'year', width: 80, align: 'center' },
{ header: '계도-일반', name: 'instructNormalCnt', width: 80, align: 'right' },
{ header: '계도-등기', name: 'instructRegistCnt', width: 80, align: 'right' },
{ header: '사전-일반', name: 'sajunNormalCnt', width: 80, align: 'right' },
{ header: '사전-등기', name: 'sajunRegistCnt', width: 80, align: 'right' },
{ header: '부과-일반', name: 'bugwaNormalCnt', width: 80, align: 'right' },
{ header: '부과-등기', name: 'bugwaRegistCnt', width: 80, align: 'right' },
{ header: '독촉-일반', name: 'dokNormalCnt', width: 80, align: 'right' },
{ header: '독촉-등기', name: 'dokRegistCnt', width: 80, align: 'right' },
{ header: '합계', name: 'totalCnt', width: 80, align: 'right' }
];
const state = { cursor, mmCodes, savedAt: Date.now() };
localStorage.setItem('TOTAL_INFO_STATE', JSON.stringify(state));
const gridOptions = {
el: 'gridDetail',
rowHeaders: ['rowNum'],
columns: gridColumns,
noData: "자료가 없습니다.",
height: 150,
bodyHeight: 100,
pageOptions: {
useClient: true,
perPage: perPage
}
};
// 2) 팝업이 없거나 닫혀 있으면 새로 열기
if (!INIT_POPUP || INIT_POPUP.closed) {
INIT_POPUP = window.open(popUrl, popTitle, popOption);
} else {
// 이미 떠 있으면 새로 안 만들고, 그 창에 포커스만 줌
INIT_POPUP.focus();
INIT_POPUP.INIT_POP_API.search();
const gridDatasource = {
api: {
readData: {
url: '<c:url value="/search/caution/caution-select.ajax"/>',
method: 'POST',
contentType: 'application/x-www-form-urlencoded',
processData: true
}
});
});
},
initialRequest: true,
serializer: function (params) {
setSearchCond();
SEARCH_COND.perPage = params.perPage;
SEARCH_COND.page = params.page;
SEARCH_COND.gridId = 'DETAIL';
// 최초 1페이지 조회
GRID.readData(1);
return $.param(SEARCH_COND);
}
};
GRID_DETAIL = TuiGrid.of(gridOptions, gridDatasource, (res) => {});
GRID_DETAIL.readData(1);
};
const loadWarningStats = () => {
setSearchCond();
$(function () {
$.ajax({
url: '<c:url value="/caution/statistics.ajax"/>',
type: 'POST',
data: SEARCH_COND,
success: function (res) {
const startInput = $("#searchStartDt");
const endInput = $("#searchEndDt");
const yearList = res.yearList || [];
const deviceList = res.deviceList || [];
const typeList = res.typeList || [];
const detailList = res.detailList || [];
if (!startInput.val() || !endInput.val()) {
const today = new Date();
const yyyy = today.getFullYear();
const mm = String(today.getMonth() + 1).padStart(2, '0');
const dd = String(today.getDate()).padStart(2, '0');
GRID_YEAR.resetData(yearList);
GRID_DEVICE.resetData(deviceList);
GRID_TYPE.resetData(typeList);
GRID_DETAIL.resetData(detailList);
},
error: function () {
alert('경고 통계 조회 중 오류가 발생했습니다.');
const todayStr = yyyy + "-" + mm + "-" + dd;
const firstDayOfYear = yyyy + "-01-01";
startInput.val(firstDayOfYear);
endInput.val(todayStr);
}
});
};
// 레디펑션
$(function () {
fnBiz.init();
fnBiz.eventListener();
});

@ -40,6 +40,7 @@
<link rel="stylesheet" href="<c:url value='/css/bootstrap-datepicker.min.css' />">
<link rel="stylesheet" href="<c:url value='/css/style_new.css' />">
<link rel="stylesheet" href="<c:url value='/css/cc.css' />">
<link rel="stylesheet" href="<c:url value='/css/cc-dialog.css' />">
<%--================== Main Scripts ======================--%>

@ -43,6 +43,7 @@
<link rel="stylesheet" href="<c:url value='/css/jquery-ui.css' />">
<link rel="stylesheet" href="<c:url value='/css/cc.css' />">
<link rel="stylesheet" href="<c:url value='/css/cc-popup.css' />">
<link rel="stylesheet" href="<c:url value='/css/cc-dialog.css' />">
<%--================== Main Scripts ======================--%>

@ -0,0 +1,47 @@
.ui-dialog .ui-dialog-titlebar {
background: #202342;
color: #fff;
border-bottom: 1px solid #444;
border-radius: 4px;
}
.ui-dialog .ui-dialog-title {
color: #fff;
font-weight: 600;
}
/* 닫기 버튼 기본 버튼 스타일 제거 */
.ui-dialog .ui-dialog-titlebar-close {
background: transparent !important;
border: none !important;
width: 28px;
height: 28px;
right: 6px;
top: 50%;
transform: translateY(-50%);
}
/* 기존 jQuery UI 아이콘 완전히 숨김 */
.ui-dialog .ui-dialog-titlebar-close .ui-icon {
display: none !important;
}
/* 텍스트 X 직접 그리기 */
.ui-dialog .ui-dialog-titlebar-close::before {
content: "✕";
color: #fff;
font-size: 25px;
font-weight: 600;
line-height: 45px;
text-align: center;
display: block;
}
.disdoc-btn-area {
display: flex;
justify-content: flex-end;
}
.disdoc-btn {
margin-top: 10px;
}

@ -0,0 +1,28 @@
package go.kr.project.domain.entity;
import lombok.Getter;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Table;
@Entity
@Table(name = "cp_cancel_answer")
@Getter
public class CpCancelAnswer {
@EmbeddedId
private CpCancelAnswerId id;
@Column(name = "CA_ID", length = 50)
private String caId;
@Column(name = "CA_ISANSWER", length = 1)
private String caIsAnswer;
@Column(name = "CA_ANSWERTEXT", length = 50)
private String caAnswerText;
}

@ -0,0 +1,29 @@
package go.kr.project.domain.entity;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import java.io.Serializable;
@Embeddable
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CpCancelAnswerId implements Serializable {
@Column(name = "CA_SGGCODE", length = 5, nullable = false)
private String caSggCode;
@Column(name = "CA_CODE", length = 3, nullable = false)
private String caCode;
}

@ -0,0 +1,33 @@
package go.kr.project.domain.entity;
import lombok.Getter;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Table;
@Entity
@Table(name = "cp_cancel_answer")
@Getter
public class CpCancelAnswer {
@EmbeddedId
private CpCancelAnswerId id;
@Column(name = "nrcg_rsnnm", length = 50)
private String caId;
@Column(name = "nrcgans_yn", length = 1)
private String caIsAnswer;
@Column(name = "nrcgans_cn", length = 50)
private String caAnswerText;
}

@ -0,0 +1,27 @@
package go.kr.project.domain.entity;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import java.io.Serializable;
@Embeddable
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CpCancelAnswerId implements Serializable {
@Column(name = "sggcd", length = 5, nullable = false)
private String caSggCode;
@Column(name = "nrcgans_id", length = 3, nullable = false)
private String caCode;
}
Loading…
Cancel
Save