From f423c3d4e14191aa7ff01267d9a9e4c3ad33d18f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=86=8C=EC=A0=95?= Date: Fri, 2 Feb 2024 17:22:51 +0900 Subject: [PATCH 1/5] =?UTF-8?q?=F0=9F=90=9B=20fix:=20Announcement=20?= =?UTF-8?q?=EC=97=90=EC=84=9C=20Image=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20A?= =?UTF-8?q?ttachment=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/request/AnnouncementCreateRequest.java | 7 +++++-- .../domain/announcement/entity/Announcement.java | 2 +- ...ncementAttachment.java => AnnouncementImage.java} | 12 +++++------- 3 files changed, 11 insertions(+), 10 deletions(-) rename src/main/java/com/sponus/sponusbe/domain/announcement/entity/{AnnouncementAttachment.java => AnnouncementImage.java} (83%) diff --git a/src/main/java/com/sponus/sponusbe/domain/announcement/dto/request/AnnouncementCreateRequest.java b/src/main/java/com/sponus/sponusbe/domain/announcement/dto/request/AnnouncementCreateRequest.java index bf37d20b..c815b118 100644 --- a/src/main/java/com/sponus/sponusbe/domain/announcement/dto/request/AnnouncementCreateRequest.java +++ b/src/main/java/com/sponus/sponusbe/domain/announcement/dto/request/AnnouncementCreateRequest.java @@ -2,7 +2,10 @@ import static com.sponus.sponusbe.domain.announcement.entity.enums.AnnouncementStatus.*; +import java.util.List; + import com.sponus.sponusbe.domain.announcement.entity.Announcement; +import com.sponus.sponusbe.domain.announcement.entity.AnnouncementImage; import com.sponus.sponusbe.domain.announcement.entity.enums.AnnouncementCategory; import com.sponus.sponusbe.domain.announcement.entity.enums.AnnouncementStatus; import com.sponus.sponusbe.domain.announcement.entity.enums.AnnouncementType; @@ -12,13 +15,13 @@ import jakarta.validation.constraints.NotNull; public record AnnouncementCreateRequest( - @NotBlank(message = "[ERROR] 타이틀 입력은 필수 입니다.") + @NotNull(message = "[ERROR] 타이틀 입력은 필수 입니다.") String title, @NotNull(message = "[ERROR] 유형 입력은 필수 입니다.") AnnouncementType type, @NotNull(message = "[ERROR] 카테코리 입력은 필수 입니다.") AnnouncementCategory category, - @NotBlank(message = "[ERROR] 내용 입력은 필수 입니다.") + @NotNull(message = "[ERROR] 내용 입력은 필수 입니다.") String content, AnnouncementStatus status diff --git a/src/main/java/com/sponus/sponusbe/domain/announcement/entity/Announcement.java b/src/main/java/com/sponus/sponusbe/domain/announcement/entity/Announcement.java index 66dec89f..9e6a3d3d 100644 --- a/src/main/java/com/sponus/sponusbe/domain/announcement/entity/Announcement.java +++ b/src/main/java/com/sponus/sponusbe/domain/announcement/entity/Announcement.java @@ -69,7 +69,7 @@ public class Announcement extends BaseEntity { @Builder.Default @OneToMany(mappedBy = "announcement") - private List announcementAttachments = new ArrayList<>(); + private List announcementImages = new ArrayList<>(); public void increaseViewCount() { this.viewCount++; diff --git a/src/main/java/com/sponus/sponusbe/domain/announcement/entity/AnnouncementAttachment.java b/src/main/java/com/sponus/sponusbe/domain/announcement/entity/AnnouncementImage.java similarity index 83% rename from src/main/java/com/sponus/sponusbe/domain/announcement/entity/AnnouncementAttachment.java rename to src/main/java/com/sponus/sponusbe/domain/announcement/entity/AnnouncementImage.java index 5f7c92a4..651e1061 100644 --- a/src/main/java/com/sponus/sponusbe/domain/announcement/entity/AnnouncementAttachment.java +++ b/src/main/java/com/sponus/sponusbe/domain/announcement/entity/AnnouncementImage.java @@ -16,24 +16,22 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; - @Builder @NoArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor(access = AccessLevel.PRIVATE) @Getter @Entity -@Table(name = "announcement_attachment") -public class AnnouncementAttachment { - +@Table(name = "announcement_image") +public class AnnouncementImage { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "attachment_id") + @Column(name = "image_id") private Long id; - @Column(name = "file_name", nullable = false) + @Column(name = "image_name", nullable = false) private String name; - @Column(name = "file_url", nullable = false) + @Column(name = "image_url", nullable = false) private String url; @ManyToOne(fetch = FetchType.LAZY, optional = false) From a945395a3241c5fbf7ded8ab57a6bc729e1818fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=86=8C=EC=A0=95?= Date: Sat, 3 Feb 2024 16:11:32 +0900 Subject: [PATCH 2/5] =?UTF-8?q?:sparkles:=20feat:=20=EA=B3=B5=EA=B3=A0=20R?= =?UTF-8?q?equest=20=EB=B0=8F=20Response=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- http/test.http | 6 +++-- .../controller/AnnouncementController.java | 7 +++-- .../request/AnnouncementCreateRequest.java | 6 +---- .../response/AnnouncementImageResponse.java | 26 +++++++++++++++++++ .../dto/response/AnnouncementResponse.java | 6 +++++ 5 files changed, 42 insertions(+), 9 deletions(-) create mode 100644 src/main/java/com/sponus/sponusbe/domain/announcement/dto/response/AnnouncementImageResponse.java diff --git a/http/test.http b/http/test.http index df3f904f..2c44a967 100644 --- a/http/test.http +++ b/http/test.http @@ -31,14 +31,16 @@ Content-Type: application/json ### 공고 생성 POST http://localhost:8080/api/v1/announcements -Authorization: Bearer {{matsterToken}} +Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxIiwiZW1haWwiOiJzcG9udXNAZ21haWwuY29tIiwiYXV0aCI6IlNUVURFTlQiLCJpYXQiOjE3MDY4Njc0NTUsImV4cCI6MTcwNzg2NzQ1NX0.HB9MvC9Oq-9P5BOsHwioZK6S3nk6G_MTVtnunMAf9uo Content-Type: application/json { "title": "무신사 스폰서십", "type": "SPONSORSHIP", "category": "MARKETING", - "content": "무신사 스폰서십을 진행할 대학교 학생회를 모집합니다." + "content": "무신사 스폰서십을 진행할 대학교 학생회를 모집합니다.", + "images": [ + ] } ### 공고 상세 조회 diff --git a/src/main/java/com/sponus/sponusbe/domain/announcement/controller/AnnouncementController.java b/src/main/java/com/sponus/sponusbe/domain/announcement/controller/AnnouncementController.java index 53825bcc..2f051050 100644 --- a/src/main/java/com/sponus/sponusbe/domain/announcement/controller/AnnouncementController.java +++ b/src/main/java/com/sponus/sponusbe/domain/announcement/controller/AnnouncementController.java @@ -10,7 +10,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 com.sponus.sponusbe.auth.annotation.AuthOrganization; import com.sponus.sponusbe.domain.announcement.dto.request.AnnouncementCreateRequest; @@ -22,6 +24,7 @@ import com.sponus.sponusbe.domain.announcement.service.AnnouncementQueryService; import com.sponus.sponusbe.domain.announcement.service.AnnouncementService; import com.sponus.sponusbe.domain.organization.entity.Organization; +import com.sponus.sponusbe.domain.s3.S3Controller; import com.sponus.sponusbe.global.common.ApiResponse; import jakarta.validation.Valid; @@ -63,10 +66,10 @@ public ApiResponse> searchAnnouncement(@RequestParam( return ApiResponse.onSuccess(announcementQueryService.searchAnnouncement(keyword)); } - @PostMapping + @PostMapping(consumes = "multipart/form-data") public ApiResponse createAnnouncement( @AuthOrganization Organization authOrganization, - @RequestBody @Valid AnnouncementCreateRequest request + @RequestPart @Valid AnnouncementCreateRequest request ) { return ApiResponse.onSuccess(announcementService.createAnnouncement(authOrganization, request)); } diff --git a/src/main/java/com/sponus/sponusbe/domain/announcement/dto/request/AnnouncementCreateRequest.java b/src/main/java/com/sponus/sponusbe/domain/announcement/dto/request/AnnouncementCreateRequest.java index c815b118..0af84434 100644 --- a/src/main/java/com/sponus/sponusbe/domain/announcement/dto/request/AnnouncementCreateRequest.java +++ b/src/main/java/com/sponus/sponusbe/domain/announcement/dto/request/AnnouncementCreateRequest.java @@ -2,16 +2,12 @@ import static com.sponus.sponusbe.domain.announcement.entity.enums.AnnouncementStatus.*; -import java.util.List; - import com.sponus.sponusbe.domain.announcement.entity.Announcement; -import com.sponus.sponusbe.domain.announcement.entity.AnnouncementImage; import com.sponus.sponusbe.domain.announcement.entity.enums.AnnouncementCategory; import com.sponus.sponusbe.domain.announcement.entity.enums.AnnouncementStatus; import com.sponus.sponusbe.domain.announcement.entity.enums.AnnouncementType; import com.sponus.sponusbe.domain.organization.entity.Organization; -import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; public record AnnouncementCreateRequest( @@ -23,7 +19,6 @@ public record AnnouncementCreateRequest( AnnouncementCategory category, @NotNull(message = "[ERROR] 내용 입력은 필수 입니다.") String content, - AnnouncementStatus status ) { @@ -38,3 +33,4 @@ public Announcement toEntity(Organization writer) { .build(); } } + diff --git a/src/main/java/com/sponus/sponusbe/domain/announcement/dto/response/AnnouncementImageResponse.java b/src/main/java/com/sponus/sponusbe/domain/announcement/dto/response/AnnouncementImageResponse.java new file mode 100644 index 00000000..3847a0e2 --- /dev/null +++ b/src/main/java/com/sponus/sponusbe/domain/announcement/dto/response/AnnouncementImageResponse.java @@ -0,0 +1,26 @@ +package com.sponus.sponusbe.domain.announcement.dto.response; + +import java.util.List; +import java.util.stream.Collectors; + +import com.sponus.sponusbe.domain.announcement.entity.AnnouncementImage; + +import lombok.Builder; + +@Builder +public record AnnouncementImageResponse( + Long id, + String name, + String url +) { + + public static List announcementImage(List announcementImages) { + return announcementImages.stream() + .map(imageUrl -> AnnouncementImageResponse.builder() + .id(imageUrl.getId()) + .name(imageUrl.getName()) + .url(imageUrl.getUrl()) + .build()) + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/com/sponus/sponusbe/domain/announcement/dto/response/AnnouncementResponse.java b/src/main/java/com/sponus/sponusbe/domain/announcement/dto/response/AnnouncementResponse.java index abe7f38e..cf7b42f0 100644 --- a/src/main/java/com/sponus/sponusbe/domain/announcement/dto/response/AnnouncementResponse.java +++ b/src/main/java/com/sponus/sponusbe/domain/announcement/dto/response/AnnouncementResponse.java @@ -1,5 +1,9 @@ package com.sponus.sponusbe.domain.announcement.dto.response; +import static com.sponus.sponusbe.domain.announcement.dto.response.AnnouncementImageResponse.*; + +import java.util.List; + import com.sponus.sponusbe.domain.announcement.entity.Announcement; import com.sponus.sponusbe.domain.announcement.entity.enums.AnnouncementCategory; import com.sponus.sponusbe.domain.announcement.entity.enums.AnnouncementStatus; @@ -15,6 +19,7 @@ public record AnnouncementResponse( AnnouncementType type, AnnouncementCategory category, String content, + List announcementImages, AnnouncementStatus status, Long viewCount ) { @@ -26,6 +31,7 @@ public static AnnouncementResponse from(Announcement announcement) { .type(announcement.getType()) .category(announcement.getCategory()) .content(announcement.getContent()) + .announcementImages(announcementImage(announcement.getAnnouncementImages())) .status(announcement.getStatus()) .viewCount(announcement.getViewCount()) .build(); From 96d5ca996ff6d1a39848bef6e0df3f95f966c194 Mon Sep 17 00:00:00 2001 From: marooo326 Date: Mon, 5 Feb 2024 00:15:22 +0900 Subject: [PATCH 3/5] =?UTF-8?q?feat:=20=EA=B3=B5=EA=B3=A0=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1=20=EC=8B=9C=20=EC=9D=B4=EB=AF=B8=EC=A7=80=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 --- .../controller/AnnouncementController.java | 14 +++++++---- .../response/AnnouncementImageResponse.java | 18 +++++---------- .../dto/response/AnnouncementResponse.java | 9 +++++--- .../entity/AnnouncementImage.java | 9 ++++++++ .../service/AnnouncementService.java | 23 +++++++++++++++---- src/main/resources/data.sql | 2 +- 6 files changed, 50 insertions(+), 25 deletions(-) diff --git a/src/main/java/com/sponus/sponusbe/domain/announcement/controller/AnnouncementController.java b/src/main/java/com/sponus/sponusbe/domain/announcement/controller/AnnouncementController.java index a4b1904e..6ad6199a 100644 --- a/src/main/java/com/sponus/sponusbe/domain/announcement/controller/AnnouncementController.java +++ b/src/main/java/com/sponus/sponusbe/domain/announcement/controller/AnnouncementController.java @@ -24,7 +24,6 @@ import com.sponus.sponusbe.domain.announcement.service.AnnouncementQueryService; import com.sponus.sponusbe.domain.announcement.service.AnnouncementService; import com.sponus.sponusbe.domain.organization.entity.Organization; -import com.sponus.sponusbe.domain.s3.S3Controller; import com.sponus.sponusbe.global.common.ApiResponse; import jakarta.validation.Valid; @@ -66,12 +65,19 @@ public ApiResponse> searchAnnouncement(@RequestParam( return ApiResponse.onSuccess(announcementQueryService.searchAnnouncement(keyword)); } - @PostMapping + @PostMapping(consumes = "multipart/form-data") public ApiResponse createAnnouncement( @AuthOrganization Organization authOrganization, - @RequestPart @Valid AnnouncementCreateRequest request + @RequestPart("request") @Valid AnnouncementCreateRequest request, + @RequestPart(value = "images") List images ) { - return ApiResponse.onSuccess(announcementService.createAnnouncement(authOrganization, request)); + return ApiResponse.onSuccess( + announcementService.createAnnouncement( + authOrganization, + request, + images + ) + ); } @DeleteMapping("/{announcementId}") diff --git a/src/main/java/com/sponus/sponusbe/domain/announcement/dto/response/AnnouncementImageResponse.java b/src/main/java/com/sponus/sponusbe/domain/announcement/dto/response/AnnouncementImageResponse.java index 3847a0e2..316a9ffe 100644 --- a/src/main/java/com/sponus/sponusbe/domain/announcement/dto/response/AnnouncementImageResponse.java +++ b/src/main/java/com/sponus/sponusbe/domain/announcement/dto/response/AnnouncementImageResponse.java @@ -1,8 +1,5 @@ package com.sponus.sponusbe.domain.announcement.dto.response; -import java.util.List; -import java.util.stream.Collectors; - import com.sponus.sponusbe.domain.announcement.entity.AnnouncementImage; import lombok.Builder; @@ -13,14 +10,11 @@ public record AnnouncementImageResponse( String name, String url ) { - - public static List announcementImage(List announcementImages) { - return announcementImages.stream() - .map(imageUrl -> AnnouncementImageResponse.builder() - .id(imageUrl.getId()) - .name(imageUrl.getName()) - .url(imageUrl.getUrl()) - .build()) - .collect(Collectors.toList()); + public static AnnouncementImageResponse from(AnnouncementImage image) { + return AnnouncementImageResponse.builder() + .id(image.getId()) + .name(image.getName()) + .url(image.getUrl()) + .build(); } } diff --git a/src/main/java/com/sponus/sponusbe/domain/announcement/dto/response/AnnouncementResponse.java b/src/main/java/com/sponus/sponusbe/domain/announcement/dto/response/AnnouncementResponse.java index cf7b42f0..2de68c9f 100644 --- a/src/main/java/com/sponus/sponusbe/domain/announcement/dto/response/AnnouncementResponse.java +++ b/src/main/java/com/sponus/sponusbe/domain/announcement/dto/response/AnnouncementResponse.java @@ -1,7 +1,5 @@ package com.sponus.sponusbe.domain.announcement.dto.response; -import static com.sponus.sponusbe.domain.announcement.dto.response.AnnouncementImageResponse.*; - import java.util.List; import com.sponus.sponusbe.domain.announcement.entity.Announcement; @@ -24,6 +22,11 @@ public record AnnouncementResponse( Long viewCount ) { public static AnnouncementResponse from(Announcement announcement) { + List announcementImages = announcement.getAnnouncementImages() + .stream() + .map(AnnouncementImageResponse::from) + .toList(); + return AnnouncementResponse.builder() .id(announcement.getId()) .writerId(announcement.getWriter().getId()) @@ -31,7 +34,7 @@ public static AnnouncementResponse from(Announcement announcement) { .type(announcement.getType()) .category(announcement.getCategory()) .content(announcement.getContent()) - .announcementImages(announcementImage(announcement.getAnnouncementImages())) + .announcementImages(announcementImages) .status(announcement.getStatus()) .viewCount(announcement.getViewCount()) .build(); diff --git a/src/main/java/com/sponus/sponusbe/domain/announcement/entity/AnnouncementImage.java b/src/main/java/com/sponus/sponusbe/domain/announcement/entity/AnnouncementImage.java index 651e1061..9f8b0453 100644 --- a/src/main/java/com/sponus/sponusbe/domain/announcement/entity/AnnouncementImage.java +++ b/src/main/java/com/sponus/sponusbe/domain/announcement/entity/AnnouncementImage.java @@ -16,6 +16,7 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; + @Builder @NoArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor(access = AccessLevel.PRIVATE) @@ -37,4 +38,12 @@ public class AnnouncementImage { @ManyToOne(fetch = FetchType.LAZY, optional = false) @JoinColumn(name = "announcement_id", foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)) private Announcement announcement; + + public void setAnnouncement(Announcement announcement) { + if (this.announcement != null) { + this.announcement.getAnnouncementImages().remove(this); + } + this.announcement = announcement; + announcement.getAnnouncementImages().add(this); + } } diff --git a/src/main/java/com/sponus/sponusbe/domain/announcement/service/AnnouncementService.java b/src/main/java/com/sponus/sponusbe/domain/announcement/service/AnnouncementService.java index 4bb937ff..508f706e 100644 --- a/src/main/java/com/sponus/sponusbe/domain/announcement/service/AnnouncementService.java +++ b/src/main/java/com/sponus/sponusbe/domain/announcement/service/AnnouncementService.java @@ -1,10 +1,10 @@ package com.sponus.sponusbe.domain.announcement.service; import java.util.List; -import java.util.stream.Collectors; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; import com.sponus.sponusbe.domain.announcement.dto.request.AnnouncementCreateRequest; import com.sponus.sponusbe.domain.announcement.dto.request.AnnouncementUpdateRequest; @@ -12,11 +12,13 @@ import com.sponus.sponusbe.domain.announcement.dto.response.AnnouncementResponse; import com.sponus.sponusbe.domain.announcement.dto.response.AnnouncementUpdateResponse; import com.sponus.sponusbe.domain.announcement.entity.Announcement; +import com.sponus.sponusbe.domain.announcement.entity.AnnouncementImage; import com.sponus.sponusbe.domain.announcement.entity.enums.AnnouncementStatus; import com.sponus.sponusbe.domain.announcement.exception.AnnouncementErrorCode; import com.sponus.sponusbe.domain.announcement.exception.AnnouncementException; import com.sponus.sponusbe.domain.announcement.repository.AnnouncementRepository; import com.sponus.sponusbe.domain.organization.entity.Organization; +import com.sponus.sponusbe.domain.s3.S3Service; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -28,12 +30,23 @@ public class AnnouncementService { private final AnnouncementRepository announcementRepository; + private final S3Service s3Service; public AnnouncementCreateResponse createAnnouncement( Organization authOrganization, - AnnouncementCreateRequest request) { - final Announcement announcement = announcementRepository.save(request.toEntity(authOrganization)); - return AnnouncementCreateResponse.from(announcement); + AnnouncementCreateRequest request, + List images + ) { + final Announcement announcement = request.toEntity(authOrganization); + images.forEach(image -> { + final String url = s3Service.uploadFile(image); + AnnouncementImage announcementImage = AnnouncementImage.builder() + .name(image.getOriginalFilename()) + .url(url) + .build(); + announcementImage.setAnnouncement(announcement); + }); + return AnnouncementCreateResponse.from(announcementRepository.save(announcement)); } public AnnouncementResponse getAnnouncement(Long announcementId) { @@ -47,7 +60,7 @@ public List getListAnnouncement(AnnouncementStatus status) List announcements = announcementRepository.findByStatus(status); return announcements.stream() .map(AnnouncementResponse::from) - .collect(Collectors.toList()); + .toList(); } public void deleteAnnouncement(Organization organization, Long announcementId) { diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql index 97b3a25c..c945ce9a 100644 --- a/src/main/resources/data.sql +++ b/src/main/resources/data.sql @@ -38,7 +38,7 @@ VALUES ('무신사 스폰서십', 'SPONSORSHIP', 'MARKETING', '무신사 스폰서십을 진행할 대학교 학생회를 모집합니다.', - 'IN_PROGRESS', + 'OPENED', 0, 1); INSERT INTO tag (organization_id, tag_name) From 7672fe68957b7db10230cd94e564ca6676047531 Mon Sep 17 00:00:00 2001 From: marooo326 Date: Mon, 5 Feb 2024 22:18:52 +0900 Subject: [PATCH 4/5] =?UTF-8?q?fix:=20=EA=B3=B5=EA=B3=A0=20=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=EC=A7=80=20=EC=9D=91=EB=8B=B5=20=ED=98=95=EC=8B=9D=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/AnnouncementController.java | 9 +++-- .../response/AnnouncementBriefResponse.java | 4 -- ...e.java => AnnouncementDetailResponse.java} | 6 +-- .../response/AnnouncementSummaryResponse.java | 38 +++++++++++++++++++ .../announcement/entity/Announcement.java | 3 +- .../service/AnnouncementQueryService.java | 12 ++---- .../service/AnnouncementService.java | 11 +++--- 7 files changed, 57 insertions(+), 26 deletions(-) delete mode 100644 src/main/java/com/sponus/sponusbe/domain/announcement/dto/response/AnnouncementBriefResponse.java rename src/main/java/com/sponus/sponusbe/domain/announcement/dto/response/{AnnouncementResponse.java => AnnouncementDetailResponse.java} (87%) create mode 100644 src/main/java/com/sponus/sponusbe/domain/announcement/dto/response/AnnouncementSummaryResponse.java diff --git a/src/main/java/com/sponus/sponusbe/domain/announcement/controller/AnnouncementController.java b/src/main/java/com/sponus/sponusbe/domain/announcement/controller/AnnouncementController.java index 6ad6199a..1be0efa8 100644 --- a/src/main/java/com/sponus/sponusbe/domain/announcement/controller/AnnouncementController.java +++ b/src/main/java/com/sponus/sponusbe/domain/announcement/controller/AnnouncementController.java @@ -18,7 +18,8 @@ import com.sponus.sponusbe.domain.announcement.dto.request.AnnouncementCreateRequest; import com.sponus.sponusbe.domain.announcement.dto.request.AnnouncementUpdateRequest; import com.sponus.sponusbe.domain.announcement.dto.response.AnnouncementCreateResponse; -import com.sponus.sponusbe.domain.announcement.dto.response.AnnouncementResponse; +import com.sponus.sponusbe.domain.announcement.dto.response.AnnouncementDetailResponse; +import com.sponus.sponusbe.domain.announcement.dto.response.AnnouncementSummaryResponse; import com.sponus.sponusbe.domain.announcement.dto.response.AnnouncementUpdateResponse; import com.sponus.sponusbe.domain.announcement.entity.enums.AnnouncementStatus; import com.sponus.sponusbe.domain.announcement.service.AnnouncementQueryService; @@ -50,18 +51,18 @@ public ApiResponse getAnnouncement() { } @GetMapping("/{announcementId}") - public ApiResponse getAnnouncement(@PathVariable Long announcementId) { + public ApiResponse getAnnouncement(@PathVariable Long announcementId) { return ApiResponse.onSuccess(announcementService.getAnnouncement(announcementId)); } @GetMapping("/status") - public ApiResponse> getListAnnouncement( + public ApiResponse> getListAnnouncement( @RequestParam("status") AnnouncementStatus status) { return ApiResponse.onSuccess(announcementService.getListAnnouncement(status)); } @GetMapping - public ApiResponse> searchAnnouncement(@RequestParam("search") String keyword) { + public ApiResponse> searchAnnouncement(@RequestParam("search") String keyword) { return ApiResponse.onSuccess(announcementQueryService.searchAnnouncement(keyword)); } diff --git a/src/main/java/com/sponus/sponusbe/domain/announcement/dto/response/AnnouncementBriefResponse.java b/src/main/java/com/sponus/sponusbe/domain/announcement/dto/response/AnnouncementBriefResponse.java deleted file mode 100644 index 11c10770..00000000 --- a/src/main/java/com/sponus/sponusbe/domain/announcement/dto/response/AnnouncementBriefResponse.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.sponus.sponusbe.domain.announcement.dto.response; - -public record AnnouncementBriefResponse() { -} diff --git a/src/main/java/com/sponus/sponusbe/domain/announcement/dto/response/AnnouncementResponse.java b/src/main/java/com/sponus/sponusbe/domain/announcement/dto/response/AnnouncementDetailResponse.java similarity index 87% rename from src/main/java/com/sponus/sponusbe/domain/announcement/dto/response/AnnouncementResponse.java rename to src/main/java/com/sponus/sponusbe/domain/announcement/dto/response/AnnouncementDetailResponse.java index 2de68c9f..6eb27aa7 100644 --- a/src/main/java/com/sponus/sponusbe/domain/announcement/dto/response/AnnouncementResponse.java +++ b/src/main/java/com/sponus/sponusbe/domain/announcement/dto/response/AnnouncementDetailResponse.java @@ -10,7 +10,7 @@ import lombok.Builder; @Builder -public record AnnouncementResponse( +public record AnnouncementDetailResponse( Long id, Long writerId, String title, @@ -21,13 +21,13 @@ public record AnnouncementResponse( AnnouncementStatus status, Long viewCount ) { - public static AnnouncementResponse from(Announcement announcement) { + public static AnnouncementDetailResponse from(Announcement announcement) { List announcementImages = announcement.getAnnouncementImages() .stream() .map(AnnouncementImageResponse::from) .toList(); - return AnnouncementResponse.builder() + return AnnouncementDetailResponse.builder() .id(announcement.getId()) .writerId(announcement.getWriter().getId()) .title(announcement.getTitle()) diff --git a/src/main/java/com/sponus/sponusbe/domain/announcement/dto/response/AnnouncementSummaryResponse.java b/src/main/java/com/sponus/sponusbe/domain/announcement/dto/response/AnnouncementSummaryResponse.java new file mode 100644 index 00000000..6d5bcf6b --- /dev/null +++ b/src/main/java/com/sponus/sponusbe/domain/announcement/dto/response/AnnouncementSummaryResponse.java @@ -0,0 +1,38 @@ +package com.sponus.sponusbe.domain.announcement.dto.response; + +import com.sponus.sponusbe.domain.announcement.entity.Announcement; +import com.sponus.sponusbe.domain.announcement.entity.AnnouncementImage; +import com.sponus.sponusbe.domain.announcement.entity.enums.AnnouncementCategory; +import com.sponus.sponusbe.domain.announcement.entity.enums.AnnouncementStatus; +import com.sponus.sponusbe.domain.announcement.entity.enums.AnnouncementType; + +import lombok.Builder; + +@Builder +public record AnnouncementSummaryResponse( + Long id, + Long writerId, + String title, + AnnouncementType type, + AnnouncementCategory category, + AnnouncementImageResponse mainImage, + AnnouncementStatus status, + Long viewCount +) { + public static AnnouncementSummaryResponse from(Announcement announcement) { + AnnouncementImage mainImage = announcement.getAnnouncementImages() + .stream() + .findFirst().orElseThrow(); + + return AnnouncementSummaryResponse.builder() + .id(announcement.getId()) + .writerId(announcement.getWriter().getId()) + .title(announcement.getTitle()) + .type(announcement.getType()) + .category(announcement.getCategory()) + .mainImage(AnnouncementImageResponse.from(mainImage)) + .status(announcement.getStatus()) + .viewCount(announcement.getViewCount()) + .build(); + } +} diff --git a/src/main/java/com/sponus/sponusbe/domain/announcement/entity/Announcement.java b/src/main/java/com/sponus/sponusbe/domain/announcement/entity/Announcement.java index 102f9bca..25af5375 100644 --- a/src/main/java/com/sponus/sponusbe/domain/announcement/entity/Announcement.java +++ b/src/main/java/com/sponus/sponusbe/domain/announcement/entity/Announcement.java @@ -9,6 +9,7 @@ import com.sponus.sponusbe.domain.organization.entity.Organization; import com.sponus.sponusbe.global.common.BaseEntity; +import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.ConstraintMode; import jakarta.persistence.Entity; @@ -68,7 +69,7 @@ public class Announcement extends BaseEntity { private Organization writer; @Builder.Default - @OneToMany(mappedBy = "announcement") + @OneToMany(mappedBy = "announcement", cascade = CascadeType.ALL, orphanRemoval = true) private List announcementImages = new ArrayList<>(); public void increaseViewCount() { diff --git a/src/main/java/com/sponus/sponusbe/domain/announcement/service/AnnouncementQueryService.java b/src/main/java/com/sponus/sponusbe/domain/announcement/service/AnnouncementQueryService.java index a6502437..8b10cd90 100644 --- a/src/main/java/com/sponus/sponusbe/domain/announcement/service/AnnouncementQueryService.java +++ b/src/main/java/com/sponus/sponusbe/domain/announcement/service/AnnouncementQueryService.java @@ -5,9 +5,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import com.sponus.sponusbe.domain.announcement.dto.request.AnnouncementCreateRequest; -import com.sponus.sponusbe.domain.announcement.dto.response.AnnouncementBriefResponse; -import com.sponus.sponusbe.domain.announcement.dto.response.AnnouncementResponse; +import com.sponus.sponusbe.domain.announcement.dto.response.AnnouncementSummaryResponse; import com.sponus.sponusbe.domain.announcement.repository.AnnouncementRepository; import lombok.RequiredArgsConstructor; @@ -21,13 +19,9 @@ public class AnnouncementQueryService { private final AnnouncementRepository announcementRepository; - public List searchAnnouncement(String keyword) { + public List searchAnnouncement(String keyword) { log.info("search announcement by keyword: {}", keyword); return announcementRepository.findByTitleContains(keyword).stream() - .map(AnnouncementResponse::from).toList(); - } - - public AnnouncementBriefResponse createAnnouncement(AnnouncementCreateRequest request) { - return null; + .map(AnnouncementSummaryResponse::from).toList(); } } diff --git a/src/main/java/com/sponus/sponusbe/domain/announcement/service/AnnouncementService.java b/src/main/java/com/sponus/sponusbe/domain/announcement/service/AnnouncementService.java index 508f706e..3c66f68f 100644 --- a/src/main/java/com/sponus/sponusbe/domain/announcement/service/AnnouncementService.java +++ b/src/main/java/com/sponus/sponusbe/domain/announcement/service/AnnouncementService.java @@ -9,7 +9,8 @@ import com.sponus.sponusbe.domain.announcement.dto.request.AnnouncementCreateRequest; import com.sponus.sponusbe.domain.announcement.dto.request.AnnouncementUpdateRequest; import com.sponus.sponusbe.domain.announcement.dto.response.AnnouncementCreateResponse; -import com.sponus.sponusbe.domain.announcement.dto.response.AnnouncementResponse; +import com.sponus.sponusbe.domain.announcement.dto.response.AnnouncementDetailResponse; +import com.sponus.sponusbe.domain.announcement.dto.response.AnnouncementSummaryResponse; import com.sponus.sponusbe.domain.announcement.dto.response.AnnouncementUpdateResponse; import com.sponus.sponusbe.domain.announcement.entity.Announcement; import com.sponus.sponusbe.domain.announcement.entity.AnnouncementImage; @@ -49,17 +50,17 @@ public AnnouncementCreateResponse createAnnouncement( return AnnouncementCreateResponse.from(announcementRepository.save(announcement)); } - public AnnouncementResponse getAnnouncement(Long announcementId) { + public AnnouncementDetailResponse getAnnouncement(Long announcementId) { Announcement announcement = announcementRepository.findById(announcementId) .orElseThrow(() -> new AnnouncementException(AnnouncementErrorCode.ANNOUNCEMENT_NOT_FOUND)); announcement.increaseViewCount(); - return AnnouncementResponse.from(announcement); + return AnnouncementDetailResponse.from(announcement); } - public List getListAnnouncement(AnnouncementStatus status) { + public List getListAnnouncement(AnnouncementStatus status) { List announcements = announcementRepository.findByStatus(status); return announcements.stream() - .map(AnnouncementResponse::from) + .map(AnnouncementSummaryResponse::from) .toList(); } From fa487751e05e41fe861a041af87f8c94b88ce97f Mon Sep 17 00:00:00 2001 From: marooo326 Date: Mon, 5 Feb 2024 22:33:30 +0900 Subject: [PATCH 5/5] =?UTF-8?q?fix:=20=EA=B3=B5=EA=B3=A0=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EC=8B=9C=20=EC=9D=B4=EB=AF=B8=EC=A7=80=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 --- .../controller/AnnouncementController.java | 14 +++++--- .../announcement/entity/Announcement.java | 9 ++++- .../service/AnnouncementService.java | 33 ++++++++++++------- 3 files changed, 39 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/sponus/sponusbe/domain/announcement/controller/AnnouncementController.java b/src/main/java/com/sponus/sponusbe/domain/announcement/controller/AnnouncementController.java index 1be0efa8..006db534 100644 --- a/src/main/java/com/sponus/sponusbe/domain/announcement/controller/AnnouncementController.java +++ b/src/main/java/com/sponus/sponusbe/domain/announcement/controller/AnnouncementController.java @@ -7,7 +7,6 @@ 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.RequestPart; @@ -89,14 +88,19 @@ public ApiResponse deleteAnnouncement( return ApiResponse.onSuccess(null); } - @PatchMapping("/{announcementId}") + @PatchMapping(value = "/{announcementId}", consumes = "multipart/form-data") public ApiResponse updateAnnouncement( @AuthOrganization Organization authOrganization, @PathVariable Long announcementId, - @RequestBody @Valid AnnouncementUpdateRequest request + @RequestPart("request") @Valid AnnouncementUpdateRequest request, + @RequestPart(value = "images", required = false) List images ) { - announcementService.updateAnnouncement(authOrganization, announcementId, request); - return ApiResponse.onSuccess(announcementService.updateAnnouncement(authOrganization, announcementId, request)); + return ApiResponse.onSuccess(announcementService.updateAnnouncement( + authOrganization, + announcementId, + request, + images + )); } } diff --git a/src/main/java/com/sponus/sponusbe/domain/announcement/entity/Announcement.java b/src/main/java/com/sponus/sponusbe/domain/announcement/entity/Announcement.java index 25af5375..c3c907fa 100644 --- a/src/main/java/com/sponus/sponusbe/domain/announcement/entity/Announcement.java +++ b/src/main/java/com/sponus/sponusbe/domain/announcement/entity/Announcement.java @@ -76,7 +76,7 @@ public void increaseViewCount() { this.viewCount++; } - public void update(String title, AnnouncementType type, AnnouncementCategory category, String content, + public void updateInfo(String title, AnnouncementType type, AnnouncementCategory category, String content, AnnouncementStatus status) { this.title = title == null ? this.title : title; this.type = type == null ? this.type : type; @@ -85,6 +85,13 @@ public void update(String title, AnnouncementType type, AnnouncementCategory cat this.status = (status != null) ? status : this.status; } + public void updateImages(List images) { + if (images != null) { + this.announcementImages.clear(); + this.announcementImages.addAll(images); + } + } + public boolean isAvailable() { return this.status == AnnouncementStatus.OPENED; } diff --git a/src/main/java/com/sponus/sponusbe/domain/announcement/service/AnnouncementService.java b/src/main/java/com/sponus/sponusbe/domain/announcement/service/AnnouncementService.java index 3c66f68f..f06e6ca1 100644 --- a/src/main/java/com/sponus/sponusbe/domain/announcement/service/AnnouncementService.java +++ b/src/main/java/com/sponus/sponusbe/domain/announcement/service/AnnouncementService.java @@ -39,14 +39,7 @@ public AnnouncementCreateResponse createAnnouncement( List images ) { final Announcement announcement = request.toEntity(authOrganization); - images.forEach(image -> { - final String url = s3Service.uploadFile(image); - AnnouncementImage announcementImage = AnnouncementImage.builder() - .name(image.getOriginalFilename()) - .url(url) - .build(); - announcementImage.setAnnouncement(announcement); - }); + setAnnouncementImages(images, announcement); return AnnouncementCreateResponse.from(announcementRepository.save(announcement)); } @@ -73,8 +66,12 @@ public void deleteAnnouncement(Organization organization, Long announcementId) { announcementRepository.delete(announcement); } - public AnnouncementUpdateResponse updateAnnouncement(Organization authOrganization, Long proposeId, - AnnouncementUpdateRequest request) { + public AnnouncementUpdateResponse updateAnnouncement( + Organization authOrganization, + Long proposeId, + AnnouncementUpdateRequest request, + List images + ) { final Announcement announcement = announcementRepository.findById(proposeId) .orElseThrow(() -> new AnnouncementException(AnnouncementErrorCode.ANNOUNCEMENT_NOT_FOUND)); @@ -83,7 +80,9 @@ public AnnouncementUpdateResponse updateAnnouncement(Organization authOrganizati if (!isOrganizationsAnnouncement(authOrganization.getId(), announcement)) throw new AnnouncementException(AnnouncementErrorCode.INVALID_ORGANIZATION); - announcement.update(request.title(), request.type(), request.category(), request.content(), request.status()); + announcement.updateInfo(request.title(), request.type(), request.category(), request.content(), + request.status()); + setAnnouncementImages(images, announcement); announcementRepository.save(announcement); return AnnouncementUpdateResponse.from(announcement); } @@ -92,4 +91,16 @@ private boolean isOrganizationsAnnouncement(Long organizationId, Announcement an return announcement.getWriter().getId().equals(organizationId); } + private void setAnnouncementImages(List images, Announcement announcement) { + announcement.getAnnouncementImages().clear(); + images.forEach(image -> { + final String url = s3Service.uploadFile(image); + AnnouncementImage announcementImage = AnnouncementImage.builder() + .name(image.getOriginalFilename()) + .url(url) + .build(); + announcementImage.setAnnouncement(announcement); + }); + } + }