diff --git a/pom.xml b/pom.xml index 04973ca1..dae061ad 100644 --- a/pom.xml +++ b/pom.xml @@ -140,8 +140,8 @@ 23.04.01-SNAPSHOT - - - \ No newline at end of file diff --git a/src/main/java/cokr/xit/fims/FimsConf.java b/src/main/java/cokr/xit/fims/FimsConf.java index ab8f1288..7be979b5 100644 --- a/src/main/java/cokr/xit/fims/FimsConf.java +++ b/src/main/java/cokr/xit/fims/FimsConf.java @@ -44,7 +44,8 @@ public class FimsConf extends AbstractComponent { private String violationFileDir; // 단속파일 디렉토리 private String txtCharset; - private boolean disableLvis; + private boolean disableLvis; // 차적정보 연계 사용하지 않음 + private boolean lookupEqpPlc; // cctv연계파일에서 단속장소 설정 시 단속장비/장소 테이블 참조 여부 public String violationFileDir(String dir) { String root = blankIfEmpty(violationFileDir).replace("\\", "/"); diff --git a/src/main/java/cokr/xit/fims/Vhrno.java b/src/main/java/cokr/xit/fims/Vhrno.java index 51b872dc..8a1a3368 100644 --- a/src/main/java/cokr/xit/fims/Vhrno.java +++ b/src/main/java/cokr/xit/fims/Vhrno.java @@ -191,14 +191,21 @@ public class Vhrno extends AbstractObject { public String toString() { return fullNumber; } - +/* public static void main(String[] args) { Vhrno vhrno = new Vhrno(); String str = "25오1778"; - System.out.println(vhrno.setFullNumber(str).describe()); - System.out.println(vhrno.setFullNumber(str = "123가4567").describe()); - System.out.println(vhrno.setFullNumber(str = "서울바9867").describe()); - System.out.println(vhrno.setFullNumber(str = "경기32더5678").describe()); - System.out.println(vhrno.setFullNumber(str = "외교001-001").describe()); + System.out.println(vhrno.setFullNumber(str).describe() + ", target: " + (Vhrno.VAN.equals(vhrno.getVehicleType()) && vhrno.isCommercial())); + System.out.println(vhrno.setFullNumber(str = "123가4567").describe() + ", target: " + (Vhrno.VAN.equals(vhrno.getVehicleType()) && vhrno.isCommercial())); + System.out.println(vhrno.setFullNumber(str = "서울바9867").describe() + ", target: " + (Vhrno.VAN.equals(vhrno.getVehicleType()) && vhrno.isCommercial())); + System.out.println(vhrno.setFullNumber(str = "경기32더5678").describe() + ", target: " + (Vhrno.VAN.equals(vhrno.getVehicleType()) && vhrno.isCommercial())); + System.out.println(vhrno.setFullNumber(str = "외교001-001").describe() + ", target: " + (Vhrno.VAN.equals(vhrno.getVehicleType()) && vhrno.isCommercial())); + System.out.println(vhrno.setFullNumber(str = "71버3581").describe() + ", target: " + (Vhrno.VAN.equals(vhrno.getVehicleType()) && vhrno.isCommercial())); + System.out.println(vhrno.setFullNumber(str = "72수4545").describe() + ", target: " + (Vhrno.VAN.equals(vhrno.getVehicleType()) && vhrno.isCommercial())); + System.out.println(vhrno.setFullNumber(str = "경기70사7668").describe() + ", target: " + (Vhrno.VAN.equals(vhrno.getVehicleType()) && vhrno.isCommercial())); + System.out.println(vhrno.setFullNumber(str = "경기70사3015").describe() + ", target: " + (Vhrno.VAN.equals(vhrno.getVehicleType()) && vhrno.isCommercial())); + System.out.println(vhrno.setFullNumber(str = "경기76아9252").describe() + ", target: " + (Vhrno.VAN.equals(vhrno.getVehicleType()) && vhrno.isCommercial())); + System.out.println(vhrno.setFullNumber(str = "서울70아1477").describe() + ", target: " + (Vhrno.VAN.equals(vhrno.getVehicleType()) && vhrno.isCommercial())); } +*/ } \ No newline at end of file diff --git a/src/main/java/cokr/xit/fims/crdn/Crdn.java b/src/main/java/cokr/xit/fims/crdn/Crdn.java index 47cbc586..4c7f8927 100644 --- a/src/main/java/cokr/xit/fims/crdn/Crdn.java +++ b/src/main/java/cokr/xit/fims/crdn/Crdn.java @@ -48,6 +48,8 @@ public class Crdn extends AbstractEntity { private String crdnTm; /** 차량번호 */ private String vhrno; + /** 장비코드 */ + private String eqpCd; /** 단속 법정동 명 */ private String crdnStdgNm; /** 단속 도로 명 */ diff --git a/src/main/java/cokr/xit/fims/crdn/service/bean/ImportServiceBean.java b/src/main/java/cokr/xit/fims/crdn/service/bean/ImportServiceBean.java index 1ca04934..719cf6a2 100644 --- a/src/main/java/cokr/xit/fims/crdn/service/bean/ImportServiceBean.java +++ b/src/main/java/cokr/xit/fims/crdn/service/bean/ImportServiceBean.java @@ -3,6 +3,7 @@ package cokr.xit.fims.crdn.service.bean; import java.io.File; import java.math.BigInteger; import java.util.ArrayList; +import java.util.Collections; import java.util.Comparator; import java.util.LinkedHashMap; import java.util.List; @@ -18,6 +19,7 @@ import cokr.xit.base.file.FileInfo; import cokr.xit.base.file.service.bean.FileBean; import cokr.xit.base.file.web.FileInfoFactory; import cokr.xit.base.user.dao.UserMapper; +import cokr.xit.fims.FimsConf; import cokr.xit.fims.cmmn.CmmnUtil; import cokr.xit.fims.crdn.Crdn; import cokr.xit.fims.crdn.Team; @@ -106,12 +108,19 @@ public class ImportServiceBean extends AbstractServiceBean implements ImportServ divided.removeAll(errors); // 오류 항목 제외 resp.set("normal", divided.size()) .set("malformed", errors.size()); - log().debug("Before creating Crdns: {}", resp); + + setCrdnPlc(divided); + + List invalidPlace = divided.stream() + .filter(info -> "invalid".equals(info.get("status"))) + .toList(); + divided.removeAll(invalidPlace); // 잘못된 단속장소 제외 + resp.set("invalidPlace", invalidPlace.size()); Map crdnMap = divided.stream() .map(dividedInfo -> { - DataObject result = new DataObject(); DataObject metaInfo = (DataObject)dividedInfo.get("metaInfo"); + DataObject result = new DataObject(); List imageList = CmmnUtil.getDataObjectListFromMap(dividedInfo,"imageInfo"); DataObject bgngData = (DataObject)dividedInfo.get("bgngData"); @@ -144,6 +153,7 @@ public class ImportServiceBean extends AbstractServiceBean implements ImportServ crdn.setGpsX(metaInfo.string("GPS_X")); crdn.setGpsY(metaInfo.string("GPS_Y")); + crdn.setEqpCd(metaInfo.string("EQPMNT_CD")); crdn.setCrdnPlc(metaInfo.string("CRDN_PLC")); crdn.setCrdnRoadNm(metaInfo.string("CRDN_ROAD_NM")); crdn.setCrdnStdgNm(metaInfo.string("CRDN_STDG_NM")); @@ -310,6 +320,38 @@ public class ImportServiceBean extends AbstractServiceBean implements ImportServ .collect(Collectors.toCollection(ArrayList::new)); } + private void setCrdnPlc(List divided) { + if (!FimsConf.get().isLookupEqpPlc()) return; + + List metaInfoList = divided.stream() + .map(info -> (DataObject)info.get("metaInfo")) + .toList(); + if (metaInfoList.isEmpty()) return; + + List eqpPlcList = Collections.emptyList(); // TODO: EquipmentPlace 완료되면 교체할 것 + if (eqpPlcList.isEmpty()) return; + + //키 = 장비코드-장소이름 + Map eqpPlcMap = eqpPlcList.stream().collect(Collectors.toMap( + info -> info.get("EQP_CD") + "-" + info.get("PLC_NM"), + info -> info + )); + + for (DataObject metaInfo: metaInfoList) { + String key = metaInfo.get("EQPMNT_CD") + "-" + metaInfo.get("CRDN_PLC"); + DataObject eqpPlc = eqpPlcMap.get(key); + if (eqpPlc == null) { + metaInfo.set("status", "invalid"); + continue; + } + + metaInfo + .set("CRDN_STDG_NM", eqpPlc.get("STDG_NM")) + .set("CRDN_ROAD_NM", eqpPlcMap.get("ROAD_NM")) + .set("CRDN_PLC", eqpPlcMap.get("PLC")); + } + } + /**단속이미지정보 목록 내에서 최초단속자료와 최종단속자료를 반환한다. 단속일시 정보가 없을 경우 null을 반환한다.
* @param imageDataList 단속이미지정보 목록 * @return 최초단속자료, 최종단속자료 diff --git a/src/main/java/cokr/xit/fims/crdn/web/Crdn06Controller.java b/src/main/java/cokr/xit/fims/crdn/web/Crdn06Controller.java index 5a8efebe..a0edff55 100644 --- a/src/main/java/cokr/xit/fims/crdn/web/Crdn06Controller.java +++ b/src/main/java/cokr/xit/fims/crdn/web/Crdn06Controller.java @@ -5,6 +5,7 @@ import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; @@ -99,7 +100,7 @@ public class Crdn06Controller extends ApplicationController { ModelAndView mav = new ModelAndView("fims/crdn/crdn06010-main") .addObject("pageName", "crdn06010" + ifEmpty(openType, ()-> "")); - if(!isEmpty(taskSeCd)) + if (!isEmpty(taskSeCd)) mav.addObject("taskSeCd", taskSeCd); mav.addObject("FIM003List", commonCodes.get("FIM003")) .addObject("FIM005List", commonCodes.get("FIM005")) @@ -120,9 +121,10 @@ public class Crdn06Controller extends ApplicationController { public ModelAndView getCrackdownList(CrdnQuery query) { setFetchSize(query.setSggCd(currentUser().getOrgID())); - if("xls".equals(query.getDownload())) { + if ("xls".equals(query.getDownload())) { List cellDefs = fromJson(query.getCellDefs(), CellDef.listType()); - if("Y".equals(query.getIncludePhoto())) { + boolean includePhoto = "Y".equals(query.getIncludePhoto()); + if (includePhoto) { cellDefs.add((new CellDef()).setLabel("사진1").setWidth(18).setField("CRDN_PHOTO_PATH1")); cellDefs.add((new CellDef()).setLabel("사진2").setWidth(18).setField("CRDN_PHOTO_PATH2")); } @@ -137,45 +139,61 @@ public class Crdn06Controller extends ApplicationController { CellStyle dateDT = format.yyyy_mm_dd_hh_mm_ss(); Map valueMap = new HashMap(); - for(CellDef def : cellDefs) { - switch(def.getLabel()) { - case "자료출처"->{ valueMap.put("자료출처", format.of("CRDN_INPT_SE_NM").style(center)); } - case "차량번호"->{ valueMap.put("차량번호", left); } - case "위반일시"->{ valueMap.put("위반일시", FormatMaker.yyyy_mm_dd_hh_mm_ss(format,"CRDN_YMD_TM").style(dateDT)); } - case "단속장소"->{ valueMap.put("단속장소", left); } - case "사진건수"->{ valueMap.put("사진건수", center); } - case "스티커번호"->{ valueMap.put("스티커번호", left); } - case "장애차량확인"->{ valueMap.put("장애차량확인", format.of("PRK_PSBLTY_RSLT_NM").style(center)); } - case "처리상태"->{ valueMap.put("처리상태", format.of("CRDN_STTS_NM").style(center)); } - case "제외사유"->{ valueMap.put("제외사유", format.of("LEVY_EXCL_RSN_NM").style(center)); } - case "제외처리일자"->{ valueMap.put("제외처리일자", FormatMaker.yyyy_mm_dd(format,"LEVY_EXCL_YMD").style(dateYMD)); } - case "제외내역"->{ valueMap.put("제외내역", left); } - case "사진1"->{ valueMap.put("사진1", FormatMaker.photoCellForApproval(format, comment, "CRDN_PHOTO_PATH1")); } - case "사진2"->{ valueMap.put("사진2", FormatMaker.photoCellForApproval(format, comment, "CRDN_PHOTO_PATH2")); } - } + for (CellDef def : cellDefs) { + String label = def.getLabel(); + Object obj = switch (label) { + case "자료출처" -> format.of("CRDN_INPT_SE_NM").style(center); + case "차량번호" -> left; + case "위반일시" -> FormatMaker.yyyy_mm_dd_hh_mm_ss(format,"CRDN_YMD_TM").style(dateDT); + case "단속장소" -> left; + case "사진건수" -> center; + case "스티커번호" -> left; + case "장애차량확인" -> format.of("PRK_PSBLTY_RSLT_NM").style(center); + case "상태" -> format.of("CRDN_STTS_NM").style(center); + case "제외사유" -> format.of("LEVY_EXCL_RSN_NM").style(center); + case "제외처리일자" -> FormatMaker.yyyy_mm_dd(format,"LEVY_EXCL_YMD").style(dateYMD); + case "제외내역" -> left; + case "사진1" -> FormatMaker.photoCellForApproval(format, comment, "CRDN_PHOTO_PATH1"); + case "사진2" -> FormatMaker.photoCellForApproval(format, comment, "CRDN_PHOTO_PATH2"); + default -> null; + }; + if (obj != null) + valueMap.put(label, obj); } CellDef.setValues(cellDefs, valueMap); List list = crdnService.getCrackdownList(query.setFetchSize(0)); - if(ifEmpty(query.getIncludePhoto(), () -> "").equals("Y")) { - for(DataObject crdn : list) { - String crdnId = crdn.string("CRDN_ID"); - FileQuery fileQuery = new FileQuery(); - fileQuery.setInfoType(Crdn.INF_TYPE); - fileQuery.setInfoKeys(crdnId); - List fileInfoList = fileBean.getFileList(fileQuery); - - if(fileInfoList != null && fileInfoList.size() > 0) { - for(int j=0; (j < fileInfoList.size()) && (j < 2); j++) { - crdn.set("CRDN_PHOTO_PATH"+(j+1), fileInfoList.get(j).string("FILE_PATH")); - } + if (includePhoto) { + Map> fileInfoMap = fileBean.getFilesOf( + Crdn.INF_TYPE, + list.stream().map(info -> info.string("CRDN_ID")).toList().toArray(new String[list.size()]) + ).stream().collect( + Collectors.groupingBy(info -> info.getInfoKey()) + ); + + for (DataObject crdn : list) { + List fileInfoList = fileInfoMap.get(crdn.get("CRDN_ID")); + for (int j = 0; (j < fileInfoList.size()) && (j < 2); j++) { + crdn.set("CRDN_PHOTO_PATH"+(j+1), fileInfoList.get(j).getPath()); } } } - xlsx.cell(0, 0).value("단속자료 목록").value(center).merge(0, cellDefs.size()-1); - xlsx.cell(3, 0).rowValues(CellDef.header(cellDefs, () -> StyleMaker.headerStyle(xlsx))); - xlsx.cell(4, 0).values(list, CellDef.values(cellDefs.stream().map(i -> {if(i.getValue() instanceof Format) {i.setField(null);}; return i;}).toList())); + xlsx.cell(0, 0).value("단속자료 목록").value(center).merge(0, cellDefs.size()-1) + .cell(3, 0).rowValues(CellDef.header(cellDefs, () -> StyleMaker.headerStyle(xlsx))) + .cell(4, 0).values( + list, + CellDef.values( + cellDefs.stream() + .map(def -> { + if (def.getValue() instanceof Format) { + def.setField(null); + }; + return def; + }) + .toList() + ) + ); return new ModelAndView("downloadView") .addObject("download", xlsx.getDownloadable().setFilename("단속자료 목록.xlsx")) @@ -247,8 +265,8 @@ public class Crdn06Controller extends ApplicationController { String rtnMsg = crdnService.removeCrackdownPayer(crdn); return new ModelAndView("jsonView") - .addObject("saved", rtnMsg.contains("[S]")) - .addObject("rtnMsg", rtnMsg); + .addObject("saved", rtnMsg.contains("[S]")) + .addObject("rtnMsg", rtnMsg); } /**지정한 조회조건으로 단속 건수를 반환한다. @@ -374,7 +392,7 @@ public class Crdn06Controller extends ApplicationController { @PostMapping(name= "단속 사진 추가", value = "/insertCrdnImageFile.do") public ModelAndView insertCrdnImageFile(String crdnId, int atchFileCnt, MultipartFile[] newFileList) { String retMessage = "[F] "; - if(newFileList == null || newFileList.length == 0 || newFileList[0] == null || newFileList[0].isEmpty()) + if (newFileList == null || newFileList.length == 0 || newFileList[0] == null || newFileList[0].isEmpty()) throw new RuntimeException("파일 업로드 오류"); Relation relation = new Relation().setInfoType(Crdn.INF_TYPE).setInfoKey(crdnId); @@ -383,7 +401,7 @@ public class Crdn06Controller extends ApplicationController { List> processList = new ArrayList<>(); int newFileSort = 999; - for(FileInfo newFileInfo : newFileInfoList) { + for (FileInfo newFileInfo : newFileInfoList) { newFileInfo.setSortOrder(newFileSort++); processList.add(Map.of("process", "insert", "obj", newFileInfo)); } @@ -401,7 +419,7 @@ public class Crdn06Controller extends ApplicationController { @PostMapping(name= "단속 사진 수정", value = "/updateCrdnImageFile.do") public ModelAndView updateCrdnImageFile(String crdnId, int atchFileCnt, String beforeKey, int beforeOrder, MultipartFile modifyFile) { - if(isEmpty(modifyFile)) + if (isEmpty(modifyFile)) throw new RuntimeException("파일 업로드 오류"); Relation relation = new Relation().setInfoType(Crdn.INF_TYPE).setInfoKey(crdnId); @@ -424,11 +442,11 @@ public class Crdn06Controller extends ApplicationController { @PostMapping(name= "단속 사진 삭제", value = "/deleteCrdnImageFile.do") public ModelAndView deleteCrdnImageFile(String crdnId, int atchFileCnt, String[] deleteKeys) { - if(deleteKeys == null || deleteKeys.length == 0 || deleteKeys[0] == null || deleteKeys[0].isEmpty()) + if (deleteKeys == null || deleteKeys.length == 0 || deleteKeys[0] == null || deleteKeys[0].isEmpty()) throw new RuntimeException("파일 삭제 오류"); List> processList = new ArrayList<>(); - for(String deleteKey : deleteKeys) { + for (String deleteKey : deleteKeys) { processList.add(Map.of("process", "delete", "key", deleteKey)); } @@ -444,11 +462,11 @@ public class Crdn06Controller extends ApplicationController { @PostMapping(name= "단속 사진 순서 변경", value = "/changeOrderCrdnImageFile.do") public ModelAndView changeOrderCrdnImageFile(String crdnId, int atchFileCnt, String[] orderedKeys) { - if(orderedKeys == null || orderedKeys.length == 0 || orderedKeys[0] == null || orderedKeys[0].isEmpty()) + if (orderedKeys == null || orderedKeys.length == 0 || orderedKeys[0] == null || orderedKeys[0].isEmpty()) throw new RuntimeException("파일 순서 변경 오류"); List> processList = new ArrayList<>(); - for(String orderedKey : orderedKeys) { + for (String orderedKey : orderedKeys) { processList.add(Map.of("process", "order", "key", orderedKey)); } @@ -469,13 +487,13 @@ public class Crdn06Controller extends ApplicationController { //파일 목록 List fileInfoList = fileService.getFileList(req); - for(DataObject fileInfo : fileInfoList) { + for (DataObject fileInfo : fileInfoList) { List mosaicInfos = mediaBean.getMosaicList(fileInfo.string("FILE_ID")); - if(mosaicInfos != null) { + if (mosaicInfos != null) { String mosaic = ""; - for(int i=0; i < mosaicInfos.size(); i++) { + for (int i = 0; i < mosaicInfos.size(); i++) { DataObject mosaicInfo = mosaicInfos.get(i); - if(i != 0) { + if (i != 0) { mosaic += "|"; } mosaic += mosaicInfo.string("X_AXS") @@ -490,15 +508,15 @@ public class Crdn06Controller extends ApplicationController { } //민원 동영상파일 첨부 여부 String cvlcptVideoExistYn = "N"; - if(infoType.equals(Crdn.INF_TYPE) && singleKey) { + if (infoType.equals(Crdn.INF_TYPE) && singleKey) { DataObject dataObject = crdnInfoMapper.selectCrdnInfo(req.getInfoKeys().get(0)); String linkTblNm = dataObject.string("LINK_TBL_NM"); - if(!linkTblNm.equals("")) { //민원연계자료 + if (!linkTblNm.equals("")) { //민원연계자료 FileQuery cvlcptFileQuery = new FileQuery(); - if(linkTblNm.equals("TB_ESB_INTERFACE")) { + if (linkTblNm.equals("TB_ESB_INTERFACE")) { cvlcptFileQuery.setInfoType("010"); - } else if(linkTblNm.equals("TB_SAEOL_CVLCPT_DTL")) { + } else if (linkTblNm.equals("TB_SAEOL_CVLCPT_DTL")) { cvlcptFileQuery.setInfoType("020"); } else { throw new RuntimeException("파일 조회 중 오류가 발생하였습니다."); @@ -506,10 +524,10 @@ public class Crdn06Controller extends ApplicationController { cvlcptFileQuery.setInfoKeys(dataObject.string("LINK_ID")); List linkFileList = fileBean.getFileList(cvlcptFileQuery); - if(linkFileList != null && !linkFileList.isEmpty()) { - for(int i=0; i < linkFileList.size(); i++) { + if (linkFileList != null && !linkFileList.isEmpty()) { + for (int i = 0; i < linkFileList.size(); i++) { String mimeType = linkFileList.get(i).string("MIME_TYPE"); - if(Arrays.asList(Sprt.VIDEO_MIME_TYPE).contains(mimeType)) { + if (Arrays.asList(Sprt.VIDEO_MIME_TYPE).contains(mimeType)) { cvlcptVideoExistYn = "Y"; } } diff --git a/src/main/resources/sql/mapper/fims/crdn/crdn-inst-mapper.xml b/src/main/resources/sql/mapper/fims/crdn/crdn-inst-mapper.xml index 33a6f8c3..03a078ff 100644 --- a/src/main/resources/sql/mapper/fims/crdn/crdn-inst-mapper.xml +++ b/src/main/resources/sql/mapper/fims/crdn/crdn-inst-mapper.xml @@ -133,6 +133,7 @@ INSERT INTO TB_CRDN_ADI ( , OVTM_YN , OVTM_PRTTN_YN , TEAM_ID + , EQP_CD , DEL_YN , REG_DT , RGTR @@ -159,6 +160,7 @@ INSERT INTO TB_CRDN_ADI ( , IFNULL(#{ovtmYn},'N') , 'N' , #{teamId} + , #{eqpCd} , 'N' , #{createdAt} , #{createdBy}