From 8457e3343d7695f2c6b9adaea1171df641d4af4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EC=84=9D=20=EC=B5=9C?= Date: Thu, 16 Dec 2021 17:36:05 +0900 Subject: [PATCH] =?UTF-8?q?=EA=B2=8C=EC=8B=9C=EB=AC=BC=20=EB=82=B4?= =?UTF-8?q?=EC=9A=A9=20=EC=A1=B0=ED=9A=8C,=20=EB=8B=A4=EC=9A=B4=EB=A1=9C?= =?UTF-8?q?=EB=93=9C=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/BoardController.java | 149 +++++++++++++++++- .../dbnt/kcgfilemanager/model/BaseModel.java | 8 +- .../com/dbnt/kcgfilemanager/model/Board.java | 2 + .../dbnt/kcgfilemanager/model/FileInfo.java | 6 + .../kcgfilemanager/service/BoardService.java | 51 ++++-- .../resources/mybatisMapper/BoardMapper.xml | 5 +- .../mybatisMapper/UserInfoMapper.xml | 2 +- .../resources/static/js/board/contentList.js | 76 ++++++--- .../resources/templates/admin/userMgt.html | 6 +- .../templates/board/contentDetail.html | 45 +++++- .../templates/board/contentList.html | 27 ++-- .../resources/templates/board/contentLog.html | 1 + 12 files changed, 324 insertions(+), 54 deletions(-) diff --git a/src/main/java/com/dbnt/kcgfilemanager/controller/BoardController.java b/src/main/java/com/dbnt/kcgfilemanager/controller/BoardController.java index a977ede..45df7fb 100644 --- a/src/main/java/com/dbnt/kcgfilemanager/controller/BoardController.java +++ b/src/main/java/com/dbnt/kcgfilemanager/controller/BoardController.java @@ -2,16 +2,30 @@ package com.dbnt.kcgfilemanager.controller; import com.dbnt.kcgfilemanager.config.LogStatus; import com.dbnt.kcgfilemanager.model.Board; +import com.dbnt.kcgfilemanager.model.FileInfo; import com.dbnt.kcgfilemanager.model.UserInfo; import com.dbnt.kcgfilemanager.service.BoardService; import lombok.RequiredArgsConstructor; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.util.FileCopyUtils; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartHttpServletRequest; import org.springframework.web.servlet.ModelAndView; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.*; +import java.net.URLEncoder; import java.security.Principal; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Date; import java.util.HashMap; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; @RestController @RequiredArgsConstructor @@ -50,14 +64,147 @@ public class BoardController { @GetMapping("/selectBoardContent") public ModelAndView selectBoardContent(Board content){ ModelAndView mav = new ModelAndView("board/contentDetail"); - mav.addObject("content", boardService.selectContentDetail(content.getContentSeq())); + Board target = boardService.selectContentByContentSeqAndViewCntUp(content.getContentSeq()); + mav.addObject("content", boardService.SelectContentForeignAttribute(target)); return mav; } @GetMapping("/selectBoardLog") public ModelAndView selectBoardLog(Board content){ ModelAndView mav = new ModelAndView("board/contentLog"); + mav.addObject("contentSeq", content.getContentSeq()); mav.addObject("statusMap", LogStatus.getStatusMap()); mav.addObject("logList", boardService.selectContentLog(content.getContentSeq())); return mav; } + + @GetMapping("/fileDownload") + public void fileDownload(Integer contentSeq, Integer fileSeq, HttpServletRequest request, HttpServletResponse response){ + FileInfo downlodFileInfo = boardService.selectDownloadFileInfo(contentSeq, fileSeq); + + BufferedInputStream in; + BufferedOutputStream out; + try { + File file = new File(downlodFileInfo.getSavePath(), downlodFileInfo.getConversionName()); + setDisposition(downlodFileInfo.getFullName(), request, response); + in = new BufferedInputStream(new FileInputStream(file)); + out = new BufferedOutputStream(response.getOutputStream()); + FileCopyUtils.copy(in, out); + out.flush(); + if(out!=null) out.close(); + if(in!=null )in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @GetMapping("/fileDownloadToZip") + public void fileDownloadToZip(Integer contentSeq, @RequestParam(value = "fileSeq") List fileSeqList, HttpServletResponse response){ + List targetList = boardService.selectDownloadFileInfoList(contentSeq, fileSeqList); + + BufferedInputStream in; + BufferedOutputStream out; + + String tempZipPath = "D:\\kcgFileManager\\tempZip\\"; + File tempFolder = new File(tempZipPath); + if (!tempFolder.exists() || tempFolder.isFile()) { + tempFolder.mkdirs(); + } + String downloadFileName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS")); + + tempZipPath += downloadFileName+".zip"; + try{ + FileOutputStream fout = new FileOutputStream(tempZipPath); + ZipOutputStream zout = new ZipOutputStream(fout); + for(FileInfo downLoadFile: targetList){ + ZipEntry zipEntry = new ZipEntry(downLoadFile.getFullName()); + zout.putNextEntry(zipEntry); + + FileInputStream fin = new FileInputStream(downLoadFile.getSavePath()+"\\"+downLoadFile.getConversionName()); + byte[] buffer = new byte[1024]; + int length; + while((length = fin.read(buffer)) > 0){ + zout.write(buffer, 0, length); + } + + zout.closeEntry(); + fin.close(); + } + zout.close(); + + response.setContentType("application/zip"); + response.addHeader("Content-Disposition", "attachment; filename="+downloadFileName+".zip"); + + FileInputStream fis=new FileInputStream(tempZipPath); + ServletOutputStream so=response.getOutputStream(); + in=new BufferedInputStream(fis); + out=new BufferedOutputStream(so); + + byte[] data=new byte[2048]; + int input; + while((input=in.read(data))!=-1){ + out.write(data,0,input); + out.flush(); + } + + if(out!=null) out.close(); + if(fis!=null) fis.close(); + if(in!=null) in.close(); + if(so!=null) so.close(); + }catch (IOException e){ + e.printStackTrace(); + } finally { + File tempZip = new File(tempZipPath); + tempZip.delete(); + } + } + + private void setDisposition(String filename, HttpServletRequest request, HttpServletResponse response) throws IOException { + String browser = getBrowser(request); + + String dispositionPrefix = "attachment; filename="; + String encodedFilename = null; + + if (browser.equals("MSIE")) { + encodedFilename = URLEncoder.encode(filename, "UTF-8").replaceAll("\\+", "%20"); + } else if (browser.equals("Trident")) { // IE11 문자열 깨짐 방지 + encodedFilename = URLEncoder.encode(filename, "UTF-8").replaceAll("\\+", "%20"); + } else if (browser.equals("Firefox")) { + encodedFilename = "\"" + new String(filename.getBytes("UTF-8"), "8859_1") + "\""; + } else if (browser.equals("Opera")) { + encodedFilename = "\"" + new String(filename.getBytes("UTF-8"), "8859_1") + "\""; + } else if (browser.equals("Chrome")) { + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < filename.length(); i++) { + char c = filename.charAt(i); + if (c > '~') { + sb.append(URLEncoder.encode("" + c, "UTF-8")); + } else { + sb.append(c); + } + } + encodedFilename = sb.toString(); + } else { + throw new IOException("Not supported browser"); + } + + response.setHeader("Content-Disposition", dispositionPrefix + encodedFilename); + + if ("Opera".equals(browser)) { + response.setContentType("application/octet-stream;charset=UTF-8"); + } + } + + private String getBrowser(HttpServletRequest request) { + String header = request.getHeader("User-Agent"); + if (header.indexOf("MSIE") > -1) { + return "MSIE"; + } else if (header.indexOf("Trident") > -1) { // IE11 문자열 깨짐 방지 + return "Trident"; + } else if (header.indexOf("Chrome") > -1) { + return "Chrome"; + } else if (header.indexOf("Opera") > -1) { + return "Opera"; + } + return "Firefox"; + } } diff --git a/src/main/java/com/dbnt/kcgfilemanager/model/BaseModel.java b/src/main/java/com/dbnt/kcgfilemanager/model/BaseModel.java index a979732..82e631a 100644 --- a/src/main/java/com/dbnt/kcgfilemanager/model/BaseModel.java +++ b/src/main/java/com/dbnt/kcgfilemanager/model/BaseModel.java @@ -15,7 +15,7 @@ public class BaseModel { @Transient private Integer firstIndex=0; // 쿼리의 시작 row @Transient - private Integer viewCnt=10; //한 페이지에 표현되는 row 수 + private Integer rowCnt=10; //한 페이지에 표현되는 row 수 @Transient private Integer startNum=1; // pagination 시작값 @Transient @@ -30,13 +30,13 @@ public class BaseModel { private String endDate; public void setQueryInfo(){ - setFirstIndex((getPageIndex()-1)*getViewCnt()); + setFirstIndex((getPageIndex()-1)*getRowCnt()); } public void setPaginationInfo(){ int contentCnt = getContentCnt(); - int viewCnt = getViewCnt(); - int maxNum = (int)Math.ceil(((double)contentCnt)/viewCnt); + int rowCnt = getRowCnt(); + int maxNum = (int)Math.ceil(((double)contentCnt)/rowCnt); setMaxNum(maxNum); int pageIndex = getPageIndex(); diff --git a/src/main/java/com/dbnt/kcgfilemanager/model/Board.java b/src/main/java/com/dbnt/kcgfilemanager/model/Board.java index 7a68dd4..d506182 100644 --- a/src/main/java/com/dbnt/kcgfilemanager/model/Board.java +++ b/src/main/java/com/dbnt/kcgfilemanager/model/Board.java @@ -32,6 +32,8 @@ public class Board extends BaseModel{ private String description; @Column(name = "STATUS") private String status; + @Column(name = "VIEW_CNT") + private Integer viewCnt; @Column(name = "CREATE_ID") private String createId; @Column(name = "CREATE_DATE") diff --git a/src/main/java/com/dbnt/kcgfilemanager/model/FileInfo.java b/src/main/java/com/dbnt/kcgfilemanager/model/FileInfo.java index df76bcb..3f0fccc 100644 --- a/src/main/java/com/dbnt/kcgfilemanager/model/FileInfo.java +++ b/src/main/java/com/dbnt/kcgfilemanager/model/FileInfo.java @@ -30,6 +30,8 @@ public class FileInfo { private String conversionName; @Column(name = "EXTENTION") private String extention; + @Column(name = "FILE_SIZE") + private String fileSize; @Column(name = "SAVE_PATH") private String savePath; @@ -41,4 +43,8 @@ public class FileInfo { private Integer contentSeq; private Integer fileSeq; } + + public String getFullName(){ + return originalName+"."+extention; + } } diff --git a/src/main/java/com/dbnt/kcgfilemanager/service/BoardService.java b/src/main/java/com/dbnt/kcgfilemanager/service/BoardService.java index d37f6e3..6377cf8 100644 --- a/src/main/java/com/dbnt/kcgfilemanager/service/BoardService.java +++ b/src/main/java/com/dbnt/kcgfilemanager/service/BoardService.java @@ -11,6 +11,7 @@ import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.IOException; +import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.UUID; @@ -100,6 +101,7 @@ public class BoardService { fileInfo.setOriginalName(originalFilename[0]); fileInfo.setExtention(originalFilename[1]); fileInfo.setConversionName(saveName); + fileInfo.setFileSize(calculationFileSize(file.getSize())); fileInfo.setSavePath(path); fileInfoRepository.save(fileInfo); saveBoardLog(content.getContentSeq(), LogStatus.FILE_ADD, file.getOriginalFilename(), content.getCreateId()); @@ -114,14 +116,6 @@ public class BoardService { return getPageTitle(category.getParentSeq())+" > "+category.getCategoryName(); } - public String makeFilePath(Integer categorySeq){ - BoardCategory category = boardCategoryRepository.findById(categorySeq).orElse(null); - if(category.getParentSeq()==null){ - return "D:\\kcgFileManager\\"+category.getCategoryName(); - } - return makeFilePath(category.getParentSeq())+"\\"+category.getCategoryName(); - } - public List selectContentList(Board board) { return boardMapper.selectContentList(board); } @@ -129,13 +123,48 @@ public class BoardService { return boardMapper.selectContentListCnt(board); } - public Board selectContentDetail(Integer contentSeq) { + @Transactional + public Board selectContentByContentSeqAndViewCntUp(Integer contentSeq) { Board target = boardRepository.findById(contentSeq).orElse(null); - target.setHashTagList(boardMapper.selectHashTagListFromContentSeq(contentSeq)); - target.setChildFileList(fileInfoRepository.findByContentSeqOrderByFileSeqAsc(contentSeq)); + target.setViewCnt(target.getViewCnt()+1); return target; } + + public List selectDownloadFileInfoList(Integer contentSeq, List fileSeqList) { + List fileList = fileInfoRepository.findByContentSeqOrderByFileSeqAsc(contentSeq); + List targetList = new ArrayList<>(); + for(FileInfo file: fileList){ + if(fileSeqList.contains(file.getFileSeq())){ + targetList.add(file); + } + } + return targetList; + } + public FileInfo selectDownloadFileInfo(Integer contestSeq, Integer fileSeq){ + return fileInfoRepository.findById(new FileInfo.FileInfoId(contestSeq, fileSeq)).orElse(null); + } + public List selectContentLog(Integer contentSeq){ return boardMapper.selectBoardLogFromContentSeq(contentSeq); } + + public Board SelectContentForeignAttribute(Board target) { + target.setHashTagList(boardMapper.selectHashTagListFromContentSeq(target.getContentSeq())); + target.setChildFileList(fileInfoRepository.findByContentSeqOrderByFileSeqAsc(target.getContentSeq())); + return target; + } + + private String makeFilePath(Integer categorySeq){ + BoardCategory category = boardCategoryRepository.findById(categorySeq).orElse(null); + if(category.getParentSeq()==null){ + return "D:\\kcgFileManager\\"+category.getCategoryName(); + } + return makeFilePath(category.getParentSeq())+"\\"+category.getCategoryName(); + } + private String calculationFileSize(Long fileSize){ + String[] units = {"bytes", "KB", "MB"}; + double unitSelector = Math.floor(Math.log(fileSize)/Math.log(1024)); + return Math.round((fileSize/Math.pow(1024, unitSelector))*100)/100d+" "+units[(int)unitSelector]; + } + } diff --git a/src/main/resources/mybatisMapper/BoardMapper.xml b/src/main/resources/mybatisMapper/BoardMapper.xml index f11cb1a..5941115 100644 --- a/src/main/resources/mybatisMapper/BoardMapper.xml +++ b/src/main/resources/mybatisMapper/BoardMapper.xml @@ -9,7 +9,8 @@ A.TITLE AS title, C.FILE_CNT AS fileCnt, B.NAME AS createName, - A.CREATE_DATE AS createDate + A.CREATE_DATE AS createDate, + A.VIEW_CNT AS viewCnt FROM BOARD A INNER JOIN USER_INFO B ON A.CREATE_ID = B.USER_ID @@ -19,7 +20,7 @@ ON A.CONTENT_SEQ = C.CONTENT_SEQ WHERE A.CATEGORY_SEQ = #{categorySeq} ORDER BY A.CREATE_DATE DESC - LIMIT #{viewCnt} OFFSET #{firstIndex} + LIMIT #{rowCnt} OFFSET #{firstIndex}