Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,5 @@ public interface FileService {
// 파일 이름 가져오기
List<String> getFileName(Long id) throws Exception;

// 버킷 이름 생성
String getBucketName() throws Exception;
String newFileName() throws Exception;
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ public class FileServiceImpl implements FileService {
private final MinioClient minioClient;
private final ArticleRepository articleRepository;

String bucketName = "article";

// 버킷 네임 생성
@Override
public String getBucketName() {
public String newFileName() {
TimeBasedGenerator generator = Generators.timeBasedGenerator();
// UUID 버전 1 생성
UUID uuid = generator.generate();
Expand All @@ -35,13 +37,16 @@ public String getBucketName() {
// 파일 업로드 과정 (생성, 수정 중복)
@Override
public FileResponse uploadFile(List<MultipartFile> files, String bucketName) throws Exception {

// 이미지 url 저장
List<String> urls = new ArrayList<>();

for (MultipartFile file : files) {
String fileName = file.getOriginalFilename(); // 파일이름 가져오고
String fileName = newFileName(); // 파일이름 가져오고
InputStream fileStream = file.getInputStream(); // 파일 데이터를 읽고 가져온다.



PutObjectArgs putObjectArgs = PutObjectArgs.builder()
.bucket(bucketName)
.object(fileName)
Expand Down Expand Up @@ -69,8 +74,6 @@ public FileResponse uploadFile(List<MultipartFile> files, String bucketName) thr
// 파일 업로드
@Override
public FileResponse createFile(List<MultipartFile> files) throws Exception {
// 버킷 이름 저장
String bucketName = getBucketName();

if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
Expand All @@ -81,17 +84,17 @@ public FileResponse createFile(List<MultipartFile> files) throws Exception {

@Override
public FileResponse updateFile(List<MultipartFile> files, Long id) throws Exception {
String bucketName = articleRepository.getByIdOrThrow(id).getBucketName();

deleteFile(id);
return uploadFile(files, bucketName);
}


// 이미지 파일 삭제하기
@Override
public void deleteFile(Long id) throws Exception {
String bucketName = articleRepository.getByIdOrThrow(id).getBucketName();
List<String> fileNames = getFileName(id);

List<String> fileNames = getFileName(id); // 각 파일이름 받아오고 거기서 삭제

for (String file : fileNames) {
minioClient.removeObject(
Expand Down Expand Up @@ -121,6 +124,7 @@ public void deleteBucket(Long id) throws Exception {
@Override
public List<String> getFileName(Long id) {
List<String> urls = articleRepository.getByIdOrThrow(id).getFiles();
log.info("[getFileName] urls : {}", urls);

List<String> fileNames = new ArrayList<>();

Expand All @@ -131,7 +135,7 @@ public List<String> getFileName(Long id) {

fileNames.add(fileName);
}

log.info("[getFileName] fileNames : {}", fileNames);
return fileNames;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
package project.buysellservice.domain.article.controller;

import jakarta.validation.Valid;
import jakarta.ws.rs.core.Response;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import project.buysellservice.domain.article.dto.request.ArticleRequest;
import project.buysellservice.domain.article.dto.response.ArticleResponse;
import project.buysellservice.domain.article.entity.Category;
import project.buysellservice.domain.article.service.ArticleService;

import java.util.List;
Expand All @@ -23,9 +24,14 @@ public class ApiV1ArticleController {

// 게시글 전체 페이징 처리
@GetMapping
public ResponseEntity<List<ArticleResponse>> getArticle(@Valid @RequestParam("page") int page,
@Valid @RequestParam("size") int size) {
return ResponseEntity.ok(articleService.readAllArticles(PageRequest.of(page, size)));
public ResponseEntity<List<ArticleResponse>> getArticle(Pageable pageable) {
return ResponseEntity.ok(articleService.readAllArticles(pageable));
}

// 게시글 전체 (오래된순)
@GetMapping("/asc")
public ResponseEntity<List<ArticleResponse>> getArticleAsc(Pageable pageable) {
return ResponseEntity.ok(articleService.readAllArticlesOrderByAsc(pageable));
}

// 게시글 가져오기
Expand All @@ -34,12 +40,26 @@ public ResponseEntity<ArticleResponse> getArticleById(@PathVariable("id") Long i
return ResponseEntity.ok(articleService.readArticle(id));
}

// 구매가능 게시글만 보기
@GetMapping("/stateSell")
public ResponseEntity<List<ArticleResponse>> getArticleStateSell(Pageable pageable) {
return ResponseEntity.ok(articleService.readByStateSell(pageable));
}

// 가격대 별로 게시판 보기
@GetMapping("/price")
public ResponseEntity<List<ArticleResponse>> getArticlePrice(Pageable pageable,
@Valid @RequestParam("minPrice") int minPrice,
@Valid @RequestParam("maxPrice") int maxPrice) {
return ResponseEntity.ok(articleService.readByPrice(pageable, minPrice, maxPrice));
}

// 게시글 생성
@PostMapping(consumes = "multipart/form-data")
public ResponseEntity<ArticleResponse> createArticle(@RequestPart("articleRequest") @Valid ArticleRequest articleRequest,
@RequestPart("file") List<MultipartFile> files) throws Exception {
return ResponseEntity.ok(articleService.createArticle(
articleRequest.title(), articleRequest.content(), files, articleRequest.price()
articleRequest.title(), articleRequest.content(), files, articleRequest.price(), articleRequest.category()
));
}

Expand All @@ -49,7 +69,7 @@ public ResponseEntity<ArticleResponse> updateArticle(@Valid @PathVariable("id")
@RequestPart("articleRequest") ArticleRequest articleRequest,
@RequestPart("file") List<MultipartFile> files) throws Exception {
return ResponseEntity.ok(articleService.updateArticle(
id, articleRequest.title(), articleRequest.content(), files, articleRequest.price()
id, articleRequest.title(), articleRequest.content(), files, articleRequest.price(), articleRequest.category()
));
}

Expand All @@ -65,4 +85,11 @@ public ResponseEntity<ArticleResponse> soldArticle(@Valid @PathVariable("id") Lo
return ResponseEntity.ok(articleService.soldArticle(id));
}

// 해당 카테고리 글만 가져오기
@GetMapping("/category")
public ResponseEntity<List<ArticleResponse>> getArticleByCategory(@Valid @RequestParam("category") Category category,
Pageable pageable) {
return ResponseEntity.ok(articleService.readCategoryArticle(category, pageable));
}

}
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package project.buysellservice.domain.article.dto.request;

import org.springframework.web.multipart.MultipartFile;
import project.buysellservice.domain.article.entity.Category;

public record ArticleRequest(
String title,
String content,
Long price
Long price,
Category category
) {

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package project.buysellservice.domain.article.dto.response;

import project.buysellservice.domain.article.entity.Article;
import project.buysellservice.domain.article.entity.Category;
import project.buysellservice.domain.article.entity.State;

import java.util.List;
Expand All @@ -11,7 +12,8 @@ public record ArticleResponse(
String content,
Long price,
List<String> files,
State state
State state,
Category category

) {
public static ArticleResponse of(Article article) {
Expand All @@ -20,7 +22,8 @@ public static ArticleResponse of(Article article) {
article.getContent(),
article.getPrice(),
article.getFiles(),
article.getState()
article.getState(),
article.getCategory()

);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ public class Article extends BaseEntity {
@Column(name = "price", length = 20)
private Long price; // 가격

@ElementCollection // List<String>을 JPA에서 사용할 수 있도록 설정
// 도메인, 엔티티로 빼야되는 경우가 많음
// 원투매니 ( 수정이 거의 없을 때 )
@ElementCollection(fetch = FetchType.EAGER) // List<String>을 JPA에서 사용할 수 있도록 설정 ( 더티체킹을 변경할 때 마다 안 함) / 로딩 비효율적 잘 찾아볼것
@CollectionTable(name = "bucketName") // 별도의 테이블을 생성 (file_images 테이블)
@Column(name = "image_url", length = 2048) // 테이블의 컬럼명 지정
private List<String> files; // 이미지 저장
Expand All @@ -40,27 +42,33 @@ public class Article extends BaseEntity {
@Enumerated(EnumType.STRING)
private State state;

@Column(name = "category")
@Enumerated(EnumType.STRING) // 다이어리 코드 공부 좀 했슴다
private Category category;

// 게시글 생성 빌더
public static Article createFrom(String title, String content, List<String> files, Long price, String bucketName) {
public static Article createFrom(String title, String content, List<String> files, Long price, String bucketName, Category category) {
return Article.builder()
.title(title)
.content(content)
.files(files)
.price(price)
.bucketName(bucketName)
.category(category)
.state(State.SELL)
.build();
}

// 게시글 수정 빌더
public static Article updateFrom(Long id, String title, String content, List<String> files, Long price, String bucketName) {
public static Article updateFrom(Long id, String title, String content, List<String> files, Long price, String bucketName, Category category) {
return Article.builder()
.id(id)
.title(title)
.content(content)
.files(files)
.price(price)
.bucketName(bucketName)
.category(category)
.state(State.SELL)
.build();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package project.buysellservice.domain.article.entity;

public enum Category {
ELECTRONICS,
FURNITURE,
CLOTHING,
TOYS,
BOOKS,
VEHICLES,
REAL_ESTATE;

public static Category fromString(String category) {
return Category.valueOf(category.toUpperCase());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,4 @@ default Article getByIdOrThrow(Long id) {
// 예외처리 만들기
}

// 버킷 네임 생성
default String bucketName() {
return "Post - " + UUID.randomUUID();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,24 @@

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import project.buysellservice.domain.article.entity.Article;
import project.buysellservice.domain.article.entity.Category;

public interface ArticleRepositoryCustom {
// 전체 게시글 받아오기
Page<Article> findAllByOrderByCreatedAt(Pageable pageable);
// 전체 게시글 받아오기 (최신순)
Slice<Article> findAllByOrderByCreatedAtDesc(Pageable pageable);

// 전체 게시글 받아오기 (오래된순)
Slice<Article> findAllByOrderByCreatedAtAsc(Pageable pageable);

// 해당 카테고리 글 가져오기
Slice<Article> findAllByCategory(Category category, Pageable pageable);

// 거래가능만 보기
Slice<Article> findBySellStatus(Pageable pageable);

// 가격별로 보기 (직접 설정)
Slice<Article> findByPrice(Pageable pageable, int minPrice, int maxPrice);

}
Loading