Skip to content

Commit

Permalink
Merge pull request #85 from UMC-ON/feat/companypost
Browse files Browse the repository at this point in the history
[Refactor] 동행구하기 API 리팩토링
  • Loading branch information
isuHan authored Sep 18, 2024
2 parents ff1bc93 + cd22ad2 commit 4117f14
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 97 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@
import com.on.server.domain.companyPost.dto.CompanyPostResponseDTO;
import com.on.server.domain.user.domain.Gender;
import com.on.server.domain.user.domain.User;
import com.on.server.domain.user.domain.repository.UserRepository;
import com.on.server.global.aws.s3.uuidFile.application.UuidFileService;
import com.on.server.global.aws.s3.uuidFile.domain.FilePath;
import com.on.server.global.aws.s3.uuidFile.domain.UuidFile;
import com.on.server.global.aws.s3.uuidFile.domain.repository.UuidFileRepository;
import com.on.server.global.common.ResponseCode;
import com.on.server.global.common.exceptions.BadRequestException;
import com.on.server.global.common.exceptions.UnauthorizedException;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
Expand All @@ -27,13 +31,11 @@
public class CompanyPostService {

private final CompanyPostRepository companyPostRepository;
private final UserRepository userRepository;
private final UuidFileService uuidFileService;
private final UuidFileRepository uuidFileRepository;

// 필터링 기능 추가
public List<CompanyPostResponseDTO> getFilteredCompanyPosts(LocalDate startDate, LocalDate endDate, Gender gender, String country) {
List<CompanyPost> posts = companyPostRepository.findFilteredCompanyPostsWithoutCountry(startDate, endDate, gender);
public Page<CompanyPostResponseDTO> getFilteredCompanyPosts(LocalDate startDate, LocalDate endDate, Gender gender, String country, Pageable pageable) {
Page<CompanyPost> posts = companyPostRepository.findFilteredCompanyPostsWithoutCountry(startDate, endDate, gender, pageable);

if (country != null && !country.isEmpty()) {
posts = posts.stream()
Expand All @@ -42,35 +44,29 @@ public List<CompanyPostResponseDTO> getFilteredCompanyPosts(LocalDate startDate,
String firstWord = area.split(" ")[0]; // travelArea의 첫 번째 단어 추출
return firstWord.equalsIgnoreCase(country);
}))
.collect(Collectors.toList());
.collect(Collectors.collectingAndThen(Collectors.toList(), list -> new PageImpl<>(list, pageable, list.size())));
}

// DTO 변환
return posts.stream()
.map(this::mapToCompanyPostResponseDTO)
.collect(Collectors.toList());
return posts.map(CompanyPostResponseDTO::from);
}

// 1. 모든 게시글 조회
public List<CompanyPostResponseDTO> getAllCompanyPosts() {
return companyPostRepository.findAllByOrderByCreatedAtDesc().stream()
.map(this::mapToCompanyPostResponseDTO)
.collect(Collectors.toList());
public Page<CompanyPostResponseDTO> getAllCompanyPosts(Pageable pageable) {
return companyPostRepository.findAllByOrderByCreatedAtDesc(pageable)
.map(CompanyPostResponseDTO::from);
}

// 2. 특정 게시글 조회
public List<CompanyPostResponseDTO> getCompanyPostById(Long companyPostId) {
return companyPostRepository.findById(companyPostId)
.stream()
.map(this::mapToCompanyPostResponseDTO)
.map(CompanyPostResponseDTO::from)
.collect(Collectors.toList());
}

// 3. 새로운 게시글 작성
@Transactional
public CompanyPostResponseDTO createCompanyPost(CompanyPostRequestDTO requestDTO, List<MultipartFile> imageFiles) {
User user = userRepository.findById(requestDTO.getUserId())
.orElseThrow(() -> new RuntimeException("사용자를 찾을 수 없습니다. ID: " + requestDTO.getUserId()));
public CompanyPostResponseDTO createCompanyPost(User user, CompanyPostRequestDTO requestDTO, List<MultipartFile> imageFiles) {

List<UuidFile> uploadedImages = new ArrayList<>();
if (imageFiles != null && !imageFiles.isEmpty()) {
Expand Down Expand Up @@ -98,29 +94,23 @@ public CompanyPostResponseDTO createCompanyPost(CompanyPostRequestDTO requestDTO

companyPost = companyPostRepository.save(companyPost);

return mapToCompanyPostResponseDTO(companyPost);
return CompanyPostResponseDTO.from(companyPost);
}

// 4. 특정 사용자가 작성한 모든 게시글 조회
public List<CompanyPostResponseDTO> getCompanyPostsByUserId(Long userId) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new RuntimeException("사용자를 찾을 수 없습니다. ID: " + userId));

return companyPostRepository.findByUserOrderByCreatedAtDesc(user).stream()
.map(this::mapToCompanyPostResponseDTO)
.collect(Collectors.toList());
public Page<CompanyPostResponseDTO> getCompanyPostsByUser(User user, Pageable pageable) {
return companyPostRepository.findByUserOrderByCreatedAtDesc(user, pageable)
.map(CompanyPostResponseDTO::from);
}

// 5. 특정 게시글 삭제
@Transactional
public void deleteCompanyPost(Long userId, Long companyPostId) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new RuntimeException("사용자를 찾을 수 없습니다. ID: " + userId));
public void deleteCompanyPost(User user, Long companyPostId) {
CompanyPost companyPost = companyPostRepository.findById(companyPostId)
.orElseThrow(() -> new RuntimeException("게시글을 찾을 수 없습니다. ID: " + companyPostId));
.orElseThrow(() -> new BadRequestException(ResponseCode.ROW_DOES_NOT_EXIST, "게시글을 찾을 수 없습니다. ID: " + companyPostId));

if (!companyPost.getUser().getId().equals(userId)) {
throw new RuntimeException("삭제 권한이 없습니다.");
if (!companyPost.getUser().getId().equals(user.getId())) {
throw new UnauthorizedException(ResponseCode.GRANT_ROLE_NOT_ALLOWED, "삭제 권한이 없습니다.");
}

// 연관된 이미지 삭제
Expand All @@ -132,7 +122,7 @@ public void deleteCompanyPost(Long userId, Long companyPostId) {
// 6. 최신 4개의 동행 구하기 게시글 조회
public List<CompanyPostResponseDTO> getRecentCompanyPosts() {
return companyPostRepository.findTop4ByOrderByCreatedAtDesc().stream()
.map(this::mapToCompanyPostResponseDTO)
.map(CompanyPostResponseDTO::from)
.collect(Collectors.toList());
}

Expand All @@ -149,35 +139,7 @@ public List<CompanyPostResponseDTO> getNearbyCompanyPostsByLikeTravelArea(Long c
List<CompanyPost> nearbyPosts = companyPostRepository.findTop5ByTravelAreaLike(firstCountry, companyPostId);

return nearbyPosts.stream()
.map(this::mapToCompanyPostResponseDTO)
.map(CompanyPostResponseDTO::from)
.collect(Collectors.toList());
}

// CompanyPost 엔티티를 CompanyPostResponseDto로 매핑하는 메서드
private CompanyPostResponseDTO mapToCompanyPostResponseDTO(CompanyPost companyPost) {
return CompanyPostResponseDTO.builder()
.companyPostId(companyPost.getId())
.userId(companyPost.getUser().getId())
.age(companyPost.getUser().getAge())
.ageAnonymous(companyPost.isAgeAnonymous())
.dispatchedUniversity(companyPost.getUser().getDispatchedUniversity())
.nickname(companyPost.getUser().getNickname())
.gender(companyPost.getUser().getGender())
.universityAnonymous(companyPost.isUniversityAnonymous())
.title(companyPost.getTitle())
.content(companyPost.getContent())
.travelArea(companyPost.getTravelArea())
.currentRecruitNumber(companyPost.getCurrentRecruitNumber()) // 현재 모집 인원 수
.totalRecruitNumber(companyPost.getTotalRecruitNumber()) // 전체 모집 인원 수
.isRecruitCompleted(companyPost.isRecruitCompleted())
.schedulePeriodDay(companyPost.getSchedulePeriodDay())
.startDate(companyPost.getStartDate())
.endDate(companyPost.getEndDate())
.currentCountry(companyPost.getCurrentCountry())
.createdAt(companyPost.getCreatedAt())
.imageUrls(companyPost.getImages().stream()
.map(UuidFile::getFileUrl)
.collect(Collectors.toList())) // 이미지 URL 리스트
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.on.server.domain.companyPost.domain.CompanyPost;
import com.on.server.domain.user.domain.Gender;
import com.on.server.domain.user.domain.User;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
Expand All @@ -17,34 +18,30 @@
@Repository
public interface CompanyPostRepository extends JpaRepository<CompanyPost, Long> {

List<CompanyPost> findByUser(User user);

// 필터링을 위한 쿼리
@Query("SELECT cp FROM CompanyPost cp WHERE (:startDate IS NULL OR cp.startDate >= :startDate) " +
"AND (:endDate IS NULL OR cp.endDate <= :endDate) " +
"AND (:gender IS NULL OR cp.user.gender = :gender) " +
"ORDER BY cp.createdAt DESC")
List<CompanyPost> findFilteredCompanyPostsWithoutCountry(
Page<CompanyPost> findFilteredCompanyPostsWithoutCountry(
@Param("startDate") LocalDate startDate,
@Param("endDate") LocalDate endDate,
@Param("gender") Gender gender);
@Param("gender") Gender gender,
Pageable pageable);

// 최신 4개의 글을 최신순으로 가져오기
default List<CompanyPost> findTop4ByOrderByCreatedAtDesc() {
Pageable pageable = PageRequest.of(0, 4, Sort.by(Sort.Direction.DESC, "createdAt"));
return findAll(pageable).getContent();
}

// @Query("SELECT c FROM CompanyPost c JOIN c.travelArea t WHERE t LIKE CONCAT('%', :country, '%') AND c.currentRecruitNumber < c.totalRecruitNumber ORDER BY c.createdAt DESC")
// List<CompanyPost> findTop5ByTravelArea(@Param("country") String country);

@Query("SELECT c FROM CompanyPost c JOIN c.travelArea t WHERE t LIKE CONCAT('%', :country, '%') AND c.isRecruitCompleted = false ORDER BY c.createdAt DESC")
List<CompanyPost> findTop5ByTravelArea(@Param("country") String country, Pageable pageable);

@Query("SELECT c FROM CompanyPost c JOIN c.travelArea t WHERE t LIKE CONCAT('%', :country, '%') AND c.isRecruitCompleted = false AND c.id <> :companyPostId ORDER BY c.createdAt DESC")
List<CompanyPost> findTop5ByTravelAreaLike(@Param("country") String country, @Param("companyPostId") Long companyPostId);

// 최신순 정렬
List<CompanyPost> findAllByOrderByCreatedAtDesc();
List<CompanyPost> findByUserOrderByCreatedAtDesc(User user);
Page<CompanyPost> findAllByOrderByCreatedAtDesc(Pageable pageable);
Page<CompanyPost> findByUserOrderByCreatedAtDesc(User user, Pageable pageable);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDate;
import java.util.List;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.on.server.domain.companyPost.dto;

import com.on.server.domain.companyPost.domain.CompanyPost;
import com.on.server.domain.user.domain.Gender;
import com.on.server.global.aws.s3.uuidFile.domain.UuidFile;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
Expand All @@ -9,6 +11,7 @@
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

@Getter
@Builder
Expand Down Expand Up @@ -75,4 +78,31 @@ public class CompanyPostResponseDTO {

// 작성 시간
private LocalDateTime createdAt;

public static CompanyPostResponseDTO from(CompanyPost companyPost) {
return CompanyPostResponseDTO.builder()
.companyPostId(companyPost.getId())
.userId(companyPost.getUser().getId())
.age(companyPost.getUser().getAge())
.ageAnonymous(companyPost.isAgeAnonymous())
.dispatchedUniversity(companyPost.getUser().getDispatchedUniversity())
.nickname(companyPost.getUser().getNickname())
.gender(companyPost.getUser().getGender())
.universityAnonymous(companyPost.isUniversityAnonymous())
.title(companyPost.getTitle())
.content(companyPost.getContent())
.travelArea(companyPost.getTravelArea())
.currentRecruitNumber(companyPost.getCurrentRecruitNumber()) // 현재 모집 인원 수
.totalRecruitNumber(companyPost.getTotalRecruitNumber()) // 전체 모집 인원 수
.isRecruitCompleted(companyPost.isRecruitCompleted())
.schedulePeriodDay(companyPost.getSchedulePeriodDay())
.startDate(companyPost.getStartDate())
.endDate(companyPost.getEndDate())
.currentCountry(companyPost.getCurrentCountry())
.createdAt(companyPost.getCreatedAt())
.imageUrls(companyPost.getImages().stream()
.map(UuidFile::getFileUrl)
.collect(Collectors.toList())) // 이미지 URL 리스트
.build();
}
}
Loading

0 comments on commit 4117f14

Please sign in to comment.