Skip to content
Open
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
23 changes: 23 additions & 0 deletions chapter4_umc/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,31 @@ dependencies {
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'

// QueryDSL : OpenFeign
implementation "io.github.openfeign.querydsl:querydsl-jpa:7.0"
implementation "io.github.openfeign.querydsl:querydsl-core:7.0"
annotationProcessor "io.github.openfeign.querydsl:querydsl-apt:7.0:jpa"
annotationProcessor "jakarta.persistence:jakarta.persistence-api"
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0'
}

tasks.named('test') {
useJUnitPlatform()
}

// QueryDSL 관련 설정
def querydslDir = layout.buildDirectory.dir("generated/querydsl").get().asFile

sourceSets {
main.java.srcDirs += [ querydslDir ]
}

tasks.withType(JavaCompile).configureEach {
options.generatedSourceOutputDirectory.set(querydslDir)
}

clean.doLast {
file(querydslDir).deleteDir()
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// Member 클래스가 속한 패키지 경로
package com.example.chapter4_umc.domain.member.entity;

import com.example.chapter4_umc.domain.notification.entity.Notification;
import com.example.chapter4_umc.domain.review.entity.Review;
import com.example.chapter4_umc.domain.inquiry.entity.Inquiry;
import com.example.chapter4_umc.domain.region.entity.Region;
import com.example.chapter4_umc.domain.member.enums.Gender;
import org.hibernate.annotations.ColumnDefault;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.example.chapter4_umc.domain.member.repository;

import com.example.chapter4_umc.domain.member.entity.Member;
import org.springframework.data.jpa.repository.JpaRepository;

public interface MemberRepository extends JpaRepository<Member, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.example.chapter4_umc.domain.mission.controller;

import com.example.chapter4_umc.domain.mission.dto.MissionJoinResDTO;
import com.example.chapter4_umc.domain.mission.service.MissionService;
import com.example.chapter4_umc.global.apiPayload.ApiResponse;
import com.example.chapter4_umc.global.apiPayload.code.GeneralSuccessCode;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/missions")
@Tag(name = "Mission", description = "미션 도전 API")
public class MissionController {

private final MissionService missionService;

private Long getLoggedInMemberId() {
return 1L; // 하드코딩
}

@Operation(summary = "미션 도전하기", description = "특정 미션을 도전합니다.")
@PostMapping("/{missionId}/join")
public ApiResponse<MissionJoinResDTO> joinMission(
@PathVariable Long missionId
) {
MissionJoinResDTO res = missionService.joinMission(missionId, getLoggedInMemberId());

return ApiResponse.onSuccess(
GeneralSuccessCode.MISSION_JOIN,
res
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.example.chapter4_umc.domain.mission.dto;

import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
public class MissionJoinResDTO {

private Long missionId;
private Long memberId;
private String status;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.example.chapter4_umc.domain.mission.entity;

import com.example.chapter4_umc.domain.member.entity.MemberMission;
import com.example.chapter4_umc.domain.store.entity.Store;
import jakarta.persistence.*;
import lombok.*;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.example.chapter4_umc.domain.mission.entity;

import com.example.chapter4_umc.domain.member.entity.Member;
import jakarta.persistence.*;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Getter
@NoArgsConstructor
public class MissionProgress {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "mission_progress_id")
private Long id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "mission_id")
private Mission mission;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
private Member member;

private String status;

@Builder
public MissionProgress(Mission mission, Member member, String status) {
this.mission = mission;
this.member = member;
this.status = status;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.example.chapter4_umc.domain.mission.repository;

import com.example.chapter4_umc.domain.mission.entity.MissionProgress;
import org.springframework.data.jpa.repository.JpaRepository;

public interface MissionProgressRepository extends JpaRepository<MissionProgress, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.example.chapter4_umc.domain.mission.repository;

import com.example.chapter4_umc.domain.mission.entity.Mission;
import org.springframework.data.jpa.repository.JpaRepository;

public interface MissionRepository extends JpaRepository<Mission, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.example.chapter4_umc.domain.mission.service;

import com.example.chapter4_umc.domain.member.entity.Member;
import com.example.chapter4_umc.domain.member.repository.MemberRepository;
import com.example.chapter4_umc.domain.mission.dto.MissionJoinResDTO;
import com.example.chapter4_umc.domain.mission.entity.Mission;
import com.example.chapter4_umc.domain.mission.entity.MissionProgress;
import com.example.chapter4_umc.domain.mission.repository.MissionProgressRepository;
import com.example.chapter4_umc.domain.mission.repository.MissionRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class MissionService {

private final MissionRepository missionRepository;
private final MissionProgressRepository missionProgressRepository;
private final MemberRepository memberRepository;

public MissionJoinResDTO joinMission(Long missionId, Long memberId) {

Mission mission = missionRepository.findById(missionId).orElseThrow();
Member member = memberRepository.findById(memberId).orElseThrow();

MissionProgress progress = MissionProgress.builder()
.mission(mission)
.member(member)
.status("도전중")
.build();

missionProgressRepository.save(progress);

return MissionJoinResDTO.builder()
.missionId(missionId)
.memberId(memberId)
.status("도전중")
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.example.chapter4_umc.domain.region.repository;

import com.example.chapter4_umc.domain.region.entity.Region;
import org.springframework.data.jpa.repository.JpaRepository;

public interface RegionRepository extends JpaRepository<Region, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.example.chapter4_umc.domain.review.controller;

import com.example.chapter4_umc.domain.review.dto.ReviewDto;
import com.example.chapter4_umc.domain.review.dto.ReviewSearchCondition;
import com.example.chapter4_umc.domain.review.service.ReviewService;
import com.example.chapter4_umc.global.apiPayload.ApiResponse;
import com.example.chapter4_umc.global.apiPayload.code.GeneralSuccessCode;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/reviews")
@RequiredArgsConstructor
public class MyReviewController {

private final ReviewService reviewService;

// 로그인된 사용자 ID 가져오기 (임시 하드코딩)
private Long getLoggedInMemberId(){
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아직 로그인 구현이 안되어서 이렇게 처리하신 것 같습니다.
pathvariable로 멤버의 아이디를 받아도 좋을 것 같아요!

return 1L;
}

@GetMapping("/my")
public ApiResponse<List<ReviewDto>> getMyReviews(
@RequestParam(required = false) String storeName,
@RequestParam(required = false) String ratingRange) {

Long memberId = getLoggedInMemberId();

ReviewSearchCondition condition = new ReviewSearchCondition();
condition.setStoreName(storeName);
condition.setRatingRange(ratingRange);

List<ReviewDto> response = reviewService.findMyReviews(memberId, condition);

return ApiResponse.onSuccess(
GeneralSuccessCode.REVIEW_READ,
response
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.example.chapter4_umc.domain.review.controller;

import com.example.chapter4_umc.domain.review.dto.req.ReviewCreateReqDTO;
import com.example.chapter4_umc.domain.review.dto.res.ReviewCreateResDTO;
import com.example.chapter4_umc.domain.review.service.ReviewService;
import com.example.chapter4_umc.global.apiPayload.ApiResponse;
import com.example.chapter4_umc.global.apiPayload.code.GeneralSuccessCode;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1")
@Tag(name = "Review", description = "리뷰 작성 API")
public class ReviewCreateController {

private final ReviewService reviewService;

private Long getLoggedInMemberId() {
return 1L;
}

@Operation(
summary = "가게 리뷰 작성",
description = "특정 가게에 리뷰를 작성합니다."
)
@PostMapping("/{storeId}/reviews")
public ApiResponse<ReviewCreateResDTO> createReview(
@PathVariable Long storeId,
@RequestBody ReviewCreateReqDTO req
) {
req.setStoreId(storeId);
req.setMemberId(getLoggedInMemberId());

ReviewCreateResDTO response = reviewService.createReview(req);

return ApiResponse.onSuccess(
GeneralSuccessCode.REVIEW_CREATED,
response
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.example.chapter4_umc.domain.review.converter;

import com.example.chapter4_umc.domain.review.dto.res.ReviewCreateResDTO;
import com.example.chapter4_umc.domain.review.dto.res.ReviewDetailResDTO;
import com.example.chapter4_umc.domain.review.dto.res.ReviewListResDTO;
import com.example.chapter4_umc.domain.review.dto.res.ReviewSimpleResDTO;
import com.example.chapter4_umc.domain.review.entity.Review;

import java.util.ArrayList;
import java.util.List;

public class ReviewConverter {

// 리뷰 생성 응답
public static ReviewCreateResDTO toCreateDTO(Review review){
return ReviewCreateResDTO.builder()
.reviewId(review.getId())
.message("리뷰가 성공적으로 생성되었습니다.")
.build();
}

public static ReviewDetailResDTO toDetailDTO(Review review){
return ReviewDetailResDTO.builder()
.reviewId(review.getId())
.rating(review.getRating())
.content(review.getContent())
.imageUrl(review.getImageUrl())
.createdAt(review.getCreatedAt().toString())

.memberId(review.getMember().getId())
.memberName(review.getMember().getNickname())

.storeId(review.getStore().getId())
.storeName(review.getStore().getStoreName())

.regionId(review.getRegion().getId())
.regionName(review.getRegion().getRegionName())
.build();
}

public static ReviewSimpleResDTO toSimpleDTO(Review review){
return ReviewSimpleResDTO.builder()
.reviewId(review.getId())
.rating(review.getRating())
.content(review.getContent())
.imageUrl(review.getImageUrl())
.createdAt(review.getCreatedAt().toString())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.example.chapter4_umc.domain.review.dto;

public class ReviewDto {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

지금은 dto가 하나뿐이지만, 추후 리뷰와 관련된 여러가지의 dto가 필요할 경우를 생각하면서, 네이밍에 대해 한 번 고민해보셔도 좋을 것 같습니다!

private Long reviewId;
private Integer rating;
private String content;
private String storeName;
private String imageUrl;

public ReviewDto(Long reviewId, Integer rating, String content, String storeName, String imageUrl) {
this.reviewId = reviewId;
this.rating = rating;
this.content = content;
this.storeName = storeName;
this.imageUrl = imageUrl;
}

public Long getReviewId() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분은 롬복의 다양한 어노테이션을 사용해서 깔끔하게 처리해도 좋을 것 같습니다!

return reviewId;
}
public Integer getRating() {
return rating;
}
public String getContent() {
return content;
}
public String getStoreName() {
return storeName;
}
public String getImageUrl() {
return imageUrl;
}

}
Loading