From 587b8a20c1c372a696f14723c4f05b1a229c47f7 Mon Sep 17 00:00:00 2001 From: "y.tnwjd" Date: Mon, 1 Sep 2025 15:32:24 +0900 Subject: [PATCH 1/2] feat: add Link Upload --- .../controller/admin/LinkAdminController.java | 40 +++++++++++++ .../controller/user/LinkController.java | 39 +++++++++++++ .../ajouchong/dto/request/LinkRequestDto.java | 15 +++++ .../dto/response/LinkResponseDto.java | 15 +++++ src/main/java/com/ajouchong/entity/Link.java | 37 ++++++++++++ .../ajouchong/repository/LinkRepository.java | 13 +++++ .../com/ajouchong/service/LinkService.java | 58 +++++++++++++++++++ 7 files changed, 217 insertions(+) create mode 100644 src/main/java/com/ajouchong/controller/admin/LinkAdminController.java create mode 100644 src/main/java/com/ajouchong/controller/user/LinkController.java create mode 100644 src/main/java/com/ajouchong/dto/request/LinkRequestDto.java create mode 100644 src/main/java/com/ajouchong/dto/response/LinkResponseDto.java create mode 100644 src/main/java/com/ajouchong/entity/Link.java create mode 100644 src/main/java/com/ajouchong/repository/LinkRepository.java create mode 100644 src/main/java/com/ajouchong/service/LinkService.java diff --git a/src/main/java/com/ajouchong/controller/admin/LinkAdminController.java b/src/main/java/com/ajouchong/controller/admin/LinkAdminController.java new file mode 100644 index 0000000..371a233 --- /dev/null +++ b/src/main/java/com/ajouchong/controller/admin/LinkAdminController.java @@ -0,0 +1,40 @@ +package com.ajouchong.controller.admin; + +import com.ajouchong.common.ApiResponse; +import com.ajouchong.dto.request.LinkRequestDto; +import com.ajouchong.dto.response.LinkResponseDto; +import com.ajouchong.service.LinkService; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import jakarta.validation.Valid; +import java.util.List; + +@RestController +@RequestMapping("/api/admin/link") +@RequiredArgsConstructor +public class LinkAdminController { + + private final LinkService linkService; + + @PostMapping("/upload") + public ApiResponse uploadLink(@Valid @RequestBody LinkRequestDto requestDto) { + LinkResponseDto response = linkService.uploadLink(requestDto); + + return new ApiResponse<>(1, "링크가 성공적으로 업로드되었습니다.", response); + } + + @GetMapping + public ApiResponse> getAllLinks() { + List links = linkService.getAllLinks(); + + return new ApiResponse<>(1, "링크 목록을 조회했습니다.", links); + } + + @DeleteMapping("/{id}/delete") + public ApiResponse deleteLink(@PathVariable Long id) { + linkService.deleteLink(id); + + return new ApiResponse<>(1, "링크가 삭제되었습니다.", null); + } +} diff --git a/src/main/java/com/ajouchong/controller/user/LinkController.java b/src/main/java/com/ajouchong/controller/user/LinkController.java new file mode 100644 index 0000000..6e9a01b --- /dev/null +++ b/src/main/java/com/ajouchong/controller/user/LinkController.java @@ -0,0 +1,39 @@ +package com.ajouchong.controller.user; + +import com.ajouchong.common.ApiResponse; +import com.ajouchong.dto.request.LinkRequestDto; +import com.ajouchong.dto.response.LinkResponseDto; +import com.ajouchong.service.LinkService; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import jakarta.validation.Valid; +import java.util.List; + +@RestController +@RequestMapping("/api/link") +@RequiredArgsConstructor +public class LinkController { + private final LinkService linkService; + + @PostMapping("/upload") + public ApiResponse uploadLink(@Valid @RequestBody LinkRequestDto requestDto) { + LinkResponseDto response = linkService.uploadLink(requestDto); + + return new ApiResponse<>(1, "링크가 성공적으로 업로드되었습니다.", response); + } + + @GetMapping + public ApiResponse> getAllLinks() { + List links = linkService.getAllLinks(); + + return new ApiResponse<>(1, "링크 목록을 조회했습니다.", links); + } + + @DeleteMapping("/{id}/delete") + public ApiResponse deleteLink(@PathVariable Long id) { + linkService.deleteLink(id); + + return new ApiResponse<>(1, "링크가 삭제되었습니다.", null); + } +} diff --git a/src/main/java/com/ajouchong/dto/request/LinkRequestDto.java b/src/main/java/com/ajouchong/dto/request/LinkRequestDto.java new file mode 100644 index 0000000..02a8f0b --- /dev/null +++ b/src/main/java/com/ajouchong/dto/request/LinkRequestDto.java @@ -0,0 +1,15 @@ +package com.ajouchong.dto.request; + +import lombok.Data; + +import jakarta.validation.constraints.NotBlank; + +@Data +public class LinkRequestDto { + + @NotBlank(message = "제목은 필수입니다.") + private String title; + + @NotBlank(message = "링크는 필수입니다.") + private String link; +} diff --git a/src/main/java/com/ajouchong/dto/response/LinkResponseDto.java b/src/main/java/com/ajouchong/dto/response/LinkResponseDto.java new file mode 100644 index 0000000..64ab210 --- /dev/null +++ b/src/main/java/com/ajouchong/dto/response/LinkResponseDto.java @@ -0,0 +1,15 @@ +package com.ajouchong.dto.response; + +import lombok.Data; +import lombok.Builder; + +import java.time.LocalDateTime; + +@Data +@Builder +public class LinkResponseDto { + private Long id; + private String title; + private String link; + private LocalDateTime createdAt; +} diff --git a/src/main/java/com/ajouchong/entity/Link.java b/src/main/java/com/ajouchong/entity/Link.java new file mode 100644 index 0000000..128f720 --- /dev/null +++ b/src/main/java/com/ajouchong/entity/Link.java @@ -0,0 +1,37 @@ +package com.ajouchong.entity; + +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import jakarta.persistence.PrePersist; +import java.time.LocalDateTime; + +@Entity +@Table(name = "links") +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class Link { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false) + private String title; + + @Column(nullable = false) + private String link; + + @Column(name = "created_at", nullable = false, updatable = false) + private LocalDateTime createdAt; + + @PrePersist + protected void onCreate() { + createdAt = LocalDateTime.now(); + } +} diff --git a/src/main/java/com/ajouchong/repository/LinkRepository.java b/src/main/java/com/ajouchong/repository/LinkRepository.java new file mode 100644 index 0000000..708f66f --- /dev/null +++ b/src/main/java/com/ajouchong/repository/LinkRepository.java @@ -0,0 +1,13 @@ +package com.ajouchong.repository; + +import com.ajouchong.entity.Link; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface LinkRepository extends JpaRepository { + + List findAllByOrderByCreatedAtDesc(); +} diff --git a/src/main/java/com/ajouchong/service/LinkService.java b/src/main/java/com/ajouchong/service/LinkService.java new file mode 100644 index 0000000..082b631 --- /dev/null +++ b/src/main/java/com/ajouchong/service/LinkService.java @@ -0,0 +1,58 @@ +package com.ajouchong.service; + +import com.ajouchong.dto.request.LinkRequestDto; +import com.ajouchong.dto.response.LinkResponseDto; +import com.ajouchong.entity.Link; +import com.ajouchong.repository.LinkRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class LinkService { + + private final LinkRepository linkRepository; + + @Transactional + public LinkResponseDto uploadLink(LinkRequestDto requestDto) { + Link link = Link.builder() + .title(requestDto.getTitle()) + .link(requestDto.getLink()) + .build(); + + Link savedLink = linkRepository.save(link); + + return LinkResponseDto.builder() + .id(savedLink.getId()) + .title(savedLink.getTitle()) + .link(savedLink.getLink()) + .createdAt(savedLink.getCreatedAt()) + .build(); + } + + public List getAllLinks() { + List links = linkRepository.findAllByOrderByCreatedAtDesc(); + + return links.stream() + .map(link -> LinkResponseDto.builder() + .id(link.getId()) + .title(link.getTitle()) + .link(link.getLink()) + .createdAt(link.getCreatedAt()) + .build()) + .collect(Collectors.toList()); + } + + @Transactional + public void deleteLink(Long id) { + Link link = linkRepository.findById(id) + .orElseThrow(() -> new IllegalArgumentException("링크를 찾을 수 없습니다. ID: " + id)); + + linkRepository.delete(link); + } +} From 7d1c01c05e7350c0af70480c66efcfcb73476b1a Mon Sep 17 00:00:00 2001 From: "y.tnwjd" Date: Mon, 1 Sep 2025 17:24:49 +0900 Subject: [PATCH 2/2] fix: change desc to asc --- src/main/java/com/ajouchong/repository/LinkRepository.java | 2 +- src/main/java/com/ajouchong/service/LinkService.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/ajouchong/repository/LinkRepository.java b/src/main/java/com/ajouchong/repository/LinkRepository.java index 708f66f..96924de 100644 --- a/src/main/java/com/ajouchong/repository/LinkRepository.java +++ b/src/main/java/com/ajouchong/repository/LinkRepository.java @@ -9,5 +9,5 @@ @Repository public interface LinkRepository extends JpaRepository { - List findAllByOrderByCreatedAtDesc(); + List findAllByOrderByCreatedAtAsc(); } diff --git a/src/main/java/com/ajouchong/service/LinkService.java b/src/main/java/com/ajouchong/service/LinkService.java index 082b631..199fb1d 100644 --- a/src/main/java/com/ajouchong/service/LinkService.java +++ b/src/main/java/com/ajouchong/service/LinkService.java @@ -36,7 +36,7 @@ public LinkResponseDto uploadLink(LinkRequestDto requestDto) { } public List getAllLinks() { - List links = linkRepository.findAllByOrderByCreatedAtDesc(); + List links = linkRepository.findAllByOrderByCreatedAtAsc(); return links.stream() .map(link -> LinkResponseDto.builder()