-
Notifications
You must be signed in to change notification settings - Fork 0
[Feat/#216] 공지 수정 시 이미지 최대 20장 첨부 기능 추가 #217
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
95dcfc2
f9a7273
7df53ac
846c924
0a516cf
dd02a38
0ee8133
8f4fa67
a4612a5
dea8594
7ffe54a
fce2355
0ee4535
91dcc02
e021ec4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,8 +16,11 @@ | |
| import org.springframework.http.ResponseEntity; | ||
| import org.springframework.validation.annotation.Validated; | ||
| import org.springframework.web.bind.annotation.*; | ||
| import org.springframework.web.multipart.MultipartFile; | ||
| import org.springframework.security.access.prepost.PreAuthorize; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| @RestController | ||
| @RequestMapping("/api/v1/festivals") | ||
| @Tag(name = "Notice") | ||
|
|
@@ -33,9 +36,10 @@ public class NoticeCreateController { | |
| @PostMapping(path = "/{festivalId}/notices", | ||
| consumes = MediaType.MULTIPART_FORM_DATA_VALUE) | ||
| public ResponseEntity<BaseResponse<NoticeCreateResponse>> createNotice( | ||
| @PathVariable("festivalId") @Positive Long festivalId, | ||
| @ModelAttribute @Valid NoticeCreateRequest request) { | ||
| NoticeCreateResponse response = noticeService.createNotice(festivalId, request); | ||
| @PathVariable @Positive Long festivalId, | ||
| @RequestPart("noticeCreateRequest") @Valid NoticeCreateRequest noticeCreateRequest, | ||
| @RequestPart(value = "images", required = false) List<MultipartFile> images) { | ||
|
Comment on lines
+40
to
+41
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 여기에는 requestPart적용해서 처리했군요 앞서 삭제기능도 이렇게 처리해도 좋을거같습니다 |
||
| NoticeCreateResponse response = noticeService.createNotice(festivalId, noticeCreateRequest, images); | ||
| return ResponseEntity | ||
| .status(SuccessStatus.NOTICE_CREATE_SUCCESS.getHttpStatus()) | ||
| .body(BaseResponse.create(SuccessStatus.NOTICE_CREATE_SUCCESS.getMsg(), response)); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,16 +3,16 @@ | |
| import jakarta.validation.constraints.NotBlank; | ||
| import jakarta.validation.constraints.NotNull; | ||
| import jakarta.validation.constraints.Size; | ||
| import org.springframework.web.multipart.MultipartFile; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| public record NoticeUpdateRequest( | ||
| @NotNull(message = "페스티벌 아이디는 필수값입니다.") Long festivalId, | ||
| @NotBlank(message = "공지 제목은 필수값입니다.") | ||
| @Size(max = 50, message = "공지 제목은 최대 50자까지 입력할 수 있습니다.") String title, | ||
| @NotNull(message = "공지 카테고리 값은 필수값입니다.") Long categoryId, | ||
| MultipartFile newImage, | ||
| List<String> keepImageUrls, | ||
chaeyuuu marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "== syncImages 구현 =="
sed -n '294,342p' src/main/java/com/amp/domain/notice/service/organizer/NoticeService.java
echo
echo "== invalid keepImageUrls 검증/테스트 검색 =="
rg -n -C2 'keepImageUrls|keepUrls|containsKey|NOTICE_.*IMAGE' \
src/main/java/com/amp/domain/notice/service/organizer/NoticeService.java \
src/test/javaRepository: TEAM-DECIBEL/AMP-SERVER Length of output: 11996 🏁 Script executed: # Verify if there are any validation checks elsewhere or in DTOs
rg -n 'keepImageUrls|keepUrls' src/main/java/com/amp/domain/notice --type java -B2 -A2 | head -60Repository: TEAM-DECIBEL/AMP-SERVER Length of output: 3754
구체적 문제:
권장: 유효하지 않은 🤖 Prompt for AI Agents |
||
| @NotBlank(message = "공지 내용은 필수값입니다.") String content, | ||
| boolean isPinned, | ||
| String previousImageUrl //기존 첨부이미지에서 이미지 수정 없이 업로드시 기존 이미지url 첨부 | ||
| @NotNull(message = "고정 여부 값은 필수 값입니다.") Boolean isPinned | ||
| ) { | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,14 +1,15 @@ | ||
| package com.amp.domain.notice.dto.response; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| public record FestivalNoticeListResponse( | ||
| Long noticeId, | ||
| String categoryName, | ||
| String title, | ||
| String content, | ||
| String imageUrl, | ||
| List<String> imageUrls, | ||
chaeyuuu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| boolean isPinned, | ||
| boolean isSaved, | ||
| String createdAt | ||
| ) { | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| package com.amp.domain.notice.entity; | ||
|
|
||
| import jakarta.persistence.*; | ||
| import lombok.AccessLevel; | ||
| import lombok.Getter; | ||
| import lombok.NoArgsConstructor; | ||
|
|
||
| import static jakarta.persistence.GenerationType.IDENTITY; | ||
|
|
||
| @Entity | ||
| @Table(name = "notice_images") | ||
| @Getter | ||
| @NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
| public class NoticeImage { | ||
| @Id | ||
| @GeneratedValue(strategy = IDENTITY) | ||
| private Long id; | ||
|
|
||
| @ManyToOne(fetch = FetchType.LAZY) | ||
| @JoinColumn(name = "notice_id") | ||
| private Notice notice; | ||
chaeyuuu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| @Column(nullable = false, length = 500) | ||
| private String imageUrl; | ||
|
|
||
| @Column(nullable = false) | ||
| private int imageOrder; | ||
|
|
||
| private NoticeImage(Notice notice, String imageUrl, int imageOrder) { | ||
| this.notice = notice; | ||
| this.imageUrl = imageUrl; | ||
| this.imageOrder = imageOrder; | ||
| } | ||
|
|
||
| public static NoticeImage of(Notice notice, String imageUrl, int imageOrder) { | ||
| return new NoticeImage(notice, imageUrl, imageOrder); | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| public void updateOrder(int imageOrder) { | ||
| this.imageOrder = imageOrder; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| package com.amp.domain.notice.repository; | ||
|
|
||
| import com.amp.domain.notice.entity.NoticeImage; | ||
| import org.springframework.data.jpa.repository.JpaRepository; | ||
|
|
||
| public interface NoticeImageRepository extends JpaRepository<NoticeImage, Long> { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,6 +6,7 @@ | |
| import com.amp.domain.notice.dto.response.FestivalNoticeListResponse; | ||
| import com.amp.domain.notice.dto.response.NoticeListResponse; | ||
| import com.amp.domain.notice.entity.Notice; | ||
| import com.amp.domain.notice.entity.NoticeImage; | ||
| import com.amp.domain.notice.exception.NoticeException; | ||
| import com.amp.domain.notice.repository.BookmarkRepository; | ||
| import com.amp.domain.notice.repository.NoticeRepository; | ||
|
|
@@ -22,10 +23,7 @@ | |
| import org.springframework.stereotype.Service; | ||
| import org.springframework.transaction.annotation.Transactional; | ||
|
|
||
| import java.util.Collections; | ||
| import java.util.HashSet; | ||
| import java.util.List; | ||
| import java.util.Set; | ||
| import java.util.*; | ||
| import java.util.stream.Collectors; | ||
|
|
||
| import static com.amp.global.common.dto.TimeFormatter.formatTimeAgo; | ||
|
|
@@ -57,12 +55,17 @@ public NoticeListResponse getFestivalNoticeList(Long festivalId, Long categoryId | |
|
|
||
| List<FestivalNoticeListResponse> announcements = noticePage.getContent().stream().map(notice -> { | ||
| boolean isSaved = savedNoticeIds.contains(notice.getId()); | ||
| List<String> imageUrls = notice.getImages().stream() | ||
| .sorted(Comparator.comparingInt(NoticeImage::getImageOrder)) | ||
| .map(NoticeImage::getImageUrl) | ||
| .toList(); | ||
|
Comment on lines
+58
to
+61
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial 이미지 URL 정렬 로직을 한 곳으로 모아두는 편이 안전합니다. 같은 🤖 Prompt for AI Agents |
||
|
|
||
| return new FestivalNoticeListResponse( | ||
| notice.getId(), | ||
| notice.getFestivalCategory().getCategory().getCategoryName(), | ||
| notice.getTitle(), | ||
| notice.getContent(), | ||
| notice.getImageUrl(), | ||
| imageUrls, | ||
| notice.getIsPinned(), | ||
| isSaved, | ||
| formatTimeAgo(notice.getCreatedAt()) | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.