diff --git a/src/main/java/cokr/xit/fims/cmmn/CmmnQuery.java b/src/main/java/cokr/xit/fims/cmmn/CmmnQuery.java index 9a3d9090..28bc4dc2 100644 --- a/src/main/java/cokr/xit/fims/cmmn/CmmnQuery.java +++ b/src/main/java/cokr/xit/fims/cmmn/CmmnQuery.java @@ -222,4 +222,4 @@ public class CmmnQuery extends QueryRequest { return self(); } -} +} \ 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 fada3a6b..d2c43f6b 100644 --- a/src/main/java/cokr/xit/fims/crdn/Crdn.java +++ b/src/main/java/cokr/xit/fims/crdn/Crdn.java @@ -181,6 +181,15 @@ public class Crdn extends AbstractEntity { private List attachments; + public void clearAttachments() { + if (attachments != null) { + for (FileInfo attachment: attachments) + attachment.close(); + attachments.clear(); + } + attachments = null; + } + public static final String location(Object obj) { if (Assert.isEmpty(obj)) return ""; diff --git a/src/main/java/cokr/xit/fims/crdn/service/bean/CrdnBean.java b/src/main/java/cokr/xit/fims/crdn/service/bean/CrdnBean.java index 09037402..e9987086 100644 --- a/src/main/java/cokr/xit/fims/crdn/service/bean/CrdnBean.java +++ b/src/main/java/cokr/xit/fims/crdn/service/bean/CrdnBean.java @@ -1,8 +1,6 @@ package cokr.xit.fims.crdn.service.bean; import java.io.File; -import java.nio.file.Files; -import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; @@ -10,7 +8,6 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.stream.Stream; import javax.annotation.Resource; @@ -18,7 +15,6 @@ import org.springframework.stereotype.Component; import cokr.xit.base.file.FileInfo; import cokr.xit.base.file.service.bean.FileBean; -import cokr.xit.fims.cmmn.CmmnUtil; import cokr.xit.fims.cmmn.CrdnPayerAddrHstry; import cokr.xit.fims.cmmn.CrdnSttsHstry; import cokr.xit.fims.cmmn.service.bean.CrdnPayerAddrHstryBean; @@ -66,14 +62,16 @@ public class CrdnBean extends AbstractBean { TaskProcessor taskProcessor = TaskProcessor.get(); List duplicates = taskProcessor.getDuplicates(crdns), // 중복 단속목록 distincts = crdns.stream().filter(crdn -> !duplicates.contains(crdn)).toList(); // 중복되지 않는 단속목록 - ArrayList result = new ArrayList<>(); - duplicates.forEach(crdn -> result.add( - new DataProc() - .setTarget(crdn) - .setSuccess(false) - .setInfo("reason", "duplicate") - )); + + for (Crdn crdn: duplicates) { + result.add( + new DataProc() + .setTarget(crdn) + .setSuccess(false) + .setInfo("reason", "duplicate") + ); + } if (distincts.isEmpty()) return result; @@ -152,7 +150,12 @@ public class CrdnBean extends AbstractBean { DataProc dataProc = new DataProc().setTarget(crdn); String ersrRegYmd = crdn.getErsrRegYmd(); if (!isEmpty(ersrRegYmd)) // 말소차량 - dataProc.setInfo("erased", new DataObject().set("vhrno", crdn.getVhrno()).set("date", DataFormat.yyyy_mm_dd(ersrRegYmd))); + dataProc.setInfo( + "erased", + new DataObject() + .set("vhrno", crdn.getVhrno()) + .set("date", DataFormat.yyyy_mm_dd(ersrRegYmd)) + ); result.add(dataProc); } @@ -426,20 +429,9 @@ public class CrdnBean extends AbstractBean { * @return 저장 여부 */ public boolean removeEquipmentLinkFile(String workPath, String fileName) { - try (Stream walk = Files.walk(Paths.get(workPath));) { - List deleteFilePaths = walk.filter(Files::isRegularFile) - .filter(p -> p.toFile().getName().equalsIgnoreCase(fileName)) - .map(item -> item.toFile().getPath()) - .toList(); - - boolean saved = false; - for (String deleteFilePath : deleteFilePaths) - saved = new File(deleteFilePath).delete(); - - //빈 디렉토리 삭제 - CmmnUtil.deleteEmptyDir(new File(workPath), false); - - return saved; + try { + File file = Paths.get(workPath, fileName).toFile(); + return file.exists() && file.delete(); } catch (Exception e) { throw runtimeException(e); } 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 acd9115b..1ca04934 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 @@ -99,10 +99,13 @@ public class ImportServiceBean extends AbstractServiceBean implements ImportServ List divided = divideFiles(fileList); resp.set("divided", divided.size()); - List errors = divided.stream().filter(info -> info.get("metaInfo") == null).toList(); + List errors = divided.stream() + .filter(info -> info.get("metaInfo") == null) + .distinct() + .toList(); divided.removeAll(errors); // 오류 항목 제외 resp.set("normal", divided.size()) - .set("malformed", errors.size()); + .set("malformed", errors.size()); log().debug("Before creating Crdns: {}", resp); Map crdnMap = divided.stream() @@ -185,14 +188,18 @@ public class ImportServiceBean extends AbstractServiceBean implements ImportServ //3.등록 List dataProcs = crdnBean.create(crdns, excludeExempted); LinkedHashMap> fileMap = new LinkedHashMap<>(); - String[] strs = {"success", "duplicate"}; + String[] strs = {"success", "duplicates"}; for (DataProc dataProc: dataProcs) { Crdn crdn = dataProc.getTarget(); + crdn.clearAttachments(); DataObject info = crdnMap.get(crdn); List files = (List)info.get("files"); if (isEmpty(files)) continue; - List extracted = files.stream().map(file -> (File)file.get("file")).toList(); + List extracted = files.stream() + .map(file -> (File)file.get("file")) + .distinct() + .toList(); for (String str: strs) { List list = fileMap.get(str); @@ -200,33 +207,47 @@ public class ImportServiceBean extends AbstractServiceBean implements ImportServ fileMap.put(str, list = new ArrayList<>()); if ("success".equals(str) && dataProc.isSuccess()) list.addAll(extracted); - if ("duplicates".equals(str) && "duplicate".equals(dataProc.getInfo("reason"))) + else if ("duplicates".equals(str) && "duplicate".equals(dataProc.getInfo("reason"))) { list.addAll(extracted); + } } } fileMap.put("fail", errors.stream().flatMap(info -> { - List tmp = ((List)info.get("files")); + List tmp = (List)info.get("files"); return tmp.stream().map(file -> (File)file.get("file")); }).toList()); resp.set("success", dataProcs.stream().filter(DataProc::isSuccess).count()) .set("duplicates", dataProcs.stream().filter(dp -> "duplicate".equals(dp.getInfo("reason"))).count()); - if (!isEmpty(workPath)) - fileList.forEach(delInfo -> crdnBean.removeEquipmentLinkFile(workPath, delInfo.string("FILE_NAME"))); - - String dir = null; - for (Map.Entry> entry: fileMap.entrySet()) { - String key = entry.getKey(); - List files = entry.getValue(); - for (File file: files) { - String srcDir = file.getParentFile().getAbsolutePath(), - destDir = srcDir.replace(File.separator + "work", File.separator + key); - if (!equals(dir, destDir)) - ensureDir(dir = destDir); - - file.renameTo(new File(destDir + File.separator + file.getName())); + if (!cctv) + for (DataObject delInfo: fileList) { + crdnBean.removeEquipmentLinkFile(workPath, delInfo.string("FILE_NAME")); + } + else { + String dir = null; + for (Map.Entry> entry: fileMap.entrySet()) { + String key = entry.getKey(); + List files = entry.getValue(); + for (File file: files) { + String srcDir = file.getParent(), + destDir = srcDir.replace(File.separator + "work", File.separator + key); + if (!equals(dir, destDir)) + ensureDir(dir = destDir); + String destPath = destDir + File.separator + file.getName(); + boolean moved = file.renameTo(new File(destPath)); + if (!moved) + log().debug("Failed to move {} -> {}", file.getPath(), destPath); +/* + try { + Files.move(file.toPath(), Paths.get(destDir, file.getName())); + } catch (Exception e) { + throw runtimeException(e); + } +*/ + } } } + log().debug("process result: {}", resp); return resp; } @@ -285,6 +306,7 @@ public class ImportServiceBean extends AbstractServiceBean implements ImportServ return result; }) + .distinct() .collect(Collectors.toCollection(ArrayList::new)); } diff --git a/src/main/java/cokr/xit/fims/crdn/web/Crdn05Controller.java b/src/main/java/cokr/xit/fims/crdn/web/Crdn05Controller.java index a5684588..fc0ccd1f 100644 --- a/src/main/java/cokr/xit/fims/crdn/web/Crdn05Controller.java +++ b/src/main/java/cokr/xit/fims/crdn/web/Crdn05Controller.java @@ -17,6 +17,7 @@ import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.ModelAndView; @@ -357,7 +358,7 @@ public class Crdn05Controller extends ApplicationController { */ } - @RequestMapping(name="장비업체 단속파일로 단속자료 생성", value="/020/upload.do") + @PostMapping(name="장비업체 단속파일로 단속자료 생성", value="/020/upload.do") public ModelAndView createCrdnFromLinkFile(HttpServletRequest hreq, MultipartFile[] uploadFiles) { UserInfo currentUser = currentUser(); String sggCd = currentUser.getOrgID(), @@ -397,67 +398,58 @@ public class Crdn05Controller extends ApplicationController { parsed.addAll(parser.parse(workPath, List.of(uploadFiles))); } else { // 서버 cctv 디렉토리 String[] dirs = blankIfEmpty(hreq.getParameter("dirs")).split(","); - Stream.of(dirs) - .forEach(dir -> { - String srcDir = FimsConf.get().violationFileDir(dir); - Path destDir = ensureDir(srcDir + File.separator + "work").toPath(); - try { - Files.list(Paths.get(srcDir)) - .filter(src -> { - String str = src.toString(); - return !str.contains("work") - && !str.contains("success") - && Files.isRegularFile(src); - }) - .forEach(src -> { - try { - Files.move(src, destDir.resolve(src.getFileName()), StandardCopyOption.REPLACE_EXISTING); - } catch (Exception e) { - throw runtimeException(e); - } - }); - } catch (Exception e) { - throw runtimeException(e); - } - }); - List files = Stream.of(dirs) - .map(path -> Paths.get(FimsConf.get().violationFileDir(path) + File.separator + "work")) - .flatMap(path -> { - try { - return Files.walk(path).filter(file -> Files.isRegularFile(file)); - } catch (Exception e) { - throw runtimeException(e); - } - }) - .map(Path::toFile) - .toList(); - parsed.addAll(parser.parse(files)); + for (String dir: dirs) { + String srcDir = FimsConf.get().violationFileDir(dir); + List filenames = List.of(blankIfEmpty(hreq.getParameter("filenames")).split(",")); + log().debug("{} filenames received", filenames.size()); + Path workDir = ensureDir(srcDir + File.separator + "work").toPath(); + try { + // 파일들을 작업 디렉토리로 이동 + List filepaths = Files.list(Paths.get(srcDir)) + .filter(path -> contains(path.toString(), filenames, false)) + .toList(); + log().debug("{} filepaths extracted", filepaths.size()); + filepaths.forEach(src -> { + try { + Files.move(src, workDir.resolve(src.getFileName()), StandardCopyOption.REPLACE_EXISTING); + } catch (Exception e) { + throw runtimeException(e); + } + }); + + List files = Files.list(workDir) + .filter(path -> contains(path.toString(), filenames, true)) + .map(path -> path.toFile()) + .toList(); + log().debug("{} files parsed", files.size()); + parsed.addAll(parser.parse(files)); + } catch (Exception e) { + throw runtimeException(e); + } + } } nextTempGroupSeq = parser.getTempGroupSeq(); } -/* - if (parsed.isEmpty()) - return new ModelAndView("jsonView") - .addObject("saved", false) - .addObject("alertMessage", "등록할 파일을 찾지 못했습니다") - .addObject("failReason", "등록할 파일을 찾지 못했습니다"); -*/ + Map result = importService.createCrdnByEquipmentLinkFile(processInfo, parsed); return new ModelAndView("jsonView") - .addAllObjects(result); -/* - boolean saved = (boolean)resultMap.get("saved"); - - ModelAndView mav = new ModelAndView("jsonView") - .addObject("saved", saved); - if (!isEmpty(resultMap.get("alertMessage"))) - mav.addObject("alertMessage", resultMap.get("alertMessage")); + .addAllObjects(result); + } - if (!saved) - mav.addObject("failReason", ifEmpty(resultMap.get("failReason"), () -> "알 수 없는 오류")); + private boolean contains(String path, List filenames, boolean inWork) { + if (!inWork) { + if (path.contains("work") + || path.contains("success") + || path.contains("fail") + || path.contains("duplicates") + ) return false; + } - return mav; -*/ + for (String filename: filenames) { + if (path.endsWith(filename)) + return true; + } + return false; } /**단속자료 수기 등록 팝업화면을 반환한다. diff --git a/src/main/java/cokr/xit/fims/mngt/service/bean/TaskProcessor.java b/src/main/java/cokr/xit/fims/mngt/service/bean/TaskProcessor.java index 0e35a8ac..0166ace9 100644 --- a/src/main/java/cokr/xit/fims/mngt/service/bean/TaskProcessor.java +++ b/src/main/java/cokr/xit/fims/mngt/service/bean/TaskProcessor.java @@ -118,30 +118,34 @@ public class TaskProcessor extends AbstractBean { return crdns; ArrayList copies = new ArrayList<>(crdns); - Map duplicates = crdnStngMapper.selectDuplicateCrdns(copies).stream().collect(Collectors.toMap( - info -> info.get("VHRNO") + "-" + info.get("CRDN_YMD"), - info -> info - )); - List found = copies.stream() + Map selected = crdnStngMapper.selectDuplicateCrdns(copies).stream().collect(Collectors.toMap( + info -> info.get("VHRNO") + "-" + info.get("CRDN_YMD"), + info -> info + )); + List duplicates = copies.stream() .filter(crdn -> { String key = crdn.getVhrno() + "-" + crdn.getCrdnYmd(); - DataObject info = duplicates.get(key); + DataObject info = selected.get(key); return info != null && toInt(info.get("CRDN_CNT")) > 0; }) .collect(Collectors.toCollection(ArrayList::new)); - copies.removeAll(found); - copies.stream().collect(Collectors.groupingBy( - crdn -> crdn.getVhrno() + "-" + crdn.getCrdnYmd()) - ).forEach((str, items) -> { - int size = items.size(); - if (size < 2) return; + copies.removeAll(duplicates); - for (int i = 1; i < size; ++i) { - found.add(items.get(i)); - } - }); + copies.stream().collect(Collectors.groupingBy( + crdn -> crdn.getVhrno() + "-" + crdn.getCrdnYmd()) + ).forEach((str, items) -> { + int size = items.size(); + if (size < 2) return; + + for (int i = 1; i < size; ++i) { + Crdn item = items.get(i); + if (!duplicates.contains(item)) + duplicates.add(item); + } + }); - return found; + duplicates.forEach(Crdn::clearAttachments); + return duplicates; } public Map getExcluded(List crdns) {