Compare commits

...

7 Commits

Author SHA1 Message Date
Kurt92 09e0865033 feat : 차적조회 후처리 로직 수정, 소유주정보 코드 이넘클래스 추가 2 days ago
Kurt92 d3336543ff feat : 사전통보 현황 작업 2 days ago
Kurt92 5fa4b73ddd feat : 계도 발송대상, 계도현황 페이지 추가 2 days ago
Kurt92 670f86f55b feat : CpInstructRepository 추가 2 days ago
Kurt92 c765dc6fcc feat : 다이얼로그 작업.
1. 계도처리 다이얼로그 로직
2. 묶음자료 다이얼로그 추가
2 days ago
Kurt92 1127980315 feat : 프론트 공통
1. 날짜 벨리데이션
2. css div wrap 클래스 추가
2 days ago
Kurt92 2c11ff2b4d feat : 상태업데이트 통합.
mmcode 타겟의 상태값만 업데이트 하는 매서드 추가
3 days ago

@ -24,6 +24,16 @@ public class CommonDto {
}
@Getter
@Setter
public static class UpdateGuidance {
private String itSggcode;
private String itDate;
private String itCause;
private String itEtc;
private String itIndt;
private Integer itInuser;
}

@ -84,11 +84,13 @@ public class CommonServiceImpl implements CommonService {
switch(stateEnum) {
case VEHICLE_CHECKED:
updateStateService.updateCarInfoFromCpMain(mmCode, dtoConverter.toStrictDto(req, WebClientCallDto.CarInfoResponse.CarInfoIfBody.class));
updateStateService.updateCarInfoFromCpMain(mmCode, dtoConverter.toDto(req, WebClientCallDto.CarInfoResponse.CarInfoIfBody.class));
break;
case DESTRUCTION_DOC:
updateStateService.updateState(mmCode, MmStateEnum.DESTRUCTION_DOC);
break;
case GUIDANCE:
updateStateService.updateStateToGuidance(mmCode, MmStateEnum.GUIDANCE, dtoConverter.toDto(req, CommonDto.Request.UpdateGuidance.class));
break;
case GUIDANCE_PROCESSED:
break;

@ -1,15 +1,23 @@
package go.kr.project.biz.common.service.impl;
import go.kr.project.biz.common.dto.CommonDto;
import go.kr.project.biz.common.dto.WebClientCallDto;
import go.kr.project.biz.common.repository.CommonQueryDslRepository;
import go.kr.project.domain.entity.CpInstruct;
import go.kr.project.domain.entity.CpMain;
import go.kr.project.domain.entity.CpMainhist;
import go.kr.project.domain.entity.CpOwner;
import go.kr.project.domain.repo.cp.CpInstructRepository;
import go.kr.project.domain.repo.cp.CpMainRepository;
import go.kr.project.domain.repo.cp.CpMainhistRepository;
import go.kr.project.domain.repo.cp.CpOwnerRepository;
import go.kr.project.vo.code.MmStateEnum;
import go.kr.project.vo.code.OmIngbEnum;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.swing.text.html.Option;
import javax.transaction.Transactional;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@ -22,9 +30,27 @@ public class UpdateStateService {
private final CommonQueryDslRepository commonQueryDslRepository;
private final CpMainRepository cpMainRepository;
private final CpOwnerRepository cpOwnerRepository;
private final CpMainhistRepository cpMainhistRepository;
private final CpInstructRepository cpInstructRepository;
/**
* mmcode
* */
@Transactional
public void updateState(String mmCode, MmStateEnum disDocCodeEnum) {
Optional<CpMain> cpMain = cpMainRepository.findById(mmCode);
cpMain.ifPresent(e-> e.changeMmState(disDocCodeEnum));
}
/**
*
* */
@Transactional
public void updateCarInfoFromCpMain(String mmCode, WebClientCallDto.CarInfoResponse.CarInfoIfBody carInfoIfBody) {
@ -46,7 +72,7 @@ public class UpdateStateService {
.omBldNo1(carInfoIfBody.getUseStrnghldBuldMainNo())
.omBldNo2(carInfoIfBody.getUseStrnghldBuldSubNo())
// .omBldAdmno()
.omIngb(carInfoIfBody.getErsrRegistSeCode())
.omIngb(OmIngbEnum.CARINFO_API.getCode())
.omIndt(carInfoIfBody.getTransrRegistDe())
.build();
cpOwnerRepository.save(cpOwner);
@ -55,12 +81,58 @@ public class UpdateStateService {
commonQueryDslRepository.updateCarinfoFromCpMain(mmCode, cpOwner, carInfoIfBody);
// main hist 인서트
StateChangeHistSaveToMainHist("21", mmCode);
InsertStateChangeHistToMainHist("21", mmCode);
}
public void StateChangeHistSaveToMainHist(String mmState, String mmCode) {
/**
*
* 1.
* 2. CpInstruct
* */
@Transactional
public void updateStateToGuidance(String mmCode, MmStateEnum GuidanceEnum, CommonDto.Request.UpdateGuidance dto) {
//CpMain 조회후 mmState 업데이트
Optional<CpMain> cpMain = cpMainRepository.findById(mmCode);
cpMain.ifPresent(e -> e.changeMmState(GuidanceEnum));
// CpInstruct 인서트
CpInstruct cpInstruct = CpInstruct.builder()
.itSggcode(dto.getItSggcode())
.itMmcode(mmCode)
.itDate(dto.getItDate())
.itCause(dto.getItCause())
.itEtc(dto.getItEtc())
.itIndt(dto.getItIndt())
.itInuser(dto.getItInuser())
.build();
cpInstructRepository.save(cpInstruct);
}
private void InsertStateChangeHistToMainHist(String mmState, String mmCode) {
Optional<CpMainhist> prevOpt = cpMainhistRepository.findTopByMhMmcodeOrderByMhIndtDesc(mmCode);
@ -90,6 +162,4 @@ public class UpdateStateService {
}

@ -0,0 +1,51 @@
package go.kr.project.biz.post.guide.sendTarget.controller;
import egovframework.constant.TilesConstants;
import egovframework.util.ApiResponseUtil;
import go.kr.project.biz.post.guide.sendTarget.dto.GuideSendTargetDto;
import go.kr.project.biz.post.guide.sendTarget.service.GuideSendTargetService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import java.util.List;
@Controller
@RequiredArgsConstructor
public class GuideSendTargetController {
private final GuideSendTargetService guideSendTargetService;
/**
* / > >
* @return
*/
@GetMapping("post/guide/sendTarget/guideSendTarget.do")
public String guideSendTargetView() {
return "biz/post/guide/sendTarget/guideSendTarget" + TilesConstants.BASE;
}
@PostMapping("/post/guide/sendTarget/sendTargetList.ajax")
public ResponseEntity<?> getGuideSendTargetListAjax(@ModelAttribute GuideSendTargetDto.Request.Search dto) {
// 총 게시물 수 조회
int totalCount = 0;
dto.setTotalCount(totalCount);
// 페이징 처리를 위한 설정
dto.setPagingYn("N");
// 리스트 조회
List<GuideSendTargetDto.Response.GuideSendTargetFlat> result = guideSendTargetService.findPreNoticeSendTarget(dto);
return ApiResponseUtil.successWithGrid(result, dto);
}
}

@ -0,0 +1,69 @@
package go.kr.project.biz.post.guide.sendTarget.dto;
import go.kr.project.domain.entity.CpAnswer;
import go.kr.project.domain.entity.CpMain;
import go.kr.project.domain.entity.CpOwner;
import go.kr.project.system.common.model.PagingVO;
import go.kr.project.vo.CpAnswerVO;
import go.kr.project.vo.CpMainVO;
import go.kr.project.vo.CpOwnerVO;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
public class GuideSendTargetDto {
public static class Request {
@Getter
@Setter
public static class Search extends PagingVO {
private String mmSggcode;
private String searchLawgb;
}
}
public static class Response {
@Getter
@Setter
public static class GuideSendTargetEntities {
private CpMain cpMain;
private CpAnswer cpAnswer;
private CpOwner cpOwner;
private String vlId;
}
@Getter
@Setter
@Builder
public static class GuideSendTarget {
private CpMainVO cpMain;
private CpAnswerVO cpAnswer;
private CpOwnerVO cpOwner;
private String vlId;
}
@Getter
@Setter
@Builder
public static class GuideSendTargetFlat {
private String mmDlgb;
private String asBbsNo;
private String asJsdate;
private String mmSgnm;
private String mmSgtel;
private String vlId;
private String mmDate;
private String mmCarno;
private String omName;
private String omNogb;
private String omJno;
private String mmSgpos;
private String mmCode;
}
}
}

@ -0,0 +1,57 @@
package go.kr.project.biz.post.guide.sendTarget.repository;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQueryFactory;
import go.kr.project.biz.post.guide.sendTarget.dto.GuideSendTargetDto;
import go.kr.project.vo.code.MmStateEnum;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
import java.util.List;
import static go.kr.project.domain.entity.QCpAnswer.cpAnswer;
import static go.kr.project.domain.entity.QCpInstruct.cpInstruct;
import static go.kr.project.domain.entity.QCpMain.cpMain;
import static go.kr.project.domain.entity.QCpOwner.cpOwner;
import static go.kr.project.domain.entity.QCpUser.cpUser;
import static go.kr.project.domain.entity.QCpViolation.cpViolation;
@Repository
@RequiredArgsConstructor
public class GuideSendTargetQueryDslRepository {
private final JPAQueryFactory queryFactory;
public List<GuideSendTargetDto.Response.GuideSendTargetEntities> findGuideSendTarget(GuideSendTargetDto.Request.Search dto) {
List<GuideSendTargetDto.Response.GuideSendTargetEntities> result = queryFactory
.select(
Projections.fields(
GuideSendTargetDto.Response.GuideSendTargetEntities.class,
cpMain,
cpAnswer,
cpOwner,
cpViolation.vlId
)
)
.from(cpMain)
.leftJoin(cpAnswer).on(cpMain.mmCode.eq(cpAnswer.asMmcode))
.leftJoin(cpInstruct).on(cpMain.mmCode.eq(cpInstruct.itMmcode))
.leftJoin(cpOwner).on(cpMain.mmOmcode.eq(cpOwner.omCode))
.innerJoin(cpViolation).on(
cpMain.mmLawgb.eq(cpViolation.id.vlCode),
cpMain.mmSggcode.eq(cpViolation.id.vlSggcode))
.where(
cpMain.mmState.eq(MmStateEnum.GUIDANCE.getCode()),
cpMain.mmLawgb.eq(dto.getSearchLawgb())
)
.orderBy(cpMain.mmCarno.asc(), cpMain.mmDate.asc(), cpMain.mmTime.asc())
.fetch();
return result;
}
}

@ -0,0 +1,9 @@
package go.kr.project.biz.post.guide.sendTarget.service;
import go.kr.project.biz.post.guide.sendTarget.dto.GuideSendTargetDto;
import java.util.List;
public interface GuideSendTargetService {
List<GuideSendTargetDto.Response.GuideSendTargetFlat> findPreNoticeSendTarget(GuideSendTargetDto.Request.Search dto);
}

@ -0,0 +1,57 @@
package go.kr.project.biz.post.guide.sendTarget.service.impl;
import go.kr.project.biz.post.guide.sendTarget.dto.GuideSendTargetDto;
import go.kr.project.biz.post.guide.sendTarget.repository.GuideSendTargetQueryDslRepository;
import go.kr.project.biz.post.guide.sendTarget.service.GuideSendTargetService;
import go.kr.project.vo.CpAnswerVO;
import go.kr.project.vo.CpMainVO;
import go.kr.project.vo.CpOwnerVO;
import go.kr.project.vo.code.MmDlgbEnum;
import go.kr.project.vo.mapper.EntityVoMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
@Service
@RequiredArgsConstructor
public class GuideSendTargetServiceImpl implements GuideSendTargetService {
private final EntityVoMapper mapper;
private final GuideSendTargetQueryDslRepository guideSendTargetQueryDslRepository;
@Override
public List<GuideSendTargetDto.Response.GuideSendTargetFlat> findPreNoticeSendTarget(GuideSendTargetDto.Request.Search dto) {
List<GuideSendTargetDto.Response.GuideSendTargetEntities> list = guideSendTargetQueryDslRepository.findGuideSendTarget(dto);
List<GuideSendTargetDto.Response.GuideSendTargetFlat> result =
list.stream()
.map(e -> {
CpMainVO cpMainVO = mapper.toCpMainVO(e.getCpMain());
CpAnswerVO cpAnswerVO = mapper.toCpAnswerVO(e.getCpAnswer());
CpOwnerVO cpOwnerVO = mapper.toCpOwnerVO(e.getCpOwner());
return GuideSendTargetDto.Response.GuideSendTargetFlat.builder()
// 평탄화 필드
.mmDlgb(MmDlgbEnum.getDescByCode(cpMainVO.getMmDlgb()))
.asBbsNo(cpMainVO.getMmBdcode())
.asJsdate(cpAnswerVO.getAsJsdate())
.mmSgnm(cpMainVO.getMmSgnm())
.mmSgtel(cpMainVO.getMmSgtel())
.vlId(e.getVlId())
.mmDate(cpMainVO.getMmDate())
.mmCarno(cpMainVO.getMmCarno())
.omName(cpOwnerVO.getOmName())
.omNogb(cpOwnerVO.getOmNOGb())
.omJno(cpOwnerVO.getOmJno())
.mmSgpos(cpMainVO.getMmSgpos())
.mmCode(cpMainVO.getMmCode())
.build();
})
.collect(Collectors.toList());
return result;
}
}

@ -3,7 +3,8 @@ package go.kr.project.biz.post.preNotice.status.controller;
import egovframework.constant.TilesConstants;
import egovframework.util.ApiResponseUtil;
import go.kr.project.biz.minwon.init.dto.MinwonInitDto;
import go.kr.project.biz.post.preNotice.status.service.StatusService;
import go.kr.project.biz.post.preNotice.status.dto.PreNoticeStatusDto;
import go.kr.project.biz.post.preNotice.status.service.PreNoticeStatusService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
@ -15,9 +16,9 @@ import java.util.List;
@Controller
@RequiredArgsConstructor
public class StatusController {
public class PreNoticeStatusController {
private final StatusService statusService;
private final PreNoticeStatusService preNoticeStatusService;
/**
@ -27,12 +28,12 @@ public class StatusController {
@GetMapping("/post/preNotice/status/status.do")
public String minwonInitView() {
return "preNoticeStatus" + TilesConstants.BASE;
return "biz/post/preNotice/status/preNoticeStatus" + TilesConstants.BASE;
}
@PostMapping("post/preNotice/status/status.ajax")
public ResponseEntity<?> getPreNoticeStatusListAjax(@ModelAttribute MinwonInitDto.Request.SearchMinwonInitList dto) {
public ResponseEntity<?> getPreNoticeStatusListAjax(@ModelAttribute PreNoticeStatusDto.Request.Search dto) {
// 총 게시물 수 조회
int totalCount = 0;
@ -42,7 +43,7 @@ public class StatusController {
dto.setPagingYn("N");
// 리스트 조회
List<MinwonInitDto.Response.InitAnswers> result = statusService.findPreNoticeStatus();
List<PreNoticeStatusDto.Response.DailyStatus> result = preNoticeStatusService.findPreNoticeStatus();
return ApiResponseUtil.successWithGrid(result, dto);
}

@ -0,0 +1,37 @@
package go.kr.project.biz.post.preNotice.status.dto;
import go.kr.project.system.common.model.PagingVO;
import lombok.Getter;
import lombok.Setter;
public class PreNoticeStatusDto {
public static class Request {
@Getter
@Setter
public static class Search extends PagingVO {
private String mmSggcode;
}
}
public static class Response {
@Getter
@Setter
public static class DailyStatus {
}
}
}

@ -0,0 +1,11 @@
package go.kr.project.biz.post.preNotice.status.service;
import go.kr.project.biz.minwon.init.dto.MinwonInitDto;
import go.kr.project.biz.post.preNotice.status.dto.PreNoticeStatusDto;
import java.util.List;
public interface PreNoticeStatusService {
List<PreNoticeStatusDto.Response.DailyStatus> findPreNoticeStatus();
}

@ -1,11 +0,0 @@
package go.kr.project.biz.post.preNotice.status.service;
import go.kr.project.biz.minwon.init.dto.MinwonInitDto;
import org.springframework.stereotype.Service;
import java.util.List;
public interface StatusService {
List<MinwonInitDto.Response.InitAnswers> findPreNoticeStatus();
}

@ -0,0 +1,26 @@
package go.kr.project.biz.post.preNotice.status.service.impl;
import go.kr.project.biz.post.preNotice.status.dto.PreNoticeStatusDto;
import go.kr.project.biz.post.preNotice.status.service.PreNoticeStatusService;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class PreNoticeStatusServiceImpl implements PreNoticeStatusService {
@Override
public List<PreNoticeStatusDto.Response.DailyStatus> findPreNoticeStatus() {
return null;
}
}

@ -1,16 +0,0 @@
package go.kr.project.biz.post.preNotice.status.service.impl;
import go.kr.project.biz.minwon.init.dto.MinwonInitDto;
import go.kr.project.biz.post.preNotice.status.service.StatusService;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class StatusServiceImpl implements StatusService {
@Override
public List<MinwonInitDto.Response.InitAnswers> findPreNoticeStatus() {
return null;
}
}

@ -1,4 +1,55 @@
package go.kr.project.vo.code;
import lombok.Getter;
import java.util.HashMap;
import java.util.Map;
@Getter
public enum OmIngbEnum {
MANUAL_INPUT("1", "수기입력"),
CARINFO_API("2", "차적망조회"),
RESIDENT_API("3", "주민망조회"),
RESIDENCE_REG("4", "거소지등록"),
CONVERSION_REG("5", "변환등록"),
FILE("6", "파일처리");
private String code;
private String desc;
OmIngbEnum(String code, String desc) {
this.code = code;
this.desc = desc;
}
private static final Map<String, OmIngbEnum> CODE_MAP = new HashMap<>();
private static final Map<String, OmIngbEnum> DESC_MAP = new HashMap<>();
static {
for (OmIngbEnum e : values()) {
CODE_MAP.put(e.code, e);
DESC_MAP.put(e.desc, e);
}
}
// code → desc
public static String getDescByCode(String code) {
OmIngbEnum e = CODE_MAP.get(code);
return e != null ? e.desc : null;
}
// desc → code
public static String getCodeByDesc(String desc) {
OmIngbEnum e = DESC_MAP.get(desc);
return e != null ? e.code : null;
}
// code → enum
public static OmIngbEnum fromCode(String code) {
return CODE_MAP.get(code);
}
}

@ -31,7 +31,7 @@
<div class="field-group">
<div class="lbl">처리일자</div>
<div class="fld">
<input type="text" id="desDate" name="desDate" class="input calender datepicker" />
<input type="text" id="itDate" name="cpInstruct" class="input calender datepicker" />
</div>
</div>
<div class="field-group empty"></div>
@ -39,7 +39,7 @@
</div>
</div>
<div class="disdoc-btn-area">
<button type="button" class="btn btn-light disdoc-btn" name="" id="guide">계도처리</button>
<button type="button" class="btn btn-light disdoc-btn" name="" id="guideSave">계도처리</button>
</div>
</div>
@ -63,12 +63,18 @@
},
updateGuide: () => {
const { cursor, mmCodes } = JSON.parse(localStorage.getItem("TOTAL_INFO_STATE"));
$.ajax({
url: "",
type: "post",
url: `/common/update/\${cursor}/83/state.ajax`,
type: "PUT",
data: JSON.stringify({
"itEtc" : $("#cpInstructAnswer").val() ,
"itDate": $("#itDate").val(),
}),
contentType: 'application/json',
success: function(response) {
alert("계도처리 성공")
//다이얼로그 하이드
@ -79,6 +85,11 @@
//로컬스토리지 mmCodes에 해당 mmCode 제거
//그리드는 어떻게 할꺼??
//1. 로우만 remove -> 페이징 괜찮나??
//2. 재조회 -> 하면 1페이지로 돌아감
},
error: function(xhr, status, error) {
@ -90,10 +101,26 @@
eventListener: () => {
$("#guide").on("click", () => {
// 처리사유 벨리데이션
$("#guideSave").on("click", () => {
//차적조회 확인
if(!CAR_INFO_STATE) {
alert("차량조회가 필요합니다.")
$("#guidance_dialog").dialog("close");
return false;
}
// 처리사유 확인
if($("#cpInstructAnswer").val() == null || $("#cpInstructAnswer").val() == '') {
alert("처리사유를 선택해주세요.")
return false;
}
// 날짜 벨리데이션
if (!validateDate("guideDate")) {
return false; // 여기서 클릭 핸들러 종료
}
// 업데이트
fnGuide.updateGuide();
})
@ -121,9 +148,9 @@
});
/* 오늘날짜 기본세팅 */
$('#desDate').datepicker('setDate', new Date());
$('#guideDate').datepicker('setDate', new Date());
fnGuide.eventListener();
});

@ -0,0 +1,201 @@
<%--
Created by IntelliJ IDEA.
User: kurt
Date: 2025. 12. 12.
Time: 오후 4:21
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="preNoticeWrap_dialog" style="display:none;">
<div class="left">
<div class="form-grid">
</div>
<div class="gs_booking">
<div class="row">
<div class="col-sm-12">
<div class="box_column">
<div class="containers">
<div id="grid"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="disdoc-btn-area">
<button type="button" class="btn btn-light disdoc-btn" name="" id="guideSave">묶음자료 생성</button>
</div>
</div>
<script type="text/javascript">
let PRE_NOTICE_WRAP_DIALOG_GRID = null;
let fnPreNoticeWrap = {
init: () => {
initGrid();
},
setCode: () => {
},
updateGuide: () => {
const { cursor, mmCodes } = JSON.parse(localStorage.getItem("TOTAL_INFO_STATE"));
$.ajax({
// url: `/common/update/\${cursor}/83/state.ajax`,
type: "PUT",
data: JSON.stringify({
"itEtc" : $("#cpInstructAnswer").val() ,
"itDate": $("#itDate").val(),
}),
contentType: 'application/json',
success: function(response) {
alert("계도처리 성공")
//다이얼로그 하이드
//네이게이팅 다음으로
//로컬스토리지 mmCodes에 해당 mmCode 제거
//그리드는 어떻게 할꺼??
//1. 로우만 remove -> 페이징 괜찮나??
//2. 재조회 -> 하면 1페이지로 돌아감
},
error: function(xhr, status, error) {
$("#result").text("서손처리 실패");
}
});
},
eventListener: () => {
}
}
/** tui-grid Set */
let preNoticeWrapInitGrid = () => {
const gridColumns = [
{header: '등록구분', name: 'mmDlgb', sortable: true, width: 100,},
{header: '목록번호', name: 'asBbsNo', sortable: true, width: 100,},
{header: '접수일', name: 'asJsdate', sortable: true, width: 100,},
{header: '신고자', name: 'mmSgnm', sortable: true, width: 100,},
{header: '담당자', name: 'mmSgtel', width: 100,},
{header: '위반내용', name: 'vlId', sortable: true, width: 100,},
{header: '위반일시', name: 'mmDate', sortable: true, width: 100,},
{header: '차량번호', name: 'mmCarno', sortable: true, width: 150,},
{header: '소유자', name: 'omName', width: 150,},
{header: '소유주구분', name: 'omNogb', width: 100,},
{header: '주민번호', name: 'omJno', width: 250,},
{header: '위반장소', name: 'mmSgpos', sortable: true, width: 150,},
{header: 'mmCode', name: 'mmCode', sortable: true, width: 150, align: 'center', hidden: true}
];
let gridDatasource = {
api: {
readData: {
url: '<c:url value="/post/preNotice/sendTarget/sendTargetList.ajax"/>',
method: 'POST',
contentType: 'application/x-www-form-urlencoded',
processData: true
}
},
initialRequest: false, //초기화시 조회
serializer: function (params) {
setSearchCond();
SEARCH_COND.perPage = params.perPage;
SEARCH_COND.page = params.page;
return $.param(SEARCH_COND);
}
}
let gridOptions = {
el: 'grid',
rowHeaders: ['checkbox'],
columns: gridColumns,
noData: "조회된 사전통보 대상이 없습니다.",
pageOptions: {
useClient: true, // 클라이언트 페이징 여부(false: 서버 페이징)
perPage: perPage,
},
};
PRE_NOTICE_WRAP_DIALOG_GRID = TuiGrid.of(gridOptions, gridDatasource, (res) => {
GRID.on("dblclick", (e) => {
var popUrl = '/total/info.do';
var popTitle = "TotalPopup";
var popOption = "width=1400px, height=900px, resizable=yes, scrollbars=yes, location=no, top=100px, left=100px";
// 1) localStorage에 저장
console.log(e)
let cursor = e.instance.getValue(e.rowKey, 'mmCode');
let mmCodes = e.instance.getData().map(row => row.mmCode);
const state = { cursor, mmCodes, savedAt: Date.now() };
localStorage.setItem('TOTAL_INFO_STATE', JSON.stringify(state));
// 2) 팝업이 없거나 닫혀 있으면 새로 열기
if (!TOTAL_POPUP || TOTAL_POPUP.closed) {
TOTAL_POPUP = window.open(popUrl, popTitle, popOption);
} else {
// 이미 떠 있으면 새로 안 만들고, 그 창에 포커스만 줌
TOTAL_POPUP.focus();
TOTAL_POPUP.TOTAL_INFO_POPUP_API.search();
}
});
});
};
$(function () {
/* 다이얼로그 설정 */
$("#preNoticeWrap_dialog").dialog({
autoOpen: false,
modal: true,
resizable: true,
// width: "auto",
width: 500,
maxHeight: 800,
show: { effect: "drop", direction: "left", duration: 200 },
hide: { effect: "drop", direction: "left", duration: 200 },
title: "사전통보 묶음자료(대장) 생성",
open: function () {
fnPreNoticeWrap.init();
}
});
/* 오늘날짜 기본세팅 */
$('#guideDate').datepicker('setDate', new Date());
fnPreNoticeWrap.eventListener();
});
</script>

@ -33,9 +33,9 @@
</div>
<div class="nav-group">
<button type="button" class="nav-btn" name="navigate" data-act="first" id="first">◀◀</button>
<button type="button" class="nav-btn" name="navigate" data-act="prev">◀</button>
<button type="button" class="nav-btn" name="navigate" data-act="next">▶</button>
<button type="button" class="nav-btn" name="navigate" data-act="last">▶▶</button>
<button type="button" class="nav-btn" name="navigate" data-act="prev" id="prev">◀</button>
<button type="button" class="nav-btn" name="navigate" data-act="next" id="next">▶</button>
<button type="button" class="nav-btn" name="navigate" data-act="last" id="last">▶▶</button>
</div>
</div>
@ -345,7 +345,7 @@
</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" />
<jsp:include page="/WEB-INF/views/biz/dialog/destructionDoc_dialog.jsp" />
<jsp:include page="/WEB-INF/views/biz/dialog/guidance_dialog.jsp" />
</div>
@ -564,13 +564,24 @@
console.log("!!!!!!!!!!!!!",CAR_INFO)
$.ajax({
url: `/common/update/\${cursor}/21/update.ajax`,
url: `/common/update/\${cursor}/21/state.ajax`,
type: "PUT",
data: JSON.stringify(CAR_INFO[0]),
contentType: "application/json",
success: function(response) {
alert("차적조회 완료 상태로 변경 완료.")
const updatedCodes = mmCodes.filter(code => code !== cursor);
localStorage.setItem("TOTAL_INFO_STATE", JSON.stringify({
cursor: null,
mmCodes: updatedCodes
}));
$("#next").trigger("click");
},
error: function(xhr, status, error) {
$("#result").text("수정 실패");
@ -658,15 +669,10 @@
return false;
}
// 오너 테이블 인서트
// 차량조회가 완료되었으면 스테이트 변경
fnBiz.carInfoUpdate(e);
})
}

@ -55,6 +55,18 @@
</li>
</ul>
</div>
<div class="state-tab-wrap">
<ul class="state-tabs">
<%-- <li data-state="FIN_BU" value="6">답변완료(부과)</li>--%>
<%-- <li data-state="FIN_GE" value="7">답변완료(계도)</li>--%>
<%-- <li data-state="FIN_ME" value="8">답변완료(미부과)</li>--%>
<%-- <li data-state="FIN_ADD" value="9">답변완료(수기)</li>--%>
<%-- <li data-state="FAIL" value="5">답변실패</li>--%>
<%-- <li data-state="INCOMP" value="fail">답변미대상</li>--%>
</ul>
</div>
<div class="gs_booking">
<div class="row">
<div class="col-sm-12">
@ -72,8 +84,9 @@
<script type="text/javascript">
let GRID = null;
let INIT_POPUP = null;
let TOTAL_POPUP = null;
let SEARCH_COND = {};
@ -86,12 +99,15 @@
let searchUseYn = $.trim(nvl($("#searchUseYn").val(), ""));
let searchStartDt = $.trim(nvl($("#searchStartDt").val(), ""));
let searchEndDt = $.trim(nvl($("#searchEndDt").val(), ""));
let searchLawgb = $(".state-tabs li.on").attr("value");
SEARCH_COND.searchCondition = searchCondition;
SEARCH_COND.searchKeyword = searchKeyword;
SEARCH_COND.searchUseYn = searchUseYn;
SEARCH_COND.searchStartDt = searchStartDt;
SEARCH_COND.searchEndDt = searchEndDt;
SEARCH_COND.searchLawgb = searchLawgb;
};
@ -99,8 +115,28 @@
init: () => {
initGrid();
fnBiz.setCode();
},
setCode: () => {
$.ajax({
url: "/common/code/find.ajax",
type: "GET",
contentType: 'application/json',
success: function(response) {
response.cpViolation.forEach((item) => {
$(".state-tabs").append('<li value="' + item.vlCode + '">' + item.vlId + '</li>');
});
initGrid();
$(".state-tabs li").first().addClass("on").trigger("click");
},
error: function(xhr, status, error) {
$("#result").text("조회 실패");
}
});
},
@ -159,6 +195,19 @@
TuiGrid.instance.readData(1);
});
// 상태 탭 클릭
$(".state-tabs").on("click", "li", function () {
$(".state-tabs li").removeClass("on");
$(this).addClass("on");
// const state = $(this).data('state') || '';
// $('#tabState').val(state);
SEARCH_COND = {};
TuiGrid.instance.readData(1);
});
}
}
@ -167,31 +216,30 @@
/** tui-grid Set */
let initGrid = () => {
const gridColumns = [
{header: '등록구분', name: 'mmDlgb', sortable: true, width: 50,},
{header: '목록번호', name: 'asBbsNo', sortable: true, width: 70,},
{header: '등록구분', name: 'mmDlgb', sortable: true, width: 100,},
{header: '목록번호', name: 'asBbsNo', sortable: true, width: 100,},
{header: '접수일', name: 'asJsdate', sortable: true, width: 100,},
{header: '신고자', name: 'mmSgnm', sortable: true, width: 100,},
{header: '담당자', name: 'mmSgtel', sortable: true, width: 100,},
{header: '전화번호', name: 'asTel', width: 150,},
{header: '접수일자', name: 'asJsdate', sortable: true, width: 70,},
{header: '처리기한', name: 'asLimitDt', sortable: true, width: 70,},
{header: '위반일자', name: 'mmDate', sortable: true, width: 150,},
{header: '첨부', name: 'mmImagegb', width: 150,},
{header: '사진갯수', name: 'mmImagecnt', width: 50,},
{header: '위반내용', name: 'mmSgcont', width: 250,},
{header: '접수번호', name: 'asJsno', sortable: true, width: 150,},
{header: '담당자', name: 'mmSgtel', width: 100,},
{header: '위반내용', name: 'vlId', sortable: true, width: 100,},
{header: '위반일시', name: 'mmDate', sortable: true, width: 100,},
{header: '차량번호', name: 'mmCarno', sortable: true, width: 150,},
{header: '소유자', name: 'omName', width: 150,},
{header: '소유주구분', name: 'omNogb', width: 100,},
{header: '주민번호', name: 'omJno', width: 250,},
{header: '위반장소', name: 'mmSgpos', sortable: true, width: 150,},
{header: 'mmCode', name: 'mmCode', sortable: true, width: 150, align: 'center', hidden: true}
];
let gridDatasource = {
api: {
readData: {
url: '<c:url value="/minwon/init/list.ajax"/>',
url: '<c:url value="/post/guide/sendTarget/sendTargetList.ajax"/>',
method: 'POST',
contentType: 'application/x-www-form-urlencoded',
processData: true
}
},
initialRequest: true, //초기화시 조회
initialRequest: false, //초기화시 조회
serializer: function (params) {
setSearchCond();
SEARCH_COND.perPage = params.perPage;
@ -204,7 +252,7 @@
el: 'grid',
rowHeaders: ['checkbox'],
columns: gridColumns,
noData: "처리 할 초기자료가 없습니다.",
noData: "조회된 사전통보 대상이 없습니다.",
pageOptions: {
useClient: true, // 클라이언트 페이징 여부(false: 서버 페이징)
perPage: perPage,
@ -214,8 +262,8 @@
GRID = TuiGrid.of(gridOptions, gridDatasource, (res) => {
GRID.on("dblclick", (e) => {
var popUrl = '/minwon/init/init_popup.do';
var popTitle = "initPopup";
var popUrl = '/total/info.do';
var popTitle = "TotalPopup";
var popOption = "width=1400px, height=900px, resizable=yes, scrollbars=yes, location=no, top=100px, left=100px";
// 1) localStorage에 저장
@ -227,12 +275,12 @@
localStorage.setItem('TOTAL_INFO_STATE', JSON.stringify(state));
// 2) 팝업이 없거나 닫혀 있으면 새로 열기
if (!INIT_POPUP || INIT_POPUP.closed) {
INIT_POPUP = window.open(popUrl, popTitle, popOption);
if (!TOTAL_POPUP || TOTAL_POPUP.closed) {
TOTAL_POPUP = window.open(popUrl, popTitle, popOption);
} else {
// 이미 떠 있으면 새로 안 만들고, 그 창에 포커스만 줌
INIT_POPUP.focus();
INIT_POPUP.INIT_POP_API.search();
TOTAL_POPUP.focus();
TOTAL_POPUP.TOTAL_INFO_POPUP_API.search();
}
});
});

@ -55,16 +55,20 @@
</li>
</ul>
</div>
<div class="state-tab-wrap">
<ul class="state-tabs">
<%-- <li data-state="FIN_BU" value="6">답변완료(부과)</li>--%>
<%-- <li data-state="FIN_GE" value="7">답변완료(계도)</li>--%>
<%-- <li data-state="FIN_ME" value="8">답변완료(미부과)</li>--%>
<%-- <li data-state="FIN_ADD" value="9">답변완료(수기)</li>--%>
<%-- <li data-state="FAIL" value="5">답변실패</li>--%>
<%-- <li data-state="INCOMP" value="fail">답변미대상</li>--%>
</ul>
<div class="div-flex-wrap-space-btw">
<div class="state-tab-wrap">
<ul class="state-tabs">
<%-- <li data-state="FIN_BU" value="6">답변완료(부과)</li>--%>
<%-- <li data-state="FIN_GE" value="7">답변완료(계도)</li>--%>
<%-- <li data-state="FIN_ME" value="8">답변완료(미부과)</li>--%>
<%-- <li data-state="FIN_ADD" value="9">답변완료(수기)</li>--%>
<%-- <li data-state="FAIL" value="5">답변실패</li>--%>
<%-- <li data-state="INCOMP" value="fail">답변미대상</li>--%>
</ul>
</div>
<div class="state-tab-wrap">
<button type="button" class="btn btn-light" id="wrap-pre-notice" value="">사전통보 묶음자료(대장) 생성</button>
</div>
</div>
<div class="gs_booking">
@ -80,6 +84,7 @@
</div>
</div>
</div>
<jsp:include page="/WEB-INF/views/biz/dialog/preNoticeWrap_dialog.jsp" />
<!-- /Main body -->
<script type="text/javascript">
@ -208,6 +213,10 @@
SEARCH_COND = {};
TuiGrid.instance.readData(1);
});
$("#wrap-pre-notice").on('click', ()=> {
$("#preNoticeWrap_dialog").dialog("open");
})
}
}

@ -168,24 +168,13 @@
let initGrid = () => {
const gridColumns = [
{header: '등록구분', name: 'mmDlgb', sortable: true, width: 50,},
{header: '목록번호', name: 'asBbsNo', sortable: true, width: 70,},
{header: '신고자', name: 'mmSgnm', sortable: true, width: 100,},
{header: '담당자', name: 'mmSgtel', sortable: true, width: 100,},
{header: '전화번호', name: 'asTel', width: 150,},
{header: '접수일자', name: 'asJsdate', sortable: true, width: 70,},
{header: '처리기한', name: 'asLimitDt', sortable: true, width: 70,},
{header: '위반일자', name: 'mmDate', sortable: true, width: 150,},
{header: '첨부', name: 'mmImagegb', width: 150,},
{header: '사진갯수', name: 'mmImagecnt', width: 50,},
{header: '위반내용', name: 'mmSgcont', width: 250,},
{header: '접수번호', name: 'asJsno', sortable: true, width: 150,},
{header: '차량번호', name: 'mmCarno', sortable: true, width: 150,},
{header: 'mmCode', name: 'mmCode', sortable: true, width: 150, align: 'center', hidden: true}
];
let gridDatasource = {
api: {
readData: {
url: '<c:url value="/minwon/init/list.ajax"/>',
url: '<c:url value=""/>',
method: 'POST',
contentType: 'application/x-www-form-urlencoded',
processData: true

@ -0,0 +1,16 @@
<%--
Created by IntelliJ IDEA.
User: kurt
Date: 2025. 12. 12.
Time: 오후 3:56
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
</body>
</html>

@ -41,6 +41,7 @@
<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' />">
<link rel="stylesheet" href="<c:url value='/css/jquery-ui.css' />">
<%--================== Main Scripts ======================--%>
@ -49,6 +50,7 @@
<script type="text/javascript" src="<c:url value='/js/bootstrap.bundle.min.js' />"></script>
<script type="text/javascript" src="<c:url value='/js/popper/1.16.1/popper.min.js' />"></script>
<script type="text/javascript" src="<c:url value='/js/bootstrap-datepicker.min.js' />"></script>
<script type="text/javascript" src="<c:url value='/js/jquery-ui.min.js' />"></script>
<!-- Plugins -->
<%--<script type="text/javascript" src="<c:url value='/js/jquery.treeview.js' />"></script>--%>
<script type="text/javascript" src="<c:url value='/plugins/simplebar/simplebar.min.js' />"></script>

@ -54,4 +54,10 @@
/** dayanswer end */
/** dayanswer end */
.div-flex-wrap-space-btw {
display: flex;
justify-content: space-between;
}

@ -481,3 +481,41 @@ var buildUrlWithParamCondAndId = function(paramCond, idName, idValue, baseUrl) {
return addUrlParam(idName, idValue, urlWithParams);
};
/**
* 날짜 벨리데이션
* 1. null 또는 빈값 체크
* 2. 포맷 체크 (YYYY-MM-DD)
* 3. 날짜 형식 체크 ( 맥스값)
* 4. 미래 날짜 방지
* */
let validateDate = function(inputId) {
const value = $(`#${inputId}`).val()?.trim();
if (!value) {
alert("처리일자를 선택해주세요.");
return false;
}
const dateRegex = /^\d{4}-\d{2}-\d{2}$/;
if (!dateRegex.test(value)) {
alert("날짜 형식이 올바르지 않습니다. (예: 2025-12-12)");
return false;
}
const date = new Date(value + "T00:00:00");
if (isNaN(date.getTime())) {
alert("유효하지 않은 날짜입니다.");
return false;
}
const today = new Date();
today.setHours(0, 0, 0, 0);
if (date > today) {
alert("미래 일자는 선택할 수 없습니다.");
return false;
}
return true;
}

@ -4,6 +4,8 @@ import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import go.kr.project.vo.code.MmStateEnum;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
@ -160,6 +162,10 @@ public class CpMain {
private String mmTransmitTeam;
public void changeMmState(MmStateEnum mmStateEnum) {
this.mmState = mmStateEnum.getCode();
}
public void changeMmStateAfterSunap() {
String newState;
switch (this.mmState) {

@ -4,6 +4,8 @@ import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import go.kr.project.vo.code.MmStateEnum;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
@ -192,15 +194,34 @@ public class CpMain {
private String mmCarname;
public void changeMmState(MmStateEnum mmStateEnum) {
this.mmState = mmStateEnum.getCode();
}
public void changeMmStateAfterSunap() {
this.mmState = switch (this.mmState) {
case "41" -> "71";
case "51" -> "72";
case "52" -> "73";
case "53" -> "74";
case "54", "55" -> "75";
default -> "71";
};
String newState;
switch (this.mmState) {
case "41":
newState = "71";
break;
case "51":
newState = "72";
break;
case "52":
newState = "73";
break;
case "53":
newState = "74";
break;
case "54":
case "55":
newState = "75";
break;
default:
newState = "71";
break;
}
this.mmState = newState;
}
}

@ -0,0 +1,7 @@
package go.kr.project.domain.repo.cp;
import go.kr.project.domain.entity.CpInstruct;
import org.springframework.data.jpa.repository.JpaRepository;
public interface CpInstructRepository extends JpaRepository<CpInstruct, String> {
}

@ -0,0 +1,8 @@
package go.kr.project.domain.repo.cp;
import go.kr.project.domain.entity.CpInstruct;
import org.springframework.data.jpa.repository.JpaRepository;
;
public interface CpInstructRepository extends JpaRepository<CpInstruct, String> {
}
Loading…
Cancel
Save