From eaa246201cc8991032b2c6541e00acb3a8be6e72 Mon Sep 17 00:00:00 2001 From: taking Date: Wed, 11 Oct 2023 11:43:32 +0000 Subject: [PATCH 01/14] =?UTF-8?q?Chore:=20=ED=8C=8C=EC=9D=BC=20FileUrl=20?= =?UTF-8?q?=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 --- nw/build.gradle | 2 +- nw/src/main/java/lab/cherry/nw/model/FileEntity.java | 7 ++++++- nw/src/main/java/lab/cherry/nw/model/QsheetEntity.java | 1 + .../java/lab/cherry/nw/service/Impl/FileServiceImpl.java | 8 +++++++- nw/src/main/java/lab/cherry/nw/util/Common.java | 9 ++++----- 5 files changed, 19 insertions(+), 8 deletions(-) diff --git a/nw/build.gradle b/nw/build.gradle index 708c692..8cc8aff 100644 --- a/nw/build.gradle +++ b/nw/build.gradle @@ -14,7 +14,7 @@ dependencies { runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5' implementation 'org.springframework:spring-context:6.0.7' implementation 'org.springframework:spring-context-support:6.0.7' - implementation 'com.sun.mail:jakarta.mail:2.0.1' + implementation 'jakarta.mail:jakarta.mail-api:2.1.2' implementation 'org.springframework.boot:spring-boot-starter-mail:3.0.2' implementation 'org.springframework.boot:spring-boot-starter-data-redis:3.0.2' implementation 'io.lettuce:lettuce-core' diff --git a/nw/src/main/java/lab/cherry/nw/model/FileEntity.java b/nw/src/main/java/lab/cherry/nw/model/FileEntity.java index 18f6029..f409517 100644 --- a/nw/src/main/java/lab/cherry/nw/model/FileEntity.java +++ b/nw/src/main/java/lab/cherry/nw/model/FileEntity.java @@ -27,7 +27,7 @@ @Builder @NoArgsConstructor @AllArgsConstructor @Document(collection = "files") -@JsonPropertyOrder({ "fileSeq", "fileName", "fileType", "fileExt", "filePath", "fileSize", "userId", "orgId", "created_at" }) +@JsonPropertyOrder({ "fileSeq", "fileName", "fileType", "fileExt", "filePath", "fileUrl", "fileSize", "userId", "orgId", "created_at" }) public class FileEntity implements Serializable { @Id @@ -50,6 +50,11 @@ public class FileEntity implements Serializable { @Schema(title = "파일 경로", example = "관리/더 글로리/IMG_61E29A079818-1.jpeg") private String path; + @NotNull + @JsonProperty("fileUrl") + @Schema(title = "파일 URL", example = "https://{IP_ADDR}:{PORT}/api/v1/file/download/6506ebb61b6deb1602d85c35?path=/관리/더 글로리/IMG_61E29A079818-1.jpeg") + private String url; + @NotNull @JsonProperty("fileSize") @Schema(title = "파일 사이즈", example = "20MB") diff --git a/nw/src/main/java/lab/cherry/nw/model/QsheetEntity.java b/nw/src/main/java/lab/cherry/nw/model/QsheetEntity.java index 009dcf8..a750c40 100644 --- a/nw/src/main/java/lab/cherry/nw/model/QsheetEntity.java +++ b/nw/src/main/java/lab/cherry/nw/model/QsheetEntity.java @@ -74,6 +74,7 @@ public class QsheetEntity implements Serializable { @Getter @Builder + @NoArgsConstructor @AllArgsConstructor public static class ItemData { @Schema(title = "큐시트 순서", example = "1") private int orderIndex; diff --git a/nw/src/main/java/lab/cherry/nw/service/Impl/FileServiceImpl.java b/nw/src/main/java/lab/cherry/nw/service/Impl/FileServiceImpl.java index f6b0904..8bde2c9 100644 --- a/nw/src/main/java/lab/cherry/nw/service/Impl/FileServiceImpl.java +++ b/nw/src/main/java/lab/cherry/nw/service/Impl/FileServiceImpl.java @@ -8,6 +8,7 @@ import lab.cherry.nw.util.FormatConverter; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; @@ -31,6 +32,9 @@ public class FileServiceImpl implements FileService { private final MinioService minioService; private final FileRepository fileRepository; + @Value("${server.port}") + private String server_port; + public Page getFiles(Pageable pageable) { return fileRepository.findAll(pageable); } @@ -67,14 +71,16 @@ public List uploadFiles(Map info, List fi throw new RuntimeException(e); } + String fileUrl = "/api/v1/file/download/" + orgId + "?path=" + filePath; // 파일 객체 ID 저장 - fileObjectIds.add(filePath); + fileObjectIds.add(fileUrl); FileEntity fileEntity = FileEntity.builder() .name(file.getOriginalFilename()) .size(FormatConverter.convertInputBytes(file.getSize())) .type(file.getContentType()) .path(filePath) + .url(fileUrl) .userid(userName) .orgid(orgId) .created_at(Instant.now()) diff --git a/nw/src/main/java/lab/cherry/nw/util/Common.java b/nw/src/main/java/lab/cherry/nw/util/Common.java index 895294c..abe34b7 100644 --- a/nw/src/main/java/lab/cherry/nw/util/Common.java +++ b/nw/src/main/java/lab/cherry/nw/util/Common.java @@ -1,13 +1,12 @@ package lab.cherry.nw.util; -import jakarta.servlet.http.HttpServletRequest; -import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; +import java.util.List; import org.springframework.data.domain.Sort; import org.springframework.util.StringUtils; import org.springframework.web.multipart.MultipartFile; - -import java.util.ArrayList; -import java.util.List; +import jakarta.servlet.http.HttpServletRequest; +import lombok.extern.slf4j.Slf4j; @Slf4j public class Common { From bafc971ba3b43c62302dad817ee78739e0f65966 Mon Sep 17 00:00:00 2001 From: yby654 Date: Wed, 11 Oct 2023 13:32:06 +0000 Subject: [PATCH 02/14] =?UTF-8?q?Chore:=20=ED=81=90=EC=8B=9C=ED=8A=B8=20?= =?UTF-8?q?=EC=B5=9C=EC=A2=85=ED=99=95=EC=9D=B8,=20=EC=8B=9C=ED=81=AC?= =?UTF-8?q?=EB=A6=BF=EB=A9=94=EB=AA=A8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nw/build.gradle | 2 +- .../lab/cherry/nw/model/QsheetEntity.java | 59 +++++++++++++++++-- .../cherry/nw/repository/BoardRepository.java | 2 +- .../nw/repository/BookmarkRepository.java | 2 +- .../nw/repository/QsheetRepository.java | 2 +- .../cherry/nw/repository/TagRepository.java | 2 +- .../nw/service/Impl/QsheetServiceImpl.java | 33 ++++++++++- 7 files changed, 89 insertions(+), 13 deletions(-) diff --git a/nw/build.gradle b/nw/build.gradle index 708c692..8cc8aff 100644 --- a/nw/build.gradle +++ b/nw/build.gradle @@ -14,7 +14,7 @@ dependencies { runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5' implementation 'org.springframework:spring-context:6.0.7' implementation 'org.springframework:spring-context-support:6.0.7' - implementation 'com.sun.mail:jakarta.mail:2.0.1' + implementation 'jakarta.mail:jakarta.mail-api:2.1.2' implementation 'org.springframework.boot:spring-boot-starter-mail:3.0.2' implementation 'org.springframework.boot:spring-boot-starter-data-redis:3.0.2' implementation 'io.lettuce:lettuce-core' diff --git a/nw/src/main/java/lab/cherry/nw/model/QsheetEntity.java b/nw/src/main/java/lab/cherry/nw/model/QsheetEntity.java index a47eeee..04c14fe 100644 --- a/nw/src/main/java/lab/cherry/nw/model/QsheetEntity.java +++ b/nw/src/main/java/lab/cherry/nw/model/QsheetEntity.java @@ -13,7 +13,6 @@ import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.DBRef; import org.springframework.data.mongodb.core.mapping.Document; - import java.io.Serializable; import java.time.Instant; import java.util.Comparator; @@ -57,8 +56,7 @@ public class QsheetEntity implements Serializable { private String name; @JsonProperty("data") - @Schema(title = "큐시트 내용",type="List", example = "[{'orderIndex':1, }]") - + @Schema(title = "큐시트 내용") private List data; @JsonProperty("created_at") @@ -71,24 +69,54 @@ public class QsheetEntity implements Serializable { @Schema(title = "큐시트 업데이트 시간", example = "2023-07-04 12:00:00") private Instant updated_at; + @JsonProperty("memo") + @Schema(title = "메모", type="String", example = "신랑 깜짝 이벤트 준비") + private String memo; + + @DBRef + @JsonProperty("org_approver") + @Schema(title = "업체 확인자 정보",type="String",example = "38352658567418867") + private UserEntity org_approver; + @JsonProperty("org_confirm") + @Schema(title = "업체 확인", type="Boolean", example = "false") + private boolean org_confirm; + @JsonProperty("client_confirm") + @Schema(title = "신랑신부 확인", type="Boolean", example = "false") + private boolean client_confirm; + // @JsonProperty("final_confirm") + // @Schema(title = "최종 확인") + // private FinalConfirm finalConfirm; + @Getter @Builder + @NoArgsConstructor @AllArgsConstructor public static class ItemData { - @Schema(title = "큐시트 순서", example = "1") - private int orderIndex; + @Schema(title = "큐시트 순서",type="integer" ,example = "1") + private Integer orderIndex; @Schema(title = "큐시트 순서명", example = "축가") private String process; @Schema(title = "큐시트 내용", example = "니가사는그집-박진영") private String content; @Schema(title = "큐시트 행위자", example = "신부") private String actor; - @Schema(title = "메모", example = "신부가 노래를 못함") + @Schema(title = "비고", example = "신부가 노래를 못함") private String note; @Schema(title = "파일위치", example = "./") private String filePath; } + @Getter + @Builder + @NoArgsConstructor @AllArgsConstructor + public static class FinalConfirm { + @Schema(title = "업체 확인자 정보",type="String",example = "38352658567418867") + private String org_approver; + @Schema(title = "업체 확인", type="Boolean", example = "false") + private boolean org_confirm; + @Schema(title = "신랑신부 확인", type="Boolean", example = "false") + private boolean client_confirm; + } // TODO: Permission Entity // @Builder.Default @@ -116,6 +144,17 @@ public static class QsheetCreateDto { private String orgSeq; @Schema(title = "데이터 리스트") private List data; + @Schema(title = "메모", type="String", example = "신랑 깜짝 이벤트 준비") + private String memo; + @Schema(title = "업체 확인자 정보",type="String",example = "38352658567418867") + private String org_approverSeq; + @Schema(title = "업체 확인", type="Boolean", example = "false") + private boolean org_confirm; + @Schema(title = "신랑신부 확인", type="Boolean", example = "false") + private boolean client_confirm; + // @Schema(title = "최종 확인") + // private FinalConfirm finalConfirm; + } public void sortDataByOrderIndex() { @@ -144,6 +183,14 @@ public static class QsheetUpdateDto { private String orgSeq; @Schema(title = "데이터 리스트") private List data; + @Schema(title = "메모", type="String", example = "신랑 깜짝 이벤트 준비") + private String memo; + @Schema(title = "업체 확인자 정보",type="String",example = "38352658567418867") + private String org_approverSeq; + @Schema(title = "업체 확인", type="Boolean", example = "false") + private boolean org_confirm; + @Schema(title = "신랑신부 확인", type="Boolean", example = "false") + private boolean client_confirm; } public void updateFromDto(QsheetUpdateDto updateDto) { diff --git a/nw/src/main/java/lab/cherry/nw/repository/BoardRepository.java b/nw/src/main/java/lab/cherry/nw/repository/BoardRepository.java index 0696b11..048c2f9 100644 --- a/nw/src/main/java/lab/cherry/nw/repository/BoardRepository.java +++ b/nw/src/main/java/lab/cherry/nw/repository/BoardRepository.java @@ -16,7 +16,7 @@ * Related : BoardServiceImpl, BoardService * */ -public interface BoardRepository extends MongoRepository { +public interface BoardRepository extends MongoRepository { Page findAll(Pageable pageable); Page findPageByUserid(String userid, Pageable pageable); diff --git a/nw/src/main/java/lab/cherry/nw/repository/BookmarkRepository.java b/nw/src/main/java/lab/cherry/nw/repository/BookmarkRepository.java index 020eee5..7655f2a 100644 --- a/nw/src/main/java/lab/cherry/nw/repository/BookmarkRepository.java +++ b/nw/src/main/java/lab/cherry/nw/repository/BookmarkRepository.java @@ -19,7 +19,7 @@ * Related : BookmarkServiceImpl, BookmarkService * */ -public interface BookmarkRepository extends MongoRepository { +public interface BookmarkRepository extends MongoRepository { Page findAll(Pageable pageable); diff --git a/nw/src/main/java/lab/cherry/nw/repository/QsheetRepository.java b/nw/src/main/java/lab/cherry/nw/repository/QsheetRepository.java index 9aaff75..555954b 100644 --- a/nw/src/main/java/lab/cherry/nw/repository/QsheetRepository.java +++ b/nw/src/main/java/lab/cherry/nw/repository/QsheetRepository.java @@ -16,7 +16,7 @@ * Related : QsheetServiceImpl, QsheetService * */ -public interface QsheetRepository extends MongoRepository { +public interface QsheetRepository extends MongoRepository { Page findAll(Pageable pageable); Page findPageByUserid(String userid, Pageable pageable); diff --git a/nw/src/main/java/lab/cherry/nw/repository/TagRepository.java b/nw/src/main/java/lab/cherry/nw/repository/TagRepository.java index 17de5ae..4678294 100644 --- a/nw/src/main/java/lab/cherry/nw/repository/TagRepository.java +++ b/nw/src/main/java/lab/cherry/nw/repository/TagRepository.java @@ -16,7 +16,7 @@ * Related : TagServiceImpl, TagService * */ -public interface TagRepository extends MongoRepository { +public interface TagRepository extends MongoRepository { Page findAll(Pageable pageable); Optional findByName(String name); diff --git a/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetServiceImpl.java b/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetServiceImpl.java index 861c2d9..e0863a2 100644 --- a/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetServiceImpl.java +++ b/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetServiceImpl.java @@ -72,14 +72,24 @@ public void createQsheet(QsheetEntity.QsheetCreateDto qsheetCreateDto) { Instant instant = Instant.now(); UserEntity userEntity = userService.findById(qsheetCreateDto.getUserSeq()); OrgEntity orgEntity = null; + UserEntity orgUserEntity = null; + userService.findById(qsheetCreateDto.getUserSeq()); if (qsheetCreateDto.getOrgSeq() != null){ orgEntity = orgService.findById(qsheetCreateDto.getOrgSeq()); } + if ( qsheetCreateDto.getOrg_approverSeq() != null){ + orgUserEntity = userService.findById(qsheetCreateDto.getOrg_approverSeq()); + } QsheetEntity qsheetEntity = QsheetEntity.builder() .userid(userEntity) .orgid(orgEntity) .name(qsheetCreateDto.getName()) .data(qsheetCreateDto.getData()) + .memo(qsheetCreateDto.getMemo()) + .org_approver(orgUserEntity) + .org_confirm(false) + .client_confirm(false) + // .finalConfirm(FinalConfirm.builder().build()) .created_at(instant) .build(); qsheetRepository.save(qsheetEntity); @@ -107,17 +117,36 @@ public void updateById(String id, QsheetEntity.QsheetUpdateDto qsheetUpdateDto) // qsheetEntity.updateFromDto(qsheetUpdateDto); // qsheetRepository.save(qsheetEntity); OrgEntity orgEntity = qsheetEntity.getOrgid(); + UserEntity orgUserEntity = qsheetEntity.getOrg_approver(); if (qsheetUpdateDto.getOrgSeq() != null){ orgEntity = orgService.findById(qsheetUpdateDto.getOrgSeq()); } - + if (qsheetUpdateDto.isOrg_confirm()){ + if(qsheetUpdateDto.getOrg_approverSeq()!=null){ + orgUserEntity = userService.findById(qsheetUpdateDto.getOrg_approverSeq()); + }else{ + log.error("[QsheetServiceImpl - udpateQsheet] org_approver와 isOrg_confirm 입력이 잘못되었습니다."); + throw new CustomException(ErrorCode.INVALID_INPUT_VALUE); + } + + } qsheetEntity = QsheetEntity.builder() .id(qsheetEntity.getId()) .name(qsheetEntity.getName()) .orgid(orgEntity) .userid(qsheetEntity.getUserid()) .created_at(qsheetEntity.getCreated_at()) - .data(qsheetUpdateDto.getData()) + .data(qsheetUpdateDto.getData()!=null?qsheetUpdateDto.getData():qsheetEntity.getData()) + .org_approver(orgUserEntity) + .org_confirm(qsheetUpdateDto.isOrg_confirm()==!(qsheetEntity.isOrg_confirm())?qsheetUpdateDto.isOrg_confirm():qsheetEntity.isOrg_confirm()) + .client_confirm(qsheetUpdateDto.isClient_confirm()==!(qsheetEntity.isClient_confirm())?qsheetUpdateDto.isClient_confirm():qsheetEntity.isClient_confirm()) + // .finalConfirm(qsheetUpdateDto.getFinalConfirm()!=null? + // FinalConfirm.builder() + // .org_approver(qsheetUpdateDto.getFinalConfirm().getOrg_approver()!=null?qsheetUpdateDto.getFinalConfirm().getOrg_approver():null) + // .org_confirm(qsheetUpdateDto.getFinalConfirm().isOrg_confirm()==!(qsheetEntity.getFinalConfirm().isOrg_confirm())?qsheetUpdateDto.getFinalConfirm().isOrg_confirm():qsheetEntity.getFinalConfirm().isOrg_confirm()) + // .client_confirm(qsheetUpdateDto.getFinalConfirm().isClient_confirm()==!(qsheetEntity.getFinalConfirm().isClient_confirm())?qsheetUpdateDto.getFinalConfirm().isClient_confirm():qsheetEntity.getFinalConfirm().isClient_confirm()) + // .build():qsheetEntity.getFinalConfirm() ) + .memo(qsheetUpdateDto.getMemo()) .updated_at(instant) .build(); qsheetRepository.save(qsheetEntity); From c5ce99d9043c848ccca9626f46d1e17b1776814e Mon Sep 17 00:00:00 2001 From: taking Date: Thu, 12 Oct 2023 11:37:55 +0000 Subject: [PATCH 03/14] Feat: Qsheet Download, Fix: Minor Updated --- .../cherry/nw/configuration/Initalizer.java | 18 ++- .../WebSecurityConfiguration.java | 3 +- .../cherry/nw/controller/FileController.java | 141 ++++++++++++------ .../nw/controller/QsheetController.java | 22 +++ .../nw/controller/WeddinghallController.java | 34 +++-- .../lab/cherry/nw/error/enums/ErrorCode.java | 3 +- .../lab/cherry/nw/model/QsheetEntity.java | 7 + .../cherry/nw/repository/BoardRepository.java | 2 +- .../nw/repository/BookmarkRepository.java | 2 +- .../nw/repository/FinalTemplRepository.java | 10 +- .../nw/repository/FinaldocsRepository.java | 15 +- .../nw/repository/QsheetRepository.java | 2 +- .../nw/repository/ScheduleRepository.java | 11 +- .../cherry/nw/repository/TagRepository.java | 2 +- .../nw/repository/UserCardRepository.java | 12 +- .../lab/cherry/nw/service/FileService.java | 7 +- .../nw/service/Impl/FileServiceImpl.java | 79 +++++++--- .../nw/service/Impl/MinioServiceImpl.java | 51 ++++--- .../nw/service/Impl/QsheetServiceImpl.java | 60 +++++++- .../nw/service/Impl/UserServiceImpl.java | 10 ++ .../lab/cherry/nw/service/QsheetService.java | 2 + .../lab/cherry/nw/service/UserService.java | 1 + .../java/lab/cherry/nw/util/HttpUtils.java | 50 +++++++ 23 files changed, 407 insertions(+), 137 deletions(-) create mode 100644 nw/src/main/java/lab/cherry/nw/util/HttpUtils.java diff --git a/nw/src/main/java/lab/cherry/nw/configuration/Initalizer.java b/nw/src/main/java/lab/cherry/nw/configuration/Initalizer.java index 0be2f3e..77772e9 100644 --- a/nw/src/main/java/lab/cherry/nw/configuration/Initalizer.java +++ b/nw/src/main/java/lab/cherry/nw/configuration/Initalizer.java @@ -7,12 +7,15 @@ import lab.cherry.nw.repository.OrgRepository; import lab.cherry.nw.repository.RoleRepository; import lab.cherry.nw.repository.UserRepository; +import lab.cherry.nw.service.MinioService; import lombok.RequiredArgsConstructor; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Component; - +import java.io.IOException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; import java.time.Instant; @RequiredArgsConstructor @@ -23,6 +26,7 @@ public class Initalizer implements ApplicationRunner { private final RoleRepository roleRepository; private final OrgRepository orgRepository; private final PasswordEncoder passwordEncoder; + private final MinioService minioService; @Override public void run(ApplicationArguments args) { @@ -69,7 +73,7 @@ public void run(ApplicationArguments args) { .userid("admin") .username("관리자") .password(passwordEncoder.encode("admin")) - .email("admin@test.com") + .email("admin@localhost.com") .type("org") .role(roleEntity) .enabled(true) @@ -91,5 +95,15 @@ public void run(ApplicationArguments args) { .enabled(true) .build()); } + + // 'user' Bucket 생성 + try { + minioService.createBucketIfNotExists("user"); + minioService.createGlobalPolicy("user"); + minioService.setBucketPolicy("user"); + } catch (InvalidKeyException | NoSuchAlgorithmException | IOException e) { + // log.error("{}, e"); + // e.printStackTrace(); + } } } \ No newline at end of file diff --git a/nw/src/main/java/lab/cherry/nw/configuration/WebSecurityConfiguration.java b/nw/src/main/java/lab/cherry/nw/configuration/WebSecurityConfiguration.java index c5cc5b7..85b1ab6 100644 --- a/nw/src/main/java/lab/cherry/nw/configuration/WebSecurityConfiguration.java +++ b/nw/src/main/java/lab/cherry/nw/configuration/WebSecurityConfiguration.java @@ -60,7 +60,8 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti "/swagger-resources/**", "/swagger-ui/**", "/swagger-ui.html", - "/api/v1/file/download/**" // TODO: download/{orgId} 에 대해 각 orgId 소속만 접근 가능하는 기능 추가 필요 + "/api/v1/file/download/**", // TODO: download/{orgId} 에 대해 각 orgId 소속만 접근 가능하는 기능 추가 필요 + "/api/v1/file/test" ) .permitAll() .requestMatchers("/api/v1/**").hasAnyRole("ADMIN", "USER") // spring boot 에서 ROLE_ 은 자동으로 붙음 diff --git a/nw/src/main/java/lab/cherry/nw/controller/FileController.java b/nw/src/main/java/lab/cherry/nw/controller/FileController.java index 5879e2b..3b1a93e 100644 --- a/nw/src/main/java/lab/cherry/nw/controller/FileController.java +++ b/nw/src/main/java/lab/cherry/nw/controller/FileController.java @@ -1,14 +1,11 @@ package lab.cherry.nw.controller; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.tags.Tag; -import lab.cherry.nw.error.ResultResponse; -import lab.cherry.nw.error.enums.SuccessCode; -import lab.cherry.nw.model.FileEntity; -import lab.cherry.nw.service.FileService; -import lab.cherry.nw.util.Common; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; +import java.util.zip.ZipOutputStream; +import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import org.springframework.core.io.InputStreamResource; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -18,9 +15,22 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; - -import java.io.InputStream; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lab.cherry.nw.error.ResultResponse; +import lab.cherry.nw.error.enums.SuccessCode; +import lab.cherry.nw.model.FileEntity; +import lab.cherry.nw.service.FileService; +import lab.cherry.nw.util.Common; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; /** *
@@ -64,17 +74,6 @@ public ResponseEntity findAllFiles(
 		Pageable pageable = PageRequest.of(page, size, Sort.by(Common.getOrder(sort)));
 
 		Page fileEntity = fileService.getFiles(pageable);
-//		if(userid == null && orgid == null) {
-//			fileEntity = fileService.getFiles(pageable);
-//		}
-//		else {
-//			fileEntity = fileService.findPageByUserId(userid, pageable);
-//		}
-//		} else {
-//			fileEntity = fileService.getFiles(pageable);
-//		}
-
-		//        final ResultResponse response = ResultResponse.of(SuccessCode.OK, userService.getUsers());
 		return new ResponseEntity<>(fileEntity, new HttpHeaders(), HttpStatus.OK);
 	}
 
@@ -121,7 +120,6 @@ public ResponseEntity findByFilePath(@RequestParam(required = true) String pa
 		return new ResponseEntity<>(response, new HttpHeaders(), HttpStatus.OK);
 	}
 
-
 	/**
      * [FileController] 특정 파일 다운로드 함수
      *
@@ -129,31 +127,80 @@ public ResponseEntity findByFilePath(@RequestParam(required = true) String pa
      *
      * Author : taking(taking@duck.com)
      */
-	@GetMapping("/download/{orgId}")
-    @Operation(summary = "특정 파일 다운로드", description = "특정 파일을 다운로드합니다.")
-    public ResponseEntity downloadFile(
-			@RequestParam(required = false) String path,
+     @GetMapping("/download/{orgId}")
+     @Operation(summary = "특정 파일 다운로드", description = "특정 파일을 다운로드합니다.")
+     public ResponseEntity downloadFile(
+               @RequestParam(required = false) Boolean qsheet,
+			@RequestParam(required = false) List path,
 			@PathVariable String orgId) {
 
-		// MinioService를 사용하여 MinIO 서버로부터 파일을 가져옵니다.
-		InputStream fileInputStream = fileService.downloadFile(orgId, path);
+          if(path.size() > 1) {
+
+               ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+               try (ZipOutputStream zipOut = new ZipOutputStream(byteArrayOutputStream)) {
+                    for (String data : path) {
+
+                         String[] parts = data.split("/");
+                         String fileName = parts[parts.length - 1];
+
+                         byte[] objectData = fileService.downloadZip(orgId, data);
+
+                         // Zip 아카이브에 객체 추가
+                         ZipArchiveEntry zipEntry = new ZipArchiveEntry(fileName + ".zip");
+                         zipOut.putNextEntry(zipEntry);
+                         zipOut.write(objectData);
+                         zipOut.closeEntry();
+
+                    }
+               } catch (IOException e) {
+                    log.error("{}", e);
+               }
+          
+               byte[] zipBytes = byteArrayOutputStream.toByteArray();
+               
+               HttpHeaders headers = new HttpHeaders();
+               headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + "download.zip");
+
+               return new ResponseEntity<>(zipBytes, headers, HttpStatus.OK);
+
+          } else {
+
+               String objectName = path.get(0);
 
-		// 문자열을 '/'로 분할
-		String[] parts = path.split("/");
+               if(chkExtension(path.get(0))) {
 
-		// 마지막 요소 확인
-		String fileName = parts[parts.length - 1];
+                    // MinioService를 사용하여 MinIO 서버로부터 파일을 가져옵니다.
+                    InputStream fileInputStream = fileService.downloadFile(orgId, objectName);
 
-		// 파일 다운로드를 위한 헤더 설정
-		HttpHeaders headers = new HttpHeaders();
-		headers.setContentDispositionFormData("attachment", fileName); // 다운로드할 때 파일 이름 지정
-		headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
+                    // 문자열을 '/'로 분할
+                    String[] parts = objectName.split("/");
 
-		// 파일 스트림을 InputStreamResource로 래핑하여 응답합니다.
-		InputStreamResource resource = new InputStreamResource(fileInputStream);
+                    // 마지막 요소 확인
+                    String fileName = parts[parts.length - 1];
+
+                    // 파일 다운로드를 위한 헤더 설정
+                    HttpHeaders headers = new HttpHeaders();
+                    headers.setContentDispositionFormData("attachment", fileName); // 다운로드할 때 파일 이름 지정
+                    headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
+
+                    // 파일 스트림을 InputStreamResource로 래핑하여 응답합니다.
+                    InputStreamResource resource = new InputStreamResource(fileInputStream);
+
+                    return new ResponseEntity<>(resource, headers, HttpStatus.OK);
+
+               } else {
+
+                    // 파일 다운로드를 위한 헤더 설정
+                    HttpHeaders headers = new HttpHeaders();
+                    headers.setContentDispositionFormData("attachment", "download.zip"); // 다운로드할 때 파일 이름 지정
+                    headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
+
+                    return new ResponseEntity<>(fileService.downloadZip(orgId, objectName), headers, HttpStatus.OK);
+
+               }
+
+          }
 
-		//        final ResultResponse response = ResultResponse.of(SuccessCode.OK, userService.getUsers());
-		return new ResponseEntity<>(resource, headers, HttpStatus.OK);
 	}
 
 
@@ -180,4 +227,14 @@ public ResponseEntity deleteFile(@PathVariable("id") String id) {
 		final ResultResponse response = ResultResponse.of(SuccessCode.OK);
 		return new ResponseEntity<>(response, new HttpHeaders(), HttpStatus.OK);
 	}
+
+     public Boolean chkExtension(String path) {
+          String extension = StringUtils.getFilenameExtension(path);
+
+          if (extension == null) {
+               return false;
+          } else {
+               return true;
+          }
+     }
 }
diff --git a/nw/src/main/java/lab/cherry/nw/controller/QsheetController.java b/nw/src/main/java/lab/cherry/nw/controller/QsheetController.java
index fc3c413..646c8de 100644
--- a/nw/src/main/java/lab/cherry/nw/controller/QsheetController.java
+++ b/nw/src/main/java/lab/cherry/nw/controller/QsheetController.java
@@ -15,6 +15,7 @@
 import lab.cherry.nw.util.Common;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import java.util.List;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.PageRequest;
 import org.springframework.data.domain.Pageable;
@@ -171,5 +172,26 @@ public ResponseEntity findByQsheetId(@PathVariable("id") String id) {
         //        final ResultResponse response = ResultResponse.of(SuccessCode.OK, userService.findById(id));
         return new ResponseEntity<>(qsheetService.findById(id), new HttpHeaders(), HttpStatus.OK);
     }
+    
+	/**
+     * [QsheetController] 큐시트 사용자 파일 다운로드 함수
+     *
+     * @return 큐시트 사용자 파일을 반환합니다.
+     *
+     * Author : taking(taking@duck.com)
+     */
+    @PostMapping("/download")
+    @Operation(summary = "큐시트 사용자 파일 다운로드", description = "큐시트 사용자 파일을 다운로드합니다.")
+    public ResponseEntity downloadQsheetBySeq(@RequestBody QsheetEntity.QsheetDownloadDto qsheetDownloadDto) {
+
+        log.info("[QsheetController] downloadQsheetBySeq...!");
+
+
+        HttpHeaders headers = new HttpHeaders();
+        headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + "download.zip");
+
+        return new ResponseEntity<>(qsheetService.download(qsheetDownloadDto.getUser()), new HttpHeaders(), HttpStatus.OK);
+
+   }
 
 }
diff --git a/nw/src/main/java/lab/cherry/nw/controller/WeddinghallController.java b/nw/src/main/java/lab/cherry/nw/controller/WeddinghallController.java
index be9dc4e..2f4ced5 100644
--- a/nw/src/main/java/lab/cherry/nw/controller/WeddinghallController.java
+++ b/nw/src/main/java/lab/cherry/nw/controller/WeddinghallController.java
@@ -1,5 +1,23 @@
 package lab.cherry.nw.controller;
 
+import java.util.List;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RequestPart;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.media.Content;
 import io.swagger.v3.oas.annotations.media.Schema;
@@ -10,27 +28,11 @@
 import lab.cherry.nw.error.ErrorResponse;
 import lab.cherry.nw.error.ResultResponse;
 import lab.cherry.nw.error.enums.SuccessCode;
-import lab.cherry.nw.model.UserEntity;
 import lab.cherry.nw.model.WeddinghallEntity;
-import lab.cherry.nw.service.MinioService;
-import lab.cherry.nw.service.UserService;
 import lab.cherry.nw.service.WeddinghallService;
 import lab.cherry.nw.util.Common;
 import lombok.RequiredArgsConstructor;
-import lombok.SneakyThrows;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.domain.Sort;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.MediaType;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
-import org.springframework.web.multipart.MultipartFile;
-
-import java.util.List;
 
 /**
  * 
diff --git a/nw/src/main/java/lab/cherry/nw/error/enums/ErrorCode.java b/nw/src/main/java/lab/cherry/nw/error/enums/ErrorCode.java
index 17b36f7..24bf4f3 100644
--- a/nw/src/main/java/lab/cherry/nw/error/enums/ErrorCode.java
+++ b/nw/src/main/java/lab/cherry/nw/error/enums/ErrorCode.java
@@ -29,7 +29,8 @@ public enum ErrorCode {
     FORBIDDEN(403, "접근 권한이 없어 거부되었습니다."),
     ACCESS_DENIED_EXCEPTION(401, "인증 정보가 유효하지 않습니다."),
     DUPLICATE(409, "중복된 데이터가 있습니다."),
-    NO_BODY(400, "파라미터 값이 입력되지 않았습니다.");
+    NO_BODY(400, "파라미터 값이 입력되지 않았습니다."),
+    URL_NOTFOUND(400, "Minio URL을 다시 확인해주세요.");
 
     private final int status;
     private final String message;
diff --git a/nw/src/main/java/lab/cherry/nw/model/QsheetEntity.java b/nw/src/main/java/lab/cherry/nw/model/QsheetEntity.java
index 7c28fea..7ab109b 100644
--- a/nw/src/main/java/lab/cherry/nw/model/QsheetEntity.java
+++ b/nw/src/main/java/lab/cherry/nw/model/QsheetEntity.java
@@ -154,5 +154,12 @@ public void updateFromDto(QsheetUpdateDto updateDto) {
         }
     }
 
+    @Getter
+    @Builder
+    @NoArgsConstructor @AllArgsConstructor
+    public static class QsheetDownloadDto {
+		@Schema(title = "사용자 리스트")
+		private List user;
+    }
 
 }
diff --git a/nw/src/main/java/lab/cherry/nw/repository/BoardRepository.java b/nw/src/main/java/lab/cherry/nw/repository/BoardRepository.java
index 0696b11..048c2f9 100644
--- a/nw/src/main/java/lab/cherry/nw/repository/BoardRepository.java
+++ b/nw/src/main/java/lab/cherry/nw/repository/BoardRepository.java
@@ -16,7 +16,7 @@
  * Related : BoardServiceImpl, BoardService
  * 
*/ -public interface BoardRepository extends MongoRepository { +public interface BoardRepository extends MongoRepository { Page findAll(Pageable pageable); Page findPageByUserid(String userid, Pageable pageable); diff --git a/nw/src/main/java/lab/cherry/nw/repository/BookmarkRepository.java b/nw/src/main/java/lab/cherry/nw/repository/BookmarkRepository.java index 020eee5..7655f2a 100644 --- a/nw/src/main/java/lab/cherry/nw/repository/BookmarkRepository.java +++ b/nw/src/main/java/lab/cherry/nw/repository/BookmarkRepository.java @@ -19,7 +19,7 @@ * Related : BookmarkServiceImpl, BookmarkService *
*/ -public interface BookmarkRepository extends MongoRepository { +public interface BookmarkRepository extends MongoRepository { Page findAll(Pageable pageable); diff --git a/nw/src/main/java/lab/cherry/nw/repository/FinalTemplRepository.java b/nw/src/main/java/lab/cherry/nw/repository/FinalTemplRepository.java index 9a632e1..da47db9 100644 --- a/nw/src/main/java/lab/cherry/nw/repository/FinalTemplRepository.java +++ b/nw/src/main/java/lab/cherry/nw/repository/FinalTemplRepository.java @@ -1,13 +1,11 @@ package lab.cherry.nw.repository; -import lab.cherry.nw.model.FinalTemplEntity; +import java.util.List; +import java.util.Optional; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.mongodb.repository.MongoRepository; - -import java.util.List; -import java.util.Optional; -import java.util.UUID; +import lab.cherry.nw.model.FinalTemplEntity; /** @@ -19,7 +17,7 @@ * */ //@Repository -public interface FinalTemplRepository extends MongoRepository { +public interface FinalTemplRepository extends MongoRepository { Page findAll(Pageable pageable); diff --git a/nw/src/main/java/lab/cherry/nw/repository/FinaldocsRepository.java b/nw/src/main/java/lab/cherry/nw/repository/FinaldocsRepository.java index e0e3df7..1d1fa15 100644 --- a/nw/src/main/java/lab/cherry/nw/repository/FinaldocsRepository.java +++ b/nw/src/main/java/lab/cherry/nw/repository/FinaldocsRepository.java @@ -1,17 +1,12 @@ package lab.cherry.nw.repository; -import lab.cherry.nw.model.FinaldocsEntity; -import lab.cherry.nw.model.OrgEntity; -import lab.cherry.nw.model.ScheduleEntity; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.mongodb.repository.MongoRepository; - import java.time.Instant; -import java.time.LocalDateTime; import java.util.List; import java.util.Optional; -import java.util.UUID; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.mongodb.repository.MongoRepository; +import lab.cherry.nw.model.FinaldocsEntity; /** @@ -23,7 +18,7 @@ * */ //@Repository -public interface FinaldocsRepository extends MongoRepository { +public interface FinaldocsRepository extends MongoRepository { Page findAll(Pageable pageable); diff --git a/nw/src/main/java/lab/cherry/nw/repository/QsheetRepository.java b/nw/src/main/java/lab/cherry/nw/repository/QsheetRepository.java index 9aaff75..555954b 100644 --- a/nw/src/main/java/lab/cherry/nw/repository/QsheetRepository.java +++ b/nw/src/main/java/lab/cherry/nw/repository/QsheetRepository.java @@ -16,7 +16,7 @@ * Related : QsheetServiceImpl, QsheetService * */ -public interface QsheetRepository extends MongoRepository { +public interface QsheetRepository extends MongoRepository { Page findAll(Pageable pageable); Page findPageByUserid(String userid, Pageable pageable); diff --git a/nw/src/main/java/lab/cherry/nw/repository/ScheduleRepository.java b/nw/src/main/java/lab/cherry/nw/repository/ScheduleRepository.java index 8691c1c..69a63c5 100644 --- a/nw/src/main/java/lab/cherry/nw/repository/ScheduleRepository.java +++ b/nw/src/main/java/lab/cherry/nw/repository/ScheduleRepository.java @@ -1,14 +1,11 @@ package lab.cherry.nw.repository; -import lab.cherry.nw.model.ScheduleEntity; +import java.util.List; +import java.util.Optional; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.mongodb.repository.MongoRepository; - -import java.time.LocalDateTime; -import java.util.List; -import java.util.Optional; -import java.util.UUID; +import lab.cherry.nw.model.ScheduleEntity; /** @@ -20,7 +17,7 @@ * */ //@Repository -public interface ScheduleRepository extends MongoRepository { +public interface ScheduleRepository extends MongoRepository { Page findAll(Pageable pageable); diff --git a/nw/src/main/java/lab/cherry/nw/repository/TagRepository.java b/nw/src/main/java/lab/cherry/nw/repository/TagRepository.java index 17de5ae..4678294 100644 --- a/nw/src/main/java/lab/cherry/nw/repository/TagRepository.java +++ b/nw/src/main/java/lab/cherry/nw/repository/TagRepository.java @@ -16,7 +16,7 @@ * Related : TagServiceImpl, TagService * */ -public interface TagRepository extends MongoRepository { +public interface TagRepository extends MongoRepository { Page findAll(Pageable pageable); Optional findByName(String name); diff --git a/nw/src/main/java/lab/cherry/nw/repository/UserCardRepository.java b/nw/src/main/java/lab/cherry/nw/repository/UserCardRepository.java index 8293cad..199dd19 100644 --- a/nw/src/main/java/lab/cherry/nw/repository/UserCardRepository.java +++ b/nw/src/main/java/lab/cherry/nw/repository/UserCardRepository.java @@ -1,15 +1,11 @@ package lab.cherry.nw.repository; -import lab.cherry.nw.model.OrgEntity; -import lab.cherry.nw.model.UserCardEntity; -import org.apache.catalina.User; +import java.util.List; +import java.util.Optional; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.mongodb.repository.MongoRepository; - -import java.util.List; -import java.util.Optional; -import java.util.UUID; +import lab.cherry.nw.model.UserCardEntity; /** @@ -21,7 +17,7 @@ * */ //@Repository -public interface UserCardRepository extends MongoRepository { +public interface UserCardRepository extends MongoRepository { Page findAll(Pageable pageable); diff --git a/nw/src/main/java/lab/cherry/nw/service/FileService.java b/nw/src/main/java/lab/cherry/nw/service/FileService.java index 2f06eff..3835f71 100644 --- a/nw/src/main/java/lab/cherry/nw/service/FileService.java +++ b/nw/src/main/java/lab/cherry/nw/service/FileService.java @@ -1,12 +1,16 @@ package lab.cherry.nw.service; import lab.cherry.nw.model.FileEntity; +import org.springframework.core.io.ByteArrayResource; +import org.springframework.core.io.InputStreamResource; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; - +import java.io.IOException; import java.io.InputStream; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; import java.util.List; import java.util.Map; @@ -29,5 +33,6 @@ public interface FileService { void deleteById(String id); InputStream downloadFile(String orgId, String path); + byte[] downloadZip(String bucketName, String objectName); void deleteFiles(String orgId, List images); } \ No newline at end of file diff --git a/nw/src/main/java/lab/cherry/nw/service/Impl/FileServiceImpl.java b/nw/src/main/java/lab/cherry/nw/service/Impl/FileServiceImpl.java index 8bde2c9..c88472d 100644 --- a/nw/src/main/java/lab/cherry/nw/service/Impl/FileServiceImpl.java +++ b/nw/src/main/java/lab/cherry/nw/service/Impl/FileServiceImpl.java @@ -1,28 +1,36 @@ package lab.cherry.nw.service.Impl; -import lab.cherry.nw.error.exception.EntityNotFoundException; -import lab.cherry.nw.model.FileEntity; -import lab.cherry.nw.repository.FileRepository; -import lab.cherry.nw.service.FileService; -import lab.cherry.nw.service.MinioService; -import lab.cherry.nw.util.FormatConverter; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.multipart.MultipartFile; - import java.io.IOException; import java.io.InputStream; +import java.net.URI; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.time.Instant; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; +import org.apache.tomcat.util.codec.binary.Base64; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.io.InputStreamResource; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpHeaders; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.util.UriComponentsBuilder; +import lab.cherry.nw.error.enums.ErrorCode; +import lab.cherry.nw.error.exception.CustomException; +import lab.cherry.nw.error.exception.EntityNotFoundException; +import lab.cherry.nw.model.FileEntity; +import lab.cherry.nw.repository.FileRepository; +import lab.cherry.nw.service.FileService; +import lab.cherry.nw.service.MinioService; +import lab.cherry.nw.util.FormatConverter; +import lab.cherry.nw.util.HttpUtils; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; @Slf4j @Service @@ -32,8 +40,15 @@ public class FileServiceImpl implements FileService { private final MinioService minioService; private final FileRepository fileRepository; - @Value("${server.port}") - private String server_port; + + @Value("${minio.url}") + private String minioUrl; + + @Value("${minio.access-key}") + private String accessKey; + + @Value("${minio.secret-key}") + private String secretKey; public Page getFiles(Pageable pageable) { return fileRepository.findAll(pageable); @@ -118,7 +133,35 @@ public InputStream downloadFile(String orgId, String path) { return null; } - public void deleteById(String id) { + @Override + public byte[] downloadZip(String bucketName, String objectName) { + + objectName = Base64.encodeBase64String(objectName.getBytes()); + String addr = minioUrl.substring(0, minioUrl.length()-5) + ":9001"; + + try { + URI uri = UriComponentsBuilder + .fromUriString(addr) + .path("/api/v1/buckets/{bucketName}/objects/download") + // .encode() + .queryParam("prefix", objectName) + .build() + .expand(bucketName, objectName) + .toUri(); + + log.error("uri {}", uri); + return HttpUtils.getForObject(uri); + + } catch (Exception ex) { + log.error("error {}", ex); + log.error("error.msg {}", ex.getMessage()); + // throw new CustomException(ErrorCode.URL_NOTFOUND); + } + + return null; + } + + public void deleteById(String id) { FileEntity fileEntity = findById(id); try { diff --git a/nw/src/main/java/lab/cherry/nw/service/Impl/MinioServiceImpl.java b/nw/src/main/java/lab/cherry/nw/service/Impl/MinioServiceImpl.java index 34ce5a0..0265774 100644 --- a/nw/src/main/java/lab/cherry/nw/service/Impl/MinioServiceImpl.java +++ b/nw/src/main/java/lab/cherry/nw/service/Impl/MinioServiceImpl.java @@ -1,34 +1,41 @@ package lab.cherry.nw.service.Impl; -import io.minio.*; +import java.io.IOException; +import java.io.InputStream; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import org.bouncycastle.crypto.InvalidCipherTextException; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; +import io.minio.BucketExistsArgs; +import io.minio.GetBucketPolicyArgs; +import io.minio.GetObjectArgs; +import io.minio.GetPresignedObjectUrlArgs; +import io.minio.ListObjectsArgs; +import io.minio.MakeBucketArgs; +import io.minio.MinioClient; +import io.minio.PutObjectArgs; +import io.minio.RemoveBucketArgs; +import io.minio.RemoveObjectArgs; +import io.minio.RemoveObjectsArgs; +import io.minio.Result; +import io.minio.SetBucketPolicyArgs; import io.minio.admin.MinioAdminClient; import io.minio.admin.UserInfo; -import io.minio.errors.*; +import io.minio.errors.MinioException; import io.minio.http.Method; import io.minio.messages.DeleteError; import io.minio.messages.DeleteObject; import io.minio.messages.Item; import lab.cherry.nw.model.UserEntity; import lab.cherry.nw.service.MinioService; -import lab.cherry.nw.service.UserService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.bouncycastle.crypto.InvalidCipherTextException; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.stereotype.Service; -import org.springframework.web.multipart.MultipartFile; - -import java.io.IOException; -import java.io.InputStream; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -import org.springframework.beans.factory.annotation.Value; @Slf4j @Service @@ -153,7 +160,7 @@ public InputStream getObject(String bucketName, String objectName) throws IOExce log.error("Minio Connect Check : {}", isMinioConnected()); - log.error("bucketName is {}, objectName is {}", bucketName, objectName); + log.error("\nbucketName is {}\nobjectName is {}\n", bucketName, objectName); // bucketName에 있는 objectName을 조회합니다. InputStream stream = minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(objectName).build()); @@ -341,6 +348,9 @@ public String getPresignedURL(String bucketName, String objectName) throws IOExc Map reqParams = new HashMap(); reqParams.put("response-content-type", "application/json"); + log.error("bucketName {}", bucketName); + log.error("objectName {}", objectName); + // Presigned URL 생성 return minioClient.getPresignedObjectUrl( GetPresignedObjectUrlArgs.builder() @@ -350,6 +360,7 @@ public String getPresignedURL(String bucketName, String objectName) throws IOExc .expiry(1, TimeUnit.HOURS) // 시간 .extraQueryParams(reqParams) .build()); + } catch (MinioException e) { log.error("Error occurred: " + e); } diff --git a/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetServiceImpl.java b/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetServiceImpl.java index 861c2d9..4f96cd0 100644 --- a/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetServiceImpl.java +++ b/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetServiceImpl.java @@ -7,17 +7,25 @@ import lab.cherry.nw.model.QsheetEntity; import lab.cherry.nw.model.UserEntity; import lab.cherry.nw.repository.QsheetRepository; +import lab.cherry.nw.service.FileService; import lab.cherry.nw.service.OrgService; import lab.cherry.nw.service.QsheetService; import lab.cherry.nw.service.UserService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; - +import java.io.ByteArrayOutputStream; +import java.io.IOException; import java.time.Instant; +import java.util.ArrayList; +import java.util.List; +import java.util.zip.ZipOutputStream; /** *
@@ -36,6 +44,7 @@ public class QsheetServiceImpl implements QsheetService {
     private final QsheetRepository qsheetRepository;
     private final UserService userService;
     private final OrgService orgService;
+    private final FileService fileService;
     /**
      * [QsheetServiceImpl] 전체 큐시트 조회 함수
      *
@@ -207,4 +216,53 @@ public Page findPageByOrgId(String orgid, Pageable pageable) {
         return qsheetRepository.findPageByOrgid(orgid, pageable);
     }
     
+    public byte[] download(List users) {
+        
+        List userList = new ArrayList<>();
+        List userData = new ArrayList<>();
+
+        for(String user : users) {
+            if (userService.checkId(user)) {
+                UserEntity _user = userService.findById(user);
+                userList.add(_user);
+
+                String objectName = _user.getId() +"/";
+                userData.add(fileService.downloadZip("user", objectName)); 
+            }
+        }
+
+        if(userList.size() > 1) {
+
+            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+            try (ZipOutputStream zipOut = new ZipOutputStream(byteArrayOutputStream)) {
+                for (UserEntity user : userList) {
+
+                        String objectName = user.getId() +"/";
+
+                        byte[] objectData = fileService.downloadZip("user", objectName);
+
+                        // Zip 아카이브에 객체 추가
+                        ZipArchiveEntry zipEntry = new ZipArchiveEntry(user.getUsername() + ".zip");
+                        zipOut.putNextEntry(zipEntry);
+                        zipOut.write(objectData);
+                        zipOut.closeEntry();
+
+                }
+            } catch (IOException e) {
+                log.error("{}", e);
+            }
+        
+            byte[] zipBytes = byteArrayOutputStream.toByteArray();
+            
+            return zipBytes;
+
+        } else {
+
+            UserEntity user = userService.findById(users.get(0));
+
+            String objectName = "사용자/" + user.getId();
+
+            return fileService.downloadZip(user.getOrg().getId(), objectName);
+        }
+    }
 }
diff --git a/nw/src/main/java/lab/cherry/nw/service/Impl/UserServiceImpl.java b/nw/src/main/java/lab/cherry/nw/service/Impl/UserServiceImpl.java
index fdc87b7..8d47443 100644
--- a/nw/src/main/java/lab/cherry/nw/service/Impl/UserServiceImpl.java
+++ b/nw/src/main/java/lab/cherry/nw/service/Impl/UserServiceImpl.java
@@ -179,4 +179,14 @@ public UserEntity findById(String id) {
     public Page findPageByUserId(String userid, Pageable pageable) {
         return userRepository.findPageByUserid(userid, pageable);
     }
+
+    public Boolean checkId(String id) {
+
+        // userSeq가 DB에 존재할 시, true
+        if(userRepository.findById(id).isPresent()) {
+            return true;
+        } else {
+            return false;
+        }
+    }
 }
diff --git a/nw/src/main/java/lab/cherry/nw/service/QsheetService.java b/nw/src/main/java/lab/cherry/nw/service/QsheetService.java
index c19bbf7..61ced63 100644
--- a/nw/src/main/java/lab/cherry/nw/service/QsheetService.java
+++ b/nw/src/main/java/lab/cherry/nw/service/QsheetService.java
@@ -1,6 +1,7 @@
 package lab.cherry.nw.service;
 
 import lab.cherry.nw.model.QsheetEntity;
+import java.util.List;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Component;
@@ -25,4 +26,5 @@ public interface QsheetService {
  Page findPageByUserId(String userid, Pageable pageable);
  Page findPageByOrgId(String orgid, Pageable pageable);
 // void updateOrgById(String id, List orgIds);
+byte[] download(List users);
 }
\ No newline at end of file
diff --git a/nw/src/main/java/lab/cherry/nw/service/UserService.java b/nw/src/main/java/lab/cherry/nw/service/UserService.java
index 775e127..07e5011 100644
--- a/nw/src/main/java/lab/cherry/nw/service/UserService.java
+++ b/nw/src/main/java/lab/cherry/nw/service/UserService.java
@@ -17,6 +17,7 @@
 public interface UserService {
     Page getUsers(Pageable pageable);
     UserEntity findById(String id);
+    Boolean checkId(String id);
 	UserEntity findByUserId(String userid);
     void updateById(String id, UserEntity.UserUpdateDto user);
     void deleteById(String id);
diff --git a/nw/src/main/java/lab/cherry/nw/util/HttpUtils.java b/nw/src/main/java/lab/cherry/nw/util/HttpUtils.java
new file mode 100644
index 0000000..c33523e
--- /dev/null
+++ b/nw/src/main/java/lab/cherry/nw/util/HttpUtils.java
@@ -0,0 +1,50 @@
+package lab.cherry.nw.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.ObjectInputStream;
+import java.net.URI;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.client.RestTemplate;
+import lombok.extern.slf4j.Slf4j;
+
+
+@Slf4j
+public class HttpUtils {
+
+	public static byte[] httpRequest(URI uri, String Method, HttpHeaders headers){
+
+		HttpMethod _method;
+
+		switch (Method) {
+			case "GET":
+				_method = HttpMethod.GET;
+			case "POST":
+				_method = HttpMethod.POST;
+			case "DELETE":
+				_method = HttpMethod.DELETE;
+			default:
+				_method = HttpMethod.GET;
+		}
+
+		RestTemplate restTemplate = new RestTemplate();
+		ResponseEntity result = restTemplate.exchange(uri, _method, new HttpEntity<>(headers), byte[].class);
+
+		return result.getBody();
+
+		// log.error("result {}", result);
+
+		// return result.getBody();
+
+	}
+
+
+	public static byte[] getForObject(URI uri){
+
+		RestTemplate restTemplate = new RestTemplate();
+		return restTemplate.getForObject(uri, byte[].class);
+
+	}	
+}
\ No newline at end of file

From adaa85f3312e537a72ca36b6a80d1aeaa3e3cb04 Mon Sep 17 00:00:00 2001
From: taking 
Date: Thu, 12 Oct 2023 11:44:42 +0000
Subject: [PATCH 04/14] Refactor: Organize Imports

---
 .../nw/configuration/email/EmailConfig.java   |  7 -----
 .../nw/controller/BookmarkController.java     | 25 +++++++++++-------
 .../cherry/nw/controller/EmailController.java |  7 ++---
 .../nw/controller/FinalTemplController.java   | 25 +++++++++++-------
 .../nw/controller/FinaldocsController.java    | 25 +++++++++++-------
 .../nw/controller/QsheetController.java       | 25 +++++++++++-------
 .../cherry/nw/controller/TagController.java   | 23 +++++++++-------
 .../nw/controller/UserCardController.java     | 26 ++++++++++++-------
 .../lab/cherry/nw/error/ErrorResponse.java    |  1 -
 .../java/lab/cherry/nw/model/BoardEntity.java | 14 +++++-----
 .../lab/cherry/nw/model/BookmarkEntity.java   | 18 +++++--------
 .../lab/cherry/nw/model/ScheduleEntity.java   | 22 ++++++++--------
 .../java/lab/cherry/nw/model/TagEntity.java   | 14 ++--------
 .../lab/cherry/nw/model/UserCardEntity.java   | 16 +++++-------
 .../cherry/nw/repository/OrgRepository.java   |  8 +++---
 15 files changed, 132 insertions(+), 124 deletions(-)

diff --git a/nw/src/main/java/lab/cherry/nw/configuration/email/EmailConfig.java b/nw/src/main/java/lab/cherry/nw/configuration/email/EmailConfig.java
index 8524e57..87a3594 100644
--- a/nw/src/main/java/lab/cherry/nw/configuration/email/EmailConfig.java
+++ b/nw/src/main/java/lab/cherry/nw/configuration/email/EmailConfig.java
@@ -1,7 +1,6 @@
 package lab.cherry.nw.configuration.email;
 
 import java.util.Properties;
-
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
@@ -9,12 +8,6 @@
 import org.springframework.mail.javamail.JavaMailSender;
 import org.springframework.mail.javamail.JavaMailSenderImpl;
 
-import org.springframework.boot.context.properties.ConfigurationProperties;
-
-import lombok.Getter;
-import lombok.Setter;
-import lombok.ToString;
-
 
 //@ConfigurationProperties(prefix = "mail")
 @Configuration
diff --git a/nw/src/main/java/lab/cherry/nw/controller/BookmarkController.java b/nw/src/main/java/lab/cherry/nw/controller/BookmarkController.java
index 8c3aaed..910872a 100644
--- a/nw/src/main/java/lab/cherry/nw/controller/BookmarkController.java
+++ b/nw/src/main/java/lab/cherry/nw/controller/BookmarkController.java
@@ -1,5 +1,21 @@
 package lab.cherry.nw.controller;
 
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PatchMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.media.Content;
 import io.swagger.v3.oas.annotations.media.Schema;
@@ -15,15 +31,6 @@
 import lab.cherry.nw.util.Common;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.bson.types.ObjectId;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.domain.Sort;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
 
 /**
  * 
diff --git a/nw/src/main/java/lab/cherry/nw/controller/EmailController.java b/nw/src/main/java/lab/cherry/nw/controller/EmailController.java
index e1c5a7d..87631d5 100644
--- a/nw/src/main/java/lab/cherry/nw/controller/EmailController.java
+++ b/nw/src/main/java/lab/cherry/nw/controller/EmailController.java
@@ -1,10 +1,11 @@
 package lab.cherry.nw.controller;
 
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
 import lab.cherry.nw.service.EmailService;
 import lombok.RequiredArgsConstructor;
-import org.springframework.data.crossstore.ChangeSetPersister;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
 
 @RestController
 @RequiredArgsConstructor
diff --git a/nw/src/main/java/lab/cherry/nw/controller/FinalTemplController.java b/nw/src/main/java/lab/cherry/nw/controller/FinalTemplController.java
index 907d70d..f30e5cf 100644
--- a/nw/src/main/java/lab/cherry/nw/controller/FinalTemplController.java
+++ b/nw/src/main/java/lab/cherry/nw/controller/FinalTemplController.java
@@ -1,5 +1,21 @@
 package lab.cherry.nw.controller;
 
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PatchMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.media.Content;
 import io.swagger.v3.oas.annotations.media.Schema;
@@ -11,19 +27,10 @@
 import lab.cherry.nw.error.ResultResponse;
 import lab.cherry.nw.error.enums.SuccessCode;
 import lab.cherry.nw.model.FinalTemplEntity;
-import lab.cherry.nw.model.OrgEntity;
 import lab.cherry.nw.service.FinalTemplService;
 import lab.cherry.nw.util.Common;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.domain.Sort;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
 
 /**
  * 
diff --git a/nw/src/main/java/lab/cherry/nw/controller/FinaldocsController.java b/nw/src/main/java/lab/cherry/nw/controller/FinaldocsController.java
index dfb23b0..5f8cfb3 100644
--- a/nw/src/main/java/lab/cherry/nw/controller/FinaldocsController.java
+++ b/nw/src/main/java/lab/cherry/nw/controller/FinaldocsController.java
@@ -1,5 +1,21 @@
 package lab.cherry.nw.controller;
 
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PatchMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.media.Content;
 import io.swagger.v3.oas.annotations.media.Schema;
@@ -11,19 +27,10 @@
 import lab.cherry.nw.error.ResultResponse;
 import lab.cherry.nw.error.enums.SuccessCode;
 import lab.cherry.nw.model.FinaldocsEntity;
-import lab.cherry.nw.model.OrgEntity;
 import lab.cherry.nw.service.FinaldocsService;
 import lab.cherry.nw.util.Common;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.domain.Sort;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
 
 /**
  * 
diff --git a/nw/src/main/java/lab/cherry/nw/controller/QsheetController.java b/nw/src/main/java/lab/cherry/nw/controller/QsheetController.java
index 646c8de..0f22e1e 100644
--- a/nw/src/main/java/lab/cherry/nw/controller/QsheetController.java
+++ b/nw/src/main/java/lab/cherry/nw/controller/QsheetController.java
@@ -1,5 +1,21 @@
 package lab.cherry.nw.controller;
 
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PatchMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.media.Content;
 import io.swagger.v3.oas.annotations.media.Schema;
@@ -15,15 +31,6 @@
 import lab.cherry.nw.util.Common;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import java.util.List;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.domain.Sort;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
 
 /**
  * 
diff --git a/nw/src/main/java/lab/cherry/nw/controller/TagController.java b/nw/src/main/java/lab/cherry/nw/controller/TagController.java
index c16d997..c757dbe 100644
--- a/nw/src/main/java/lab/cherry/nw/controller/TagController.java
+++ b/nw/src/main/java/lab/cherry/nw/controller/TagController.java
@@ -1,5 +1,19 @@
 package lab.cherry.nw.controller;
 
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.media.Content;
 import io.swagger.v3.oas.annotations.media.Schema;
@@ -15,15 +29,6 @@
 import lab.cherry.nw.util.Common;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.bson.types.ObjectId;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.domain.Sort;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
 
 /**
  * 
diff --git a/nw/src/main/java/lab/cherry/nw/controller/UserCardController.java b/nw/src/main/java/lab/cherry/nw/controller/UserCardController.java
index 0f8080f..1ace637 100644
--- a/nw/src/main/java/lab/cherry/nw/controller/UserCardController.java
+++ b/nw/src/main/java/lab/cherry/nw/controller/UserCardController.java
@@ -1,5 +1,21 @@
 package lab.cherry.nw.controller;
 
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PatchMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.media.Content;
 import io.swagger.v3.oas.annotations.media.Schema;
@@ -10,21 +26,11 @@
 import lab.cherry.nw.error.ErrorResponse;
 import lab.cherry.nw.error.ResultResponse;
 import lab.cherry.nw.error.enums.SuccessCode;
-import lab.cherry.nw.model.OrgEntity;
 import lab.cherry.nw.model.UserCardEntity;
-import lab.cherry.nw.service.OrgService;
 import lab.cherry.nw.service.UserCardService;
 import lab.cherry.nw.util.Common;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.domain.Sort;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
 
 /**
  * 
diff --git a/nw/src/main/java/lab/cherry/nw/error/ErrorResponse.java b/nw/src/main/java/lab/cherry/nw/error/ErrorResponse.java
index 278e402..070d808 100644
--- a/nw/src/main/java/lab/cherry/nw/error/ErrorResponse.java
+++ b/nw/src/main/java/lab/cherry/nw/error/ErrorResponse.java
@@ -1,6 +1,5 @@
 package lab.cherry.nw.error;
 
-import io.swagger.v3.oas.annotations.media.Schema;
 import lab.cherry.nw.error.enums.ErrorCode;
 import java.util.ArrayList;
 import java.util.List;
diff --git a/nw/src/main/java/lab/cherry/nw/model/BoardEntity.java b/nw/src/main/java/lab/cherry/nw/model/BoardEntity.java
index 6ec7de9..af67ee3 100644
--- a/nw/src/main/java/lab/cherry/nw/model/BoardEntity.java
+++ b/nw/src/main/java/lab/cherry/nw/model/BoardEntity.java
@@ -1,21 +1,19 @@
 package lab.cherry.nw.model;
 
+import java.io.Serializable;
+import java.time.Instant;
+import java.util.List;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.mapping.DBRef;
+import org.springframework.data.mongodb.core.mapping.Document;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonPropertyOrder;
 import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.Size;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Getter;
 import lombok.NoArgsConstructor;
-import org.springframework.data.annotation.Id;
-import org.springframework.data.mongodb.core.mapping.DBRef;
-import org.springframework.data.mongodb.core.mapping.Document;
-
-import java.io.Serializable;
-import java.time.Instant;
-import java.util.List;
 
 
 /**
diff --git a/nw/src/main/java/lab/cherry/nw/model/BookmarkEntity.java b/nw/src/main/java/lab/cherry/nw/model/BookmarkEntity.java
index 4812d03..20aeb37 100644
--- a/nw/src/main/java/lab/cherry/nw/model/BookmarkEntity.java
+++ b/nw/src/main/java/lab/cherry/nw/model/BookmarkEntity.java
@@ -1,25 +1,19 @@
 package lab.cherry.nw.model;
 
+import java.io.Serializable;
+import java.time.Instant;
+import java.util.Map;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.mapping.DBRef;
+import org.springframework.data.mongodb.core.mapping.Document;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonPropertyOrder;
 import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.Size;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Getter;
 import lombok.NoArgsConstructor;
-import org.springframework.data.annotation.Id;
-import org.springframework.data.mongodb.core.aggregation.VariableOperators;
-import org.springframework.data.mongodb.core.mapping.DBRef;
-import org.springframework.data.mongodb.core.mapping.Document;
-
-import java.io.Serializable;
-import java.time.Instant;
-import java.util.Comparator;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.stream.Collectors;
 
 
 /**
diff --git a/nw/src/main/java/lab/cherry/nw/model/ScheduleEntity.java b/nw/src/main/java/lab/cherry/nw/model/ScheduleEntity.java
index f479cb8..5c56bc9 100644
--- a/nw/src/main/java/lab/cherry/nw/model/ScheduleEntity.java
+++ b/nw/src/main/java/lab/cherry/nw/model/ScheduleEntity.java
@@ -1,20 +1,20 @@
 package lab.cherry.nw.model;
 
-import com.fasterxml.jackson.annotation.JsonFormat;
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.mapping.DBRef;
+import org.springframework.data.mongodb.core.mapping.Document;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonPropertyOrder;
 import io.swagger.v3.oas.annotations.media.Schema;
 import jakarta.validation.constraints.Size;
-import lombok.*;
-import org.springframework.data.annotation.Id;
-import org.springframework.data.mongodb.core.mapping.DBRef;
-import org.springframework.data.mongodb.core.mapping.Document;
-
-import java.io.Serializable;
-import java.time.Instant;
-import java.time.LocalDateTime;
-import java.util.List;
-import java.util.Map;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
 
 /**
  * 
diff --git a/nw/src/main/java/lab/cherry/nw/model/TagEntity.java b/nw/src/main/java/lab/cherry/nw/model/TagEntity.java
index 29064c6..114b84a 100644
--- a/nw/src/main/java/lab/cherry/nw/model/TagEntity.java
+++ b/nw/src/main/java/lab/cherry/nw/model/TagEntity.java
@@ -1,6 +1,7 @@
 package lab.cherry.nw.model;
 
-import com.fasterxml.jackson.annotation.JsonFormat;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.mapping.Document;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonPropertyOrder;
 import io.swagger.v3.oas.annotations.media.Schema;
@@ -9,17 +10,6 @@
 import lombok.Builder;
 import lombok.Getter;
 import lombok.NoArgsConstructor;
-import org.springframework.data.annotation.Id;
-import org.springframework.data.mongodb.core.mapping.DBRef;
-import org.springframework.data.mongodb.core.mapping.Document;
-
-import java.io.Serializable;
-import java.time.Instant;
-import java.util.Comparator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
 
 
 /**
diff --git a/nw/src/main/java/lab/cherry/nw/model/UserCardEntity.java b/nw/src/main/java/lab/cherry/nw/model/UserCardEntity.java
index cf10a51..247c426 100644
--- a/nw/src/main/java/lab/cherry/nw/model/UserCardEntity.java
+++ b/nw/src/main/java/lab/cherry/nw/model/UserCardEntity.java
@@ -1,24 +1,20 @@
 package lab.cherry.nw.model;
 
+import java.io.Serializable;
+import java.time.Instant;
+import java.util.Map;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.mapping.DBRef;
+import org.springframework.data.mongodb.core.mapping.Document;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonPropertyOrder;
 import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.Email;
 import jakarta.validation.constraints.Size;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Getter;
 import lombok.NoArgsConstructor;
-import org.springframework.data.annotation.Id;
-import org.springframework.data.mongodb.core.mapping.DBRef;
-import org.springframework.data.mongodb.core.mapping.Document;
-
-import java.io.Serializable;
-import java.time.Instant;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
 
 /**
  * 
diff --git a/nw/src/main/java/lab/cherry/nw/repository/OrgRepository.java b/nw/src/main/java/lab/cherry/nw/repository/OrgRepository.java
index 836ff60..6b3dc47 100644
--- a/nw/src/main/java/lab/cherry/nw/repository/OrgRepository.java
+++ b/nw/src/main/java/lab/cherry/nw/repository/OrgRepository.java
@@ -1,13 +1,11 @@
 package lab.cherry.nw.repository;
 
-import lab.cherry.nw.model.FinaldocsEntity;
-import lab.cherry.nw.model.OrgEntity;
+import java.util.List;
+import java.util.Optional;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.mongodb.repository.MongoRepository;
-
-import java.util.List;
-import java.util.Optional;
+import lab.cherry.nw.model.OrgEntity;
 
 
 /**

From 0a6c415e89e59764c4d55addcb8eb0eda4e0f6fc Mon Sep 17 00:00:00 2001
From: yby654 
Date: Thu, 12 Oct 2023 11:49:15 +0000
Subject: [PATCH 05/14] =?UTF-8?q?Chore:=20=EA=B2=8C=EC=8B=9C=ED=8C=90=20?=
 =?UTF-8?q?=ED=83=9C=EA=B7=B8=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../java/lab/cherry/nw/model/BoardEntity.java |   5 +-
 .../java/lab/cherry/nw/model/TagEntity.java   |  20 +--
 .../nw/service/Impl/BoardServiceImpl.java     | 120 ++++++++++++------
 .../nw/service/Impl/QsheetServiceImpl.java    |   2 -
 .../nw/service/Impl/TagServiceImpl.java       |   3 +-
 5 files changed, 93 insertions(+), 57 deletions(-)

diff --git a/nw/src/main/java/lab/cherry/nw/model/BoardEntity.java b/nw/src/main/java/lab/cherry/nw/model/BoardEntity.java
index 6ec7de9..a41142b 100644
--- a/nw/src/main/java/lab/cherry/nw/model/BoardEntity.java
+++ b/nw/src/main/java/lab/cherry/nw/model/BoardEntity.java
@@ -4,7 +4,6 @@
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonPropertyOrder;
 import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.Size;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Getter;
@@ -83,7 +82,7 @@ public static class BoardCreateDto {
 		@Schema(title = "큐시트 고유번호", example = "64f82e492948d933edfaa9c0")
 		private String qsheetSeq;
 		@Schema(title = "태그 목록")
-		private List tag;
+		private List tagList;
     }
 //
     @Getter
@@ -95,7 +94,7 @@ public static class BoardUpdateDto {
 		@Schema(title = "큐시트 고유번호", example = "64f82e492948d933edfaa9c0")
 		private String qsheetSeq;
 		@Schema(title = "태그 목록")
-		private List tag;
+		private List tagList;
     }
 
 }
diff --git a/nw/src/main/java/lab/cherry/nw/model/TagEntity.java b/nw/src/main/java/lab/cherry/nw/model/TagEntity.java
index 29064c6..021573c 100644
--- a/nw/src/main/java/lab/cherry/nw/model/TagEntity.java
+++ b/nw/src/main/java/lab/cherry/nw/model/TagEntity.java
@@ -1,6 +1,5 @@
 package lab.cherry.nw.model;
 
-import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonPropertyOrder;
 import io.swagger.v3.oas.annotations.media.Schema;
@@ -10,24 +9,15 @@
 import lombok.Getter;
 import lombok.NoArgsConstructor;
 import org.springframework.data.annotation.Id;
-import org.springframework.data.mongodb.core.mapping.DBRef;
 import org.springframework.data.mongodb.core.mapping.Document;
 
-import java.io.Serializable;
-import java.time.Instant;
-import java.util.Comparator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
 
 /**
  * 
- * ClassName : BoardEntity
+ * ClassName : TagEntity
  * Type : class
- * Description : 게시판과 관련된 Entity를 구성하고 있는 클래스입니다.
- * Related : BoardRepository, BoardServiceImpl
+ * Description : 태그와 관련된 Entity를 구성하고 있는 클래스입니다.
+ * Related : TagRepository, TagServiceImpl
  * 
*/ @Getter @@ -37,8 +27,8 @@ @JsonPropertyOrder({ "created_at"}) public class TagEntity { @Id - @JsonProperty("boardSeq") - @Schema(title = "게시판 고유번호", example = "38352658567418867") // (Long) Tsid + @JsonProperty("tagSeq") + @Schema(title = "태그 고유번호", example = "38352658567418867") // (Long) Tsid private String id; @JsonProperty("content") diff --git a/nw/src/main/java/lab/cherry/nw/service/Impl/BoardServiceImpl.java b/nw/src/main/java/lab/cherry/nw/service/Impl/BoardServiceImpl.java index 83931ed..db33b4a 100644 --- a/nw/src/main/java/lab/cherry/nw/service/Impl/BoardServiceImpl.java +++ b/nw/src/main/java/lab/cherry/nw/service/Impl/BoardServiceImpl.java @@ -5,11 +5,15 @@ import lab.cherry.nw.error.exception.EntityNotFoundException; import lab.cherry.nw.model.BoardEntity; import lab.cherry.nw.model.QsheetEntity; +import lab.cherry.nw.model.TagEntity; import lab.cherry.nw.model.UserEntity; +import lab.cherry.nw.model.TagEntity.TagCreateDto; import lab.cherry.nw.repository.BoardRepository; +import lab.cherry.nw.repository.TagRepository; import lab.cherry.nw.service.OrgService; import lab.cherry.nw.service.BoardService; import lab.cherry.nw.service.QsheetService; +import lab.cherry.nw.service.TagService; import lab.cherry.nw.service.UserService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -19,12 +23,14 @@ import org.springframework.transaction.annotation.Transactional; import java.time.Instant; +import java.util.LinkedList; +import java.util.List; /** *
  * ClassName : BoardServiceImpl
  * Type : class0.20
- * Description : 게시판 태그와 관련된 서비스 구현과 관련된 함수를 포함하고 있는 클래스입니다.
+ * Description : 게시물와 관련된 서비스 구현과 관련된 함수를 포함하고 있는 클래스입니다.
  * Related : spring-boot-starter-data-jpa
  * 
*/ @@ -37,14 +43,16 @@ public class BoardServiceImpl implements BoardService { private final BoardRepository boardRepository; private final UserService userService; private final QsheetService qsheetService; + private final TagService tagService; + private final TagRepository tagRepository; /** - * [BoardServiceImpl] 전체 게시판 태그 조회 함수 + * [BoardServiceImpl] 전체 게시물 조회 함수 * - * @return DB에서 전체 게시판 태그 정보 목록을 리턴합니다. - * @throws EntityNotFoundException 게시판 태그 정보가 없을 경우 예외 처리 발생 + * @return DB에서 전체 게시물 정보 목록을 리턴합니다. + * @throws EntityNotFoundException 게시물 정보가 없을 경우 예외 처리 발생 *
-     * 전체 게시판 태그를 조회하여, 게시판 태그 목록을 반환합니다.
+     * 전체 게시물을 조회하여, 게시물 목록을 반환합니다.
      * 
* * Author : yby654(yby654@github.com) @@ -59,13 +67,13 @@ public Page getBoards(Pageable pageable) { // /** - * [BoardServiceImpl] 게시판 태그 생성 함수 + * [BoardServiceImpl] 게시물 생성 함수 * - * @param boardCreateDto 게시판 태그 생성에 필요한 게시판 태그 등록 정보를 담은 개체입니다. - * @return 생성된 게시판 태그 정보를 리턴합니다. + * @param boardCreateDto 게시물 생성에 필요한 게시물 등록 정보를 담은 개체입니다. + * @return 생성된 게시물 정보를 리턴합니다. // * @throws CustomException 중복된 이름에 대한 예외 처리 발생 *
-     * 게시판 태그을 등록합니다.
+     * 게시물을 등록합니다.
      * 
* * Author : yby654(yby654@github.com) @@ -73,11 +81,31 @@ public Page getBoards(Pageable pageable) { public void createBoard(BoardEntity.BoardCreateDto boardCreateDto) { Instant instant = Instant.now(); UserEntity userEntity = userService.findById(boardCreateDto.getUserSeq()); - QsheetEntity qsheetEntity= qsheetService.findById(boardCreateDto.getQsheetSeq()); + QsheetEntity qsheetEntity= null; + if(boardCreateDto.getQsheetSeq()!=null){ + qsheetService.findById(boardCreateDto.getQsheetSeq()); + } + List tagList = new LinkedList<>(); + if(boardCreateDto.getTagList() !=null){ + for(String tag : boardCreateDto.getTagList()){ + TagEntity tagEntity = tagService.findByName(tag); + if(tagEntity !=null){ + tagList.add(tagEntity); + }else{ + TagEntity.TagCreateDto tagCreateDto=TagCreateDto.builder() + .name(tag) + .build(); + tagService.createTag(tagCreateDto); + TagEntity newTagEntity = tagService.findByName(tag); + tagList.add(newTagEntity); + } + } + } BoardEntity boardEntity = BoardEntity.builder() .userid(userEntity) .content(boardCreateDto.getContent()) .qsheet(qsheetEntity) + .tag(tagList) // .name(boardCreateDto.getName()) // .data(boardCreateDto.getData()) .created_at(instant) @@ -86,10 +114,10 @@ public void createBoard(BoardEntity.BoardCreateDto boardCreateDto) { } /** - * [BoardServiceImpl] 게시판 태그 수정 함수 + * [BoardServiceImpl] 게시물 수정 함수 * - * @param id 조회할 게시판 태그의 고유번호입니다. - * @param boardUpdateDto 게시판 태그 수정에 필요한 사용자 정보를 담은 개체입니다. + * @param id 조회할 게시물의 고유번호입니다. + * @param boardUpdateDto 게시물 수정에 필요한 사용자 정보를 담은 개체입니다. * @throws EntityNotFoundException 사용자 정보가 없을 경우 예외 처리 발생 *
      * 특정 게시물에 대해 정보를 수정합니다.
@@ -100,15 +128,35 @@ public void createBoard(BoardEntity.BoardCreateDto boardCreateDto) {
     public void updateById(String id, BoardEntity.BoardUpdateDto boardUpdateDto) {
         Instant instant = Instant.now();
         BoardEntity boardEntity = findById(id);
-		QsheetEntity qsheetEntity= qsheetService.findById(boardUpdateDto.getQsheetSeq());
+        
+		
+
+        List tagList =  new LinkedList<>();
+        if(boardUpdateDto.getTagList() !=null){
+            for(String tag : boardUpdateDto.getTagList()){
+                TagEntity tagEntity = tagService.findByName(tag);
+                if(tagEntity !=null){
+                    tagList.add(tagEntity);
+                }else{
+                    TagEntity.TagCreateDto tagCreateDto=TagCreateDto.builder()
+                    .name(tag)
+                    .build();
+                    tagService.createTag(tagCreateDto);
+                    TagEntity newTagEntity = tagService.findByName(tag);
+                    tagList.add(newTagEntity);
+                }
+            }
+        }else{
+            tagList=boardEntity.getTag();
+        }
 
 		if (boardEntity.getContent() != null || boardEntity.getQsheet()!=null|| boardEntity.getTag()!= null) {
 			boardEntity = BoardEntity.builder()
 			.id(boardEntity.getId())
 			.userid(boardEntity.getUserid())
-			.content(boardUpdateDto.getContent())
-			.qsheet(qsheetEntity)
-			.tag(boardEntity.getTag())
+			.content(boardUpdateDto.getContent() != null ? boardUpdateDto.getContent():boardEntity.getContent() )
+			.qsheet(boardUpdateDto.getQsheetSeq()!=null? qsheetService.findById(boardUpdateDto.getQsheetSeq()) : boardEntity.getQsheet())
+			.tag(tagList)
 			.updated_at(instant)
 			.build();
             boardRepository.save(boardEntity);
@@ -121,12 +169,12 @@ public void updateById(String id, BoardEntity.BoardUpdateDto boardUpdateDto) {
     }
 
     /**
-     * [BoardServiceImpl] 게시판 태그 삭제 함수
+     * [BoardServiceImpl] 게시물 삭제 함수
      *
-     * @param id 삭제할 게시판 태그의 식별자입니다.
-     * @throws EntityNotFoundException 해당 ID의 게시판 태그 정보가 없을 경우 예외 처리 발생
+     * @param id 삭제할 게시물의 식별자입니다.
+     * @throws EntityNotFoundException 해당 ID의 게시물 정보가 없을 경우 예외 처리 발생
      * 
-     * 입력한 id를 가진 게시판 태그 정보를 삭제합니다.
+     * 입력한 id를 가진 게시물 정보를 삭제합니다.
      * 
* * Author : yby654(yby654@github.com) @@ -138,12 +186,12 @@ public void deleteById(String id) { // /** -// * [BoardServiceImpl] 게시판 태그 이름 중복 체크 함수 +// * [BoardServiceImpl] 게시물 이름 중복 체크 함수 // * -// * @param name 중복 체크에 필요한 게시판 태그 이름 객체입니다. -// * @throws CustomException 게시판 태그의 이름이 중복된 경우 예외 처리 발생 +// * @param name 중복 체크에 필요한 게시물 이름 객체입니다. +// * @throws CustomException 게시물의 이름이 중복된 경우 예외 처리 발생 // *
-//     * 입력된 게시판 태그 이름으로 이미 등록된 게시판 태그이 있는지 확인합니다.
+//     * 입력된 게시물 이름으로 이미 등록된 게시물이 있는지 확인합니다.
 //     * 
// * // * Author : yby654(yby654@github.com) @@ -151,18 +199,18 @@ public void deleteById(String id) { // @Transactional(readOnly = true) // public void checkExistsWithBoardName(String name) { // if (boardRepository.findByName(name).isPresent()) { -// throw new CustomException(ErrorCode.DUPLICATE); // 게시판 태그 이름이 중복됨 +// throw new CustomException(ErrorCode.DUPLICATE); // 게시물 이름이 중복됨 // } // } // // /** -// * [BoardServiceImpl] NAME으로 게시판 태그 조회 함수 +// * [BoardServiceImpl] NAME으로 게시물 조회 함수 // * -// * @param name 조회할 게시판 태그의 이름입니다. -// * @return 주어진 이름에 해당하는 게시판 태그 정보를 리턴합니다. -// * @throws EntityNotFoundException 해당 이름의 게시판 태그 정보가 없을 경우 예외 처리 발생 +// * @param name 조회할 게시물의 이름입니다. +// * @return 주어진 이름에 해당하는 게시물 정보를 리턴합니다. +// * @throws EntityNotFoundException 해당 이름의 게시물 정보가 없을 경우 예외 처리 발생 // *
-//     * 입력한 name에 해당하는 게시판 태그 정보를 조회합니다.
+//     * 입력한 name에 해당하는 게시물 정보를 조회합니다.
 //     * 
// * // * Author : yby654(yby654@github.com) @@ -173,13 +221,13 @@ public void deleteById(String id) { // } // /** - * [BoardServiceImpl] ID로 게시판 태그 조회 함수 + * [BoardServiceImpl] ID로 게시물 조회 함수 * - * @param id 조회할 게시판 태그의 식별자입니다. - * @return 주어진 식별자에 해당하는 게시판 태그 정보 - * @throws EntityNotFoundException 해당 ID의 게시판 태그 정보가 없을 경우 예외 처리 발생 + * @param id 조회할 게시물의 식별자입니다. + * @return 주어진 식별자에 해당하는 게시물 정보 + * @throws EntityNotFoundException 해당 ID의 게시물 정보가 없을 경우 예외 처리 발생 *
-     * 입력한 id에 해당하는 게시판 태그 정보를 조회합니다.
+     * 입력한 id에 해당하는 게시물 정보를 조회합니다.
      * 
* * Author : yby654(yby654@github.com) diff --git a/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetServiceImpl.java b/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetServiceImpl.java index e0863a2..953b5fb 100644 --- a/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetServiceImpl.java +++ b/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetServiceImpl.java @@ -112,8 +112,6 @@ public void updateById(String id, QsheetEntity.QsheetUpdateDto qsheetUpdateDto) QsheetEntity qsheetEntity = findById(id); if (qsheetEntity.getData() != null ) { - log.error("qsheetEntity : {} ", qsheetEntity); - log.error("qsheetUpdateDto.getData() : {} ", qsheetUpdateDto.getData()); // qsheetEntity.updateFromDto(qsheetUpdateDto); // qsheetRepository.save(qsheetEntity); OrgEntity orgEntity = qsheetEntity.getOrgid(); diff --git a/nw/src/main/java/lab/cherry/nw/service/Impl/TagServiceImpl.java b/nw/src/main/java/lab/cherry/nw/service/Impl/TagServiceImpl.java index 7dc181e..0cc73fa 100644 --- a/nw/src/main/java/lab/cherry/nw/service/Impl/TagServiceImpl.java +++ b/nw/src/main/java/lab/cherry/nw/service/Impl/TagServiceImpl.java @@ -137,7 +137,8 @@ public void createTag(TagEntity.TagCreateDto tagCreateDto) { */ @Transactional(readOnly = true) public TagEntity findByName(String name) { - return tagRepository.findById(name).orElseThrow(() -> new EntityNotFoundException("Tag with Name " + name + " Not Found.")); + return tagRepository.findByName(name).orElse(null); + // return tagRepository.findByName(name).orElseThrow(() -> new EntityNotFoundException("Tag with Name " + name + " Not Found.")); } // // @Transactional(readOnly = true) From 39478e0a4b76445430f25bf7b80a93d9b5e8990f Mon Sep 17 00:00:00 2001 From: yby654 Date: Thu, 12 Oct 2023 13:35:53 +0000 Subject: [PATCH 06/14] =?UTF-8?q?Chore:=20=ED=81=90=EC=8B=9C=ED=8A=B8=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EC=97=85=EB=A1=9C=EB=93=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cherry/nw/controller/FileController.java | 10 ++++++- .../nw/controller/QsheetController.java | 7 +++-- .../nw/service/Impl/FileServiceImpl.java | 30 +++++++++++-------- .../nw/service/Impl/QsheetServiceImpl.java | 24 ++++++++++++++- .../lab/cherry/nw/service/QsheetService.java | 3 +- 5 files changed, 56 insertions(+), 18 deletions(-) diff --git a/nw/src/main/java/lab/cherry/nw/controller/FileController.java b/nw/src/main/java/lab/cherry/nw/controller/FileController.java index 3b1a93e..57242f5 100644 --- a/nw/src/main/java/lab/cherry/nw/controller/FileController.java +++ b/nw/src/main/java/lab/cherry/nw/controller/FileController.java @@ -3,6 +3,8 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; import java.util.List; import java.util.zip.ZipOutputStream; import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; @@ -176,7 +178,13 @@ public ResponseEntity downloadFile( String[] parts = objectName.split("/"); // 마지막 요소 확인 - String fileName = parts[parts.length - 1]; + String fileName = parts[parts.length - 1]; + + try { + fileName = URLEncoder.encode(fileName, "UTF-8"); + } catch (UnsupportedEncodingException e) { + log.error("{}", e); + } // 파일 다운로드를 위한 헤더 설정 HttpHeaders headers = new HttpHeaders(); diff --git a/nw/src/main/java/lab/cherry/nw/controller/QsheetController.java b/nw/src/main/java/lab/cherry/nw/controller/QsheetController.java index 0f22e1e..bb6b3b2 100644 --- a/nw/src/main/java/lab/cherry/nw/controller/QsheetController.java +++ b/nw/src/main/java/lab/cherry/nw/controller/QsheetController.java @@ -1,5 +1,6 @@ package lab.cherry.nw.controller; +import java.util.List; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; @@ -15,7 +16,9 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; @@ -102,9 +105,9 @@ public ResponseEntity findAllQsheets( @ApiResponse(responseCode = "400", description = "입력 값이 잘못 되었습니다.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), }) @Operation(summary = "Qsheet 생성", description = "Qsheet를 추가합니다.") - public ResponseEntity createQsheet(@Valid @RequestBody QsheetEntity.QsheetCreateDto qsheetCreateDto) { + public ResponseEntity createQsheet(@Valid @RequestPart QsheetEntity.QsheetCreateDto qsheetCreateDto, @RequestPart List files) { log.info("[QsheetController] createQsheet...!"); - qsheetService.createQsheet(qsheetCreateDto); + qsheetService.createQsheet(qsheetCreateDto, files); final ResultResponse response = ResultResponse.of(SuccessCode.OK); return new ResponseEntity<>(response, new HttpHeaders(), HttpStatus.OK); diff --git a/nw/src/main/java/lab/cherry/nw/service/Impl/FileServiceImpl.java b/nw/src/main/java/lab/cherry/nw/service/Impl/FileServiceImpl.java index 00a19d3..68e1dab 100644 --- a/nw/src/main/java/lab/cherry/nw/service/Impl/FileServiceImpl.java +++ b/nw/src/main/java/lab/cherry/nw/service/Impl/FileServiceImpl.java @@ -57,35 +57,39 @@ public Page getFiles(Pageable pageable) { public List uploadFiles(Map info, List files) { String orgId = info.get("org"); // 조직명 - String userName = info.get("user"); // 사용자명 - String type = info.get("type"); // 파일 구분명 + String userId = info.get("user"); // 사용자명 + String type = info.get("type"); + String qsheetSeq= info.get("qsheetSeq"); // 파일 구분명 + String bucketName = null; String destPath; - if (userName != null) { - // user가 입력되면, {org_objectId}/고객/{userName}으로 Path 지정 - destPath = "/고객/" + userName + "/"; + if (userId != null) { + // user가 입력되면, /user/{userId}으로 Path 지정 + bucketName = "user"; + destPath = userId + "/" + qsheetSeq +"/"; } else { // user값이 없을 시, {org_objectId}/관리/로 Path 지정 + bucketName = orgId; destPath = "/관리/"; } List fileObjectIds = new ArrayList<>(); for (MultipartFile file : files) { - String originalFilename = (userName != null) ? file.getOriginalFilename() : type + "/" + file.getOriginalFilename(); - String filePath = destPath + originalFilename; + String originalFilename = (userId != null) ? file.getOriginalFilename() : type + "/" + file.getOriginalFilename(); + String filepath = destPath + originalFilename; - log.error("filePath is {}", filePath); + log.error("objectName is {}", filepath); try { - minioService.uploadObject(orgId, filePath, file); + minioService.uploadObject(bucketName, filepath, file); } catch (IOException e) { log.error(e.getMessage()); } catch (NoSuchAlgorithmException | InvalidKeyException e) { throw new RuntimeException(e); } - String fileUrl = "/api/v1/file/download/" + orgId + "?path=" + filePath; + String fileUrl = "/api/v1/file/download/" + bucketName + "?path=" + filepath; // 파일 객체 ID 저장 fileObjectIds.add(fileUrl); @@ -93,10 +97,10 @@ public List uploadFiles(Map info, List fi .name(file.getOriginalFilename()) .size(FormatConverter.convertInputBytes(file.getSize())) .type(file.getContentType()) - .path(filePath) + .path(filepath) .url(fileUrl) - .userid(userName) - .orgid(orgId) + .userid(userId) + .orgid(bucketName) .created_at(Instant.now()) .build(); diff --git a/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetServiceImpl.java b/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetServiceImpl.java index 568793e..5f82952 100644 --- a/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetServiceImpl.java +++ b/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetServiceImpl.java @@ -14,6 +14,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; +import org.bson.types.ObjectId; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.http.HttpStatus; @@ -24,8 +25,11 @@ import java.io.IOException; import java.time.Instant; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.zip.ZipOutputStream; +import org.springframework.web.multipart.MultipartFile; /** *
@@ -77,11 +81,12 @@ public Page getQsheets(Pageable pageable) {
      *
      * Author : yby654(yby654@github.com)
      */
-    public void createQsheet(QsheetEntity.QsheetCreateDto qsheetCreateDto) {
+    public void createQsheet(QsheetEntity.QsheetCreateDto qsheetCreateDto, List files) {
         Instant instant = Instant.now();
         UserEntity userEntity = userService.findById(qsheetCreateDto.getUserSeq());
         OrgEntity orgEntity = null;
         UserEntity orgUserEntity = null; 
+        ObjectId objectid = new ObjectId();
         userService.findById(qsheetCreateDto.getUserSeq());
 		if (qsheetCreateDto.getOrgSeq() != null){
             orgEntity = orgService.findById(qsheetCreateDto.getOrgSeq());
@@ -89,7 +94,24 @@ public void createQsheet(QsheetEntity.QsheetCreateDto qsheetCreateDto) {
         if ( qsheetCreateDto.getOrg_approverSeq() != null){
             orgUserEntity = userService.findById(qsheetCreateDto.getOrg_approverSeq());
         }
+        
+        ////////////
+
+        log.error("name {}", qsheetCreateDto.getName());
+        log.error("memo {}", qsheetCreateDto.getMemo());
+
+		Map info = new HashMap<>();
+		info.put("type", "사용자");
+		info.put("user", userEntity.getId());
+        info.put("qsheetSeq", objectid.toString());
+
+        List fileUrls = fileService.uploadFiles(info, files);
+        log.error("fileUrls {}", fileUrls);
+        ////////////
+
+
         QsheetEntity qsheetEntity = QsheetEntity.builder()
+            .id(objectid.toString())
             .userid(userEntity)
             .orgid(orgEntity)
             .name(qsheetCreateDto.getName())
diff --git a/nw/src/main/java/lab/cherry/nw/service/QsheetService.java b/nw/src/main/java/lab/cherry/nw/service/QsheetService.java
index 61ced63..dbee2fa 100644
--- a/nw/src/main/java/lab/cherry/nw/service/QsheetService.java
+++ b/nw/src/main/java/lab/cherry/nw/service/QsheetService.java
@@ -5,6 +5,7 @@
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Component;
+import org.springframework.web.multipart.MultipartFile;
 
 /**
  * 
@@ -20,7 +21,7 @@ public interface QsheetService {
  QsheetEntity findById(String id);
 // QsheetEntity findByUserId(String userid);
 // QsheetEntity findByOrgId(String orgid);
- void createQsheet(QsheetEntity.QsheetCreateDto qsheetCreateDto);
+ void createQsheet(QsheetEntity.QsheetCreateDto qsheetCreateDto, List files);
  void updateById(String id, QsheetEntity.QsheetUpdateDto updateDto);
  void deleteById(String id);
  Page findPageByUserId(String userid, Pageable pageable);

From d9f6a471dae861b8020762fd9bbedf4427333f81 Mon Sep 17 00:00:00 2001
From: taking 
Date: Sat, 14 Oct 2023 03:12:32 +0000
Subject: [PATCH 07/14] Fix: Minor Updated

---
 application.properties_docker                                  | 3 +++
 .../main/java/lab/cherry/nw/controller/QsheetController.java   | 3 ++-
 nw/src/main/resources/application.properties_sample            | 3 +++
 3 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/application.properties_docker b/application.properties_docker
index 8da10b1..f338d91 100644
--- a/application.properties_docker
+++ b/application.properties_docker
@@ -12,6 +12,9 @@ server.port=8888
 #server.error.include-message=always
 server.servlet.encoding.charset=UTF-8
 server.servlet.encoding.force=true
+spring.servlet.multipart.max-file-size=3096MB
+spring.servlet.multipart.max-request-size=3096MB
+spring.servlet.multipart.enabled=true
 
 # Swagger springdoc-ui Configuration
 spring.messages.encoding=UTF-8
diff --git a/nw/src/main/java/lab/cherry/nw/controller/QsheetController.java b/nw/src/main/java/lab/cherry/nw/controller/QsheetController.java
index bb6b3b2..0f5f0fa 100644
--- a/nw/src/main/java/lab/cherry/nw/controller/QsheetController.java
+++ b/nw/src/main/java/lab/cherry/nw/controller/QsheetController.java
@@ -7,6 +7,7 @@
 import org.springframework.data.domain.Sort;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.DeleteMapping;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -99,7 +100,7 @@ public ResponseEntity findAllQsheets(
      *
      * Author : yby654(yby654@github.com)
      */
-    @PostMapping("")
+    @PostMapping(value = "", consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.MULTIPART_FORM_DATA_VALUE, MediaType.APPLICATION_OCTET_STREAM_VALUE})
     @ApiResponses(value = {
             @ApiResponse(responseCode = "200", description = "큐시트 생성이 완료되었습니다.", content = @Content(schema = @Schema(implementation = ResponseEntity.class))),
             @ApiResponse(responseCode = "400", description = "입력 값이 잘못 되었습니다.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))),
diff --git a/nw/src/main/resources/application.properties_sample b/nw/src/main/resources/application.properties_sample
index 3d30e37..7cc8fc9 100644
--- a/nw/src/main/resources/application.properties_sample
+++ b/nw/src/main/resources/application.properties_sample
@@ -12,6 +12,9 @@ server.port=8888
 #server.error.include-message=always
 server.servlet.encoding.charset=UTF-8
 server.servlet.encoding.force=true
+spring.servlet.multipart.max-file-size=3096MB
+spring.servlet.multipart.max-request-size=3096MB
+spring.servlet.multipart.enabled=true
 
 # Swagger springdoc-ui Configuration
 spring.messages.encoding=UTF-8

From 517fcbfd90545f008b2e4d6f174e00c4679f7290 Mon Sep 17 00:00:00 2001
From: yby654 
Date: Sat, 14 Oct 2023 16:33:15 +0000
Subject: [PATCH 08/14] =?UTF-8?q?Chore:=20=ED=81=90=EC=8B=9C=ED=8A=B8=20?=
 =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EC=97=85=EB=A1=9C=EB=93=9C=20=EC=88=98?=
 =?UTF-8?q?=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../nw/controller/QsheetController.java       |  24 +++-
 .../lab/cherry/nw/model/QsheetEntity.java     |   2 +
 .../nw/service/Impl/QsheetServiceImpl.java    | 103 +++++++++++++++---
 .../lab/cherry/nw/service/QsheetService.java  |   2 +-
 .../main/java/lab/cherry/nw/util/Common.java  |   6 +
 5 files changed, 114 insertions(+), 23 deletions(-)

diff --git a/nw/src/main/java/lab/cherry/nw/controller/QsheetController.java b/nw/src/main/java/lab/cherry/nw/controller/QsheetController.java
index bb6b3b2..6169833 100644
--- a/nw/src/main/java/lab/cherry/nw/controller/QsheetController.java
+++ b/nw/src/main/java/lab/cherry/nw/controller/QsheetController.java
@@ -8,6 +8,7 @@
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
+import org.springframework.util.CollectionUtils;
 import org.springframework.web.bind.annotation.DeleteMapping;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PatchMapping;
@@ -105,8 +106,16 @@ public ResponseEntity findAllQsheets(
             @ApiResponse(responseCode = "400", description = "입력 값이 잘못 되었습니다.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))),
     })
     @Operation(summary = "Qsheet 생성", description = "Qsheet를 추가합니다.")
-    public ResponseEntity createQsheet(@Valid @RequestPart QsheetEntity.QsheetCreateDto qsheetCreateDto, @RequestPart List files) {
+    public ResponseEntity createQsheet(@RequestPart QsheetEntity.QsheetCreateDto qsheetCreateDto, @RequestPart(required = false) List files) {
         log.info("[QsheetController] createQsheet...!");
+        log.error ("files : {}", files);
+        for(MultipartFile file:files){
+            if(file.isEmpty()){
+                files = null;
+                break;
+            }
+        }
+        
         qsheetService.createQsheet(qsheetCreateDto, files);
 
         final ResultResponse response = ResultResponse.of(SuccessCode.OK);
@@ -128,11 +137,16 @@ public ResponseEntity createQsheet(@Valid @RequestPart QsheetEntity.QsheetCre
      @Operation(summary = "큐시트 업데이트", description = "특정 큐시트를 업데이트합니다.")
     public ResponseEntity updateById(
             @PathVariable("id") String id,
-            @RequestBody QsheetEntity.QsheetUpdateDto qsheetUpdateDto) {
-
+            @RequestPart QsheetEntity.QsheetUpdateDto qsheetUpdateDto, @RequestPart(required = false) List files) {
+            
         log.info("[QsheetController] updateQsheet...!");
-
-        qsheetService.updateById(id, qsheetUpdateDto);
+        for(MultipartFile file:files){
+            if(file.isEmpty()){
+                files = null;
+                break;
+            }
+        }
+        qsheetService.updateById(id, qsheetUpdateDto, files);
 
 //        final ResultResponse response = ResultResponse.of(SuccessCode.OK);
         return new ResponseEntity<>(qsheetService.findById(id), new HttpHeaders(), HttpStatus.OK);
diff --git a/nw/src/main/java/lab/cherry/nw/model/QsheetEntity.java b/nw/src/main/java/lab/cherry/nw/model/QsheetEntity.java
index 4573812..d229797 100644
--- a/nw/src/main/java/lab/cherry/nw/model/QsheetEntity.java
+++ b/nw/src/main/java/lab/cherry/nw/model/QsheetEntity.java
@@ -162,6 +162,7 @@ public void sortDataByOrderIndex() {
 			data.sort(Comparator.comparingInt(ItemData::getOrderIndex));
 		}
 	}
+   
 //    public void sortDataByOrderIndex() {
 //        if (data != null) {
 //            data = data.entrySet()
@@ -175,6 +176,7 @@ public void sortDataByOrderIndex() {
 //                ));
 //        }
 //    }
+
     @Getter
     @Builder
     @NoArgsConstructor @AllArgsConstructor
diff --git a/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetServiceImpl.java b/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetServiceImpl.java
index 5f82952..a44ff7a 100644
--- a/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetServiceImpl.java
+++ b/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetServiceImpl.java
@@ -6,6 +6,7 @@
 import lab.cherry.nw.model.OrgEntity;
 import lab.cherry.nw.model.QsheetEntity;
 import lab.cherry.nw.model.UserEntity;
+import lab.cherry.nw.model.QsheetEntity.ItemData;
 import lab.cherry.nw.repository.QsheetRepository;
 import lab.cherry.nw.service.FileService;
 import lab.cherry.nw.service.OrgService;
@@ -14,11 +15,10 @@
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
+import org.apache.tomcat.jni.FileInfo;
 import org.bson.types.ObjectId;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import java.io.ByteArrayOutputStream;
@@ -96,18 +96,39 @@ public void createQsheet(QsheetEntity.QsheetCreateDto qsheetCreateDto, List newItemData = new ArrayList<>();
+        if (files != null){
+            Map info = new HashMap<>();
+            info.put("type", "사용자");
+            info.put("user", userEntity.getId());
+            info.put("qsheetSeq", objectid.toString());
 
-        log.error("name {}", qsheetCreateDto.getName());
-        log.error("memo {}", qsheetCreateDto.getMemo());
-
-		Map info = new HashMap<>();
-		info.put("type", "사용자");
-		info.put("user", userEntity.getId());
-        info.put("qsheetSeq", objectid.toString());
+            List fileUrls = fileService.uploadFiles(info, files);
+            log.error("fileUrls {}", fileUrls);
+            ////////////
+            
 
-        List fileUrls = fileService.uploadFiles(info, files);
-        log.error("fileUrls {}", fileUrls);
-        ////////////
+            for (ItemData data : qsheetCreateDto.getData()) {
+                for (String filePath : fileUrls) {
+                    if (filePath.contains(data.getFilePath())) {
+                        ItemData tempData = ItemData.builder()
+                            .orderIndex(data.getOrderIndex())
+                            .process(data.getProcess())
+                            .content(data.getContent())
+                            .actor(data.getActor())
+                            .note(data.getNote())
+                            .filePath(filePath)
+                            .build();
+                        data = tempData;
+                        break;
+                    }
+                }
+                newItemData.add(data);
+            }
+        }else{
+            newItemData = qsheetCreateDto.getData();
+        }
+		
 
 
         QsheetEntity qsheetEntity = QsheetEntity.builder()
@@ -115,7 +136,8 @@ public void createQsheet(QsheetEntity.QsheetCreateDto qsheetCreateDto, List files) {
         Instant instant = Instant.now();
         QsheetEntity qsheetEntity = findById(id);
+        List newItemData =qsheetEntity.getData();
 
-        if (qsheetEntity.getData() != null ) {
+        if (qsheetEntity != null ) {
 //            qsheetEntity.updateFromDto(qsheetUpdateDto);
 //            qsheetRepository.save(qsheetEntity);
 			OrgEntity orgEntity = qsheetEntity.getOrgid();
@@ -156,16 +179,62 @@ public void updateById(String id, QsheetEntity.QsheetUpdateDto qsheetUpdateDto)
                 }else{
                 log.error("[QsheetServiceImpl - udpateQsheet] org_approver와 isOrg_confirm 입력이 잘못되었습니다.");
                 throw new CustomException(ErrorCode.INVALID_INPUT_VALUE);
-            }
+                }
                 
             } 
+            if(files!=null){
+                newItemData= new ArrayList<>();
+                Map info = new HashMap<>();
+                info.put("type", "사용자");
+                info.put("user", qsheetEntity.getUserid().getId());
+                info.put("qsheetSeq", qsheetEntity.getId().toString());
+
+                List fileUrls = fileService.uploadFiles(info, files);
+                log.error("fileUrls {}", fileUrls);
+            ////////////
+                
+                for (ItemData data : qsheetUpdateDto.getData()) {
+                    for (String filePath : fileUrls) {
+                        if (filePath.contains(data.getFilePath())) {
+                            ItemData tempData = ItemData.builder()
+                                .orderIndex(data.getOrderIndex())
+                                .process(data.getProcess())
+                                .content(data.getContent())
+                                .actor(data.getActor())
+                                .note(data.getNote())
+                                .filePath(filePath)
+                                .build();
+                            data = tempData;
+                            break;
+                        }
+                    }
+                    newItemData.add(data);
+                }
+            }else if(qsheetUpdateDto.getData()!=null && files==null){
+                newItemData= new ArrayList<>();
+                List updateData = qsheetUpdateDto.getData();
+                for(int i = 0; i < updateData.size(); i++){
+                    ItemData tempData = ItemData.builder()
+                                .orderIndex(updateData.get(i).getOrderIndex())
+                                .process(updateData.get(i).getProcess())
+                                .content(updateData.get(i).getContent())
+                                .actor(updateData.get(i).getActor())
+                                .note(updateData.get(i).getNote())
+                                .filePath(qsheetEntity.getData().get(i).getFilePath())
+                                .build();
+                     newItemData.add(tempData);           
+                }
+            }
+            
+
+
 			qsheetEntity = QsheetEntity.builder()
 			.id(qsheetEntity.getId())
 			.name(qsheetEntity.getName())
 			.orgid(orgEntity)
 			.userid(qsheetEntity.getUserid())
 			.created_at(qsheetEntity.getCreated_at())
-			.data(qsheetUpdateDto.getData()!=null?qsheetUpdateDto.getData():qsheetEntity.getData())
+			.data(newItemData)
             .org_approver(orgUserEntity)
             .org_confirm(qsheetUpdateDto.isOrg_confirm()==!(qsheetEntity.isOrg_confirm())?qsheetUpdateDto.isOrg_confirm():qsheetEntity.isOrg_confirm())
             .client_confirm(qsheetUpdateDto.isClient_confirm()==!(qsheetEntity.isClient_confirm())?qsheetUpdateDto.isClient_confirm():qsheetEntity.isClient_confirm())
diff --git a/nw/src/main/java/lab/cherry/nw/service/QsheetService.java b/nw/src/main/java/lab/cherry/nw/service/QsheetService.java
index dbee2fa..5fe0873 100644
--- a/nw/src/main/java/lab/cherry/nw/service/QsheetService.java
+++ b/nw/src/main/java/lab/cherry/nw/service/QsheetService.java
@@ -22,7 +22,7 @@ public interface QsheetService {
 // QsheetEntity findByUserId(String userid);
 // QsheetEntity findByOrgId(String orgid);
  void createQsheet(QsheetEntity.QsheetCreateDto qsheetCreateDto, List files);
- void updateById(String id, QsheetEntity.QsheetUpdateDto updateDto);
+ void updateById(String id, QsheetEntity.QsheetUpdateDto updateDto, List files);
  void deleteById(String id);
  Page findPageByUserId(String userid, Pageable pageable);
  Page findPageByOrgId(String orgid, Pageable pageable);
diff --git a/nw/src/main/java/lab/cherry/nw/util/Common.java b/nw/src/main/java/lab/cherry/nw/util/Common.java
index abe34b7..62146cb 100644
--- a/nw/src/main/java/lab/cherry/nw/util/Common.java
+++ b/nw/src/main/java/lab/cherry/nw/util/Common.java
@@ -90,4 +90,10 @@ public static String getFileExtension(MultipartFile file) {
 			return ""; // 확장자가 없을 경우 빈 문자열 반환
 		}
 	}
+
+    public String getFileNameFromPath(String path) {
+        String[] parts = path.split("/");
+        return parts[parts.length - 1];
+    }
+    
 }
\ No newline at end of file

From 986329e376d6ab4bd9ea791d2a7b7fdf4e9e93b9 Mon Sep 17 00:00:00 2001
From: yby654 
Date: Sat, 14 Oct 2023 16:57:28 +0000
Subject: [PATCH 09/14] =?UTF-8?q?Chore:=20=ED=81=90=EC=8B=9C=ED=8A=B8=20?=
 =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EC=97=85=EB=A1=9C=EB=93=9C=20=EC=88=98?=
 =?UTF-8?q?=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../nw/service/Impl/QsheetServiceImpl.java    | 23 ++++++++++---------
 1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetServiceImpl.java b/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetServiceImpl.java
index 90aa320..e1fb92a 100644
--- a/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetServiceImpl.java
+++ b/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetServiceImpl.java
@@ -194,7 +194,7 @@ public void updateById(String id, QsheetEntity.QsheetUpdateDto qsheetUpdateDto,
                 
                 for (ItemData data : qsheetUpdateDto.getData()) {
                     for (String filePath : fileUrls) {
-                        if (filePath.contains(data.getFilePath())) {
+                            if (filePath.contains(data.getFilePath())) {
                             ItemData tempData = ItemData.builder()
                                 .orderIndex(data.getOrderIndex())
                                 .process(data.getProcess())
@@ -205,21 +205,22 @@ public void updateById(String id, QsheetEntity.QsheetUpdateDto qsheetUpdateDto,
                                 .build();
                             data = tempData;
                             break;
+                            }
                         }
-                    }
-                    newItemData.add(data);
+                         newItemData.add(data);
                 }
+           
+                   
             }else if(qsheetUpdateDto.getData()!=null && files==null){
                 newItemData= new ArrayList<>();
-                List updateData = qsheetUpdateDto.getData();
-                for(int i = 0; i < updateData.size(); i++){
+                for(ItemData data : qsheetUpdateDto.getData()){
                     ItemData tempData = ItemData.builder()
-                                .orderIndex(updateData.get(i).getOrderIndex())
-                                .process(updateData.get(i).getProcess())
-                                .content(updateData.get(i).getContent())
-                                .actor(updateData.get(i).getActor())
-                                .note(updateData.get(i).getNote())
-                                .filePath(qsheetEntity.getData().get(i).getFilePath())
+                                .orderIndex(data.getOrderIndex())
+                                .process(data.getProcess())
+                                .content(data.getContent())
+                                .actor(data.getActor())
+                                .note(data.getNote())
+                                .filePath(data.getFilePath())
                                 .build();
                      newItemData.add(tempData);           
                 }

From 13aaf5e956086cd49ecca7765f825df42b9a52d2 Mon Sep 17 00:00:00 2001
From: taking 
Date: Sun, 15 Oct 2023 10:27:26 +0000
Subject: [PATCH 10/14] Fix: MultipartFile Fix

---
 .../cherry/nw/controller/QsheetController.java   | 16 +---------------
 1 file changed, 1 insertion(+), 15 deletions(-)

diff --git a/nw/src/main/java/lab/cherry/nw/controller/QsheetController.java b/nw/src/main/java/lab/cherry/nw/controller/QsheetController.java
index d0462a6..52b30da 100644
--- a/nw/src/main/java/lab/cherry/nw/controller/QsheetController.java
+++ b/nw/src/main/java/lab/cherry/nw/controller/QsheetController.java
@@ -109,13 +109,6 @@ public ResponseEntity findAllQsheets(
     @Operation(summary = "Qsheet 생성", description = "Qsheet를 추가합니다.")
     public ResponseEntity createQsheet(@RequestPart QsheetEntity.QsheetCreateDto qsheetCreateDto, @RequestPart(required = false) List files) {
         log.info("[QsheetController] createQsheet...!");
-        log.error ("files : {}", files);
-        for(MultipartFile file:files){
-            if(file.isEmpty()){
-                files = null;
-                break;
-            }
-        }
         
         qsheetService.createQsheet(qsheetCreateDto, files);
 
@@ -139,14 +132,7 @@ public ResponseEntity createQsheet(@RequestPart QsheetEntity.QsheetCreateDto
     public ResponseEntity updateById(
             @PathVariable("id") String id,
             @RequestPart QsheetEntity.QsheetUpdateDto qsheetUpdateDto, @RequestPart(required = false) List files) {
-            
-        log.info("[QsheetController] updateQsheet...!");
-        for(MultipartFile file:files){
-            if(file.isEmpty()){
-                files = null;
-                break;
-            }
-        }
+                
         qsheetService.updateById(id, qsheetUpdateDto, files);
 
 //        final ResultResponse response = ResultResponse.of(SuccessCode.OK);

From 1ad2e68719ae4d87369fe63e6a2e7aab7223d3c3 Mon Sep 17 00:00:00 2001
From: taking 
Date: Tue, 17 Oct 2023 08:54:23 +0000
Subject: [PATCH 11/14] Fix: QSheet File Updated

---
 .../lab/cherry/nw/configuration/bean/BeanConfig.java  |  7 +++----
 .../lab/cherry/nw/controller/QsheetController.java    |  1 -
 .../lab/cherry/nw/service/Impl/QsheetServiceImpl.java | 11 +++++++----
 3 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/nw/src/main/java/lab/cherry/nw/configuration/bean/BeanConfig.java b/nw/src/main/java/lab/cherry/nw/configuration/bean/BeanConfig.java
index d2ce64f..ecf438a 100644
--- a/nw/src/main/java/lab/cherry/nw/configuration/bean/BeanConfig.java
+++ b/nw/src/main/java/lab/cherry/nw/configuration/bean/BeanConfig.java
@@ -1,7 +1,6 @@
 package lab.cherry.nw.configuration.bean;
 
-import lab.cherry.nw.service.security.CustomUserDetailsService;
-import lombok.RequiredArgsConstructor;
+import java.util.Arrays;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.data.mongodb.core.mapping.event.ValidatingMongoEventListener;
@@ -16,8 +15,8 @@
 import org.springframework.web.cors.CorsConfigurationSource;
 import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
 import org.yaml.snakeyaml.Yaml;
-
-import java.util.Arrays;
+import lab.cherry.nw.service.security.CustomUserDetailsService;
+import lombok.RequiredArgsConstructor;
 
 /**
  * 
diff --git a/nw/src/main/java/lab/cherry/nw/controller/QsheetController.java b/nw/src/main/java/lab/cherry/nw/controller/QsheetController.java
index 52b30da..4056e3d 100644
--- a/nw/src/main/java/lab/cherry/nw/controller/QsheetController.java
+++ b/nw/src/main/java/lab/cherry/nw/controller/QsheetController.java
@@ -200,7 +200,6 @@ public ResponseEntity downloadQsheetBySeq(@RequestBody QsheetEntity.QsheetDow
 
         HttpHeaders headers = new HttpHeaders();
         headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + "download.zip");
-
         return new ResponseEntity<>(qsheetService.download(qsheetDownloadDto.getUser()), new HttpHeaders(), HttpStatus.OK);
 
    }
diff --git a/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetServiceImpl.java b/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetServiceImpl.java
index e1fb92a..ef4ad00 100644
--- a/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetServiceImpl.java
+++ b/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetServiceImpl.java
@@ -244,7 +244,7 @@ public void updateById(String id, QsheetEntity.QsheetUpdateDto qsheetUpdateDto,
             //     .org_confirm(qsheetUpdateDto.getFinalConfirm().isOrg_confirm()==!(qsheetEntity.getFinalConfirm().isOrg_confirm())?qsheetUpdateDto.getFinalConfirm().isOrg_confirm():qsheetEntity.getFinalConfirm().isOrg_confirm())
             //     .client_confirm(qsheetUpdateDto.getFinalConfirm().isClient_confirm()==!(qsheetEntity.getFinalConfirm().isClient_confirm())?qsheetUpdateDto.getFinalConfirm().isClient_confirm():qsheetEntity.getFinalConfirm().isClient_confirm())    
             //     .build():qsheetEntity.getFinalConfirm() )
-            .memo(qsheetUpdateDto.getMemo())
+            .memo(qsheetUpdateDto.getMemo() != null ? qsheetUpdateDto.getMemo() : qsheetEntity.getMemo())
 			.updated_at(instant)
 			.build();
 			qsheetRepository.save(qsheetEntity);
@@ -340,17 +340,20 @@ public byte[] download(List users) {
         List userData = new ArrayList<>();
 
         for(String user : users) {
+
             if (userService.checkId(user)) {
                 UserEntity _user = userService.findById(user);
                 userList.add(_user);
 
-                String objectName = _user.getId() +"/";
-                userData.add(fileService.downloadZip("user", objectName)); 
+                // String objectName = _user.getId() + "/";
+                // userData.add(fileService.downloadZip("user", objectName));
             }
         }
 
         if(userList.size() > 1) {
 
+            log.error("userList 가 1명 초과인 경우 # ", userList.size());
+
             ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
             try (ZipOutputStream zipOut = new ZipOutputStream(byteArrayOutputStream)) {
                 for (UserEntity user : userList) {
@@ -380,7 +383,7 @@ public byte[] download(List users) {
 
             String objectName = "사용자/" + user.getId();
 
-            return fileService.downloadZip(user.getOrg().getId(), objectName);
+            return fileService.downloadZip("user", objectName);
         }
     }
 }

From 540893cca7f652db6e27458fd07bd231125798c8 Mon Sep 17 00:00:00 2001
From: taking 
Date: Wed, 25 Oct 2023 03:33:43 +0000
Subject: [PATCH 12/14] =?UTF-8?q?Chore:=20=ED=8C=8C=EC=9D=BC=20=EA=B4=80?=
 =?UTF-8?q?=EB=A6=AC=20=EA=B8=B0=EB=8A=A5=20-=20minio=20=EC=A0=9C=EA=B1=B0?=
 =?UTF-8?q?,=20GridFS=20=EC=B6=94=EA=B0=80=20Fix:=20Organize=20Imports?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 application.properties_docker                 |  10 +-
 docker-compose.yml                            |  28 +-
 docker-compose/.env                           |  11 +-
 docker-compose/docker-compose.yml             |  16 -
 .../cherry/nw/configuration/Initalizer.java   |  21 +-
 .../nw/configuration/bean/MinioConfig.java    |  84 ----
 .../nw/configuration/filter/JwtFilter.java    |   2 +-
 .../nw/controller/BanquetController.java      |   8 +-
 .../cherry/nw/controller/FileController.java  | 104 ++---
 .../nw/controller/PyebaeksilController.java   |   8 +-
 .../nw/controller/WeddinghallController.java  |   8 +-
 .../lab/cherry/nw/error/enums/ErrorCode.java  |   4 +-
 .../lab/cherry/nw/model/BanquetEntity.java    |   6 +-
 .../java/lab/cherry/nw/model/FileEntity.java  |  23 +-
 .../java/lab/cherry/nw/model/OrgEntity.java   |  21 +-
 .../lab/cherry/nw/model/PyebaeksilEntity.java |   6 +-
 .../java/lab/cherry/nw/model/UserEntity.java  |   2 +-
 .../cherry/nw/model/WeddinghallEntity.java    |   6 +-
 .../cherry/nw/repository/FileRepository.java  |   2 +-
 .../lab/cherry/nw/service/FileService.java    |   7 +-
 .../nw/service/Impl/BanquetServiceImpl.java   |  52 ++-
 .../nw/service/Impl/FileServiceImpl.java      | 324 +++++++++------
 .../nw/service/Impl/MinioServiceImpl.java     | 369 ------------------
 .../nw/service/Impl/OrgServiceImpl.java       |  44 +--
 .../service/Impl/PyebaeksilServiceImpl.java   |  38 +-
 .../service/Impl/WeddinghallServiceImpl.java  |  88 ++---
 .../lab/cherry/nw/service/MinioService.java   |  49 ---
 .../cherry/nw/service/WeddinghallService.java |   2 +-
 .../resources/application.properties_sample   |   6 +-
 29 files changed, 398 insertions(+), 951 deletions(-)
 delete mode 100644 nw/src/main/java/lab/cherry/nw/configuration/bean/MinioConfig.java
 delete mode 100644 nw/src/main/java/lab/cherry/nw/service/Impl/MinioServiceImpl.java
 delete mode 100644 nw/src/main/java/lab/cherry/nw/service/MinioService.java

diff --git a/application.properties_docker b/application.properties_docker
index f338d91..08a57ba 100644
--- a/application.properties_docker
+++ b/application.properties_docker
@@ -12,8 +12,8 @@ server.port=8888
 #server.error.include-message=always
 server.servlet.encoding.charset=UTF-8
 server.servlet.encoding.force=true
-spring.servlet.multipart.max-file-size=3096MB
-spring.servlet.multipart.max-request-size=3096MB
+spring.servlet.multipart.max-file-size=${MAX_UPLOAD_SIZE:3096MB}
+spring.servlet.multipart.max-request-size=${MAX_UPLOAD_SIZE:3096MB}
 spring.servlet.multipart.enabled=true
 
 # Swagger springdoc-ui Configuration
@@ -45,8 +45,4 @@ spring.mail.password=${SMTP_PASS:-passWord}
 #echo 'lab-cherry-nw-project-secret-key' | base64
 lab.cherry.nw.jwtSecret= bGFiLWNoZXJyeS1udy1wcm9qZWN0LXNlY3JldC1rZXkK
 lab.cherry.nw.jwtExpirationMs= 86400000
-
-# MinIo Properties
-minio.url=${MINIO_URL:-http://nw-storage:9000}
-minio.access-key=${MINIO_ACCESS_KEY:-admin}
-minio.secret-key=${MINIO_SECRET_KEY:-nangmanwedding}
\ No newline at end of file
+lab.cherry.nw.uploadPath= ${UPLOAD_PATH:/data}
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
index a53369f..c8ef642 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -12,6 +12,8 @@ services:
       DATABASE_NAME: nw
       DATABASE_USERID: nw
       DATABASE_USERPASS: nw
+      UPLOAD_PATH: /data
+      MAX_UPLOAD_SIZE: 3096MB
       #SPRING_PROFILES_ACTIVE: prod
       JAVA_OPTS: "-Xms256m -Xmx512m -XX:+UseG1GC"
     ports:
@@ -19,10 +21,8 @@ services:
     depends_on:
       - nw-db
       - nw-redis
-      - nw-storage
-    #    volumes:
-#      - ./log:/log/spring
-
+    volumes:
+      - ./nw_data:/data
 
   nw-db:
     image: 'bitnami/mongodb:latest'
@@ -55,22 +55,4 @@ services:
       - no-new-privileges:true
     volumes:
       - './redis_data:/data'
-      - '/etc/localtime:/etc/localtime:ro'
-
-
-  nw-storage:
-    image: 'minio/minio:RELEASE.2023-09-04T19-57-37Z'
-    container_name: nw-storage
-    command: server --console-address ":9001" /data
-    restart: unless-stopped
-    logging:
-      driver: json-file
-    environment:
-      MINIO_ACCESS_KEY: admin
-      MINIO_SECRET_KEY: nangmanwedding
-    ports:
-      - "9000:9000"
-      - "9001:9001"
-    volumes:
-      - './storage_data:/data'
-
+      - '/etc/localtime:/etc/localtime:ro'
\ No newline at end of file
diff --git a/docker-compose/.env b/docker-compose/.env
index e7feaef..3ee03b4 100644
--- a/docker-compose/.env
+++ b/docker-compose/.env
@@ -8,9 +8,8 @@ DATABASE_NAME=nw
 DATABASE_USERID=admin
 DATABASE_USERPASS=admin
 #SPRING_PROFILES_ACTIVE=prod
-MINIO_URL=http://nw-storage:9000
-MINIO_ACCESS_KEY=admin
-MINIO_SECRET_KEY=4FqfsKQUVWsca3MsAUVtgcf2  
+UPLOAD_PATH=/data
+MAX_UPLOAD_SIZE=3096MB
 REDIS_HOST=nw-redis
 REDIS_PORT=8083
 JAVA_OPTS="-Xms256m -Xmx512m -XX:+UseG1GC"
@@ -26,8 +25,4 @@ SMTP_PASS=null
 # nw-db
 MONGO_INITDB_DATABASE=nw
 MONGO_INITDB_ROOT_USERNAME=admin
-MONGO_INITDB_ROOT_PASSWORD=admin
-
-# nw-storage
-MINIO_ROOT_USER=admin
-MINIO_ROOT_PASSWORD=4FqfsKQUVWsca3MsAUVtgcf2
\ No newline at end of file
+MONGO_INITDB_ROOT_PASSWORD=admin
\ No newline at end of file
diff --git a/docker-compose/docker-compose.yml b/docker-compose/docker-compose.yml
index 58b44f1..ff310c9 100644
--- a/docker-compose/docker-compose.yml
+++ b/docker-compose/docker-compose.yml
@@ -10,7 +10,6 @@ services:
     ports:
       - "8081:8888"
     depends_on:
-      - nw-storage
       - nw-db
       - nw-redis
       - nw-smtp
@@ -42,21 +41,6 @@ services:
       - './redis_data:/data'
       - '/etc/localtime:/etc/localtime:ro'
 
-  nw-storage:
-    image: 'minio/minio:RELEASE.2023-09-04T19-57-37Z'
-    container_name: nw-storage
-    command: server --console-address ":9001" /data
-    restart: unless-stopped
-    logging:
-      driver: json-file
-    env_file:
-      - ./.env
-    ports:
-      - "9000:9000"
-      - "9001:9001"
-    volumes:
-      - './storage_data:/data'
-
   mailhog:
       image: jcalonso/mailhog
       container_name: 'mailhog'
diff --git a/nw/src/main/java/lab/cherry/nw/configuration/Initalizer.java b/nw/src/main/java/lab/cherry/nw/configuration/Initalizer.java
index 77772e9..cac656e 100644
--- a/nw/src/main/java/lab/cherry/nw/configuration/Initalizer.java
+++ b/nw/src/main/java/lab/cherry/nw/configuration/Initalizer.java
@@ -7,8 +7,9 @@
 import lab.cherry.nw.repository.OrgRepository;
 import lab.cherry.nw.repository.RoleRepository;
 import lab.cherry.nw.repository.UserRepository;
-import lab.cherry.nw.service.MinioService;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.boot.ApplicationArguments;
 import org.springframework.boot.ApplicationRunner;
 import org.springframework.security.crypto.password.PasswordEncoder;
@@ -18,20 +19,23 @@
 import java.security.NoSuchAlgorithmException;
 import java.time.Instant;
 
+@Slf4j
 @RequiredArgsConstructor
 @Component
 public class Initalizer implements ApplicationRunner {
+
+
+	@Value("${lab.cherry.nw.uploadPath}")
+	private String uploadPath;
     
     private final UserRepository userRepository;
     private final RoleRepository roleRepository;
     private final OrgRepository orgRepository;
     private final PasswordEncoder passwordEncoder;
-    private final MinioService minioService;
 
     @Override
     public void run(ApplicationArguments args) {
 
-
         if(roleRepository.findByName("ROLE_ADMIN").isEmpty()) {
 
             RoleEntity roleEntity = RoleEntity.builder()
@@ -58,6 +62,7 @@ public void run(ApplicationArguments args) {
                     .name("DEFAULT")
                     .biznum("123-45-67890")
                     .contact("02-0000-0000")
+                    .address("파인에비뉴")
                     .enabled(true)
                     .created_at(instant)
                     .build();
@@ -95,15 +100,5 @@ public void run(ApplicationArguments args) {
                 .enabled(true)
                 .build());
         }
-
-        // 'user' Bucket 생성
-        try {
-            minioService.createBucketIfNotExists("user");
-			minioService.createGlobalPolicy("user");
-			minioService.setBucketPolicy("user");
-        } catch (InvalidKeyException | NoSuchAlgorithmException | IOException e) {
-            // log.error("{}, e");
-            // e.printStackTrace();
-        }
     }
 }
\ No newline at end of file
diff --git a/nw/src/main/java/lab/cherry/nw/configuration/bean/MinioConfig.java b/nw/src/main/java/lab/cherry/nw/configuration/bean/MinioConfig.java
deleted file mode 100644
index ea30977..0000000
--- a/nw/src/main/java/lab/cherry/nw/configuration/bean/MinioConfig.java
+++ /dev/null
@@ -1,84 +0,0 @@
-package lab.cherry.nw.configuration.bean;
-
-import io.minio.MinioClient;
-import io.minio.admin.MinioAdminClient;
-import io.minio.errors.MinioException;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-/**
- * 
- * ClassName : MinioConfig
- * Type : class
- * Description : Minio 연결에 필요한 정보를 포함하고 있는 클래스입니다.
- * Related : All
- * 
- */ -@Slf4j -@Configuration -@RequiredArgsConstructor -public class MinioConfig { - - @Value("${minio.url}") - private String minioUrl; - - @Value("${minio.access-key}") - private String accessKey; - - @Value("${minio.secret-key}") - private String secretKey; - - - @Bean - public MinioAdminClient minioAdminClient() throws MinioException { - - log.error("url = {}", minioUrl); - log.error("accessKey = {}", accessKey); - log.error("secretKey = {}", secretKey); - - // Minio 클라이언트 생성 - MinioAdminClient adminClient = MinioAdminClient.builder() - .endpoint(minioUrl) - .credentials(accessKey, secretKey) - .build(); - - // 연결 및 작업 시간 제한 설정 - adminClient.setTimeout(10000, 10000, 10000); // connectTimeout, writeTimeout, readTimeout - - return adminClient; - } - - @Bean - public MinioClient minioClient() throws MinioException { - - log.error("url = {}", minioUrl); - log.error("accessKey = {}", accessKey); - log.error("secretKey = {}", secretKey); - - // Minio 클라이언트 생성 - MinioClient minioClient = MinioClient.builder() - .endpoint(minioUrl) - .credentials(accessKey, secretKey) - .build(); - - // 연결 및 작업 시간 제한 설정 - minioClient.setTimeout(10000, 10000, 10000); // connectTimeout, writeTimeout, readTimeout - - return minioClient; - } - - public boolean isMinioConnected() { - try { - // 버킷 목록을 가져와서 Minio 연결 상태 확인 - minioClient().listBuckets(); - return true; // 연결이 성공적으로 확인됨 - } catch (Exception e) { - // Minio 연결 예외 처리 - return false; // 연결 실패 - } - } - -} \ No newline at end of file diff --git a/nw/src/main/java/lab/cherry/nw/configuration/filter/JwtFilter.java b/nw/src/main/java/lab/cherry/nw/configuration/filter/JwtFilter.java index 781c077..01451cd 100644 --- a/nw/src/main/java/lab/cherry/nw/configuration/filter/JwtFilter.java +++ b/nw/src/main/java/lab/cherry/nw/configuration/filter/JwtFilter.java @@ -49,7 +49,7 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse } - private boolean checkAccessToken(AccessToken accessToken) { + private Boolean checkAccessToken(AccessToken accessToken) { if (accessToken == null) return false; return tokenService.validateToken(accessToken); } diff --git a/nw/src/main/java/lab/cherry/nw/controller/BanquetController.java b/nw/src/main/java/lab/cherry/nw/controller/BanquetController.java index 9fea424..bf000d3 100644 --- a/nw/src/main/java/lab/cherry/nw/controller/BanquetController.java +++ b/nw/src/main/java/lab/cherry/nw/controller/BanquetController.java @@ -103,15 +103,11 @@ public ResponseEntity findAllBanquets( @ApiResponse(responseCode = "400", description = "입력 값이 잘못되었습니다.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))) }) public ResponseEntity createBanquet(@Valid @RequestPart BanquetEntity.BanquetCreateDto banquetCreateDto, - @RequestPart List files) { + @RequestPart List images) { log.info("[BanquetController] createBanquet...!"); - - log.error("이름 : {}", banquetCreateDto.getBanquetName()); - log.error("조직 : {}", banquetCreateDto.getOrg()); - log.error("이미지 : {}", files); - BanquetEntity banquetEntity = banquetService.createBanquet(banquetCreateDto, files); + BanquetEntity banquetEntity = banquetService.createBanquet(banquetCreateDto, images); return new ResponseEntity<>(banquetEntity, new HttpHeaders(), HttpStatus.OK); } diff --git a/nw/src/main/java/lab/cherry/nw/controller/FileController.java b/nw/src/main/java/lab/cherry/nw/controller/FileController.java index 57242f5..804857d 100644 --- a/nw/src/main/java/lab/cherry/nw/controller/FileController.java +++ b/nw/src/main/java/lab/cherry/nw/controller/FileController.java @@ -1,14 +1,10 @@ package lab.cherry.nw.controller; -import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; -import java.util.List; -import java.util.zip.ZipOutputStream; -import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; -import org.springframework.core.io.InputStreamResource; +import java.util.Map; +import org.springframework.core.io.ByteArrayResource; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; @@ -128,90 +124,42 @@ public ResponseEntity findByFilePath(@RequestParam(required = true) String pa * @return 특정 파일을 반환합니다. * * Author : taking(taking@duck.com) + * @throws IOException + * @throws IllegalStateException */ - @GetMapping("/download/{orgId}") + @GetMapping("/download/{file_id}") @Operation(summary = "특정 파일 다운로드", description = "특정 파일을 다운로드합니다.") - public ResponseEntity downloadFile( - @RequestParam(required = false) Boolean qsheet, - @RequestParam(required = false) List path, - @PathVariable String orgId) { + public ResponseEntity downloadFile(@PathVariable String file_id) throws IllegalStateException, IOException { - if(path.size() > 1) { + FileEntity.LoadFile file = fileService.downloadFile(file_id); - ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - try (ZipOutputStream zipOut = new ZipOutputStream(byteArrayOutputStream)) { - for (String data : path) { - - String[] parts = data.split("/"); - String fileName = parts[parts.length - 1]; - - byte[] objectData = fileService.downloadZip(orgId, data); - - // Zip 아카이브에 객체 추가 - ZipArchiveEntry zipEntry = new ZipArchiveEntry(fileName + ".zip"); - zipOut.putNextEntry(zipEntry); - zipOut.write(objectData); - zipOut.closeEntry(); - - } - } catch (IOException e) { - log.error("{}", e); - } + String fileName = null; + try { + fileName = URLEncoder.encode(file.getName(), "UTF-8"); + } catch (UnsupportedEncodingException e) { + log.error("{}", e); + } - byte[] zipBytes = byteArrayOutputStream.toByteArray(); - - HttpHeaders headers = new HttpHeaders(); - headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + "download.zip"); - - return new ResponseEntity<>(zipBytes, headers, HttpStatus.OK); - - } else { - - String objectName = path.get(0); - - if(chkExtension(path.get(0))) { - - // MinioService를 사용하여 MinIO 서버로부터 파일을 가져옵니다. - InputStream fileInputStream = fileService.downloadFile(orgId, objectName); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.parseMediaType(file.getType())); + headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\""); - // 문자열을 '/'로 분할 - String[] parts = objectName.split("/"); - - // 마지막 요소 확인 - String fileName = parts[parts.length - 1]; - - try { - fileName = URLEncoder.encode(fileName, "UTF-8"); - } catch (UnsupportedEncodingException e) { - log.error("{}", e); - } - - // 파일 다운로드를 위한 헤더 설정 - HttpHeaders headers = new HttpHeaders(); - headers.setContentDispositionFormData("attachment", fileName); // 다운로드할 때 파일 이름 지정 - headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); - - // 파일 스트림을 InputStreamResource로 래핑하여 응답합니다. - InputStreamResource resource = new InputStreamResource(fileInputStream); - - return new ResponseEntity<>(resource, headers, HttpStatus.OK); - - } else { + return new ResponseEntity<>(new ByteArrayResource(file.getFile()), headers, HttpStatus.OK); + } - // 파일 다운로드를 위한 헤더 설정 - HttpHeaders headers = new HttpHeaders(); - headers.setContentDispositionFormData("attachment", "download.zip"); // 다운로드할 때 파일 이름 지정 - headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); + @GetMapping("/downloads/{id}") + @Operation(summary = "특정 파일 그룹 다운로드", description = "특정 그룹의 파일을 일괄 다운로드합니다. (ex. 웨딩홀 Seq, 연회장 Seq, 큐시트 Seq 등)") + public ResponseEntity downloadFiles(@PathVariable String id) { - return new ResponseEntity<>(fileService.downloadZip(orgId, objectName), headers, HttpStatus.OK); + Map val = fileService.downloadFiles("seq", id); - } - - } + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.parseMediaType("application/zip")); + headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + val.get("name") + "\""); + return new ResponseEntity<>(val.get("data"), headers, HttpStatus.OK); } - /** * [FileController] 특정 파일 삭제 함수 * diff --git a/nw/src/main/java/lab/cherry/nw/controller/PyebaeksilController.java b/nw/src/main/java/lab/cherry/nw/controller/PyebaeksilController.java index a72afc8..bd848c1 100644 --- a/nw/src/main/java/lab/cherry/nw/controller/PyebaeksilController.java +++ b/nw/src/main/java/lab/cherry/nw/controller/PyebaeksilController.java @@ -103,15 +103,11 @@ public ResponseEntity findAllPyebaeksils( @ApiResponse(responseCode = "400", description = "입력 값이 잘못되었습니다.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))) }) public ResponseEntity createPyebaeksil(@Valid @RequestPart PyebaeksilEntity.PyebaeksilCreateDto pyebaeksilCreateDto, - @RequestPart List files) { + @RequestPart List images) { log.info("[PyebaeksilController] createPyebaeksil...!"); - - log.error("이름 : {}", pyebaeksilCreateDto.getPyebaeksilName()); - log.error("조직 : {}", pyebaeksilCreateDto.getOrg()); - log.error("이미지 : {}", files); - PyebaeksilEntity pyebaeksilEntity = pyebaeksilService.createPyebaeksil(pyebaeksilCreateDto, files); + PyebaeksilEntity pyebaeksilEntity = pyebaeksilService.createPyebaeksil(pyebaeksilCreateDto, images); return new ResponseEntity<>(pyebaeksilEntity, new HttpHeaders(), HttpStatus.OK); } diff --git a/nw/src/main/java/lab/cherry/nw/controller/WeddinghallController.java b/nw/src/main/java/lab/cherry/nw/controller/WeddinghallController.java index 2f4ced5..bdae561 100644 --- a/nw/src/main/java/lab/cherry/nw/controller/WeddinghallController.java +++ b/nw/src/main/java/lab/cherry/nw/controller/WeddinghallController.java @@ -103,15 +103,11 @@ public ResponseEntity findAllWeddinghalls( @ApiResponse(responseCode = "400", description = "입력 값이 잘못되었습니다.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))) }) public ResponseEntity createWeddinghall(@Valid @RequestPart WeddinghallEntity.WeddinghallCreateDto weddinghallCreateDto, - @RequestPart List files) { + @RequestPart List images) { log.info("[WeddinghallController] createWeddinghall...!"); - - log.error("이름 : {}", weddinghallCreateDto.getWeddinghallName()); - log.error("조직 : {}", weddinghallCreateDto.getOrg()); - log.error("이미지 : {}", files); - WeddinghallEntity weddinghallEntity = weddinghallService.createWeddinghall(weddinghallCreateDto, files); + WeddinghallEntity weddinghallEntity = weddinghallService.createWeddinghall(weddinghallCreateDto, images); return new ResponseEntity<>(weddinghallEntity, new HttpHeaders(), HttpStatus.OK); } diff --git a/nw/src/main/java/lab/cherry/nw/error/enums/ErrorCode.java b/nw/src/main/java/lab/cherry/nw/error/enums/ErrorCode.java index 24bf4f3..033ddb4 100644 --- a/nw/src/main/java/lab/cherry/nw/error/enums/ErrorCode.java +++ b/nw/src/main/java/lab/cherry/nw/error/enums/ErrorCode.java @@ -30,7 +30,9 @@ public enum ErrorCode { ACCESS_DENIED_EXCEPTION(401, "인증 정보가 유효하지 않습니다."), DUPLICATE(409, "중복된 데이터가 있습니다."), NO_BODY(400, "파라미터 값이 입력되지 않았습니다."), - URL_NOTFOUND(400, "Minio URL을 다시 확인해주세요."); + URL_NOTFOUND(400, "Minio URL을 다시 확인해주세요."), + FILE_UPLOAD_FAILED(400, "파일 업로드에 실패했습니다."), + FOLDER_CREATE_FAILED(400, "uploadPath를 찾을 수 없습니다."); private final int status; private final String message; diff --git a/nw/src/main/java/lab/cherry/nw/model/BanquetEntity.java b/nw/src/main/java/lab/cherry/nw/model/BanquetEntity.java index b45f16b..f333dd3 100644 --- a/nw/src/main/java/lab/cherry/nw/model/BanquetEntity.java +++ b/nw/src/main/java/lab/cherry/nw/model/BanquetEntity.java @@ -93,9 +93,9 @@ public static class BanquetCreateDto { @Range(min = 1, max = 300, message = "연회장의 최대인원은 1인 이상 300명 이하만 입력 가능합니다.") private Integer maxPerson; - @NotNull(message = "[필수] Org 정보") - @Schema(title = "Org 정보", example = "더모멘트") - private String org; + @NotNull(message = "[필수] Org 고유번호") + @Schema(title = "Org 정보", example = "64ed89aa9e813b5ab16da6de") + private String orgId; @NotNull(message = "[필수] 연회장 행사 시간 간격") @Schema(title = "연회장 행사 시간 간격", example = "30") diff --git a/nw/src/main/java/lab/cherry/nw/model/FileEntity.java b/nw/src/main/java/lab/cherry/nw/model/FileEntity.java index f409517..aba086a 100644 --- a/nw/src/main/java/lab/cherry/nw/model/FileEntity.java +++ b/nw/src/main/java/lab/cherry/nw/model/FileEntity.java @@ -7,6 +7,7 @@ import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; +import lombok.Data; import lombok.Getter; import lombok.NoArgsConstructor; import org.springframework.data.annotation.Id; @@ -60,18 +61,28 @@ public class FileEntity implements Serializable { @Schema(title = "파일 사이즈", example = "20MB") private String size; - @JsonProperty("userId") - @Schema(title = "사용자 아이디", example = "admin") - private String userid; + @JsonProperty("userName") + @Schema(title = "사용자명", example = "체리랩") + private String userName; @NotNull - @JsonProperty("orgId") - @Schema(title = "조직 고유번호", example = "64ed89aa9e813b5ab16da6dd") - private String orgid; + @JsonProperty("orgName") + @Schema(title = "조직명", example = "더모멘트") + private String orgName; @JsonProperty("created_at") @JsonFormat(pattern="yyyy-MM-dd hh:mm:ss", locale = "ko_KR", timezone = "Asia/Seoul") @Schema(title = "조직 생성 시간", example = "2023-07-04 12:00:00") private Instant created_at; + + + @Data + @NoArgsConstructor @AllArgsConstructor + public static class LoadFile { + private String name; + private String type; + private String size; + private byte[] file; + } } \ No newline at end of file diff --git a/nw/src/main/java/lab/cherry/nw/model/OrgEntity.java b/nw/src/main/java/lab/cherry/nw/model/OrgEntity.java index 3072b7c..be018c2 100644 --- a/nw/src/main/java/lab/cherry/nw/model/OrgEntity.java +++ b/nw/src/main/java/lab/cherry/nw/model/OrgEntity.java @@ -63,7 +63,7 @@ public class OrgEntity implements Serializable { @JsonProperty("orgEnabled") @Schema(title = "조직 활성화 여부", example = "true") - private boolean enabled; + private Boolean enabled; @JsonProperty("created_at") @JsonFormat(pattern="yyyy-MM-dd hh:mm:ss", locale = "ko_KR", timezone = "Asia/Seoul") @@ -87,22 +87,22 @@ public static class OrgCreateDto { @NotBlank @Schema(title = "조직 이름", example = "더모멘트") @Size(min = 4, max = 20, message = "Minimum name length: 4 characters") - private String name; + private String orgName; @NotBlank @Schema(title = "조직 사업자번호", example = "123-45-67890") @Size(min = 4, max = 40, message = "Minimum biznum length: 4 characters") - private String biznum; + private String orgBiznum; @NotBlank @Schema(title = "조직 연락처", example = "02-0000-0000") @Size(min = 4, max = 40, message = "Minimum contact length: 4 characters") - private String contact; + private String orgContact; @NotBlank @Schema(title = "조직 주소", example = "서울시 종로구 파인애플주스 A동") @Size(min = 4, max = 255, message = "Minimum address length: 4 characters") - private String address; + private String orgAddress; } @@ -113,19 +113,22 @@ public static class OrgUpdateDto { @Schema(title = "조직 이름", example = "더모멘트") @Size(min = 4, max = 20, message = "Minimum name length: 4 characters") - private String name; + private String orgName; @Schema(title = "조직 사업자번호", example = "123-45-67890") @Size(min = 4, max = 40, message = "Minimum biznum length: 4 characters") - private String biznum; + private String orgBiznum; @Schema(title = "조직 연락처", example = "02-0000-0000") @Size(min = 4, max = 40, message = "Minimum contact length: 4 characters") - private String contact; + private String orgContact; @Schema(title = "조직 주소", example = "서울시 종로구 파인애플주스 A동") @Size(min = 4, max = 255, message = "Minimum address length: 4 characters") - private String address; + private String orgAddress; + + @Schema(title = "조직 활성화 여부", example = "true") + private Boolean orgEnabled; } } \ No newline at end of file diff --git a/nw/src/main/java/lab/cherry/nw/model/PyebaeksilEntity.java b/nw/src/main/java/lab/cherry/nw/model/PyebaeksilEntity.java index 32559f0..913b8e6 100644 --- a/nw/src/main/java/lab/cherry/nw/model/PyebaeksilEntity.java +++ b/nw/src/main/java/lab/cherry/nw/model/PyebaeksilEntity.java @@ -75,9 +75,9 @@ public static class PyebaeksilCreateDto { @Size(min = 4, max = 10, message = "폐백실 이름은 2글자 이상 10글자 이하만 입력 가능합니다.") private String pyebaeksilName; - @NotNull(message = "[필수] Org 정보") - @Schema(title = "Org 정보", example = "더모멘트") - private String org; + @NotNull(message = "[필수] Org 고유번호") + @Schema(title = "Org 정보", example = "64ed89aa9e813b5ab16da6de") + private String orgId; } } diff --git a/nw/src/main/java/lab/cherry/nw/model/UserEntity.java b/nw/src/main/java/lab/cherry/nw/model/UserEntity.java index 7af48c3..4915eb0 100644 --- a/nw/src/main/java/lab/cherry/nw/model/UserEntity.java +++ b/nw/src/main/java/lab/cherry/nw/model/UserEntity.java @@ -69,7 +69,7 @@ public class UserEntity implements Serializable { @JsonProperty("userEnabled") @Schema(title = "사용자 활성화 여부", example = "true") - private boolean enabled; + private Boolean enabled; @JsonProperty("emailVerified") @Schema(title = "이메일 인증 여부", example = "true") diff --git a/nw/src/main/java/lab/cherry/nw/model/WeddinghallEntity.java b/nw/src/main/java/lab/cherry/nw/model/WeddinghallEntity.java index e508b92..508d72a 100644 --- a/nw/src/main/java/lab/cherry/nw/model/WeddinghallEntity.java +++ b/nw/src/main/java/lab/cherry/nw/model/WeddinghallEntity.java @@ -93,9 +93,9 @@ public static class WeddinghallCreateDto { @Range(min = 1, max = 300, message = "웨딩홀(예식장)의 최대인원은 1인 이상 300명 이하만 입력 가능합니다.") private Integer maxPerson; - @NotNull(message = "[필수] Org 정보") - @Schema(title = "Org 정보", example = "더모멘트") - private String org; + @NotNull(message = "[필수] Org 고유번호") + @Schema(title = "Org 정보", example = "64ed89aa9e813b5ab16da6de") + private String orgId; @NotNull(message = "[필수] 웨딩홀(예식장) 행사 시간 간격") @Schema(title = "웨딩홀(예식장) 행사 시간 간격", example = "30") diff --git a/nw/src/main/java/lab/cherry/nw/repository/FileRepository.java b/nw/src/main/java/lab/cherry/nw/repository/FileRepository.java index 89dd051..07a5eaa 100644 --- a/nw/src/main/java/lab/cherry/nw/repository/FileRepository.java +++ b/nw/src/main/java/lab/cherry/nw/repository/FileRepository.java @@ -21,7 +21,7 @@ public interface FileRepository extends MongoRepository { Page findAll(Pageable pageable); - Page findPageByOrgid(String orgid, Pageable pageable); + // Page findPageByOrgid(String orgid, Pageable pageable); Page findPageByName(String filename, Pageable pageable); Optional findByPath(String path); diff --git a/nw/src/main/java/lab/cherry/nw/service/FileService.java b/nw/src/main/java/lab/cherry/nw/service/FileService.java index 3835f71..89aad2a 100644 --- a/nw/src/main/java/lab/cherry/nw/service/FileService.java +++ b/nw/src/main/java/lab/cherry/nw/service/FileService.java @@ -32,7 +32,8 @@ public interface FileService { FileEntity findByPath(String path); void deleteById(String id); - InputStream downloadFile(String orgId, String path); - byte[] downloadZip(String bucketName, String objectName); - void deleteFiles(String orgId, List images); + FileEntity.LoadFile downloadFile(String id) throws IllegalStateException, IOException; + Map downloadFiles(String key, String value); + // byte[] downloadZip(String bucketName, String objectName); + void deleteFiles(String name, List files); } \ No newline at end of file diff --git a/nw/src/main/java/lab/cherry/nw/service/Impl/BanquetServiceImpl.java b/nw/src/main/java/lab/cherry/nw/service/Impl/BanquetServiceImpl.java index 1552c33..7078b80 100644 --- a/nw/src/main/java/lab/cherry/nw/service/Impl/BanquetServiceImpl.java +++ b/nw/src/main/java/lab/cherry/nw/service/Impl/BanquetServiceImpl.java @@ -11,6 +11,7 @@ import lab.cherry.nw.service.OrgService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.bson.types.ObjectId; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; @@ -69,35 +70,34 @@ public Page getBanquets(Pageable pageable) { * * Author : taking(taking@duck.com) */ - public BanquetEntity createBanquet(BanquetEntity.BanquetCreateDto banquetCreateDto, List imageFiles) { + public BanquetEntity createBanquet(BanquetEntity.BanquetCreateDto banquetCreateDto, List images) { log.error("[#0] in createBanquet"); checkExistsWithBanquetName(banquetCreateDto.getBanquetName()); // 중복 체크 - String orgId = banquetCreateDto.getOrg(); + String orgId = banquetCreateDto.getOrgId(); OrgEntity orgEntity = orgService.findById(orgId); + ObjectId objectId = new ObjectId(); - // 파일 업로드 시, 구분하기 위한 정보 입력 - // {org_objectId}/웨딩홀/{weddinghallName}/profile.jpg - // {org_objectId}/고객/{userName}/문서.xlsx - Map info = new HashMap<>(); - info.put("type", "연회장"); - info.put("org", banquetCreateDto.getOrg()); - - // 업로드한 파일의 ObjectId 를 List로 반환 - List fileObjectIds = fileService.uploadFiles(info, imageFiles); - - log.error("[#1] imageFileIds = {}", fileObjectIds); + Map info = new HashMap<>(); + info.put("org", orgEntity.getName()); + info.put("type", "연회장"); + // info.put("username", ""); + info.put("kind", banquetCreateDto.getBanquetName()); + info.put("seq", objectId.toString()); + + List imageUrls = fileService.uploadFiles(info, images); BanquetEntity banquetEntity = BanquetEntity.builder() - .name(banquetCreateDto.getBanquetName()) - .max_person(banquetCreateDto.getMaxPerson()) - .org(orgEntity) - .interval(banquetCreateDto.getInterval()) - .images(fileObjectIds) - .created_at(Instant.now()) - .build(); + .id(objectId.toString()) + .name(banquetCreateDto.getBanquetName()) + .max_person(banquetCreateDto.getMaxPerson()) + .org(orgEntity) + .interval(banquetCreateDto.getInterval()) + .images(imageUrls) + .created_at(Instant.now()) + .build(); return banquetRepository.save(banquetEntity); } @@ -156,16 +156,10 @@ public BanquetEntity findById(String id) { */ public void deleteById(String id) { - // 파일 다운로드 - BanquetEntity banquetEntity = findById(id); - - List fileObjectIds = banquetEntity.getImages(); - - if (!fileObjectIds.isEmpty()) { - fileService.deleteFiles(banquetEntity.getOrg().getId(), fileObjectIds); - } + BanquetEntity banquetEntity = findById(id); + fileService.deleteFiles(banquetEntity.getName(), banquetEntity.getImages()); - banquetRepository.delete(banquetRepository.findById(id).orElseThrow(() -> new EntityNotFoundException("Banquet with Id " + id + " Not Found."))); + banquetRepository.delete(banquetRepository.findById(id).orElseThrow(() -> new EntityNotFoundException("Banquet with Id " + id + " Not Found."))); } } \ No newline at end of file diff --git a/nw/src/main/java/lab/cherry/nw/service/Impl/FileServiceImpl.java b/nw/src/main/java/lab/cherry/nw/service/Impl/FileServiceImpl.java index 68e1dab..93ad290 100644 --- a/nw/src/main/java/lab/cherry/nw/service/Impl/FileServiceImpl.java +++ b/nw/src/main/java/lab/cherry/nw/service/Impl/FileServiceImpl.java @@ -1,34 +1,45 @@ package lab.cherry.nw.service.Impl; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; -import java.net.URI; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.attribute.PosixFilePermissions; import java.time.Instant; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import org.apache.tomcat.util.codec.binary.Base64; +import java.util.function.Consumer; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; +import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; +import org.apache.commons.compress.utils.IOUtils; import org.springframework.beans.factory.annotation.Value; -import org.springframework.core.io.InputStreamResource; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; -import org.springframework.http.HttpHeaders; +import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.data.mongodb.core.query.Query; +import org.springframework.data.mongodb.gridfs.GridFsOperations; +import org.springframework.data.mongodb.gridfs.GridFsTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; -import org.springframework.web.util.UriComponentsBuilder; +import com.mongodb.BasicDBObject; +import com.mongodb.DBObject; +import com.mongodb.client.gridfs.GridFSFindIterable; +import com.mongodb.client.gridfs.model.GridFSFile; import lab.cherry.nw.error.enums.ErrorCode; import lab.cherry.nw.error.exception.CustomException; import lab.cherry.nw.error.exception.EntityNotFoundException; import lab.cherry.nw.model.FileEntity; import lab.cherry.nw.repository.FileRepository; import lab.cherry.nw.service.FileService; -import lab.cherry.nw.service.MinioService; import lab.cherry.nw.util.FormatConverter; -import lab.cherry.nw.util.HttpUtils; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -37,17 +48,11 @@ @RequiredArgsConstructor public class FileServiceImpl implements FileService { - private final MinioService minioService; - private final FileRepository fileRepository; - - @Value("${minio.url}") - private String minioUrl; - - @Value("${minio.access-key}") - private String accessKey; - - @Value("${minio.secret-key}") - private String secretKey; + @Value("${lab.cherry.nw.uploadPath}") + private String uploadPath; + private final FileRepository fileRepository; + private final GridFsTemplate template; + private final GridFsOperations operations; public Page getFiles(Pageable pageable) { return fileRepository.findAll(pageable); @@ -55,127 +60,139 @@ public Page getFiles(Pageable pageable) { @Override public List uploadFiles(Map info, List files) { - - String orgId = info.get("org"); // 조직명 - String userId = info.get("user"); // 사용자명 - String type = info.get("type"); - String qsheetSeq= info.get("qsheetSeq"); // 파일 구분명 - String bucketName = null; - - String destPath; - if (userId != null) { - // user가 입력되면, /user/{userId}으로 Path 지정 - bucketName = "user"; - destPath = userId + "/" + qsheetSeq +"/"; + + String orgName = info.get("org"); // 조직명 + String userName = info.get("username"); // 사용자명 + String type = info.get("type"); // 타입 (ex. 웨딩홀, 연회장, 폐백실) + String kind = info.get("kind"); // 구분 (ex. 웨딩홀명, 연회장명, 폐백실명) + String seq = info.get("seq"); // 고유번호 + + Path subPath = null; + if(userName == null) { + subPath = Paths.get("조직" + File.separator + orgName + File.separator + type + File.separator + kind); } else { - // user값이 없을 시, {org_objectId}/관리/로 Path 지정 - bucketName = orgId; - destPath = "/관리/"; + subPath = Paths.get("사용자" + File.separator + userName + File.separator + kind + "-" + seq); } - List fileObjectIds = new ArrayList<>(); + String directoryPath = folderChk("mkdir", subPath.toString()); + + List fileUrls = new ArrayList<>(); for (MultipartFile file : files) { - String originalFilename = (userId != null) ? file.getOriginalFilename() : type + "/" + file.getOriginalFilename(); - String filepath = destPath + originalFilename; + - log.error("objectName is {}", filepath); + DBObject metadata = new BasicDBObject(); + metadata.put("seq", seq); + metadata.put("name", file.getOriginalFilename()); + metadata.put("size", file.getSize()); + metadata.put("type", file.getContentType()); + metadata.put("kind", kind); + metadata.put("path", directoryPath); + Object fileObjectID = null; try { - minioService.uploadObject(bucketName, filepath, file); - } catch (IOException e) { - log.error(e.getMessage()); - } catch (NoSuchAlgorithmException | InvalidKeyException e) { - throw new RuntimeException(e); + fileObjectID = template.store(file.getInputStream(), file.getOriginalFilename(), file.getContentType(), metadata); + } catch (IOException e) { + log.error("파일 업로드 실패 {}", e); + throw new CustomException(ErrorCode.FILE_UPLOAD_FAILED); } - String fileUrl = "/api/v1/file/download/" + bucketName + "?path=" + filepath; + log.error("file.getOriginalFilename() is {}", file.getOriginalFilename()); + + String fullpath = directoryPath + File.separator + file.getOriginalFilename(); + + try { + File destFile = new File(fullpath); + file.transferTo(destFile); + log.info("File uploaded successfully!"); + } catch (IOException e) { + log.info("File upload failed: " + e.getMessage()); + } + + String fileUrl = "/api/v1/file/download/" + fileObjectID.toString(); // 파일 객체 ID 저장 - fileObjectIds.add(fileUrl); + fileUrls.add(fileUrl); FileEntity fileEntity = FileEntity.builder() - .name(file.getOriginalFilename()) - .size(FormatConverter.convertInputBytes(file.getSize())) - .type(file.getContentType()) - .path(filepath) - .url(fileUrl) - .userid(userId) - .orgid(bucketName) - .created_at(Instant.now()) - .build(); + .id(fileObjectID.toString()) + .name(file.getOriginalFilename()) + .size(FormatConverter.convertInputBytes(file.getSize())) + .type(file.getContentType()) + .path(fullpath) + .url(fileUrl) + .userName(userName) + .orgName(orgName) + .created_at(Instant.now()) + .build(); fileRepository.save(fileEntity); } - return fileObjectIds; + return fileUrls; } - public List getAllFiles(String orgId, String path) { + @Override + public FileEntity.LoadFile downloadFile(String id) throws IllegalStateException, IOException { + + GridFSFile gridFSFile = template.findOne( new Query(Criteria.where("_id").is(id)) ); - try { - return minioService.listObjects(orgId, path); + FileEntity.LoadFile fileEntity = new FileEntity.LoadFile(); - } catch (IOException e) { - log.error(e.getMessage()); - } catch (NoSuchAlgorithmException | InvalidKeyException e) { - throw new RuntimeException(e); - } - return null; - } + if (gridFSFile != null && gridFSFile.getMetadata() != null) { - @Override - public InputStream downloadFile(String orgId, String path) { + log.error("fsFile.getMetadata() = {}", gridFSFile.getMetadata()); - try { - return minioService.getObject(orgId, path); + fileEntity.setName( gridFSFile.getFilename() ); + fileEntity.setSize( gridFSFile.getMetadata().get("size").toString() ); + fileEntity.setType( gridFSFile.getMetadata().get("type").toString() ); - } catch (IOException e) { - log.error("파일 콘텐츠 확인 중 오류 발생: {}", e.getMessage()); - } catch (NoSuchAlgorithmException | InvalidKeyException e) { - throw new RuntimeException(e); + fileEntity.setFile( IOUtils.toByteArray(operations.getResource(gridFSFile).getInputStream()) ); + } else { + throw new CustomException(ErrorCode.ENTITY_NOT_FOUND); } - return null; + + return fileEntity; } - @Override - public byte[] downloadZip(String bucketName, String objectName) { - - objectName = Base64.encodeBase64String(objectName.getBytes()); - String addr = minioUrl.substring(0, minioUrl.length()-5) + ":9001"; - - try { - URI uri = UriComponentsBuilder - .fromUriString(addr) - .path("/api/v1/buckets/{bucketName}/objects/download") - // .encode() - .queryParam("prefix", objectName) - .build() - .expand(bucketName, objectName) - .toUri(); - - log.error("uri {}", uri); - return HttpUtils.getForObject(uri); + + public Map downloadFiles(String key, String value) { + List allFiles = new ArrayList<>(); + GridFSFindIterable resources = template.find(new Query().addCriteria(Criteria.where("metadata." + key).is(value))); + resources.forEach((Consumer) file -> allFiles.add(file)); + + log.error("allFiles {}", allFiles); + for(GridFSFile file : allFiles) { + log.error("FileName : {}", file.getFilename()); + } - } catch (Exception ex) { - log.error("error {}", ex); - log.error("error.msg {}", ex.getMessage()); - // throw new CustomException(ErrorCode.URL_NOTFOUND); - } + try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + ZipOutputStream zipOut = new ZipOutputStream(byteArrayOutputStream)) { + for (GridFSFile file : allFiles) { - return null; - } + ZipEntry zipEntry = new ZipEntry(file.getFilename()); + zipOut.putNextEntry(zipEntry); - public void deleteById(String id) { - FileEntity fileEntity = findById(id); + byte[] objectData = IOUtils.toByteArray(operations.getResource(file).getInputStream()); + zipOut.write(objectData); + zipOut.closeEntry(); + } + zipOut.finish(); - try { - minioService.deleteObject(fileEntity.getId(), fileEntity.getPath()); + Map returnVal = new HashMap<>(); + returnVal.put("name", value + ".zip"); + returnVal.put("data", byteArrayOutputStream.toByteArray()); + + return returnVal; - System.out.println("파일 삭제 성공: " + fileEntity.getName()); - } catch (IOException e) { - log.error("파일 콘텐츠 확인 중 오류 발생: {}", e.getMessage()); - } catch (NoSuchAlgorithmException | InvalidKeyException e) { - throw new RuntimeException(e); - } + } catch (IOException e) { + log.error("Error creating and sending the zip file: {}", e); + return null; + } + } + + public void deleteById(String id) { + + FileEntity fileEntity = findById(id); + folderChk("rmdir", fileEntity.getPath()); fileRepository.delete(fileRepository.findById(id).orElseThrow(() -> new EntityNotFoundException("File with Id " + id + " Not Found."))); } @@ -186,12 +203,6 @@ public Page findPageByName(String name, Pageable pageable) { return fileRepository.findPageByName(name, pageable); } - @Transactional(readOnly = true) - public Page findPageByOrgId(String orgid, Pageable pageable) { - return fileRepository.findPageByOrgid(orgid, pageable); - } - - @Transactional(readOnly = true) public FileEntity findById(String id) { return fileRepository.findByid(id).orElseThrow(() -> new EntityNotFoundException("file with Id " + id + " Not Found.")); @@ -202,22 +213,79 @@ public FileEntity findByPath(String path) { return fileRepository.findByPath(path).orElseThrow(() -> new EntityNotFoundException("file with Path " + path + " Not Found.")); } - public void deleteFiles(String orgId, List images) { + public void deleteFiles(String name, List files) { - for (String image : images) { - FileEntity fileEntity = findByPath(image); // checkFileExists + String filePath = null; - try { - minioService.deleteObject(orgId, image); + for (String file : files){ + + String[] splitText = file.split("/"); + String objectId = splitText[splitText.length -1]; - System.out.println("파일 삭제 성공: " + image); - } catch (IOException e) { - log.error("파일 콘텐츠 확인 중 오류 발생: {}", e.getMessage()); - } catch (NoSuchAlgorithmException | InvalidKeyException e) { - throw new RuntimeException(e); - } + GridFSFile gridFSFile = template.findOne( new Query(Criteria.where("_id").is(objectId))); + + filePath = gridFSFile.getMetadata().get("path").toString(); + String fileName = gridFSFile.getMetadata().get("name").toString(); + String fullPath = filePath + File.separator + fileName; + + template.delete(new Query(Criteria.where("_id").is(objectId))); - fileRepository.delete(fileRepository.findByPath(image).orElseThrow(() -> new EntityNotFoundException("File with Path " + image + " Not Found."))); + fileRepository.delete(fileRepository.findByPath(fullPath).orElseThrow(() -> new EntityNotFoundException("File with Path " + file + " Not Found."))); } + + if(name != null) { + folderChk("rmdir", filePath); + } } + + public String folderChk(String type, String path) { + + if(!new File(uploadPath).exists()) { + log.error("Folder 생성 실패, 루트 폴더를 수동으로 생성해주세요 : {}", uploadPath); + throw new CustomException(ErrorCode.INVALID_USERNAME); + } else { + + if (type == "mkdir") { + + // 업로드 디렉토리 생성 (만약 존재하지 않는 경우) + Path directoryPath = Paths.get(uploadPath + File.separator + path); + try { + // 디렉토리 생성 + Files.createDirectories(directoryPath, + PosixFilePermissions.asFileAttribute( + PosixFilePermissions.fromString("rwxr-x---") + ));; + System.out.println(directoryPath.toString() + " 디렉토리가 생성되었습니다."); + return directoryPath.toString(); + } catch (IOException e) { + log.error("디렉토리 생성 실패 : {}", e); + } + + } else if (type == "rmdir") { + log.error("폴더 삭제"); + + // 업로드 디렉토리 생성 (만약 존재하지 않는 경우) + Path directoryPath = Paths.get(path); + log.error("directoryPath.toString() is {}", directoryPath.toString()); + File folder = new File(directoryPath.toString()); + // 디렉토리 내 파일 삭제 + while (folder.exists()) { + File[] folder_list = folder.listFiles(); // 파일리스트 얻어오기 + + for (int j = 0; j < folder_list.length; j++) { + folder_list[j].delete(); // 파일 삭제 + System.out.println("파일이 삭제되었습니다."); + } + + if (folder_list.length == 0 && folder.isDirectory()) { + folder.delete(); // 대상폴더 삭제 + System.out.println("폴더가 삭제되었습니다."); + } + } + return ""; + } + + } + return ""; +} } \ No newline at end of file diff --git a/nw/src/main/java/lab/cherry/nw/service/Impl/MinioServiceImpl.java b/nw/src/main/java/lab/cherry/nw/service/Impl/MinioServiceImpl.java deleted file mode 100644 index 0265774..0000000 --- a/nw/src/main/java/lab/cherry/nw/service/Impl/MinioServiceImpl.java +++ /dev/null @@ -1,369 +0,0 @@ -package lab.cherry.nw.service.Impl; - -import java.io.IOException; -import java.io.InputStream; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; -import org.bouncycastle.crypto.InvalidCipherTextException; -import org.springframework.stereotype.Service; -import org.springframework.web.multipart.MultipartFile; -import io.minio.BucketExistsArgs; -import io.minio.GetBucketPolicyArgs; -import io.minio.GetObjectArgs; -import io.minio.GetPresignedObjectUrlArgs; -import io.minio.ListObjectsArgs; -import io.minio.MakeBucketArgs; -import io.minio.MinioClient; -import io.minio.PutObjectArgs; -import io.minio.RemoveBucketArgs; -import io.minio.RemoveObjectArgs; -import io.minio.RemoveObjectsArgs; -import io.minio.Result; -import io.minio.SetBucketPolicyArgs; -import io.minio.admin.MinioAdminClient; -import io.minio.admin.UserInfo; -import io.minio.errors.MinioException; -import io.minio.http.Method; -import io.minio.messages.DeleteError; -import io.minio.messages.DeleteObject; -import io.minio.messages.Item; -import lab.cherry.nw.model.UserEntity; -import lab.cherry.nw.service.MinioService; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@Service -@RequiredArgsConstructor -public class MinioServiceImpl implements MinioService { - - private final MinioClient minioClient; - private final MinioAdminClient adminClient; - - public boolean isMinioConnected() { - try { - // 버킷 목록을 가져와서 Minio 연결 상태 확인 - minioClient.listBuckets(); - return true; // 연결이 성공적으로 확인됨 - } catch (Exception e) { - // Minio 연결 예외 처리 - return false; // 연결 실패 - } - } - public Map listUsers() throws InvalidCipherTextException, NoSuchAlgorithmException, IOException, InvalidKeyException { - - return adminClient.listUsers(); - } - - public void newUser(UserEntity user) throws IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidCipherTextException { - - // 새 사용자를 생성합니다. - String userAccessKey = user.getId(); - String userSecretKey = user.getPassword(); - - adminClient.addUser(userAccessKey, UserInfo.Status.ENABLED, userSecretKey, null, null); - - } - - public void deleteUser(UserEntity user) throws IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidCipherTextException { - - // 사용자를 삭제합니다. - String userAccessKey = user.getId(); - - adminClient.deleteUser(userAccessKey); - - } - - public void setUserPolicy(String bucketName, String userId) throws NoSuchAlgorithmException, IOException, InvalidKeyException { - - log.error("Minio Connect Check : {}", isMinioConnected()); - - adminClient.setPolicy(userId, false, bucketName); - - } - - public void createGlobalPolicy(String bucketName) throws NoSuchAlgorithmException, IOException, InvalidKeyException { - - log.error("Minio Connect Check : {}", isMinioConnected()); - - // TODO: bucketName-admin 또는 bucketName-user 권한으로 구분 기능 추후 개발 필요 - String policyJson = "{" + - "\"Version\": \"2012-10-17\"," + - "\"Statement\": [" + - "{" + - "\"Action\": [" + - "\"s3:GetObject\", " + - "\"s3:PutObject\", " + - "\"s3:DeleteObject\", " + - "\"s3:ListBucket\"], " + - "\"Effect\": \"Allow\", " + - "\"Resource\": [\"arn:aws:s3:::" + bucketName + "/*\"], " + // bucketName 변수 사용 - "\"Sid\": \"\"" + // Sid (선택 사항) 추가 - "}" + - "]" + - "}"; - - adminClient.addCannedPolicy(bucketName, policyJson.replaceAll("'", "\"")); - - } - - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - public List listObjects(String bucketName, String prefix) throws IOException, NoSuchAlgorithmException, InvalidKeyException { - try { - - log.error("Minio Connect Check : {}", isMinioConnected()); - - // bucketName에 있는 objectName을 조회합니다. - - Iterable> objects = null; - - if (prefix == null) { - objects = minioClient.listObjects(ListObjectsArgs.builder() - .bucket(bucketName) - .build()); - } else { - - log.error("path is {}", prefix); - - objects = minioClient.listObjects(ListObjectsArgs.builder() - .bucket(bucketName) - .prefix(prefix) - .build()); - } - - List objecLists = new ArrayList<>(); - for (Result result : objects) { - Item item = result.get(); - log.info("Object Name: {}", item.objectName()); - log.info("Object Size: {}", item.size()); - objecLists.add(item.objectName()); - } - - return objecLists; - - } catch (MinioException e) { - log.error("Error occurred: " + e); - } - - return null; - } - - public InputStream getObject(String bucketName, String objectName) throws IOException, NoSuchAlgorithmException, InvalidKeyException { - try { - - log.error("Minio Connect Check : {}", isMinioConnected()); - - - log.error("\nbucketName is {}\nobjectName is {}\n", bucketName, objectName); - - // bucketName에 있는 objectName을 조회합니다. - InputStream stream = minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(objectName).build()); - - - return stream; -// List objectList = FormatConverter.convertInputStreamToList(stream); -// -// return objectList; - - } catch (MinioException e) { - log.error("Error occurred: " + e); - } - - return null; - } - - public boolean bucketExists(String bucketName) throws IOException, NoSuchAlgorithmException, InvalidKeyException { - try { - - log.error("Minio Connect Check : {}", isMinioConnected()); - - // Check whether 'my-bucketname' exist or not. - boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build()); - - if (found) { - log.info("{} bucket이 존재합니다.", bucketName); - return true; - } else { - log.info("{} bucket이 존재하지 않습니다.", bucketName); - return false; - } - } catch (MinioException e) { - log.error("Error occurred: " + e); - } - - return false; - } - - public void createBucketIfNotExists(String bucketName) throws IOException, NoSuchAlgorithmException, InvalidKeyException { - try { - - log.error("Minio Connect Check : {}", isMinioConnected()); - - // bucketName이 존재하는지 확인 후, 없다면 bucket 생성 - if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) { - minioClient.makeBucket(MakeBucketArgs.builder() - .bucket(bucketName) -// .region("eu-west-1") -// .objectLock(true) - .build()); - log.info("{} bucket이 생성 완료되었습니다.", bucketName); - } - } catch (MinioException e) { - log.error("Error occurred: " + e); - } - } - public void uploadObject(String bucketName, String objectName, MultipartFile file) throws IOException, NoSuchAlgorithmException, InvalidKeyException { - try { - - log.error("Minio Connect Check : {}", isMinioConnected()); - - // Object를 업로드합니다. - minioClient.putObject( - PutObjectArgs.builder() - .bucket(bucketName) - .object(objectName) - .contentType(file.getContentType()) - .stream(file.getInputStream(), file.getSize(), -1) - .build() - ); - - log.info("Object가 업로드되었습니다."); - } catch (MinioException e) { - log.error("Error occurred: " + e); - } - } - - public void setBucketPolicy(String bucketName) throws IOException, NoSuchAlgorithmException, InvalidKeyException { - try { - - log.error("Minio Connect Check : {}", isMinioConnected()); - - // BucketName 에 Policy를 설정합니다. - StringBuilder builder = new StringBuilder(); - builder.append("{\n"); - builder.append(" \"Statement\": [\n"); - builder.append(" {\n"); - builder.append(" \"Action\": [\n"); - builder.append(" \"s3:GetBucketLocation\",\n"); - builder.append(" \"s3:ListBucket\"\n"); - builder.append(" ],\n"); - builder.append(" \"Effect\": \"Allow\",\n"); - builder.append(" \"Principal\": \"*\",\n"); - builder.append(" \"Resource\": \"arn:aws:s3:::" + bucketName + "\"\n"); - builder.append(" },\n"); - builder.append(" {\n"); - builder.append(" \"Action\": \"s3:GetObject\",\n"); - builder.append(" \"Effect\": \"Allow\",\n"); - builder.append(" \"Principal\": \"*\",\n"); - builder.append(" \"Resource\": \"arn:aws:s3:::" + bucketName + "/*\"\n"); - builder.append(" }\n"); - builder.append(" ],\n"); - builder.append(" \"Version\": \"2012-10-17\"\n"); - builder.append("}\n"); - - minioClient.setBucketPolicy( - SetBucketPolicyArgs.builder().bucket(bucketName).config(builder.toString()).build()); - - log.info("{} Policy 생성이 완료되었습니다.", minioClient.getBucketPolicy(GetBucketPolicyArgs.builder().bucket(bucketName).build())); - } catch (MinioException e) { - log.error("Error occurred: " + e); - } - } - - public void deleteBucket(String bucketName) throws IOException, NoSuchAlgorithmException, InvalidKeyException { - try { - - log.error("Minio Connect Check : {}", isMinioConnected()); - - // Bucket를 삭제합니다. - boolean found = - minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build()); - if (found) { - minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build()); - log.info("{} bucket이 삭제되었습니다.", bucketName); - } else { - log.info("{} bucket을 찾을 수 없습니다.", bucketName); - } - } catch (MinioException e) { - log.error("Error occurred: " + e); - } - } - - public void deleteObject(String bucketName, String objectName) throws IOException, NoSuchAlgorithmException, InvalidKeyException { - try { - - log.error("Minio Connect Check : {}", isMinioConnected()); - - // Object를 삭제합니다. - minioClient.removeObject( - RemoveObjectArgs.builder() - .bucket(bucketName) - .object(objectName) - .build()); - - log.info("Object가 삭제되었습니다."); - } catch (MinioException e) { - log.error("Error occurred: " + e); - } - } - - public void deleteObjects(String bucketName, List objectList) throws IOException, NoSuchAlgorithmException, InvalidKeyException { - try { - - log.error("Minio Connect Check : {}", isMinioConnected()); - - // List objects = new LinkedList<>(); - // objects.add(new DeleteObject("my-objectname1")); - // objects.add(new DeleteObject("my-objectname2")); - // objects.add(new DeleteObject("my-objectname3")); - - Iterable> results = - minioClient.removeObjects( - RemoveObjectsArgs.builder().bucket(bucketName).objects(objectList).build()); - for (Result result : results) { - DeleteError error = result.get(); - log.info("{} Object 삭제하는데 문제가 발생했습니다. {} ", error.objectName(), error.message()); - } - - log.info("ObjectList가 삭제되었습니다."); - } catch (MinioException e) { - log.error("Error occurred: " + e); - } - } - - public String getPresignedURL(String bucketName, String objectName) throws IOException, NoSuchAlgorithmException, InvalidKeyException { - try { - - // minioService.getPresignedURL(user, "test", "subFolder/64ed89aa9e813b5ab16da6dd"); - // expiration 기간 동안 유지되는 링크 제공 - - log.error("Minio Connect Check : {}", isMinioConnected()); - - Map reqParams = new HashMap(); - reqParams.put("response-content-type", "application/json"); - - log.error("bucketName {}", bucketName); - log.error("objectName {}", objectName); - - // Presigned URL 생성 - return minioClient.getPresignedObjectUrl( - GetPresignedObjectUrlArgs.builder() - .method(Method.GET) - .bucket(bucketName) - .object(objectName) - .expiry(1, TimeUnit.HOURS) // 시간 - .extraQueryParams(reqParams) - .build()); - - } catch (MinioException e) { - log.error("Error occurred: " + e); - } - return null; - } -} \ No newline at end of file diff --git a/nw/src/main/java/lab/cherry/nw/service/Impl/OrgServiceImpl.java b/nw/src/main/java/lab/cherry/nw/service/Impl/OrgServiceImpl.java index 046f9fb..ebd8b85 100644 --- a/nw/src/main/java/lab/cherry/nw/service/Impl/OrgServiceImpl.java +++ b/nw/src/main/java/lab/cherry/nw/service/Impl/OrgServiceImpl.java @@ -7,7 +7,6 @@ import lab.cherry.nw.error.exception.EntityNotFoundException; import lab.cherry.nw.model.OrgEntity; import lab.cherry.nw.repository.OrgRepository; -import lab.cherry.nw.service.MinioService; import lab.cherry.nw.service.OrgService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -33,7 +32,6 @@ @RequiredArgsConstructor public class OrgServiceImpl implements OrgService { - private final MinioService minioService; private final OrgRepository orgRepository; /** @@ -68,29 +66,29 @@ public Page getOrganizations(Pageable pageable) { public OrgEntity createOrganization(OrgEntity.OrgCreateDto orgCreateDto) { ObjectId orgId = new ObjectId(); - try { - // ObjectId orgId로 Bucket 생성 - minioService.createBucketIfNotExists(orgId.toString()); + // try { + // // ObjectId orgId로 Bucket 생성 + // minioService.createBucketIfNotExists(orgId.toString()); - // ObjectId orgId에 해당하는 GlobalPolicy 생성 - minioService.createGlobalPolicy(orgId.toString()); + // // ObjectId orgId에 해당하는 GlobalPolicy 생성 + // minioService.createGlobalPolicy(orgId.toString()); - // 생성된 Bucket에 Policy 적용 - minioService.setBucketPolicy(orgId.toString()); + // // 생성된 Bucket에 Policy 적용 + // minioService.setBucketPolicy(orgId.toString()); - } catch (Exception e) { - log.error(e.getMessage()); - } + // } catch (Exception e) { + // log.error(e.getMessage()); + // } Instant instant = Instant.now(); - checkExistsWithOrgName(orgCreateDto.getName()); // 동일한 이름 중복체크 + checkExistsWithOrgName(orgCreateDto.getOrgName()); // 동일한 이름 중복체크 OrgEntity orgEntity = OrgEntity.builder() .id(orgId.toString()) - .name(orgCreateDto.getName()) - .biznum(orgCreateDto.getBiznum()) - .contact(orgCreateDto.getContact()) - .address(orgCreateDto.getAddress()) + .name(orgCreateDto.getOrgName()) + .biznum(orgCreateDto.getOrgBiznum()) + .contact(orgCreateDto.getOrgContact()) + .address(orgCreateDto.getOrgAddress()) .enabled(true) .created_at(instant) .build(); @@ -113,14 +111,14 @@ public void updateById(String id, OrgEntity.OrgUpdateDto org) { OrgEntity orgEntity = findById(id); - if (org.getName() != null || org.getBiznum() != null || org.getContact() != null || org.getAddress() != null) { - + if (org.getOrgName() != null || org.getOrgBiznum() != null || org.getOrgContact() != null || org.getOrgAddress() != null || org.getOrgEnabled() != null) { orgEntity = OrgEntity.builder() .id(orgEntity.getId()) - .name((org.getName() != null) ? org.getName() : orgEntity.getName()) - .biznum((org.getBiznum() != null) ? org.getBiznum() : orgEntity.getBiznum()) - .contact((org.getContact() != null) ? org.getContact() : orgEntity.getContact()) - .address((org.getAddress() != null) ? org.getAddress() : orgEntity.getAddress()) + .name((org.getOrgName() != null) ? org.getOrgName() : orgEntity.getName()) + .biznum((org.getOrgBiznum() != null) ? org.getOrgBiznum() : orgEntity.getBiznum()) + .contact((org.getOrgContact() != null) ? org.getOrgContact() : orgEntity.getContact()) + .address((org.getOrgAddress() != null) ? org.getOrgAddress() : orgEntity.getAddress()) + .enabled((org.getOrgEnabled() != null) ? org.getOrgEnabled() : orgEntity.getEnabled()) .build(); orgRepository.save(orgEntity); diff --git a/nw/src/main/java/lab/cherry/nw/service/Impl/PyebaeksilServiceImpl.java b/nw/src/main/java/lab/cherry/nw/service/Impl/PyebaeksilServiceImpl.java index a64bbcc..3cb7a76 100644 --- a/nw/src/main/java/lab/cherry/nw/service/Impl/PyebaeksilServiceImpl.java +++ b/nw/src/main/java/lab/cherry/nw/service/Impl/PyebaeksilServiceImpl.java @@ -11,6 +11,7 @@ import lab.cherry.nw.service.OrgService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.bson.types.ObjectId; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; @@ -69,33 +70,36 @@ public Page getPyebaeksils(Pageable pageable) { * * Author : taking(taking@duck.com) */ - public PyebaeksilEntity createPyebaeksil(PyebaeksilEntity.PyebaeksilCreateDto pyebaeksilCreateDto, List imageFiles) { + public PyebaeksilEntity createPyebaeksil(PyebaeksilEntity.PyebaeksilCreateDto pyebaeksilCreateDto, List images) { log.error("[#0] in createPyebaeksil"); checkExistsWithPyebaeksilName(pyebaeksilCreateDto.getPyebaeksilName()); // 중복 체크 - String orgId = pyebaeksilCreateDto.getOrg(); + String orgId = pyebaeksilCreateDto.getOrgId(); OrgEntity orgEntity = orgService.findById(orgId); + ObjectId objectId = new ObjectId(); // 파일 업로드 시, 구분하기 위한 정보 입력 // {org_objectId}/웨딩홀/{weddinghallName}/profile.jpg // {org_objectId}/고객/{userName}/문서.xlsx Map info = new HashMap<>(); - info.put("type", "폐백실"); - info.put("org", pyebaeksilCreateDto.getOrg()); + info.put("org", orgEntity.getName()); + info.put("type", "폐백실"); + // info.put("username", ""); + info.put("kind", pyebaeksilCreateDto.getPyebaeksilName()); + info.put("seq", objectId.toString()); // 업로드한 파일의 ObjectId 를 List로 반환 - List fileObjectIds = fileService.uploadFiles(info, imageFiles); - - log.error("[#1] imageFileIds = {}", fileObjectIds); + List imageUrls = fileService.uploadFiles(info, images); PyebaeksilEntity pyebaeksilEntity = PyebaeksilEntity.builder() - .name(pyebaeksilCreateDto.getPyebaeksilName()) - .org(orgEntity) - .images(fileObjectIds) - .created_at(Instant.now()) - .build(); + .id(objectId.toString()) + .name(pyebaeksilCreateDto.getPyebaeksilName()) + .org(orgEntity) + .images(imageUrls) + .created_at(Instant.now()) + .build(); return pyebaeksilRepository.save(pyebaeksilEntity); } @@ -154,14 +158,8 @@ public PyebaeksilEntity findById(String id) { */ public void deleteById(String id) { - // 파일 다운로드 - PyebaeksilEntity pyebaeksilEntity = findById(id); - - List fileObjectIds = pyebaeksilEntity.getImages(); - - if (!fileObjectIds.isEmpty()) { - fileService.deleteFiles(pyebaeksilEntity.getOrg().getId(), fileObjectIds); - } + PyebaeksilEntity pyebaeksilEntity = findById(id); + fileService.deleteFiles(pyebaeksilEntity.getName(), pyebaeksilEntity.getImages()); pyebaeksilRepository.delete(pyebaeksilRepository.findById(id).orElseThrow(() -> new EntityNotFoundException("Pyebaeksil with Id " + id + " Not Found."))); } diff --git a/nw/src/main/java/lab/cherry/nw/service/Impl/WeddinghallServiceImpl.java b/nw/src/main/java/lab/cherry/nw/service/Impl/WeddinghallServiceImpl.java index 5446e30..e506b2e 100644 --- a/nw/src/main/java/lab/cherry/nw/service/Impl/WeddinghallServiceImpl.java +++ b/nw/src/main/java/lab/cherry/nw/service/Impl/WeddinghallServiceImpl.java @@ -1,6 +1,16 @@ package lab.cherry.nw.service.Impl; -import io.minio.errors.MinioException; +import java.io.IOException; +import java.time.Instant; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.bson.types.ObjectId; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; import lab.cherry.nw.error.enums.ErrorCode; import lab.cherry.nw.error.exception.CustomException; import lab.cherry.nw.error.exception.EntityNotFoundException; @@ -12,19 +22,6 @@ import lab.cherry.nw.service.WeddinghallService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.multipart.MultipartFile; - -import java.io.IOException; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.time.Instant; -import java.util.HashMap; -import java.util.List; -import java.util.Map; /** *
@@ -72,37 +69,36 @@ public Page getWeddinghalls(Pageable pageable) {
      * 
* * Author : taking(taking@duck.com) + * @throws IOException */ - public WeddinghallEntity createWeddinghall(WeddinghallEntity.WeddinghallCreateDto weddinghallCreateDto, List imageFiles) { + public WeddinghallEntity createWeddinghall(WeddinghallEntity.WeddinghallCreateDto weddinghallCreateDto, List images) { log.error("[#0] in createWeddinghall"); checkExistsWithWeddingHallName(weddinghallCreateDto.getWeddinghallName()); // 중복 체크 - String orgId = weddinghallCreateDto.getOrg(); + String orgId = weddinghallCreateDto.getOrgId(); OrgEntity orgEntity = orgService.findById(orgId); - - // 파일 업로드 시, 구분하기 위한 정보 입력 - // {org_objectId}/웨딩홀/{weddinghallName}/profile.jpg - // {org_objectId}/고객/{userName}/문서.xlsx - Map info = new HashMap<>(); - info.put("type", "웨딩홀"); - // info.put("type", weddinghallCreateDto.getWeddinghallName()); - info.put("org", weddinghallCreateDto.getOrg()); - - // 업로드한 파일의 ObjectId 를 List로 반환 - List fileObjectIds = fileService.uploadFiles(info, imageFiles); - - log.error("[#1] imageFileIds = {}", fileObjectIds); - - WeddinghallEntity weddinghallEntity = WeddinghallEntity.builder() - .name(weddinghallCreateDto.getWeddinghallName()) - .max_person(weddinghallCreateDto.getMaxPerson()) - .org(orgEntity) - .interval(weddinghallCreateDto.getInterval()) - .images(fileObjectIds) - .created_at(Instant.now()) - .build(); + ObjectId objectId = new ObjectId(); + + Map info = new HashMap<>(); + info.put("org", orgEntity.getName()); + info.put("type", "웨딩홀"); + // info.put("username", ""); + info.put("kind", weddinghallCreateDto.getWeddinghallName()); + info.put("seq", objectId.toString()); + + List imageUrls = fileService.uploadFiles(info, images); + + WeddinghallEntity weddinghallEntity = WeddinghallEntity.builder() + .id(objectId.toString()) + .name(weddinghallCreateDto.getWeddinghallName()) + .max_person(weddinghallCreateDto.getMaxPerson()) + .org(orgEntity) + .interval(weddinghallCreateDto.getInterval()) + .images(imageUrls) + .created_at(Instant.now()) + .build(); return weddinghallRepository.save(weddinghallEntity); } @@ -138,7 +134,7 @@ public WeddinghallEntity createWeddinghall(WeddinghallEntity.WeddinghallCreateDt @Transactional(readOnly = true) public Page findPageByName(String name, Pageable pageable) { - return weddinghallRepository.findPageByName(name, pageable); + return weddinghallRepository.findPageByName(name, pageable); } /** @@ -173,7 +169,7 @@ public void checkExistsWithWeddingHallName(String name) { */ @Transactional(readOnly = true) public WeddinghallEntity findById(String id) { - return weddinghallRepository.findById(id).orElseThrow(() -> new EntityNotFoundException("Weddinghall with Id " + id + " Not Found.")); + return weddinghallRepository.findById(id).orElseThrow(() -> new EntityNotFoundException("Weddinghall with Id " + id + " Not Found.")); } @@ -190,16 +186,10 @@ public WeddinghallEntity findById(String id) { */ public void deleteById(String id) { - // 파일 다운로드 - WeddinghallEntity weddinghallEntity = findById(id); - - List fileObjectIds = weddinghallEntity.getImages(); - - if (!fileObjectIds.isEmpty()) { - fileService.deleteFiles(weddinghallEntity.getOrg().getId(), fileObjectIds); - } + WeddinghallEntity weddinghallEntity = findById(id); + fileService.deleteFiles(weddinghallEntity.getName(), weddinghallEntity.getImages()); - weddinghallRepository.delete(weddinghallRepository.findById(id).orElseThrow(() -> new EntityNotFoundException("Weddinghall with Id " + id + " Not Found."))); + weddinghallRepository.delete(weddinghallRepository.findById(id).orElseThrow(() -> new EntityNotFoundException("Weddinghall with Id " + id + " Not Found."))); } } \ No newline at end of file diff --git a/nw/src/main/java/lab/cherry/nw/service/MinioService.java b/nw/src/main/java/lab/cherry/nw/service/MinioService.java deleted file mode 100644 index c01b651..0000000 --- a/nw/src/main/java/lab/cherry/nw/service/MinioService.java +++ /dev/null @@ -1,49 +0,0 @@ -package lab.cherry.nw.service; - - -import io.minio.admin.UserInfo; -import io.minio.messages.DeleteObject; -import lab.cherry.nw.model.UserEntity; -import org.bouncycastle.crypto.InvalidCipherTextException; -import org.springframework.stereotype.Component; -import org.springframework.web.multipart.MultipartFile; - -import java.io.IOException; -import java.io.InputStream; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.util.List; -import java.util.Map; - -/** - *
- * ClassName : MinioService
- * Type : interface
- * Description : 파일 관리에 필요한 Minio와 관련된 함수를 정리한 인터페이스입니다.
- * Related : MinioServiceImpl
- * 
- */ -@Component -public interface MinioService { - - // minioAdminClient - Map listUsers() throws IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidCipherTextException; - void newUser(UserEntity user) throws IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidCipherTextException; - void deleteUser(UserEntity user) throws IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidCipherTextException; - - void setUserPolicy(String bucketName, String userId) throws NoSuchAlgorithmException, IOException, InvalidKeyException; - void createGlobalPolicy(String bucketName) throws NoSuchAlgorithmException, IOException, InvalidKeyException; - - - // minioClient - List listObjects(String bucketName, String prefix) throws IOException, NoSuchAlgorithmException, InvalidKeyException; - InputStream getObject(String bucketName, String objectName) throws IOException, NoSuchAlgorithmException, InvalidKeyException; - boolean bucketExists(String bucketName) throws IOException, NoSuchAlgorithmException, InvalidKeyException; - void createBucketIfNotExists(String bucketName) throws IOException, NoSuchAlgorithmException, InvalidKeyException; - void uploadObject(String bucketName, String objectName, MultipartFile file) throws IOException, NoSuchAlgorithmException, InvalidKeyException; - void setBucketPolicy(String bucketName) throws IOException, NoSuchAlgorithmException, InvalidKeyException; - void deleteBucket(String bucketName) throws IOException, NoSuchAlgorithmException, InvalidKeyException; - void deleteObject(String bucketName, String objectName) throws IOException, NoSuchAlgorithmException, InvalidKeyException; - void deleteObjects(String bucketName, List objectList) throws IOException, NoSuchAlgorithmException, InvalidKeyException; - String getPresignedURL(String bucketName, String objectName) throws IOException, NoSuchAlgorithmException, InvalidKeyException; -} \ No newline at end of file diff --git a/nw/src/main/java/lab/cherry/nw/service/WeddinghallService.java b/nw/src/main/java/lab/cherry/nw/service/WeddinghallService.java index f047c52..fddd549 100644 --- a/nw/src/main/java/lab/cherry/nw/service/WeddinghallService.java +++ b/nw/src/main/java/lab/cherry/nw/service/WeddinghallService.java @@ -20,7 +20,7 @@ @Component public interface WeddinghallService { Page getWeddinghalls(Pageable pageable); - WeddinghallEntity createWeddinghall(WeddinghallEntity.WeddinghallCreateDto weddinghallCreateDto, List files); + WeddinghallEntity createWeddinghall(WeddinghallEntity.WeddinghallCreateDto weddinghallCreateDto, List images); // void updateById(String id, WeddinghallEntity.UpdateDto weddinghall); WeddinghallEntity findById(String id); // WeddinghallEntity findByName(String name); diff --git a/nw/src/main/resources/application.properties_sample b/nw/src/main/resources/application.properties_sample index 7cc8fc9..167412e 100644 --- a/nw/src/main/resources/application.properties_sample +++ b/nw/src/main/resources/application.properties_sample @@ -45,8 +45,4 @@ spring.mail.password=passWord #echo 'lab-cherry-nw-project-secret-key' | base64 lab.cherry.nw.jwtSecret= bGFiLWNoZXJyeS1udy1wcm9qZWN0LXNlY3JldC1rZXkK lab.cherry.nw.jwtExpirationMs= 86400000 - -# MinIo Properties -minio.url=http://nw-storage:9000 -minio.access-key={your-access-key} -minio.secret-key={your-secret-key} \ No newline at end of file +lab.cherry.nw.uploadPath= /data \ No newline at end of file From 003f79655d331e04261da744b23e3abd9eddbfd7 Mon Sep 17 00:00:00 2001 From: yby654 Date: Wed, 25 Oct 2023 03:40:58 +0000 Subject: [PATCH 13/14] =?UTF-8?q?Chore:=20=ED=81=90=EC=8B=9C=ED=8A=B8=20?= =?UTF-8?q?=ED=9E=88=EC=8A=A4=ED=86=A0=EB=A6=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nw/controller/QsheetController.java | 32 ++- .../controller/QsheetHistoryController.java | 71 +++++++ .../lab/cherry/nw/model/QsheetEntity.java | 6 +- .../cherry/nw/model/QsheetHistoryEntity.java | 61 ++++++ .../repository/QsheetHistoryRepository.java | 31 +++ .../nw/service/Impl/BoardServiceImpl.java | 20 +- .../nw/service/Impl/BookmarkServiceImpl.java | 16 +- .../nw/service/Impl/OrgServiceImpl.java | 2 - .../Impl/QsheetHistoryServiceImpl.java | 201 ++++++++++++++++++ .../nw/service/Impl/QsheetServiceImpl.java | 18 +- .../nw/service/Impl/TagServiceImpl.java | 17 +- .../nw/service/QsheetHistoryService.java | 30 +++ 12 files changed, 441 insertions(+), 64 deletions(-) create mode 100644 nw/src/main/java/lab/cherry/nw/controller/QsheetHistoryController.java create mode 100644 nw/src/main/java/lab/cherry/nw/model/QsheetHistoryEntity.java create mode 100644 nw/src/main/java/lab/cherry/nw/repository/QsheetHistoryRepository.java create mode 100644 nw/src/main/java/lab/cherry/nw/service/Impl/QsheetHistoryServiceImpl.java create mode 100644 nw/src/main/java/lab/cherry/nw/service/QsheetHistoryService.java diff --git a/nw/src/main/java/lab/cherry/nw/controller/QsheetController.java b/nw/src/main/java/lab/cherry/nw/controller/QsheetController.java index d0462a6..8e61060 100644 --- a/nw/src/main/java/lab/cherry/nw/controller/QsheetController.java +++ b/nw/src/main/java/lab/cherry/nw/controller/QsheetController.java @@ -9,7 +9,6 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.util.CollectionUtils; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PatchMapping; @@ -27,7 +26,6 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; -import jakarta.validation.Valid; import lab.cherry.nw.error.ErrorResponse; import lab.cherry.nw.error.ResultResponse; import lab.cherry.nw.error.enums.SuccessCode; @@ -109,13 +107,13 @@ public ResponseEntity findAllQsheets( @Operation(summary = "Qsheet 생성", description = "Qsheet를 추가합니다.") public ResponseEntity createQsheet(@RequestPart QsheetEntity.QsheetCreateDto qsheetCreateDto, @RequestPart(required = false) List files) { log.info("[QsheetController] createQsheet...!"); - log.error ("files : {}", files); - for(MultipartFile file:files){ - if(file.isEmpty()){ - files = null; - break; - } - } + // log.error ("files : {}", files); + // for(MultipartFile file:files){ + // if(file.isEmpty()){ + // files = null; + // break; + // } + // } qsheetService.createQsheet(qsheetCreateDto, files); @@ -139,16 +137,16 @@ public ResponseEntity createQsheet(@RequestPart QsheetEntity.QsheetCreateDto public ResponseEntity updateById( @PathVariable("id") String id, @RequestPart QsheetEntity.QsheetUpdateDto qsheetUpdateDto, @RequestPart(required = false) List files) { - + + // log.info("files : {} ", files); log.info("[QsheetController] updateQsheet...!"); - for(MultipartFile file:files){ - if(file.isEmpty()){ - files = null; - break; - } - } + // for(MultipartFile file:files){ + // if(file.isEmpty()){ + // files = null; + // break; + // } + // } qsheetService.updateById(id, qsheetUpdateDto, files); - // final ResultResponse response = ResultResponse.of(SuccessCode.OK); return new ResponseEntity<>(qsheetService.findById(id), new HttpHeaders(), HttpStatus.OK); } diff --git a/nw/src/main/java/lab/cherry/nw/controller/QsheetHistoryController.java b/nw/src/main/java/lab/cherry/nw/controller/QsheetHistoryController.java new file mode 100644 index 0000000..d3b524b --- /dev/null +++ b/nw/src/main/java/lab/cherry/nw/controller/QsheetHistoryController.java @@ -0,0 +1,71 @@ +package lab.cherry.nw.controller; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lab.cherry.nw.model.QsheetHistoryEntity; +import lab.cherry.nw.service.QsheetHistoryService; +import lab.cherry.nw.util.Common; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + + +/** + *
+ * ClassName : QsheetHistoryController
+ * Type : class
+ * Description : 큐시트 히스토리 목록 조회, 큐시트 히스토리 상세 조회, 큐시트 히스토리 업데이트, 큐시트 히스토리 삭제, 큐시트 히스토리 찾기 등 큐시트 히스토리과 관련된 함수를 포함하고 있는 클래스입니다.
+ * Related : QsheetHistoryRepository, QsheetHistoryService, QsheetHistoryServiceImpl
+ * 
+ */ + +// MEMO : 재사용성을 위해 ServiceImpl에서만 비즈니스 로직을 사용하기로 함 +// Dto를 통해 알맞는 파라미터로 데이터 가공 후 사용하기로 함 +@Slf4j +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/v1/qsheetHistory") +@Tag(name = "QsheetHistory", description = "QsheetHistory API Document") +public class QsheetHistoryController { + private final QsheetHistoryService qsheetHistoryService; + + /** + * [QsheetController] 전체 큐시트 히스토리 목록 함수 + * + * @return 전체 큐시트 히스토리 목록을 반환합니다. + * + * Author : yby654(yby654@github.com) + */ + @GetMapping("") + @Operation(summary = "북마크 목록", description = "북마크 목록을 조회합니다.") + public ResponseEntity findAllBookmarks( + @RequestParam(required = false) String userid, + @RequestParam(defaultValue = "0") Integer page, + @RequestParam(defaultValue = "5") Integer size, + @RequestParam(defaultValue = "id,desc") String[] sort) { + + log.info("retrieve all bookmarks controller...!"); + + Pageable pageable = PageRequest.of(page, size, Sort.by(Common.getOrder(sort))); + + Page qsheetHistoryEntity; + if(userid == null) { + qsheetHistoryEntity = qsheetHistoryService.getQsheetHistorys(pageable); + } else { + qsheetHistoryEntity = qsheetHistoryService.findPageByUserId(userid, pageable); + } + return new ResponseEntity<>(qsheetHistoryEntity, new HttpHeaders(), HttpStatus.OK); + } + + +} diff --git a/nw/src/main/java/lab/cherry/nw/model/QsheetEntity.java b/nw/src/main/java/lab/cherry/nw/model/QsheetEntity.java index d229797..181c193 100644 --- a/nw/src/main/java/lab/cherry/nw/model/QsheetEntity.java +++ b/nw/src/main/java/lab/cherry/nw/model/QsheetEntity.java @@ -31,7 +31,7 @@ @Builder @NoArgsConstructor @AllArgsConstructor @Document(collection = "qsheet") -@JsonPropertyOrder({ "id", "name", "opening"}) +@JsonPropertyOrder({ "id", "name"}) public class QsheetEntity implements Serializable { @Id @@ -181,6 +181,9 @@ public void sortDataByOrderIndex() { @Builder @NoArgsConstructor @AllArgsConstructor public static class QsheetUpdateDto { + @NotNull + @Schema(title = "업데이트 유저", example = "38352658567418867") + private String updateUser; @Schema(title = "조직 고유번호", example = "38352658567418867") private String orgSeq; @Schema(title = "데이터 리스트") @@ -193,6 +196,7 @@ public static class QsheetUpdateDto { private boolean org_confirm; @Schema(title = "신랑신부 확인", type="Boolean", example = "false") private boolean client_confirm; + } public void updateFromDto(QsheetUpdateDto updateDto) { diff --git a/nw/src/main/java/lab/cherry/nw/model/QsheetHistoryEntity.java b/nw/src/main/java/lab/cherry/nw/model/QsheetHistoryEntity.java new file mode 100644 index 0000000..c449c0f --- /dev/null +++ b/nw/src/main/java/lab/cherry/nw/model/QsheetHistoryEntity.java @@ -0,0 +1,61 @@ +package lab.cherry.nw.model; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.DBRef; +import org.springframework.data.mongodb.core.mapping.Document; +import java.io.Serializable; +import java.time.Instant; +import java.util.List; +import java.util.Map; + + +/** + *
+ * ClassName : QsheetHistoryEntity
+ * Type : class
+ * Description : 큐시트 히스토리와 관련된 Entity를 구성하고 있는 클래스입니다.
+ * Related : QsheetHistoryRepository, QsheetHistoryServiceImpl
+ * 
+ */ +@Getter +@Builder +@NoArgsConstructor @AllArgsConstructor +@Document(collection = "qsheetHistory") +@JsonPropertyOrder({ "id", "name"}) +public class QsheetHistoryEntity implements Serializable { + + @Id + @JsonProperty("qsheetHistorySeq") + @Schema(title = "큐시트 히스토리 고유번호",type="String", example = "38352658567418867") // (Long) Tsid + private String id; + + @DBRef + @JsonProperty("qsheet") + @Schema(title = "큐시트 고유번호",type="String", example = "38352658567418867") // (Long) Tsid + private QsheetEntity qsheetid; + + @DBRef + @JsonProperty("user") + @Schema(title = "유저 고유번호", type="String",example = "38352658567418867") // (Long) Tsid + private UserEntity userid; + + @JsonProperty("content") + @Schema(title = "수정 내용", type="String",example = "큐시트 제목 변경") + // @Size(min = 4, max = 255, message = "Minimum name length: 4 characters") + private List> content; + + @JsonProperty("updated_at") + @JsonFormat(pattern="yyyy-MM-dd hh:mm:ss", locale = "ko_KR", timezone = "Asia/Seoul") + @Schema(title = "큐시트 업데이트 시간", example = "2023-07-04 12:00:00") + private Instant updated_at; + + +} diff --git a/nw/src/main/java/lab/cherry/nw/repository/QsheetHistoryRepository.java b/nw/src/main/java/lab/cherry/nw/repository/QsheetHistoryRepository.java new file mode 100644 index 0000000..e0ac324 --- /dev/null +++ b/nw/src/main/java/lab/cherry/nw/repository/QsheetHistoryRepository.java @@ -0,0 +1,31 @@ +package lab.cherry.nw.repository; + +import java.util.Optional; +import java.util.UUID; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.mongodb.repository.MongoRepository; +import lab.cherry.nw.model.QsheetHistoryEntity; + +/** + *
+ * ClassName : QsheetRepository
+ * Type : interface
+ * Descrption : 큐시트 JPA 구현을 위한 인터페이스입니다.
+ * Related : QsheetServiceImpl, QsheetService
+ * 
+ */ +public interface QsheetHistoryRepository extends MongoRepository { + + Page findAll(Pageable pageable); + + Page findPageByUserid(String userid, Pageable pageable); + + Optional findById(String id); + + // @Query("{'userid.$id' : ?0}") + // Optional findByUserid(ObjectId userId); + + + void deleteById(UUID id); +} \ No newline at end of file diff --git a/nw/src/main/java/lab/cherry/nw/service/Impl/BoardServiceImpl.java b/nw/src/main/java/lab/cherry/nw/service/Impl/BoardServiceImpl.java index db33b4a..ecc9655 100644 --- a/nw/src/main/java/lab/cherry/nw/service/Impl/BoardServiceImpl.java +++ b/nw/src/main/java/lab/cherry/nw/service/Impl/BoardServiceImpl.java @@ -1,30 +1,28 @@ package lab.cherry.nw.service.Impl; +import java.time.Instant; +import java.util.LinkedList; +import java.util.List; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import lab.cherry.nw.error.enums.ErrorCode; import lab.cherry.nw.error.exception.CustomException; import lab.cherry.nw.error.exception.EntityNotFoundException; import lab.cherry.nw.model.BoardEntity; import lab.cherry.nw.model.QsheetEntity; import lab.cherry.nw.model.TagEntity; -import lab.cherry.nw.model.UserEntity; import lab.cherry.nw.model.TagEntity.TagCreateDto; +import lab.cherry.nw.model.UserEntity; import lab.cherry.nw.repository.BoardRepository; import lab.cherry.nw.repository.TagRepository; -import lab.cherry.nw.service.OrgService; import lab.cherry.nw.service.BoardService; import lab.cherry.nw.service.QsheetService; import lab.cherry.nw.service.TagService; import lab.cherry.nw.service.UserService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.time.Instant; -import java.util.LinkedList; -import java.util.List; /** *
@@ -35,7 +33,7 @@
  * 
*/ @Slf4j -@Service("BoardServiceImpl") +@Service("boardServiceImpl") @Transactional @RequiredArgsConstructor public class BoardServiceImpl implements BoardService { diff --git a/nw/src/main/java/lab/cherry/nw/service/Impl/BookmarkServiceImpl.java b/nw/src/main/java/lab/cherry/nw/service/Impl/BookmarkServiceImpl.java index 60f0484..be8a87f 100644 --- a/nw/src/main/java/lab/cherry/nw/service/Impl/BookmarkServiceImpl.java +++ b/nw/src/main/java/lab/cherry/nw/service/Impl/BookmarkServiceImpl.java @@ -1,5 +1,11 @@ package lab.cherry.nw.service.Impl; +import java.time.Instant; +import org.bson.types.ObjectId; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import lab.cherry.nw.error.enums.ErrorCode; import lab.cherry.nw.error.exception.CustomException; import lab.cherry.nw.error.exception.EntityNotFoundException; @@ -7,17 +13,9 @@ import lab.cherry.nw.model.UserEntity; import lab.cherry.nw.repository.BookmarkRepository; import lab.cherry.nw.service.BookmarkService; -import lab.cherry.nw.service.OrgService; import lab.cherry.nw.service.UserService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.bson.types.ObjectId; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.time.Instant; /** *
@@ -28,7 +26,7 @@
  * 
*/ @Slf4j -@Service("BookmarkServiceImpl") +@Service("bookmarkServiceImpl") @Transactional @RequiredArgsConstructor public class BookmarkServiceImpl implements BookmarkService { diff --git a/nw/src/main/java/lab/cherry/nw/service/Impl/OrgServiceImpl.java b/nw/src/main/java/lab/cherry/nw/service/Impl/OrgServiceImpl.java index 046f9fb..a173430 100644 --- a/nw/src/main/java/lab/cherry/nw/service/Impl/OrgServiceImpl.java +++ b/nw/src/main/java/lab/cherry/nw/service/Impl/OrgServiceImpl.java @@ -1,7 +1,5 @@ package lab.cherry.nw.service.Impl; -import io.minio.*; -import io.minio.errors.MinioException; import lab.cherry.nw.error.enums.ErrorCode; import lab.cherry.nw.error.exception.CustomException; import lab.cherry.nw.error.exception.EntityNotFoundException; diff --git a/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetHistoryServiceImpl.java b/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetHistoryServiceImpl.java new file mode 100644 index 0000000..bf9ac22 --- /dev/null +++ b/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetHistoryServiceImpl.java @@ -0,0 +1,201 @@ +package lab.cherry.nw.service.Impl; + +import java.time.Instant; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import lab.cherry.nw.error.exception.CustomException; +import lab.cherry.nw.error.exception.EntityNotFoundException; +import lab.cherry.nw.model.OrgEntity; +import lab.cherry.nw.model.QsheetEntity; +import lab.cherry.nw.model.QsheetEntity.ItemData; +import lab.cherry.nw.model.QsheetHistoryEntity; +import lab.cherry.nw.model.UserEntity; +import lab.cherry.nw.repository.QsheetHistoryRepository; +import lab.cherry.nw.service.OrgService; +import lab.cherry.nw.service.QsheetHistoryService; +import lab.cherry.nw.service.QsheetService; +import lab.cherry.nw.service.UserService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +/** + *
+ * ClassName : QsheetHistoryServiceImpl
+ * Type : class0.20
+ * Description : 북마크와 관련된 서비스 구현과 관련된 함수를 포함하고 있는 클래스입니다.
+ * Related : spring-boot-starter-data-jpa
+ * 
+ */ +@Slf4j +@Service("qsheetHistoryServiceImpl") +@Transactional +@RequiredArgsConstructor +public class QsheetHistoryServiceImpl implements QsheetHistoryService { + + private final QsheetHistoryRepository qsheetHistoryRepository; + private final UserService userService; + private final OrgService orgService; + /** + * [BookmarkServiceImpl] 전체 북마크 조회 함수 + * + * @return DB에서 전체 북마크 정보 목록을 리턴합니다. + * @throws EntityNotFoundException 북마크 정보가 없을 경우 예외 처리 발생 + *
+     * 전체 북마크를 조회하여, 북마크 목록을 반환합니다.
+     * 
+ * + * Author : yby654(yby654@github.com) + */ + @Transactional(readOnly = true) + @Override + public Page getQsheetHistorys(Pageable pageable) { + return qsheetHistoryRepository.findAll(pageable); + } + + +// + /** + * [BookmarkServiceImpl] 북마크 생성 함수 + * + * @param qsheetHistoryCreateDto 북마크 생성에 필요한 북마크 등록 정보를 담은 개체입니다. + * @return 생성된 북마크 정보를 리턴합니다. + * @throws CustomException 중복된 이름에 대한 예외 처리 발생 + *
+     * 북마크를 등록합니다.
+     * 
+ * + * Author : yby654(yby654@github.com) + */ + public void createQsheetHistory(QsheetEntity originQsheetEntity, QsheetEntity.QsheetUpdateDto qsheetUpdateDto) { + // QsheetEntity qsheetEntity = qsheetService.findById(originQsheetEntity.getId()); + UserEntity userEntity = userService.findById(qsheetUpdateDto.getUpdateUser()); + List> contentList = new ArrayList<>(); + if(qsheetUpdateDto.getOrgSeq()!=null){ + OrgEntity orgEntity = orgService.findById(qsheetUpdateDto.getOrgSeq()); + Map data = new HashMap<>(); + data.put("action", "수정"); + data.put("info", "업체"); + data.put("content",orgEntity.getName()); + contentList.add(data); + } + if(qsheetUpdateDto.getMemo()!=null){ + Map data = new HashMap<>(); + data.put("action", "수정"); + data.put("info", "시크릿 메모"); + data.put("content", qsheetUpdateDto.getMemo()); + contentList.add(data); + } + if(qsheetUpdateDto.getOrg_approverSeq()!=null && qsheetUpdateDto.isClient_confirm()){ + UserEntity Org_approverEntity = userService.findById(qsheetUpdateDto.getOrg_approverSeq()); + Map data = new HashMap<>(); + data.put("action", "최종 확인"); + data.put("info", "업체 최종 확인"); + data.put("content","최종 확인자 : " + Org_approverEntity.getUsername()); + contentList.add(data); + } + if(qsheetUpdateDto.isClient_confirm()){ + Map data = new HashMap<>(); + data.put("action", "최종 확인"); + data.put("info", "신랑&신부 최종 확인"); + data.put("content","신랑&신부 최종 확인 완료"); + contentList.add(data); + } + if(qsheetUpdateDto.getData()!=null){ + List> result = compareLists(originQsheetEntity.getData(), qsheetUpdateDto.getData()); + for (Map change : result) { + for (Map.Entry entry : change.entrySet()) { + String action = entry.getKey(); + ItemData item = entry.getValue(); + System.out.println(action + " : " + item.getProcess()); + Map data = new HashMap<>(); + data.put("action", entry.getKey()); + data.put("info", item.getProcess()); + data.put("content",item.getProcess() + " " + entry.getKey()); + contentList.add(data); + } + } + } + Instant instant = Instant.now(); + // UserEntity userEntity = userService.findById(qsheetHistoryCreateDto.getUserSeq()); + QsheetHistoryEntity qsheetHistoryEntity = QsheetHistoryEntity.builder() + .qsheetid(originQsheetEntity) + .userid(userEntity) + .content(contentList) + .updated_at(instant) + .build(); + qsheetHistoryRepository.save(qsheetHistoryEntity); + } + public List> compareLists(List list1, List list2) { + List> resultList = new ArrayList<>(); + + // 두 리스트를 순회하면서 비교 + for (ItemData item1 : list1) { + ItemData matchingItem = list2.stream() + .filter(item2 -> item2.getOrderIndex().equals(item1.getOrderIndex())) + .findFirst() + .orElse(null); + + if (matchingItem == null) { + // list2에 없는 경우, 삭제로 처리 + Map change = new HashMap<>(); + change.put("삭제", item1); + resultList.add(change); + } else if (!item1.equals(matchingItem)) { + // 내용이 다른 경우, 수정으로 처리 + Map change = new HashMap<>(); + change.put("수정", matchingItem); + resultList.add(change); + } + } + + // list2에만 있는 항목을 추가로 처리 + for (ItemData item2 : list2) { + ItemData matchingItem = list1.stream() + .filter(item1 -> item1.getOrderIndex().equals(item2.getOrderIndex())) + .findFirst() + .orElse(null); + + if (matchingItem == null) { + Map change = new HashMap<>(); + change.put("추가", item2); + resultList.add(change); + } + } + + return resultList; + } + + + /** + * [BookmarkServiceImpl] ID로 북마크 조회 함수 + * + * @param id 조회할 북마크의 식별자입니다. + * @return 주어진 식별자에 해당하는 북마크 정보 + * @throws EntityNotFoundException 해당 ID의 북마크 정보가 없을 경우 예외 처리 발생 + *
+     * 입력한 id에 해당하는 북마크 정보를 조회합니다.
+     * 
+ * + * Author : yby654(yby654@github.com) + */ + @Transactional(readOnly = true) + public QsheetHistoryEntity findById(String id) { + return qsheetHistoryRepository.findById(id).orElseThrow(() -> new EntityNotFoundException("Bookmark with Id " + id + " Not Found.")); + } + + // @Transactional(readOnly = true) + // public QsheetHistoryEntity findByUserId(ObjectId userId) { + // return bookmarkRepository.findByUserid(userId).orElseThrow(() -> new EntityNotFoundException("Bookmark with User id " + userId.toString() + " Not Found.")); + // } + + @Transactional(readOnly = true) + public Page findPageByUserId(String userid, Pageable pageable) { + return qsheetHistoryRepository.findPageByUserid(userid, pageable); + } + +} diff --git a/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetServiceImpl.java b/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetServiceImpl.java index e1fb92a..d4e5c96 100644 --- a/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetServiceImpl.java +++ b/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetServiceImpl.java @@ -10,6 +10,7 @@ import lab.cherry.nw.repository.QsheetRepository; import lab.cherry.nw.service.FileService; import lab.cherry.nw.service.OrgService; +import lab.cherry.nw.service.QsheetHistoryService; import lab.cherry.nw.service.QsheetService; import lab.cherry.nw.service.UserService; import lombok.RequiredArgsConstructor; @@ -39,7 +40,7 @@ *
*/ @Slf4j -@Service("QsheetServiceImpl") +@Service("qsheetServiceImpl") @Transactional @RequiredArgsConstructor public class QsheetServiceImpl implements QsheetService { @@ -48,6 +49,7 @@ public class QsheetServiceImpl implements QsheetService { private final UserService userService; private final OrgService orgService; private final FileService fileService; + private final QsheetHistoryService qsheetHistoryService; /** * [QsheetServiceImpl] 전체 큐시트 조회 함수 * @@ -225,9 +227,7 @@ public void updateById(String id, QsheetEntity.QsheetUpdateDto qsheetUpdateDto, newItemData.add(tempData); } } - - - + QsheetEntity originEntity = qsheetEntity; qsheetEntity = QsheetEntity.builder() .id(qsheetEntity.getId()) .name(qsheetEntity.getName()) @@ -238,17 +238,11 @@ public void updateById(String id, QsheetEntity.QsheetUpdateDto qsheetUpdateDto, .org_approver(orgUserEntity) .org_confirm(qsheetUpdateDto.isOrg_confirm()==!(qsheetEntity.isOrg_confirm())?qsheetUpdateDto.isOrg_confirm():qsheetEntity.isOrg_confirm()) .client_confirm(qsheetUpdateDto.isClient_confirm()==!(qsheetEntity.isClient_confirm())?qsheetUpdateDto.isClient_confirm():qsheetEntity.isClient_confirm()) - // .finalConfirm(qsheetUpdateDto.getFinalConfirm()!=null? - // FinalConfirm.builder() - // .org_approver(qsheetUpdateDto.getFinalConfirm().getOrg_approver()!=null?qsheetUpdateDto.getFinalConfirm().getOrg_approver():null) - // .org_confirm(qsheetUpdateDto.getFinalConfirm().isOrg_confirm()==!(qsheetEntity.getFinalConfirm().isOrg_confirm())?qsheetUpdateDto.getFinalConfirm().isOrg_confirm():qsheetEntity.getFinalConfirm().isOrg_confirm()) - // .client_confirm(qsheetUpdateDto.getFinalConfirm().isClient_confirm()==!(qsheetEntity.getFinalConfirm().isClient_confirm())?qsheetUpdateDto.getFinalConfirm().isClient_confirm():qsheetEntity.getFinalConfirm().isClient_confirm()) - // .build():qsheetEntity.getFinalConfirm() ) - .memo(qsheetUpdateDto.getMemo()) + .memo(qsheetUpdateDto.getMemo()!=null?qsheetUpdateDto.getMemo():qsheetEntity.getMemo()) .updated_at(instant) .build(); qsheetRepository.save(qsheetEntity); - + qsheetHistoryService.createQsheetHistory(originEntity, qsheetUpdateDto); } else { log.error("[QsheetServiceImpl - udpateQsheet] OrgSeq,data 만 수정 가능합니다."); throw new CustomException(ErrorCode.INVALID_INPUT_VALUE); diff --git a/nw/src/main/java/lab/cherry/nw/service/Impl/TagServiceImpl.java b/nw/src/main/java/lab/cherry/nw/service/Impl/TagServiceImpl.java index 0cc73fa..5dc5c79 100644 --- a/nw/src/main/java/lab/cherry/nw/service/Impl/TagServiceImpl.java +++ b/nw/src/main/java/lab/cherry/nw/service/Impl/TagServiceImpl.java @@ -1,24 +1,17 @@ package lab.cherry.nw.service.Impl; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import lab.cherry.nw.error.enums.ErrorCode; import lab.cherry.nw.error.exception.CustomException; import lab.cherry.nw.error.exception.EntityNotFoundException; import lab.cherry.nw.model.TagEntity; -import lab.cherry.nw.model.QsheetEntity; -import lab.cherry.nw.model.UserEntity; import lab.cherry.nw.repository.TagRepository; -import lab.cherry.nw.service.OrgService; import lab.cherry.nw.service.TagService; -import lab.cherry.nw.service.QsheetService; -import lab.cherry.nw.service.UserService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.time.Instant; /** *
@@ -29,7 +22,7 @@
  * 
*/ @Slf4j -@Service("TagServiceImpl") +@Service("tagServiceImpl") @Transactional @RequiredArgsConstructor public class TagServiceImpl implements TagService { diff --git a/nw/src/main/java/lab/cherry/nw/service/QsheetHistoryService.java b/nw/src/main/java/lab/cherry/nw/service/QsheetHistoryService.java new file mode 100644 index 0000000..904c38a --- /dev/null +++ b/nw/src/main/java/lab/cherry/nw/service/QsheetHistoryService.java @@ -0,0 +1,30 @@ +package lab.cherry.nw.service; + +import lab.cherry.nw.model.BookmarkEntity; +import lab.cherry.nw.model.QsheetEntity; +import lab.cherry.nw.model.QsheetHistoryEntity; +import org.bson.types.ObjectId; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Component; + +/** + *
+ * ClassName : QsheetService
+ * Type : interface
+ * Description : 큐시트와 관련된 함수를 정리한 인터페이스입니다.
+ * Related : QsheetController, QsheetServiceiml
+ * 
+ */ +@Component +public interface QsheetHistoryService { + Page getQsheetHistorys(Pageable pageable); + QsheetHistoryEntity findById(String id); + // QsheetHistoryEntity findByUserId(ObjectId userId); + Page findPageByUserId(String userid, Pageable pageable); + void createQsheetHistory(QsheetEntity qsheetEntity, QsheetEntity.QsheetUpdateDto qsheetUpdateDto); +// Page findPageByUserId(String userid, Pageable pageable); +// Page findPageByOrgId(String orgid, Pageable pageable); +// void updateOrgById(String id, List orgIds); +// byte[] download(List users); +} \ No newline at end of file From da9b4c0b391403551d5f5010e67c5aba1320a1d2 Mon Sep 17 00:00:00 2001 From: yby654 Date: Thu, 26 Oct 2023 06:57:09 +0000 Subject: [PATCH 14/14] =?UTF-8?q?Chore:=20=ED=81=90=EC=8B=9C=ED=8A=B8=20ID?= =?UTF-8?q?=EB=A1=9C=20=ED=9E=88=EC=8A=A4=ED=86=A0=EB=A6=AC=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=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 --- .../nw/controller/BookmarkController.java | 2 +- .../controller/QsheetHistoryController.java | 39 ++++++++++++++++--- .../repository/QsheetHistoryRepository.java | 10 ++++- .../Impl/QsheetHistoryServiceImpl.java | 13 +++++++ .../nw/service/QsheetHistoryService.java | 4 ++ 5 files changed, 60 insertions(+), 8 deletions(-) diff --git a/nw/src/main/java/lab/cherry/nw/controller/BookmarkController.java b/nw/src/main/java/lab/cherry/nw/controller/BookmarkController.java index 910872a..10bb56a 100644 --- a/nw/src/main/java/lab/cherry/nw/controller/BookmarkController.java +++ b/nw/src/main/java/lab/cherry/nw/controller/BookmarkController.java @@ -178,7 +178,7 @@ public ResponseEntity deleteById(@PathVariable("id") String id) { } /** - * [BookmarkController] 특정 역할 조회 함수 + * [BookmarkController] 특정 북마크 조회 함수 * * @param id 북마크 고유번호를 입력합니다. * @return diff --git a/nw/src/main/java/lab/cherry/nw/controller/QsheetHistoryController.java b/nw/src/main/java/lab/cherry/nw/controller/QsheetHistoryController.java index d3b524b..2b02c00 100644 --- a/nw/src/main/java/lab/cherry/nw/controller/QsheetHistoryController.java +++ b/nw/src/main/java/lab/cherry/nw/controller/QsheetHistoryController.java @@ -1,5 +1,6 @@ package lab.cherry.nw.controller; +import org.bson.types.ObjectId; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; @@ -8,6 +9,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @@ -40,32 +42,57 @@ public class QsheetHistoryController { private final QsheetHistoryService qsheetHistoryService; /** - * [QsheetController] 전체 큐시트 히스토리 목록 함수 + * [QsheetHistoryController] 전체 큐시트 히스토리 목록 함수 * * @return 전체 큐시트 히스토리 목록을 반환합니다. * * Author : yby654(yby654@github.com) */ @GetMapping("") - @Operation(summary = "북마크 목록", description = "북마크 목록을 조회합니다.") - public ResponseEntity findAllBookmarks( + @Operation(summary = "큐시트 히스토리 목록", description = "큐시트 히스토리 목록을 조회합니다.") + public ResponseEntity findAllQsheetHistory( @RequestParam(required = false) String userid, + @RequestParam(required = false) String qsheetid, @RequestParam(defaultValue = "0") Integer page, @RequestParam(defaultValue = "5") Integer size, @RequestParam(defaultValue = "id,desc") String[] sort) { - log.info("retrieve all bookmarks controller...!"); + log.info("retrieve all QsheetHistroy controller...!"); Pageable pageable = PageRequest.of(page, size, Sort.by(Common.getOrder(sort))); Page qsheetHistoryEntity; - if(userid == null) { + if(userid == null && qsheetid==null) { qsheetHistoryEntity = qsheetHistoryService.getQsheetHistorys(pageable); - } else { + } else if(userid != null && qsheetid==null) { qsheetHistoryEntity = qsheetHistoryService.findPageByUserId(userid, pageable); + }else { + qsheetHistoryEntity = qsheetHistoryService.findPageByQsheetId(qsheetid, pageable); } return new ResponseEntity<>(qsheetHistoryEntity, new HttpHeaders(), HttpStatus.OK); } + /** + * [QsheetHistoryController] 특정 큐시트 히스토리 조회 함수 + * + * @param qsheetId 큐시트 고유번호를 입력합니다. + * @return + *
+     * true  : 특정 큐시트 히스토리 목록을 반환합니다.
+     * false : 에러(400, 404)를 반환합니다.
+     * 
+ * + * Author : yby654(yby654@github.com) + */ + @GetMapping("/qsheet/{id}") + @Operation(summary = "Qsheet ID로 히스토리 찾기", description = "큐시트 히스토리를 조회합니다.") + public ResponseEntity find(@PathVariable("id") String qsheetId) { + ObjectId objectId = new ObjectId(qsheetId); + log.info("[QsheetController] findByQsheetId...!"); + + // final ResultResponse response = ResultResponse.of(SuccessCode.OK, userService.findById(id)); + return new ResponseEntity<>(qsheetHistoryService.findByQsheetId(objectId), new HttpHeaders(), HttpStatus.OK); + } + } diff --git a/nw/src/main/java/lab/cherry/nw/repository/QsheetHistoryRepository.java b/nw/src/main/java/lab/cherry/nw/repository/QsheetHistoryRepository.java index a498f96..da74061 100644 --- a/nw/src/main/java/lab/cherry/nw/repository/QsheetHistoryRepository.java +++ b/nw/src/main/java/lab/cherry/nw/repository/QsheetHistoryRepository.java @@ -1,10 +1,13 @@ package lab.cherry.nw.repository; +import java.util.List; import java.util.Optional; import java.util.UUID; +import org.bson.types.ObjectId; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.data.mongodb.repository.Query; import lab.cherry.nw.model.QsheetHistoryEntity; /** @@ -17,11 +20,16 @@ */ public interface QsheetHistoryRepository extends MongoRepository { - Page findAll(Pageable pageable); + Page findAll(Pageable pageable); Page findPageByUserid(String userid, Pageable pageable); + Page findPageByQsheetid(String qsheetid, Pageable pageable); + Optional findById(String id); + + @Query("{'qsheetid.$id' : ?0}") + List findByQsheetId(ObjectId qsheetId); // @Query("{'userid.$id' : ?0}") // Optional findByUserid(ObjectId userId); diff --git a/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetHistoryServiceImpl.java b/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetHistoryServiceImpl.java index e4a547b..dbdf101 100644 --- a/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetHistoryServiceImpl.java +++ b/nw/src/main/java/lab/cherry/nw/service/Impl/QsheetHistoryServiceImpl.java @@ -5,12 +5,14 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import org.bson.types.ObjectId; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import lab.cherry.nw.error.exception.CustomException; import lab.cherry.nw.error.exception.EntityNotFoundException; +import lab.cherry.nw.model.BookmarkEntity; import lab.cherry.nw.model.OrgEntity; import lab.cherry.nw.model.QsheetEntity; import lab.cherry.nw.model.QsheetEntity.ItemData; @@ -197,5 +199,16 @@ public QsheetHistoryEntity findById(String id) { public Page findPageByUserId(String userid, Pageable pageable) { return qsheetHistoryRepository.findPageByUserid(userid, pageable); } + + @Transactional(readOnly = true) + public Page findPageByQsheetId(String qsheetid, Pageable pageable) { + return qsheetHistoryRepository.findPageByQsheetid(qsheetid, pageable); + } + + @Transactional(readOnly = true) + @Override + public List findByQsheetId(ObjectId qsheeObjectId) { + return EntityNotFoundException.requireNotEmpty(qsheetHistoryRepository.findByQsheetId(qsheeObjectId), "QsheetId Not Found"); + } } diff --git a/nw/src/main/java/lab/cherry/nw/service/QsheetHistoryService.java b/nw/src/main/java/lab/cherry/nw/service/QsheetHistoryService.java index 09e6247..44df189 100644 --- a/nw/src/main/java/lab/cherry/nw/service/QsheetHistoryService.java +++ b/nw/src/main/java/lab/cherry/nw/service/QsheetHistoryService.java @@ -1,5 +1,7 @@ package lab.cherry.nw.service; +import java.util.List; +import org.bson.types.ObjectId; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Component; @@ -21,7 +23,9 @@ public interface QsheetHistoryService { QsheetHistoryEntity findById(String id); // QsheetHistoryEntity findByUserId(ObjectId userId); Page findPageByUserId(String userid, Pageable pageable); + Page findPageByQsheetId(String qsheetid, Pageable pageable); void createQsheetHistory(QsheetEntity qsheetEntity, QsheetEntity.QsheetUpdateDto qsheetUpdateDto); + List findByQsheetId(ObjectId qsheetId); // Page findPageByUserId(String userid, Pageable pageable); // Page findPageByOrgId(String orgid, Pageable pageable); // void updateOrgById(String id, List orgIds);