Skip to content

Commit

Permalink
feat: 사용자용, 관리자용 공지 전체 조회 및 공지 상세 조회 API 구현 (#312)
Browse files Browse the repository at this point in the history
  • Loading branch information
kdkdhoho committed Oct 30, 2024
1 parent d59695a commit 3de2eed
Show file tree
Hide file tree
Showing 9 changed files with 291 additions and 24 deletions.
14 changes: 14 additions & 0 deletions src/main/java/com/listywave/notice/application/domain/Notice.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
import jakarta.persistence.Entity;
import jakarta.persistence.OneToMany;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import lombok.Getter;
import lombok.NoArgsConstructor;

Expand All @@ -28,6 +30,10 @@ public class Notice extends BaseEntity {
@Embedded
private NoticeDescription description;

private boolean isExposed;

private boolean didSendAlarm;

@OneToMany(mappedBy = "notice", fetch = LAZY, cascade = ALL, orphanRemoval = true)
private final List<NoticeContent> contents = new ArrayList<>();

Expand All @@ -40,4 +46,12 @@ public Notice(NoticeType type, NoticeTitle title, NoticeDescription description)
public void addContents(List<NoticeContent> contents) {
this.contents.addAll(contents);
}

public String getFirstImageUrl() {
Optional<String> result = contents.stream()
.sorted(Comparator.comparingInt(NoticeContent::getOrder))
.map(NoticeContent::getImageUrl)
.findFirst();
return result.orElse(null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public class NoticeContent {

@Column(nullable = true, length = 1000)
private String description;

@Column(nullable = true, length = 2048)
private String imageUrl;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import com.listywave.notice.application.domain.Notice;
import com.listywave.notice.application.domain.NoticeContent;
import com.listywave.notice.application.service.dto.NoticeCreateRequest;
import com.listywave.notice.application.service.dto.NoticeFindAllResponseToAdmin;
import com.listywave.notice.application.service.dto.NoticeFindAllResponseToUser;
import com.listywave.notice.application.service.dto.NoticeFindResponse;
import com.listywave.notice.repository.NoticeRepository;
import java.util.List;
import lombok.RequiredArgsConstructor;
Expand All @@ -22,4 +25,24 @@ public Long create(NoticeCreateRequest request) {
notice.addContents(noticeContents);
return noticeRepository.save(notice).getId();
}

@Transactional(readOnly = true)
public List<NoticeFindAllResponseToAdmin> findAllToAdmin() {
List<Notice> notices = noticeRepository.findAll();
return NoticeFindAllResponseToAdmin.toList(notices);
}

@Transactional(readOnly = true)
public List<NoticeFindAllResponseToUser> findAllToUser() {
List<Notice> notices = noticeRepository.findAll();
return NoticeFindAllResponseToUser.toList(notices);
}

@Transactional(readOnly = true)
public NoticeFindResponse findOneSpecific(Long id) {
Notice result = noticeRepository.findOne(id);
Notice prevNotice = noticeRepository.findOne(id - 1);
Notice nextNotice = noticeRepository.findOne(id + 1);
return NoticeFindResponse.of(result, prevNotice, nextNotice);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.listywave.notice.application.service.dto;

import com.listywave.notice.application.domain.Notice;
import java.time.LocalDateTime;
import java.util.List;
import lombok.Builder;

@Builder
public record NoticeFindAllResponseToAdmin(
Long id,
LocalDateTime createdDate,
String title,
String category,
String description,
boolean isExposed,
boolean didSendAlarm
) {

public static List<NoticeFindAllResponseToAdmin> toList(List<Notice> notices) {
return notices.stream()
.map(NoticeFindAllResponseToAdmin::of)
.toList();
}

public static NoticeFindAllResponseToAdmin of(Notice notice) {
return NoticeFindAllResponseToAdmin.builder()
.id(notice.getId())
.createdDate(notice.getCreatedDate())
.title(notice.getTitle().getValue())
.category(notice.getType().getViewName())
.description(notice.getDescription().getValue())
.isExposed(notice.isDidSendAlarm())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.listywave.notice.application.service.dto;

import com.listywave.notice.application.domain.Notice;
import jakarta.annotation.Nullable;
import java.time.LocalDateTime;
import java.util.List;
import lombok.Builder;

@Builder
public record NoticeFindAllResponseToUser(
Long id,
LocalDateTime createdDate,
String title,
@Nullable String itemImageUrl,
String category,
String description
) {

public static List<NoticeFindAllResponseToUser> toList(List<Notice> notices) {
return notices.stream()
.map(NoticeFindAllResponseToUser::of)
.toList();
}

public static NoticeFindAllResponseToUser of(Notice notice) {
return NoticeFindAllResponseToUser.builder()
.id(notice.getId())
.createdDate(notice.getCreatedDate())
.title(notice.getTitle().getValue())
.itemImageUrl(notice.getFirstImageUrl())
.category(notice.getType().getViewName())
.description(notice.getDescription().getValue())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package com.listywave.notice.application.service.dto;

import com.listywave.notice.application.domain.Notice;
import com.listywave.notice.application.domain.NoticeContent;
import jakarta.annotation.Nullable;
import java.time.LocalDateTime;
import java.util.List;
import lombok.Builder;

@Builder
public record NoticeFindResponse(
Long id,
String category,
String title,
String description,
List<ContentDto> contents,
LocalDateTime createdDate,
BesideNoticeDto prevNotice,
BesideNoticeDto nextNotice
) {

public static NoticeFindResponse of(Notice notice, Notice prevNotice, Notice nextNotice) {
return NoticeFindResponse.builder()
.id(notice.getId())
.category(notice.getType().getViewName())
.title(notice.getTitle().getValue())
.description(notice.getDescription().getValue())
.contents(ContentDto.toList(notice.getContents()))
.createdDate(notice.getCreatedDate())
.prevNotice(BesideNoticeDto.of(prevNotice))
.nextNotice(BesideNoticeDto.of(nextNotice))
.build();
}

@Builder
public record ContentDto(
String type,
String description,
@Nullable String imageUrl,
@Nullable String buttonName,
@Nullable String buttonLink
) {

public static List<ContentDto> toList(List<NoticeContent> contents) {
return contents.stream()
.map(ContentDto::of)
.toList();
}

public static ContentDto of(NoticeContent content) {
return ContentDto.builder()
.type(content.getType().name().toLowerCase())
.description(content.getDescription())
.imageUrl(content.getImageUrl())
.buttonName(content.getButtonName())
.buttonLink(content.getButtonLink())
.build();
}
}

public record BesideNoticeDto(
Long id,
String title,
String description
) {

public static BesideNoticeDto of(Notice notice) {
if (notice == null) {
return null;
}
return new BesideNoticeDto(notice.getId(), notice.getTitle().getValue(), notice.getDescription().getValue());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@
import com.listywave.notice.application.domain.NoticeType;
import com.listywave.notice.application.service.NoticeService;
import com.listywave.notice.application.service.dto.NoticeCreateRequest;
import com.listywave.notice.application.service.dto.NoticeFindAllResponseToAdmin;
import com.listywave.notice.application.service.dto.NoticeFindAllResponseToUser;
import com.listywave.notice.application.service.dto.NoticeFindResponse;
import com.listywave.notice.presentation.dto.NoticeCategoryFindResponse;
import java.net.URI;
import java.util.List;
import lombok.RequiredArgsConstructor;
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.RestController;
Expand All @@ -36,4 +40,22 @@ ResponseEntity<Void> create(
Long id = noticeService.create(request);
return ResponseEntity.created(URI.create("/admin/notices/" + id)).build();
}

@GetMapping("/admin/notices")
ResponseEntity<List<NoticeFindAllResponseToAdmin>> findAllToAdmin() {
List<NoticeFindAllResponseToAdmin> result = noticeService.findAllToAdmin();
return ResponseEntity.ok(result);
}

@GetMapping("/notices")
ResponseEntity<List<NoticeFindAllResponseToUser>> findAllToUser() {
List<NoticeFindAllResponseToUser> result = noticeService.findAllToUser();
return ResponseEntity.ok(result);
}

@GetMapping("/notices/{noticeId}")
ResponseEntity<NoticeFindResponse> findOneSpecific(@PathVariable Long noticeId) {
NoticeFindResponse result = noticeService.findOneSpecific(noticeId);
return ResponseEntity.ok(result);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,19 @@
import com.listywave.common.exception.CustomException;
import com.listywave.notice.application.domain.Notice;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

public interface NoticeRepository extends JpaRepository<Notice, Long> {

default Notice getById(Long id) {
return findById(id).orElseThrow(() -> new CustomException(RESOURCE_NOT_FOUND, "존재하지 않는 공지입니다."));
}

@Query("""
select n
from Notice n
join NoticeContent nc on nc.notice = n
where n.id = :noticeId
""")
Notice findOne(Long noticeId);
}
Loading

0 comments on commit 3de2eed

Please sign in to comment.