diff --git a/src/main/java/com/example/demo/domain/food/exception/FoodException.java b/src/main/java/com/example/demo/domain/food/exception/FoodException.java new file mode 100644 index 0000000..ab971de --- /dev/null +++ b/src/main/java/com/example/demo/domain/food/exception/FoodException.java @@ -0,0 +1,10 @@ +package com.example.demo.domain.food.exception; + +import com.example.demo.global.apiPayload.code.BaseErrorCode; +import com.example.demo.global.apiPayload.exception.GeneralException; + +public class FoodException extends GeneralException { + public FoodException(BaseErrorCode code) { + super(code); + } +} diff --git a/src/main/java/com/example/demo/domain/food/exception/code/FoodErrorCode.java b/src/main/java/com/example/demo/domain/food/exception/code/FoodErrorCode.java new file mode 100644 index 0000000..9034a12 --- /dev/null +++ b/src/main/java/com/example/demo/domain/food/exception/code/FoodErrorCode.java @@ -0,0 +1,16 @@ +package com.example.demo.domain.food.exception.code; + +import com.example.demo.global.apiPayload.code.BaseErrorCode; +import com.example.demo.global.apiPayload.code.GeneralErrorCode; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.http.HttpStatus; + +@Getter +@AllArgsConstructor +public enum FoodErrorCode implements BaseErrorCode { + Food_NOT_FOUND(HttpStatus.NOT_FOUND, "FOOD404","이거는 푸드 테스트"); + private final HttpStatus status; + private final String code; + private final String message; +} diff --git a/src/main/java/com/example/demo/domain/food/repository/FoodRepository.java b/src/main/java/com/example/demo/domain/food/repository/FoodRepository.java new file mode 100644 index 0000000..2b87143 --- /dev/null +++ b/src/main/java/com/example/demo/domain/food/repository/FoodRepository.java @@ -0,0 +1,8 @@ +package com.example.demo.domain.food.repository; + +import com.example.demo.domain.food.entity.Food; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface FoodRepository extends JpaRepository { + +} diff --git a/src/main/java/com/example/demo/domain/member/controller/MemberController.java b/src/main/java/com/example/demo/domain/member/controller/MemberController.java new file mode 100644 index 0000000..0cdf3f3 --- /dev/null +++ b/src/main/java/com/example/demo/domain/member/controller/MemberController.java @@ -0,0 +1,25 @@ +package com.example.demo.domain.member.controller; + +import com.example.demo.domain.member.dto.req.MemberReqDTO; +import com.example.demo.domain.member.dto.res.MemberResDTO; +import com.example.demo.domain.member.exception.code.MemberSuccessCode; +import com.example.demo.domain.member.service.command.MemberCommandService; +import com.example.demo.global.apiPayload.ApiResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + + +@RestController +@RequiredArgsConstructor +public class MemberController { + private final MemberCommandService memberCommandService; + // 회원가입 + @PostMapping("/sign-up") + public ApiResponse signUp( + @RequestBody MemberReqDTO.JoinDTO dto + ){ + return ApiResponse.onSuccess(MemberSuccessCode.FOUND, memberCommandService.signup(dto)); + } +} diff --git a/src/main/java/com/example/demo/domain/member/converter/MemberConverter.java b/src/main/java/com/example/demo/domain/member/converter/MemberConverter.java new file mode 100644 index 0000000..1539aa9 --- /dev/null +++ b/src/main/java/com/example/demo/domain/member/converter/MemberConverter.java @@ -0,0 +1,30 @@ +package com.example.demo.domain.member.converter; + +import com.example.demo.domain.member.dto.req.MemberReqDTO; +import com.example.demo.domain.member.dto.res.MemberResDTO; +import com.example.demo.domain.member.entity.Member; + +public class MemberConverter { + // Entity -> DTO + public static MemberResDTO.JoinDTO toJoinDTO( + Member member + ){ + return MemberResDTO.JoinDTO.builder() + .memberId(member.getId()) + .createAt(member.getCreatedAt()) + .build(); + } + + // DTO -> Entity + public static Member toMember( + MemberReqDTO.JoinDTO dto + ){ + return Member.builder() + .name(dto.name()) + .birth(dto.birth()) + .address(dto.address()) + .detailAddress(dto.specAddress()) + .gender(dto.gender()) + .build(); + } +} diff --git a/src/main/java/com/example/demo/domain/member/dto/req/MemberReqDTO.java b/src/main/java/com/example/demo/domain/member/dto/req/MemberReqDTO.java new file mode 100644 index 0000000..faa5e69 --- /dev/null +++ b/src/main/java/com/example/demo/domain/member/dto/req/MemberReqDTO.java @@ -0,0 +1,21 @@ +package com.example.demo.domain.member.dto.req; + +import com.example.demo.domain.member.enums.Address; +import com.example.demo.domain.member.enums.Gender; + +import java.time.LocalDate; +import java.util.List; + +public class MemberReqDTO { + + + + public record JoinDTO( + String name, + Gender gender, + LocalDate birth, + Address address, + String specAddress, + List preferCategory + ){} +} diff --git a/src/main/java/com/example/demo/domain/member/dto/res/MemberResDTO.java b/src/main/java/com/example/demo/domain/member/dto/res/MemberResDTO.java new file mode 100644 index 0000000..42ced4a --- /dev/null +++ b/src/main/java/com/example/demo/domain/member/dto/res/MemberResDTO.java @@ -0,0 +1,13 @@ +package com.example.demo.domain.member.dto.res; + +import lombok.Builder; + +import java.time.LocalDateTime; + +public class MemberResDTO { + @Builder + public record JoinDTO( + Long memberId, + LocalDateTime createAt + ){} +} diff --git a/src/main/java/com/example/demo/domain/member/exception/MemberException.java b/src/main/java/com/example/demo/domain/member/exception/MemberException.java new file mode 100644 index 0000000..7b18715 --- /dev/null +++ b/src/main/java/com/example/demo/domain/member/exception/MemberException.java @@ -0,0 +1,10 @@ +package com.example.demo.domain.member.exception; + +import com.example.demo.global.apiPayload.code.BaseErrorCode; +import com.example.demo.global.apiPayload.exception.GeneralException; + +public class MemberException extends GeneralException { + public MemberException(BaseErrorCode code) { + super(code); + } +} diff --git a/src/main/java/com/example/demo/domain/member/exception/code/MemberErrorCode.java b/src/main/java/com/example/demo/domain/member/exception/code/MemberErrorCode.java new file mode 100644 index 0000000..e79612a --- /dev/null +++ b/src/main/java/com/example/demo/domain/member/exception/code/MemberErrorCode.java @@ -0,0 +1,18 @@ +package com.example.demo.domain.member.exception.code; + +import com.example.demo.global.apiPayload.code.BaseErrorCode; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.http.HttpStatus; + +@Getter +@AllArgsConstructor +public enum MemberErrorCode implements BaseErrorCode { + NOT_FOUND(HttpStatus.NOT_FOUND, + "MEMBER404_1", + "해당 사용자를 찾지 못했습니다."), + ; + private final HttpStatus status; + private final String code; + private final String message; +} diff --git a/src/main/java/com/example/demo/domain/member/exception/code/MemberSuccessCode.java b/src/main/java/com/example/demo/domain/member/exception/code/MemberSuccessCode.java new file mode 100644 index 0000000..a4b0c5a --- /dev/null +++ b/src/main/java/com/example/demo/domain/member/exception/code/MemberSuccessCode.java @@ -0,0 +1,19 @@ +package com.example.demo.domain.member.exception.code; + +import com.example.demo.global.apiPayload.code.BaseSuccessCode; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.http.HttpStatus; + +@Getter +@AllArgsConstructor +public enum MemberSuccessCode implements BaseSuccessCode { + FOUND(HttpStatus.OK, + "MEMBER200_1", + "성공적으로 사용자를 조회했습니다."), + ; + private final HttpStatus status; + private final String code; + private final String message; + +} diff --git a/src/main/java/com/example/demo/domain/member/repository/MemberFoodRepository.java b/src/main/java/com/example/demo/domain/member/repository/MemberFoodRepository.java new file mode 100644 index 0000000..5296599 --- /dev/null +++ b/src/main/java/com/example/demo/domain/member/repository/MemberFoodRepository.java @@ -0,0 +1,8 @@ +package com.example.demo.domain.member.repository; + +import com.example.demo.domain.member.entity.mapping.MemberFood; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface MemberFoodRepository extends JpaRepository { + +} diff --git a/src/main/java/com/example/demo/domain/member/service/command/MemberCommandService.java b/src/main/java/com/example/demo/domain/member/service/command/MemberCommandService.java new file mode 100644 index 0000000..ef21627 --- /dev/null +++ b/src/main/java/com/example/demo/domain/member/service/command/MemberCommandService.java @@ -0,0 +1,11 @@ +package com.example.demo.domain.member.service.command; + +import com.example.demo.domain.member.dto.req.MemberReqDTO; +import com.example.demo.domain.member.dto.res.MemberResDTO; + +public interface MemberCommandService { + + public MemberResDTO.JoinDTO signup( + MemberReqDTO.JoinDTO dto + ); +} diff --git a/src/main/java/com/example/demo/domain/member/service/command/MemberCommandServiceImpl.java b/src/main/java/com/example/demo/domain/member/service/command/MemberCommandServiceImpl.java new file mode 100644 index 0000000..8c58f85 --- /dev/null +++ b/src/main/java/com/example/demo/domain/member/service/command/MemberCommandServiceImpl.java @@ -0,0 +1,64 @@ +package com.example.demo.domain.member.service.command; + +import com.example.demo.domain.food.entity.Food; +import com.example.demo.domain.food.exception.FoodException; +import com.example.demo.domain.food.exception.code.FoodErrorCode; +import com.example.demo.domain.food.repository.FoodRepository; +import com.example.demo.domain.member.converter.MemberConverter; +import com.example.demo.domain.member.dto.req.MemberReqDTO; +import com.example.demo.domain.member.dto.res.MemberResDTO; +import com.example.demo.domain.member.entity.Member; +import com.example.demo.domain.member.entity.mapping.MemberFood; +import com.example.demo.domain.member.repository.MemberFoodRepository; +import com.example.demo.domain.member.repository.MemberRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; + +@Service +@RequiredArgsConstructor +public class MemberCommandServiceImpl implements MemberCommandService { + + private final MemberRepository memberRepository; + private final MemberFoodRepository memberFoodRepository; + private final FoodRepository foodRepository; + + // 회원가입 + @Override + @Transactional + public MemberResDTO.JoinDTO signup( + MemberReqDTO.JoinDTO dto + ) { + // 사용자 생성 + Member member = MemberConverter.toMember(dto); + // DB 적용 + memberRepository.save(member); + + // 선호 음식 존재 여부 확인 + if (dto.preferCategory().size() > 1) { + List memberFoodList = new ArrayList<>(); + + // 선호 음식 ID별 조회 + for (Long id : dto.preferCategory()) { + + // 음식 존재 여부 검증 + Food food = foodRepository.findById(id) + .orElseThrow(() -> new FoodException(FoodErrorCode.Food_NOT_FOUND)); + + MemberFood memberFood = MemberFood.builder() + .member(member) + .food(food) + .build(); + + memberFoodList.add(memberFood); + } + + //DB 적용 + memberFoodRepository.saveAll(memberFoodList); + } + return MemberConverter.toJoinDTO(member); + } +} diff --git a/src/main/java/com/example/demo/domain/member/service/query/MemberQueryService.java b/src/main/java/com/example/demo/domain/member/service/query/MemberQueryService.java new file mode 100644 index 0000000..29b7c9a --- /dev/null +++ b/src/main/java/com/example/demo/domain/member/service/query/MemberQueryService.java @@ -0,0 +1,5 @@ +package com.example.demo.domain.member.service.query; + +public interface MemberQueryService { + void checkFlag(Long flag); +} diff --git a/src/main/java/com/example/demo/domain/member/service/query/MemberQueryServiceImpl.java b/src/main/java/com/example/demo/domain/member/service/query/MemberQueryServiceImpl.java new file mode 100644 index 0000000..ee83324 --- /dev/null +++ b/src/main/java/com/example/demo/domain/member/service/query/MemberQueryServiceImpl.java @@ -0,0 +1,15 @@ +package com.example.demo.domain.member.service.query; + +import com.example.demo.domain.member.exception.MemberException; +import com.example.demo.domain.member.exception.code.MemberErrorCode; +import com.example.demo.domain.test.exception.TestException; +import com.example.demo.domain.test.exception.code.TestErrorCode; + +public class MemberQueryServiceImpl implements MemberQueryService { + @Override + public void checkFlag(Long flag) { + if(flag==1){ + throw new MemberException(MemberErrorCode.NOT_FOUND); + } + } +} diff --git a/src/main/java/com/example/demo/domain/mission/controller/MissionController.java b/src/main/java/com/example/demo/domain/mission/controller/MissionController.java new file mode 100644 index 0000000..4d84dc4 --- /dev/null +++ b/src/main/java/com/example/demo/domain/mission/controller/MissionController.java @@ -0,0 +1,33 @@ +package com.example.demo.domain.mission.controller; + + +import com.example.demo.domain.member.entity.mapping.MemberMission; +import com.example.demo.domain.mission.converter.MemberMissionConverter; +import com.example.demo.domain.mission.dto.req.MissionReqDTO; +import com.example.demo.domain.mission.dto.res.MissionResDTO; +import com.example.demo.domain.mission.service.command.MissionCommandService; +import com.example.demo.global.apiPayload.ApiResponse; +import com.example.demo.global.apiPayload.code.GeneralSuccessCode; +import lombok.RequiredArgsConstructor; +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.RestController; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/missions") +public class MissionController { + + private final MissionCommandService missionCommandService; + + // 미션 목록에 추가 API + @PostMapping("/add") + public ApiResponse joinMission( + @RequestBody MissionReqDTO.MissionJoinDto request) { + + MemberMission memberMission = missionCommandService.joinMission(request); + GeneralSuccessCode code = GeneralSuccessCode.OK; + return ApiResponse.onSuccess(code,MemberMissionConverter.toJoinResultDto(memberMission)); + } +} diff --git a/src/main/java/com/example/demo/domain/mission/converter/MemberMissionConverter.java b/src/main/java/com/example/demo/domain/mission/converter/MemberMissionConverter.java new file mode 100644 index 0000000..5357a7a --- /dev/null +++ b/src/main/java/com/example/demo/domain/mission/converter/MemberMissionConverter.java @@ -0,0 +1,26 @@ +package com.example.demo.domain.mission.converter; + +import com.example.demo.domain.member.entity.Member; +import com.example.demo.domain.member.entity.mapping.MemberMission; +import com.example.demo.domain.mission.dto.res.MissionResDTO; +import com.example.demo.domain.mission.entity.Mission; + +import java.time.LocalDateTime; + +public class MemberMissionConverter { + + public static MemberMission toEntity(Member member, Mission mission) { + return MemberMission.builder() + .member(member) + .mission(mission) + .isComplete(false) // 초기엔 성공 안함 + .build(); + } + + public static MissionResDTO.MissionJoinResultDto toJoinResultDto(MemberMission memberMission) { + return MissionResDTO.MissionJoinResultDto.builder() + .memberMissionId(memberMission.getId()) + .createdAt(LocalDateTime.now()) + .build(); + } +} diff --git a/src/main/java/com/example/demo/domain/mission/dto/req/MissionReqDTO.java b/src/main/java/com/example/demo/domain/mission/dto/req/MissionReqDTO.java new file mode 100644 index 0000000..ea6b559 --- /dev/null +++ b/src/main/java/com/example/demo/domain/mission/dto/req/MissionReqDTO.java @@ -0,0 +1,15 @@ +package com.example.demo.domain.mission.dto.req; + +import lombok.Getter; +import org.antlr.v4.runtime.misc.NotNull; + +public class MissionReqDTO { + + @Getter + public static class MissionJoinDto { + @NotNull + private Long memberId; + @NotNull + private Long missionId; + } +} diff --git a/src/main/java/com/example/demo/domain/mission/dto/res/MissionResDTO.java b/src/main/java/com/example/demo/domain/mission/dto/res/MissionResDTO.java new file mode 100644 index 0000000..e28102e --- /dev/null +++ b/src/main/java/com/example/demo/domain/mission/dto/res/MissionResDTO.java @@ -0,0 +1,20 @@ +package com.example.demo.domain.mission.dto.res; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +public class MissionResDTO { + + @Builder + @Getter + @NoArgsConstructor + @AllArgsConstructor + public static class MissionJoinResultDto { + private Long memberMissionId; // 생성된 매핑 ID + private LocalDateTime createdAt; + } +} diff --git a/src/main/java/com/example/demo/domain/mission/exception/MissionException.java b/src/main/java/com/example/demo/domain/mission/exception/MissionException.java new file mode 100644 index 0000000..a459201 --- /dev/null +++ b/src/main/java/com/example/demo/domain/mission/exception/MissionException.java @@ -0,0 +1,14 @@ +package com.example.demo.domain.mission.exception; + +import com.example.demo.global.apiPayload.code.BaseErrorCode; +import com.example.demo.global.apiPayload.exception.GeneralException; + +public class MissionException extends GeneralException { + public MissionException(BaseErrorCode code) { + super(code); + } +} + + + + diff --git a/src/main/java/com/example/demo/domain/mission/exception/code/MissionErrorCode.java b/src/main/java/com/example/demo/domain/mission/exception/code/MissionErrorCode.java new file mode 100644 index 0000000..a413605 --- /dev/null +++ b/src/main/java/com/example/demo/domain/mission/exception/code/MissionErrorCode.java @@ -0,0 +1,26 @@ +package com.example.demo.domain.mission.exception.code; + +import com.example.demo.global.apiPayload.code.BaseErrorCode; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.http.HttpStatus; + + +@Getter +@AllArgsConstructor +public enum MissionErrorCode implements BaseErrorCode { + + NOT_FOUND(HttpStatus.NOT_FOUND, + "MISSION404_1", + "해당 미션을 찾지 못했습니다."), + ; + private final HttpStatus status; + private final String code; + private final String message; +} + + + + + + diff --git a/src/main/java/com/example/demo/domain/mission/exception/code/MissionSuccessCode.java b/src/main/java/com/example/demo/domain/mission/exception/code/MissionSuccessCode.java new file mode 100644 index 0000000..da1aac5 --- /dev/null +++ b/src/main/java/com/example/demo/domain/mission/exception/code/MissionSuccessCode.java @@ -0,0 +1,4 @@ +package com.example.demo.domain.mission.exception.code; + +public enum MissionSuccessCode { +} diff --git a/src/main/java/com/example/demo/domain/mission/repository/MemberMissionRepository.java b/src/main/java/com/example/demo/domain/mission/repository/MemberMissionRepository.java new file mode 100644 index 0000000..2fedef1 --- /dev/null +++ b/src/main/java/com/example/demo/domain/mission/repository/MemberMissionRepository.java @@ -0,0 +1,8 @@ +package com.example.demo.domain.mission.repository; + +import com.example.demo.domain.member.entity.mapping.MemberMission; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface MemberMissionRepository extends JpaRepository { + boolean existsByMemberIdAndMissionId(Long memberId, Long missionId); +} diff --git a/src/main/java/com/example/demo/domain/mission/service/command/MissionCommandService.java b/src/main/java/com/example/demo/domain/mission/service/command/MissionCommandService.java new file mode 100644 index 0000000..066af71 --- /dev/null +++ b/src/main/java/com/example/demo/domain/mission/service/command/MissionCommandService.java @@ -0,0 +1,8 @@ +package com.example.demo.domain.mission.service.command; + +import com.example.demo.domain.member.entity.mapping.MemberMission; +import com.example.demo.domain.mission.dto.req.MissionReqDTO; + +public interface MissionCommandService { + public MemberMission joinMission(MissionReqDTO.MissionJoinDto request); +} diff --git a/src/main/java/com/example/demo/domain/mission/service/command/MissionCommandServiceImpl.java b/src/main/java/com/example/demo/domain/mission/service/command/MissionCommandServiceImpl.java new file mode 100644 index 0000000..841171a --- /dev/null +++ b/src/main/java/com/example/demo/domain/mission/service/command/MissionCommandServiceImpl.java @@ -0,0 +1,48 @@ +package com.example.demo.domain.mission.service.command; + + +import com.example.demo.domain.member.entity.Member; +import com.example.demo.domain.member.entity.mapping.MemberMission; +import com.example.demo.domain.member.exception.MemberException; +import com.example.demo.domain.member.exception.code.MemberErrorCode; +import com.example.demo.domain.member.repository.MemberRepository; +import com.example.demo.domain.mission.converter.MemberMissionConverter; +import com.example.demo.domain.mission.dto.req.MissionReqDTO; +import com.example.demo.domain.mission.entity.Mission; +import com.example.demo.domain.mission.exception.MissionException; +import com.example.demo.domain.mission.exception.code.MissionErrorCode; +import com.example.demo.domain.mission.repository.MemberMissionRepository; +import com.example.demo.domain.mission.repository.MissionRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional +public class MissionCommandServiceImpl implements MissionCommandService { + + private final MissionRepository missionRepository; + private final MemberRepository memberRepository; + private final MemberMissionRepository memberMissionRepository; + + @Override + public MemberMission joinMission(MissionReqDTO.MissionJoinDto request) { + + // 1. 회원 존재 확인 + Member member = memberRepository.findById(request.getMemberId()) + .orElseThrow(() -> new MemberException(MemberErrorCode.NOT_FOUND)); + + // 2. 미션 존재 확인 + Mission mission = missionRepository.findById(request.getMissionId()) + .orElseThrow(() -> new MissionException(MissionErrorCode.NOT_FOUND)); + + // 3. 이미 도전 중인지 확인 -> 추가해야함 + + // 4. 매핑 엔티티 생성 및 저장 + MemberMission memberMission = MemberMissionConverter.toEntity(member, mission); + + return memberMissionRepository.save(memberMission); + } + +} diff --git a/src/main/java/com/example/demo/domain/review/controller/ReviewController.java b/src/main/java/com/example/demo/domain/review/controller/ReviewController.java index b17184e..56ffcdf 100644 --- a/src/main/java/com/example/demo/domain/review/controller/ReviewController.java +++ b/src/main/java/com/example/demo/domain/review/controller/ReviewController.java @@ -2,15 +2,15 @@ import com.example.demo.domain.review.converter.ReviewConverter; +import com.example.demo.domain.review.dto.req.ReviewReqDTO; import com.example.demo.domain.review.dto.res.ReviewResDTO; +import com.example.demo.domain.review.entity.Review; +import com.example.demo.domain.review.service.command.ReviewCommandService; import com.example.demo.domain.review.service.query.ReviewQueryService; import com.example.demo.global.apiPayload.ApiResponse; import com.example.demo.global.apiPayload.code.GeneralSuccessCode; import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import java.util.List; @@ -19,6 +19,7 @@ @RequestMapping("/reviews") public class ReviewController { private final ReviewQueryService reviewQueryService; + private final ReviewCommandService reviewCommandService; @GetMapping("/my") public ApiResponse> getMyReviews( @@ -44,5 +45,16 @@ public ApiResponse exception( } + @PostMapping("/post") + public ApiResponse createReview( + @RequestBody ReviewReqDTO.ReviewRegisterDTO request) { + + // 서비스 실행 + Review review = reviewCommandService.createReview(request); + GeneralSuccessCode code = GeneralSuccessCode.OK; + // 결과 반환 + return ApiResponse.onSuccess(code,ReviewConverter.toCreateResultDTO(review)); + } + } diff --git a/src/main/java/com/example/demo/domain/review/converter/ReviewConverter.java b/src/main/java/com/example/demo/domain/review/converter/ReviewConverter.java index 52f5863..cc8e0e8 100644 --- a/src/main/java/com/example/demo/domain/review/converter/ReviewConverter.java +++ b/src/main/java/com/example/demo/domain/review/converter/ReviewConverter.java @@ -1,8 +1,14 @@ package com.example.demo.domain.review.converter; +import com.example.demo.domain.member.entity.Member; +import com.example.demo.domain.review.dto.req.ReviewReqDTO; import com.example.demo.domain.review.dto.res.ReviewResDTO; +import com.example.demo.domain.review.entity.Review; +import com.example.demo.domain.store.entity.Store; import com.example.demo.domain.test.dto.res.TestResDTO; +import java.time.LocalDateTime; + public class ReviewConverter { public static ReviewResDTO.ErrorResult toExceptionDTO( @@ -12,4 +18,26 @@ public static ReviewResDTO.ErrorResult toExceptionDTO( .ReviewString(Reviewting) .build(); } + + + // 1. DTO -> Entity 변환 (DB 저장용) + public static Review toEntity(ReviewReqDTO.ReviewRegisterDTO request, Member member, Store store) { + return Review.builder() + .member(member) + .store(store) + .star(request.getScore()) + .content(request.getContent()) + .build(); + } + + // 2. Entity -> DTO 변환 (응답용) + public static ReviewResDTO.ReviewCreateResultDTO toCreateResultDTO(Review review) { + return ReviewResDTO.ReviewCreateResultDTO.builder() + .reviewId(review.getId()) + .createdAt(LocalDateTime.now()) + .build(); + } + + + } \ No newline at end of file diff --git a/src/main/java/com/example/demo/domain/review/dto/req/ReviewReqDTO.java b/src/main/java/com/example/demo/domain/review/dto/req/ReviewReqDTO.java new file mode 100644 index 0000000..fd3248d --- /dev/null +++ b/src/main/java/com/example/demo/domain/review/dto/req/ReviewReqDTO.java @@ -0,0 +1,20 @@ +package com.example.demo.domain.review.dto.req; + +import lombok.Getter; +import org.antlr.v4.runtime.misc.NotNull; + +public class ReviewReqDTO { + + @Getter + public static class ReviewRegisterDTO { + @NotNull + private Long memberId; // 리뷰 작성자 ID + @NotNull + private Long storeId; // 가게 ID + @NotNull + private Float score; // 별점 + @NotNull + private String content; // 리뷰 내용 + } +} + diff --git a/src/main/java/com/example/demo/domain/review/dto/res/ReviewResDTO.java b/src/main/java/com/example/demo/domain/review/dto/res/ReviewResDTO.java index 80125ad..32ccb3a 100644 --- a/src/main/java/com/example/demo/domain/review/dto/res/ReviewResDTO.java +++ b/src/main/java/com/example/demo/domain/review/dto/res/ReviewResDTO.java @@ -38,5 +38,15 @@ public static class ErrorResult{ } + @Builder + @Getter + public static class ReviewCreateResultDTO { + private Long reviewId; + private LocalDateTime createdAt; + } + + + + } diff --git a/src/main/java/com/example/demo/domain/review/service/command/ReviewCommandService.java b/src/main/java/com/example/demo/domain/review/service/command/ReviewCommandService.java new file mode 100644 index 0000000..a3c5d0d --- /dev/null +++ b/src/main/java/com/example/demo/domain/review/service/command/ReviewCommandService.java @@ -0,0 +1,10 @@ +package com.example.demo.domain.review.service.command; + +import com.example.demo.domain.review.dto.req.ReviewReqDTO; +import com.example.demo.domain.review.entity.Review; + +public interface ReviewCommandService { + + public Review createReview(ReviewReqDTO.ReviewRegisterDTO request); + +} diff --git a/src/main/java/com/example/demo/domain/review/service/command/ReviewCommandServiceImpl.java b/src/main/java/com/example/demo/domain/review/service/command/ReviewCommandServiceImpl.java new file mode 100644 index 0000000..fa2fae3 --- /dev/null +++ b/src/main/java/com/example/demo/domain/review/service/command/ReviewCommandServiceImpl.java @@ -0,0 +1,43 @@ +package com.example.demo.domain.review.service.command; + +import com.example.demo.domain.member.entity.Member; +import com.example.demo.domain.member.exception.MemberException; +import com.example.demo.domain.member.exception.code.MemberErrorCode; +import com.example.demo.domain.member.repository.MemberRepository; +import com.example.demo.domain.review.converter.ReviewConverter; +import com.example.demo.domain.review.dto.req.ReviewReqDTO; +import com.example.demo.domain.review.entity.Review; +import com.example.demo.domain.review.repository.ReviewRepository; +import com.example.demo.domain.store.entity.Store; +import com.example.demo.domain.store.exception.StoreException; +import com.example.demo.domain.store.exception.code.StoreErrorCode; +import com.example.demo.domain.store.repository.StoreRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional +public class ReviewCommandServiceImpl implements ReviewCommandService { + private final ReviewRepository reviewRepository; + private final MemberRepository memberRepository; + private final StoreRepository storeRepository; + + + @Override + public Review createReview(ReviewReqDTO.ReviewRegisterDTO request) { + + Member member = memberRepository.findById(request.getMemberId()) + .orElseThrow(() -> new MemberException(MemberErrorCode.NOT_FOUND)); + + Store store = storeRepository.findById(request.getStoreId()) + .orElseThrow(() -> new StoreException(StoreErrorCode.NOT_FOUND)); + + // 3. 리뷰 엔티티 생성 + Review review = ReviewConverter.toEntity(request, member, store); + + // 4. DB 저장 + return reviewRepository.save(review); + } +} diff --git a/src/main/java/com/example/demo/domain/store/exception/StoreException.java b/src/main/java/com/example/demo/domain/store/exception/StoreException.java new file mode 100644 index 0000000..7e6b2bc --- /dev/null +++ b/src/main/java/com/example/demo/domain/store/exception/StoreException.java @@ -0,0 +1,10 @@ +package com.example.demo.domain.store.exception; + +import com.example.demo.global.apiPayload.code.BaseErrorCode; +import com.example.demo.global.apiPayload.exception.GeneralException; + +public class StoreException extends GeneralException { + public StoreException(BaseErrorCode code) { + super(code); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/demo/domain/store/exception/code/StoreErrorCode.java b/src/main/java/com/example/demo/domain/store/exception/code/StoreErrorCode.java new file mode 100644 index 0000000..a059e4c --- /dev/null +++ b/src/main/java/com/example/demo/domain/store/exception/code/StoreErrorCode.java @@ -0,0 +1,24 @@ +package com.example.demo.domain.store.exception.code; + +import com.example.demo.global.apiPayload.code.BaseErrorCode; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.http.HttpStatus; + + +@Getter +@AllArgsConstructor +public enum StoreErrorCode implements BaseErrorCode { + + NOT_FOUND(HttpStatus.NOT_FOUND, + "MEMBER404_1", + "해당 가게를 찾지 못했습니다."), + ; + private final HttpStatus status; + private final String code; + private final String message; +} + + + + diff --git a/src/main/java/com/example/demo/domain/store/exception/code/StoreSuccessCode.java b/src/main/java/com/example/demo/domain/store/exception/code/StoreSuccessCode.java new file mode 100644 index 0000000..3f985e6 --- /dev/null +++ b/src/main/java/com/example/demo/domain/store/exception/code/StoreSuccessCode.java @@ -0,0 +1,19 @@ +package com.example.demo.domain.store.exception.code; + +import com.example.demo.global.apiPayload.code.BaseSuccessCode; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.http.HttpStatus; + + +@Getter +@AllArgsConstructor +public enum StoreSuccessCode implements BaseSuccessCode { + FOUND(HttpStatus.OK, + "STORE200_1", + "성공적으로 사용자를 조회했습니다."), + ; + private final HttpStatus status; + private final String code; + private final String message; +} diff --git a/src/main/java/com/example/demo/domain/store/repository/StoreRepository.java b/src/main/java/com/example/demo/domain/store/repository/StoreRepository.java new file mode 100644 index 0000000..8cea5d7 --- /dev/null +++ b/src/main/java/com/example/demo/domain/store/repository/StoreRepository.java @@ -0,0 +1,8 @@ +package com.example.demo.domain.store.repository; + +import com.example.demo.domain.store.entity.Store; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface StoreRepository extends JpaRepository { + +}