Skip to content

Commit

Permalink
feature: 게시글 전체, 상세조회 #13
Browse files Browse the repository at this point in the history
  • Loading branch information
ujiiin committed Jul 4, 2024
1 parent 6dc0d35 commit 469e95e
Show file tree
Hide file tree
Showing 7 changed files with 158 additions and 43 deletions.
5 changes: 0 additions & 5 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,6 @@ dependencies {

// S3
implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'

// jwt
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
implementation 'io.jsonwebtoken:jjwt-impl:0.11.5'
implementation 'io.jsonwebtoken:jjwt-jackson:0.11.5'
}

tasks.named('test') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,8 @@
import java.util.List;

import org.springframework.http.MediaType;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import com.hackathon.TimeLapse.apiPayload.ApiResponse;
Expand All @@ -30,32 +26,42 @@
@RequestMapping("/api/article")
public class ArticleController {

private final ArticleService articleService;
private final S3Service s3Service;
private final ImageService imageService;

@PostMapping(value = "", consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.MULTIPART_FORM_DATA_VALUE})
public ApiResponse<ArticleResponseDTO.createArticleResultDTO> createArticle(
@RequestPart @Valid ArticleRequestDTO.createArticleDTO request,
@RequestPart List<MultipartFile> files
) throws IOException {
long memberId = Long.parseLong(SecurityContextHolder.getContext().getAuthentication().getName());
log.info("[*] memberId: " + memberId);
System.out.println(files.get(0));
List<String> uploadedFilesLinks = s3Service.uploadMultipleFiles(files);
Article article = articleService.createArticle(memberId, request, uploadedFilesLinks);

List<Image> images = new ArrayList<>();
for (String url : uploadedFilesLinks) {
Image image = Image.builder()
.image_url(url)
.article(article)
.build();
images.add(image);
}
imageService.addImages(article.getId(), new ImageRequestDTO.addImagesDTO(uploadedFilesLinks));

return ApiResponse.onSuccess(ArticleConverter.toCreateReviewResultDTO(article));
}
private final ArticleService articleService;
private final S3Service s3Service;
private final ImageService imageService;

@PostMapping(value = "", consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.MULTIPART_FORM_DATA_VALUE})
public ApiResponse<ArticleResponseDTO.createArticleResultDTO> createArticle(
@RequestPart @Valid ArticleRequestDTO.createArticleDTO request,
@RequestPart List<MultipartFile> files
) throws IOException {
Long memberId = request.getMemberId();
List<String> uploadedFilesLinks = s3Service.uploadMultipleFiles(files);
Article article = articleService.createArticle(memberId, request, uploadedFilesLinks);

List<Image> images = new ArrayList<>();
for (String url : uploadedFilesLinks) {
Image image = Image.builder()
.image_url(url)
.article(article)
.build();
images.add(image);
}
imageService.addImages(article.getId(), new ImageRequestDTO.addImagesDTO(uploadedFilesLinks));

return ApiResponse.onSuccess(ArticleConverter.toCreateReviewResultDTO(article));
}

@GetMapping("/")
public ApiResponse<ArticleResponseDTO.ArticleListDTO> getAllArticles(@RequestParam(name = "memberId") Long memberId) {
ArticleResponseDTO.ArticleListDTO articles = articleService.getAllArticles(memberId);
return ApiResponse.onSuccess(articles);
}

@GetMapping("/{articleId}")
public ApiResponse<ArticleResponseDTO.ArticleDetailDTO> getArticleDetail(@PathVariable Long articleId) {
ArticleResponseDTO.ArticleDetailDTO article = articleService.getArticleDetail(articleId);
return ApiResponse.onSuccess(article);
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.hackathon.TimeLapse.article;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

public class ArticleConverter {
public static Article toArticle(ArticleRequestDTO.createArticleDTO request){
Expand All @@ -19,4 +21,41 @@ public static ArticleResponseDTO.createArticleResultDTO toCreateReviewResultDTO(
.createdAt(LocalDateTime.now())
.build();
}

public static ArticleResponseDTO.ArticleSummaryDTO toSummaryDTO(Article article) {
String imageUrl = article.getImageList().isEmpty() ? null : article.getImageList().get(0).getImage_url();
return new ArticleResponseDTO.ArticleSummaryDTO(
article.getId(),
imageUrl
);
}

public static ArticleResponseDTO.ArticleDetailDTO toDetailDTO(Article article) {
List<String> imageUrls = article.getImageList().stream()
.map(image -> image.getImage_url())
.collect(Collectors.toList());
return new ArticleResponseDTO.ArticleDetailDTO(
article.getId(),
article.getTitle(),
article.getDescription(),
article.getLatitude(),
article.getLongitude(),
article.getStatus(),
imageUrls
);
}

public static ArticleResponseDTO.LatestArticleDTO toLatestArticleDTO(Article article) {
return new ArticleResponseDTO.LatestArticleDTO(
article.getLatitude(),
article.getLongitude()
);
}

public static ArticleResponseDTO.ArticleListDTO toArticleListDTO(List<Article> articles, Article latestArticle) {
List<ArticleResponseDTO.ArticleSummaryDTO> articleDTOs = articles.stream()
.map(ArticleConverter::toSummaryDTO)
.collect(Collectors.toList());
return new ArticleResponseDTO.ArticleListDTO(articleDTOs, toLatestArticleDTO(latestArticle));
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
package com.hackathon.TimeLapse.article;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.util.List;
import java.util.Optional;

public interface ArticleRepository extends JpaRepository<Article, Long> {
@Query("SELECT a FROM Article a WHERE a.member.id = :memberId ORDER BY a.createdAt DESC")
List<Article> findTopByMemberIdOrderByCreatedAtDesc(@Param("memberId") Long memberId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ public class ArticleRequestDTO {

@Getter
public static class createArticleDTO {
@NotNull
private Long memberId;
@NotNull
private Double latitude;
@NotNull
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package com.hackathon.TimeLapse.article;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.*;

import java.time.LocalDateTime;
import java.util.List;

public class ArticleResponseDTO {
@Builder
Expand All @@ -17,4 +15,45 @@ public static class createArticleResultDTO{
LocalDateTime createdAt;
}

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public static class ArticleSummaryDTO {
private Long id;
private String imageUrl;
}

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public static class ArticleDetailDTO {
private Long id;
private String title;
private String description;
private Double latitude;
private Double longitude;
private Long status;
private List<String> imageUrls;
}

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public static class ArticleListDTO {
private List<ArticleSummaryDTO> articles;
private LatestArticleDTO latestArticle;
}

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public static class LatestArticleDTO {
private Double latitude;
private Double longitude;
}

}
31 changes: 29 additions & 2 deletions src/main/java/com/hackathon/TimeLapse/article/ArticleService.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package com.hackathon.TimeLapse.article;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import com.hackathon.TimeLapse.apiPayload.exception.ArticleNotFoundException;
import com.hackathon.TimeLapse.apiPayload.exception.MemberNotFoundException;
import com.hackathon.TimeLapse.image.ImageService;
import com.hackathon.TimeLapse.member.MemberRepository;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand All @@ -12,19 +16,42 @@ public class ArticleService {
private final ArticleRepository articleRepository;
private final MemberRepository memberRepository;

@PersistenceContext
private EntityManager entityManager;

public ArticleService(ArticleRepository articleRepository, MemberRepository memberRepository) {
this.articleRepository = articleRepository;
this.memberRepository = memberRepository;
}

@Transactional
public Article createArticle(Long memberId, ArticleRequestDTO.createArticleDTO request,
List<String> uploadedFilesLinks) {
List<String> uploadedFilesLinks) {
Article article = ArticleConverter.toArticle(request);

article.setMember(memberRepository.findById(memberId)
.orElseThrow(() -> new MemberNotFoundException("Member not found with id: " + memberId)));

return articleRepository.save(article);
}

@Transactional
public ArticleResponseDTO.ArticleListDTO getAllArticles(Long memberId) {
List<Article> articles = articleRepository.findAll();
articles.forEach(article -> {
article.getImageList().size(); // 초기화
});

List<Article> latestArticles = articleRepository.findTopByMemberIdOrderByCreatedAtDesc(memberId);
Article latestArticle = latestArticles.isEmpty() ? null : latestArticles.get(0);

return ArticleConverter.toArticleListDTO(articles, latestArticle);
}

@Transactional
public ArticleResponseDTO.ArticleDetailDTO getArticleDetail(Long articleId) {
Article article = articleRepository.findById(articleId)
.orElseThrow(() -> new ArticleNotFoundException("Article not found with id: " + articleId));
return ArticleConverter.toDetailDTO(article);
}
}

0 comments on commit 469e95e

Please sign in to comment.