Skip to content

Commit

Permalink
Merge c915727 into 1836a2d
Browse files Browse the repository at this point in the history
  • Loading branch information
EunjiShin authored Jul 18, 2024
2 parents 1836a2d + c915727 commit 634ffcd
Show file tree
Hide file tree
Showing 46 changed files with 507 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package org.depromeet.spot.application.review;

import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;

import org.depromeet.spot.application.review.dto.request.CreateReviewRequest;
import org.depromeet.spot.application.review.dto.response.ReviewResponse;
import org.depromeet.spot.domain.review.Review;
import org.depromeet.spot.usecase.port.in.review.CreateReviewUsecase;
import org.springframework.http.HttpStatus;
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.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;

@RestController
@Tag(name = "리뷰")
@RequiredArgsConstructor
@RequestMapping("/api/v1")
public class CreateReviewController {

private final CreateReviewUsecase createReviewUsecase;

@ResponseStatus(HttpStatus.CREATED)
@Operation(summary = "특정 좌석에 신규 리뷰를 추가한다.")
@PostMapping("/seats/{seatId}/members/{memberId}/reviews")
public ReviewResponse create(
@PathVariable @Positive @NotNull final Long seatId,
@PathVariable @Positive @NotNull final Long memberId,
@RequestBody @Valid @NotNull CreateReviewRequest request) {
Review review = createReviewUsecase.create(seatId, memberId, request.toCommand());
return ReviewResponse.from(review);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.depromeet.spot.application.review.dto.request;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.List;

import org.depromeet.spot.common.exception.review.ReviewException.InvalidReviewDateTimeFormatException;
import org.depromeet.spot.usecase.port.in.review.CreateReviewUsecase.CreateReviewCommand;

public record CreateReviewRequest(
List<String> images, List<String> good, List<String> bad, String content, String dateTime) {

public CreateReviewCommand toCommand() {
return CreateReviewCommand.builder()
.images(images)
.good(good)
.bad(bad)
.content(content)
.dateTime(toLocalDateTime(dateTime))
.build();
}

private LocalDateTime toLocalDateTime(String dateTimeStr) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
try {
return LocalDateTime.parse(dateTimeStr, formatter);
} catch (DateTimeParseException e) {
throw new InvalidReviewDateTimeFormatException();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
@Getter
public enum ReviewErrorCode implements ErrorCode {
REVIEW_NOT_FOUND(HttpStatus.NOT_FOUND, "RV001", "요청한 리뷰를 찾을 수 없습니다."),
INVALID_REVIEW_DATA(HttpStatus.BAD_REQUEST, "RV002", "유효하지 않은 리뷰 데이터입니다.");
INVALID_REVIEW_DATA(HttpStatus.BAD_REQUEST, "RV002", "유효하지 않은 리뷰 데이터입니다."),
INVALID_REVIEW_DATETIME_FORMAT(
HttpStatus.BAD_REQUEST, "RV003", "리뷰 작성일시는 yyyy-MM-dd HH:mm 포맷이어야 합니다.");

private final HttpStatus status;
private final String code;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,14 @@ public InvalidReviewDataException(String str) {
super(ReviewErrorCode.INVALID_REVIEW_DATA.appended(str));
}
}

public static class InvalidReviewDateTimeFormatException extends ReviewException {
public InvalidReviewDateTimeFormatException() {
super(ReviewErrorCode.INVALID_REVIEW_DATETIME_FORMAT);
}

public InvalidReviewDateTimeFormatException(String str) {
super(ReviewErrorCode.INVALID_REVIEW_DATETIME_FORMAT.appended(str));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.depromeet.spot.common.exception.seat;

import org.depromeet.spot.common.exception.ErrorCode;
import org.springframework.http.HttpStatus;

import lombok.Getter;

@Getter
public enum SeatErrorCode implements ErrorCode {
SEAT_NOT_FOUND(HttpStatus.NOT_FOUND, "SEAT001", "요청 좌석이 존재하지 않습니다."),
;

private final HttpStatus status;
private final String code;
private String message;

SeatErrorCode(HttpStatus status, String code, String message) {
this.status = status;
this.code = code;
this.message = message;
}

public SeatErrorCode appended(Object o) {
message = message + " {" + o.toString() + "}";
return this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.depromeet.spot.common.exception.seat;

import org.depromeet.spot.common.exception.BusinessException;

public abstract class SeatException extends BusinessException {

protected SeatException(SeatErrorCode errorCode) {
super(errorCode);
}

public static class SeatNotFoundException extends SeatException {
public SeatNotFoundException() {
super(SeatErrorCode.SEAT_NOT_FOUND);
}

public SeatNotFoundException(Object obj) {
super(SeatErrorCode.SEAT_NOT_FOUND.appended(obj));
}
}
}
37 changes: 37 additions & 0 deletions domain/src/main/java/org/depromeet/spot/domain/member/Member.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,43 @@ public class Member {
private final LocalDateTime createdAt;
private final LocalDateTime deletedAt;

public int calculateLevel(long reviewCnt) {
if (reviewCnt <= 2) {
return 1;
}
if (2 < reviewCnt && reviewCnt <= 6) {
return 2;
}
if (6 < reviewCnt && reviewCnt <= 11) {
return 3;
}
if (11 < reviewCnt && reviewCnt <= 20) {
return 4;
}
if (20 < reviewCnt && reviewCnt <= 35) {
return 5;
}
return 6;
}

public Member updateLevel(int newLevel) {
return Member.builder()
.id(id)
.email(email)
.name(name)
.nickname(nickname)
.phoneNumber(phoneNumber)
.level(newLevel)
.profileImage(profileImage)
.snsProvider(snsProvider)
.idToken(idToken)
.teamId(teamId)
.role(role)
.createdAt(createdAt)
.deletedAt(deletedAt)
.build();
}

public Member updateProfile(String newProfileImage, String newNickname, Long newTeamId) {
return Member.builder()
.id(id)
Expand Down
25 changes: 23 additions & 2 deletions domain/src/main/java/org/depromeet/spot/domain/review/Review.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
import java.time.LocalDateTime;
import java.util.List;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;

@Builder
@Getter
@Builder
@AllArgsConstructor
public class Review {

private final Long id;
Expand All @@ -18,11 +20,30 @@ public class Review {
private final Long rowId;
private final Long seatNumber;

private final LocalDateTime dateTime; // 시간은 미표기
private final LocalDateTime dateTime;
private final String content;
private final LocalDateTime createdAt;
private final LocalDateTime updatedAt;
private final LocalDateTime deletedAt;
private final List<ReviewImage> images;
private final List<ReviewKeyword> keywords;

public Review addImagesAndKeywords(
List<ReviewImage> newImages, List<ReviewKeyword> newKeywords) {
return new Review(
id,
userId,
stadiumId,
blockId,
seatId,
rowId,
seatNumber,
dateTime,
content,
createdAt,
updatedAt,
deletedAt,
newImages,
newKeywords);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@
import lombok.Builder;
import lombok.Getter;

@Builder
@Getter
@Builder
public class ReviewImage {

private final Long id;
private final Long reviewId;
private final String url;
private final LocalDateTime createdAt;
private final LocalDateTime deletedAt;

public static ReviewImage of(Long reviewId, String url) {
return ReviewImage.builder().reviewId(reviewId).url(url).build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,8 @@ void updateProfile(
@Param("profileImage") String profileImage,
@Param("teamId") Long teamId,
@Param("nickname") String nickname);

@Modifying
@Query("update MemberEntity m set m.level = :level where m.id = :memberId")
void updateLevel(@Param("memberId") Long memberId, @Param("level") int level);
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,18 @@ public Member save(Member member) {
}

@Override
public Member update(Member member) {
public Member updateProfile(Member member) {
memberJpaRepository.updateProfile(
member.getId(), member.getProfileImage(), member.getTeamId(), member.getNickname());
return member;
}

@Override
public Member updateLevel(Member member) {
memberJpaRepository.updateLevel(member.getId(), member.getLevel());
return member;
}

@Override
public Optional<Member> findByIdToken(String idToken) {
return memberJpaRepository.findByIdToken(idToken).map(MemberEntity::toDomain);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ public class ReviewEntity extends BaseEntity {
@Column(name = "row_id", nullable = false)
private Long rowId;

@Column(name = "seat_id", nullable = false)
private Long seatId;

@Column(name = "seat_number", nullable = false)
private Long seatNumber;

Expand All @@ -56,6 +59,7 @@ public static Review createReviewWithDetails(
.stadiumId(entity.getStadiumId())
.blockId(entity.getBlockId())
.rowId(entity.getRowId())
.seatId(entity.getSeatId())
.seatNumber(entity.getSeatNumber())
.dateTime(entity.getDateTime())
.content(entity.getContent())
Expand All @@ -79,6 +83,7 @@ public static ReviewEntity from(Review review) {
review.getStadiumId(),
review.getBlockId(),
review.getRowId(),
review.getSeatId(),
review.getSeatNumber(),
review.getDateTime(),
review.getContent(),
Expand All @@ -92,6 +97,7 @@ public Review toDomain() {
.stadiumId(stadiumId)
.blockId(blockId)
.rowId(rowId)
.seatId(seatId)
.seatNumber(seatNumber)
.dateTime(dateTime)
.content(content)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package org.depromeet.spot.jpa.review.entity;

import java.time.LocalDateTime;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
Expand All @@ -24,12 +22,8 @@ public class ReviewImageEntity extends BaseEntity {
@Column(name = "url", nullable = false, length = 255)
private String url;

@Column(name = "deleted_at")
private LocalDateTime deletedAt;

public static ReviewImageEntity from(ReviewImage reviewImage) {
return new ReviewImageEntity(
reviewImage.getReviewId(), reviewImage.getUrl(), reviewImage.getDeletedAt());
return new ReviewImageEntity(reviewImage.getReviewId(), reviewImage.getUrl());
}

public ReviewImage toDomain() {
Expand All @@ -38,7 +32,6 @@ public ReviewImage toDomain() {
.reviewId(reviewId)
.url(url)
.createdAt(this.getCreatedAt())
.deletedAt(deletedAt)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.depromeet.spot.jpa.review.repository;

import org.depromeet.spot.jpa.review.entity.ReviewEntity;
import org.springframework.data.jpa.repository.JpaRepository;

public interface ReviewJpaRepository extends JpaRepository<ReviewEntity, Long> {
long countByUserId(Long userId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
@RequiredArgsConstructor
public class ReviewRepositoryImpl implements ReviewRepository {
private final ReviewCustomRepository reviewCustomRepository;
private final ReviewJpaRepository reviewJpaRepository;

@Override
public List<Review> findByBlockId(
Expand Down Expand Up @@ -46,11 +47,22 @@ public Long countByUserId(Long userId, Integer year, Integer month) {
return reviewCustomRepository.countByUserIdWithFilters(userId, year, month);
}

@Override
public long countByUserId(Long userId) {
return reviewJpaRepository.countByUserId(userId);
}

@Override
public List<KeywordCount> findTopKeywordsByBlockId(Long stadiumId, Long blockId, int limit) {
return reviewCustomRepository.findTopKeywordsByBlockId(stadiumId, blockId, limit);
}

@Override
public Review save(Review review) {
ReviewEntity entity = reviewJpaRepository.save(ReviewEntity.from(review));
return entity.toDomain();
}

private Review fetchReviewDetails(ReviewEntity reviewEntity) {
List<ReviewImageEntity> images =
reviewCustomRepository.findImagesByReviewIds(List.of(reviewEntity.getId()));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package org.depromeet.spot.jpa.review.repository.image;

import org.depromeet.spot.jpa.review.entity.ReviewImageEntity;
import org.springframework.data.jpa.repository.JpaRepository;

public interface ReviewImageJpaRepository extends JpaRepository<ReviewImageEntity, Long> {}
Loading

0 comments on commit 634ffcd

Please sign in to comment.