package com.its.web.service.notice; import com.its.web.dto.message.ResultDto; import com.its.web.dto.notice.AttachFileDto; import com.its.web.dto.notice.NoticeDto; import com.its.web.mapper.its.notice.NoticeMapper; import com.its.web.pagination.Pagination; import com.its.web.util.CommonUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.FileUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; import java.io.*; import java.net.URLDecoder; import java.util.*; @Slf4j @RequiredArgsConstructor @Service public class NoticeService { private final NoticeMapper mapper; @Value("${board-location}") String boardLocation; public Pagination findAllList(String page, String searchType, String searchText) { Pagination pagination = new Pagination(page, this.mapper.getNoticeTotalCount(), searchType, searchText); List list = this.mapper.findAllNotice(pagination); pagination.setList(list); return pagination; } public NoticeDto findNotice(String boardNo) { try { return this.mapper.findNoticeById(Long.parseLong(boardNo)); } catch (NumberFormatException e){ log.error("Cause NumberFormatException, Please Check The Board No -> {}", boardNo); return null; } } public List findMainNotice(int num) { return this.mapper.findMainNotice(num); } public AttachFileDto getAttachFile(String boardNo, String fileId) { AttachFileDto dto = new AttachFileDto(); dto.setBoardNo(boardNo); String message = null; if (boardNo != null && fileId != null) { Map paramMap = new HashMap<>(); paramMap.put("boardNo", boardNo); paramMap.put("fileId", fileId); int result = this.mapper.getAttachFileCount(paramMap); if (result > 0) { File file = new File(boardLocation, fileId); int fileSize = (int) file.length(); if (fileSize > 0) { try { byte[] byteArray = FileUtils.readFileToByteArray(file); if (byteArray.length > 0) { int i = 0; dto.setAttachFile(new byte[byteArray.length]); for (byte b : byteArray) { dto.getAttachFile()[i++] = b; } message = "파일 전송 완료."; } else { message = "파일을 찾을 수 없습니다."; } } catch (FileNotFoundException e) { log.error("File Not FoundException"); message = "파일을 찾을 수 없습니다."; } catch (IOException e) { log.error("IOException"); message = "파일을 읽는 중 오류가 발생하였습니다."; } } } else { message = "파일을 찾일 수 없습니다."; } } dto.setMessage(message); return dto; } public ResultDto deleteBoard(String boardNo) { NoticeDto deleteDto = this.findNotice(boardNo); String fileIds = deleteDto.getAttachFileId(); if (fileIds != null){ String[] idArray = fileIds.split("\\|"); if (idArray.length > 0) { for(String id : idArray) { File file = new File(boardLocation, id); if (file.exists()) { boolean isDelete = file.delete(); if (!isDelete) { log.error("게시물 파일이 삭제되지 않았습니다. {}", id); } } } } } int affectedRows = this.mapper.deleteBoard(boardNo); String message = "선택하신 게시물이 삭제되지 않았습니다."; String success = "F"; if (affectedRows > 0) { message = "선택하신 게시물이 삭제되었습니다."; success = "S"; } return CommonUtil.getResultDto(success, message); } public ResultDto writeNotice(NoticeDto.NoticeDtoWriteReq param, List attachFile, String webUserId) { Map paramMap = new HashMap<>(); String fileNames = ""; String fileIds = ""; String message = ""; String success = "S"; paramMap.put("bContent", param.getBcontent()); paramMap.put("bSubject", param.getBsubject()); paramMap.put("webUserId", webUserId); if (attachFile != null && attachFile.size() > 0){ for (MultipartFile file : attachFile) { String fileName = file.getOriginalFilename(); if (fileName != null) { String ext = fileName.substring(fileName.lastIndexOf(".")); String fileId = UUID.randomUUID().toString().replaceAll("-", "") + ext; boolean isSuccess = uploadAttachFile(file, fileId); fileNames = fileName + "|"; fileIds = fileId + "|"; if (!isSuccess) { message = "파일 생성 중 오류가 발생하였습니다."; success = "F"; } } } } if (success.equals("S")) { if (attachFile != null) { int fileSize = attachFile.size(); if (attachFile != null && fileSize == 1) { fileNames = fileNames + "|"; fileIds = fileIds + "|"; } else if (fileSize == 3) { fileNames = fileNames.substring(fileNames.length() - 1); fileIds = fileIds.substring(fileIds.length() - 1); } } else { fileNames = "||"; fileIds = "||"; } paramMap.put("attachFile", fileNames); paramMap.put("attachFileId", fileIds); int affectedRows = this.mapper.insertNotice(paramMap); message = "작성하신 게시물이 저장되었습니다."; if (affectedRows <= 0) { message = "작성하신 게시물이 저장되지 않았습니다."; success = "F"; } } return CommonUtil.getResultDto(success, message); } public ResultDto modifyNotice(NoticeDto.NoticeDtoUpdateReq param, List attachFile) { Map paramMap = new HashMap<>(); paramMap.put("bSubject", param.getBSubject()); paramMap.put("bContent", param.getBContent()); paramMap.put("boardNo", param.getBoardNo()); String attachFileNames = param.getAttachFileNames(); Map sameIndex = new HashMap<>(); String fileId = "||"; String success = "S"; String message = "작성하신 게시물이 수정되었습니다."; NoticeDto dto = this.findNotice(param.getBoardNo()); if (dto != null) { if (!attachFileNames.equals(dto.getAttachFile())) { String originAttachFile = dto.getAttachFile(); String originFileIds = dto.getAttachFileId(); if (originAttachFile != null && originFileIds != null) { String[] fileNameArr = originAttachFile.split("\\|"); String[] fileIdArr = originFileIds.split("\\|"); String[] nameArr = attachFileNames.split("\\|"); // 기존 파일과 같은 이름이 있는지 찾고 있으면 유지 해줘야한다 if (fileNameArr.length > 0) { for (int ii = 0; ii < fileNameArr.length; ii++) { String originName = fileNameArr[ii]; if (nameArr.length >= (ii +1) && originName.equals(nameArr[ii])) { sameIndex.put(ii, fileIdArr[ii]); } else { if (fileIdArr.length > ii && fileIdArr[ii] != null) { File file = new File(boardLocation, fileIdArr[ii]); if (file.exists()) { boolean isDelete = file.delete(); if (!isDelete) { log.error("기존 파일 삭제가 진행되지 않았습니다. {}", fileIdArr[ii]); } } } } } } } } else { fileId = dto.getAttachFileId(); } } if (attachFile != null && attachFile.size() > 0) { int cnt = 0; for (MultipartFile file : attachFile) { String orgName = file.getOriginalFilename(); if (orgName != null && orgName.lastIndexOf(".") > 0) { String ext = orgName.substring(orgName.lastIndexOf(".")); String attachFileId = UUID.randomUUID().toString().replaceAll("-", "") + ext; if (sameIndex.size() == 0) { sameIndex.put(cnt++, attachFileId); } else { for (int ii = 0; ii < 3; ii++) { if (sameIndex.get(ii) == null) { sameIndex.put(ii, attachFileId); break; } } } boolean isSuccess = uploadAttachFile(file, attachFileId); if (!isSuccess) { message = "파일 생성 중 오류가 발생하였습니다."; success = "F"; return CommonUtil.getResultDto(success, message); } } } fileId = ""; for (int ii = 0; ii < 3; ii++) { if (sameIndex.get(ii) != null) { fileId += sameIndex.get(ii); } if (ii != 2) { fileId += "|"; } } } paramMap.put("attachFile", attachFileNames); paramMap.put("attachFileId", fileId); int affectedRows = this.mapper.updateNotice(paramMap); if (affectedRows <= 0) { message ="작성하신 게시물이 수정되지 않았습니다."; success = "F"; } return CommonUtil.getResultDto(success, message); } public boolean uploadAttachFile(MultipartFile attachFile, String fileId) { File file = new File(boardLocation); boolean isMkFile = true; if (!file.exists()) { file.setExecutable(false, true); /*파일 실행 권한 설정 (파라미터 - 일반, 소유자)*/ file.setReadable(true); /*파일 읽기 권한 설정*/ file.setWritable(false, true); isMkFile = file.mkdirs(); } if (isMkFile) { File transFile = new File(boardLocation + "/" + fileId); try { attachFile.transferTo(transFile); } catch (IOException e) { log.error("IOException - 첨부 파일 파일 생성 중 오류가 발생하였습니다."); isMkFile = false; } } else { log.error("디렉토리 생성 중 오류가 발생하였습니다."); } return isMkFile; } public int updateNoticeReadCount(String boardNo) { return this.mapper.updateNoticeReadCount(boardNo); } public String imageUpload(HttpServletRequest req){ String uploadImageInfo = ""; String fileName = req.getHeader("file-name"); try { fileName = URLDecoder.decode(fileName, "UTF-8"); } catch (UnsupportedEncodingException exception) { log.error("Can not Decoding UTF-8"); } String filePath = boardLocation + "/upload"; File file = new File(filePath); boolean isMkdirs = true; if (!file.exists()) { file.setExecutable(false, true); /*파일 실행 권한 설정 (파라미터 - 일반, 소유자)*/ file.setReadable(true); /*파일 읽기 권한 설정*/ file.setWritable(false, true); isMkdirs = file.mkdirs(); } if (isMkdirs) { String realFileNm; realFileNm = UUID.randomUUID().toString().replace("-", "") + fileName.substring(fileName.lastIndexOf(".")); String rlFileNm = filePath + File.separator + realFileNm; OutputStream os = null; try ( InputStream is = req.getInputStream(); ) { os = new FileOutputStream(rlFileNm); int numRead; byte[] byteArray = new byte[Integer.parseInt(req.getHeader("file-size"))]; if (is != null) { while ((numRead = is.read(byteArray, 0, byteArray.length)) != -1) { os.write(byteArray, 0, numRead); } } os.flush(); } catch (IOException e) { log.error("IO Exception - noticeImageUpload"); } catch (Exception e1) { log.error("Exception - noticeImageUpload"); } finally { if(os != null) { try{ os.close(); } catch (IOException e) { log.error("Cause IOException..."); } } } uploadImageInfo += "&bNewLine=true"; uploadImageInfo += "&sFileName=" + fileName; uploadImageInfo += "&sFileURL=" + "/api/notice/upload/" + realFileNm; } return uploadImageInfo; } public byte[] getImage(String imageName) { byte[] image = null; File file = new File(boardLocation + "/upload", imageName); int fileSize = (int) file.length(); if (fileSize > 0) { try { byte[] byteArray = FileUtils.readFileToByteArray(file); if (byteArray.length > 0) { int ii = 0; image = new byte[byteArray.length]; for (byte b : byteArray) { image[ii++] = b; } } } catch (FileNotFoundException e) { log.error("Not Found File - {}", boardLocation + "/upload/" + imageName); } catch (IOException e) { log.error("Can Not Send Image Cause IOException - {}", boardLocation + "/upload/" + imageName); } } return image; } }