From 254bf60af454aff714d85086a01ec71842633fb5 Mon Sep 17 00:00:00 2001 From: Dayeon-Hong Date: Wed, 6 Mar 2024 00:09:48 +0900 Subject: [PATCH 1/2] =?UTF-8?q?fix=20:=20=ED=81=B4=EB=A6=B0=EC=BD=94?= =?UTF-8?q?=EB=93=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 큰 메소드들 분리하기 Repository에서 Optional으로 null Check 대신 따로 예외처리 조건문 사용하기 https://www.baeldung.com/java-optional api url 중복 -> yml prefix 설정 서비스와 서비스 impl 분리 Service와 ServiceImpl 분리 이유 : 참고글 1 , 참고글 2 --- .../gpt/controller/ChatGptController.java | 2 +- .../image/controller/ImageController.java | 2 +- .../member/controller/MemberController.java | 5 +- .../member/repository/MemberRepository.java | 7 +- .../domain/member/service/MemberService.java | 113 +--------- .../member/service/MemberServiceImpl.java | 130 ++++++++++++ .../receipt/controller/ReceiptController.java | 2 +- .../controller/ScheduleController.java | 18 +- .../repository/ScheduleRepository.java | 4 +- .../schedule/service/ScheduleService.java | 185 +--------------- .../schedule/service/ScheduleServiceImpl.java | 200 ++++++++++++++++++ .../isp/backend/global/s3/S3Controller.java | 2 +- .../security/CustomUserDetailsService.java | 6 +- backend/src/main/resources/application.yml | 4 + 14 files changed, 375 insertions(+), 305 deletions(-) create mode 100644 backend/src/main/java/com/isp/backend/domain/member/service/MemberServiceImpl.java create mode 100644 backend/src/main/java/com/isp/backend/domain/schedule/service/ScheduleServiceImpl.java diff --git a/backend/src/main/java/com/isp/backend/domain/gpt/controller/ChatGptController.java b/backend/src/main/java/com/isp/backend/domain/gpt/controller/ChatGptController.java index c801952d..273143cc 100644 --- a/backend/src/main/java/com/isp/backend/domain/gpt/controller/ChatGptController.java +++ b/backend/src/main/java/com/isp/backend/domain/gpt/controller/ChatGptController.java @@ -12,7 +12,7 @@ import org.springframework.web.bind.annotation.RestController; @RequiredArgsConstructor -@RequestMapping("api/chat-gpt") +@RequestMapping("/chat-gpt") @RestController public class ChatGptController { private final ChatGptService chatGptService; diff --git a/backend/src/main/java/com/isp/backend/domain/image/controller/ImageController.java b/backend/src/main/java/com/isp/backend/domain/image/controller/ImageController.java index 6a1741a3..c73b889a 100644 --- a/backend/src/main/java/com/isp/backend/domain/image/controller/ImageController.java +++ b/backend/src/main/java/com/isp/backend/domain/image/controller/ImageController.java @@ -5,7 +5,7 @@ import org.springframework.web.bind.annotation.RestController; @RestController -@RequestMapping("/api/images") +@RequestMapping("/images") @RequiredArgsConstructor public class ImageController { diff --git a/backend/src/main/java/com/isp/backend/domain/member/controller/MemberController.java b/backend/src/main/java/com/isp/backend/domain/member/controller/MemberController.java index 545bb526..247cfdd1 100644 --- a/backend/src/main/java/com/isp/backend/domain/member/controller/MemberController.java +++ b/backend/src/main/java/com/isp/backend/domain/member/controller/MemberController.java @@ -13,7 +13,7 @@ import org.springframework.web.bind.annotation.*; @RestController -@RequestMapping("/api/members") +@RequestMapping("/members") @RequiredArgsConstructor public class MemberController { @@ -24,11 +24,12 @@ public class MemberController { * 로그인 API */ @PostMapping("/login") - public ResponseEntity memberLogin(@RequestBody GoogleLoginRequest request) { + public String memberLogin(@RequestBody GoogleLoginRequest request) { return memberService.memberLogin(request); } + /** * 회원가입 - 추가 정보 API */ diff --git a/backend/src/main/java/com/isp/backend/domain/member/repository/MemberRepository.java b/backend/src/main/java/com/isp/backend/domain/member/repository/MemberRepository.java index 5ab04ee4..248e41bb 100644 --- a/backend/src/main/java/com/isp/backend/domain/member/repository/MemberRepository.java +++ b/backend/src/main/java/com/isp/backend/domain/member/repository/MemberRepository.java @@ -3,13 +3,12 @@ import com.isp.backend.domain.member.entity.Member; import org.springframework.data.jpa.repository.JpaRepository; -import java.util.Optional; - public interface MemberRepository extends JpaRepository { - Optional findByUidAndActivatedIsTrue(String Uid); + Member findByUidAndActivatedIsTrue(String Uid); - Optional findByUid(String Uid); + Member findByUid(String Uid); boolean existsByUid(String Uid); + } diff --git a/backend/src/main/java/com/isp/backend/domain/member/service/MemberService.java b/backend/src/main/java/com/isp/backend/domain/member/service/MemberService.java index f48b98b1..d8743687 100644 --- a/backend/src/main/java/com/isp/backend/domain/member/service/MemberService.java +++ b/backend/src/main/java/com/isp/backend/domain/member/service/MemberService.java @@ -5,117 +5,18 @@ import com.isp.backend.domain.member.dto.MemberDetailResponse; import com.isp.backend.domain.member.dto.SignUpRequest; import com.isp.backend.domain.member.entity.Member; -import com.isp.backend.domain.member.repository.MemberRepository; -import com.isp.backend.global.exception.member.AuthenticationFailedException; -import com.isp.backend.global.exception.member.MemberNotActivatedException; -import com.isp.backend.global.exception.member.MemberNotFoundException; -import com.isp.backend.global.jwt.TokenProvider; -import lombok.RequiredArgsConstructor; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import java.util.Optional; +public interface MemberService { + String memberLogin(GoogleLoginRequest request); -//import java.util.Optional; + void signUp(SignUpRequest signUpRequest, String memberUid); -@RequiredArgsConstructor -@Service + String handleExistingMemberLogin(Member existingMember); -public class MemberService { - - private final MemberRepository memberRepository; - private final TokenProvider tokenProvider; - - /** - * 로그인 메서드 - jwt 토큰 생성후 응답 - */ - @Transactional - public ResponseEntity memberLogin(GoogleLoginRequest request) { - Optional existingMember = memberRepository.findByUid(request.getUid()); - - if (existingMember.isPresent()) { - - Member activatedMember = existingMember - .filter(Member::isActivated) - .orElseThrow(MemberNotActivatedException::new); - - // 기존 회원의 로그인 - String accessToken = tokenProvider.createAccessToken(activatedMember.getUid()); - String refreshToken = tokenProvider.createRefreshToken(activatedMember.getUid()); - - return ResponseEntity.ok() - .header("Access-Token", accessToken) - .header("Refresh-Token", refreshToken) - .body("기존 회원 로그인"); - } else { - // 신규 회원의 로그인 - db 저장 - Member newMember = Member.builder() - .uid(request.getUid()) - .loginType("google") - .build(); - memberRepository.save(newMember); - - String accessToken = tokenProvider.createAccessToken(newMember.getUid()); - String refreshToken = tokenProvider.createRefreshToken(newMember.getUid()); - - return ResponseEntity.status(HttpStatus.CREATED) - .header("Access-Token", accessToken) - .header("Refresh-Token", refreshToken) - .body("신규 회원 로그인"); - } - - } - - - /** - * 회원가입 - 신규 유저의 경우 추가 정보 저장 - */ - @Transactional - public void signUp(SignUpRequest signUpRequest, String memberUid) { - Member member = memberRepository.findByUid(memberUid) - .orElseThrow(() -> new MemberNotFoundException()); - - signUpRequest.toEntity(member); - memberRepository.save(member); - } - - - /** - * 토큰 재발행 - */ - @Transactional - public ResponseEntity authRecreate(AuthRecreateRequest authRecreateRequest) { - - if (!tokenProvider.validateRefreshToken(authRecreateRequest.getRefreshToken())) { - throw new AuthenticationFailedException(); - } - String uid = tokenProvider.getUid(authRecreateRequest.getRefreshToken()); - Member member = memberRepository.findByUidAndActivatedIsTrue(uid) - .orElseThrow(MemberNotFoundException::new); - - String accessToken = tokenProvider.createAccessToken(member.getUid()); - String refreshToken = tokenProvider.createRefreshToken(member.getUid()); - - return ResponseEntity.ok() - .header("Access-Token", accessToken) - .header("Refresh-Token", refreshToken) - .body(null); - } - - - /** - * 멤버 정보 조회 - */ - @Transactional(readOnly = true) - public MemberDetailResponse getMemberInfo(String uid) { - - Member member = memberRepository.findByUid(uid) - .orElseThrow(MemberNotFoundException::new); - - return (MemberDetailResponse.fromEntity(member)); - } + String handleNewMemberLogin(GoogleLoginRequest request); + ResponseEntity authRecreate(AuthRecreateRequest authRecreateRequest); + MemberDetailResponse getMemberInfo(String uid); } diff --git a/backend/src/main/java/com/isp/backend/domain/member/service/MemberServiceImpl.java b/backend/src/main/java/com/isp/backend/domain/member/service/MemberServiceImpl.java new file mode 100644 index 00000000..d666db14 --- /dev/null +++ b/backend/src/main/java/com/isp/backend/domain/member/service/MemberServiceImpl.java @@ -0,0 +1,130 @@ +package com.isp.backend.domain.member.service; + +import com.isp.backend.domain.member.dto.AuthRecreateRequest; +import com.isp.backend.domain.member.dto.GoogleLoginRequest; +import com.isp.backend.domain.member.dto.MemberDetailResponse; +import com.isp.backend.domain.member.dto.SignUpRequest; +import com.isp.backend.domain.member.entity.Member; +import com.isp.backend.domain.member.repository.MemberRepository; +import com.isp.backend.global.exception.member.AuthenticationFailedException; +import com.isp.backend.global.exception.member.MemberNotActivatedException; +import com.isp.backend.global.exception.member.MemberNotFoundException; +import com.isp.backend.global.jwt.TokenProvider; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@RequiredArgsConstructor +@Transactional(readOnly = true) +@Service + +public class MemberServiceImpl implements MemberService { + + private final MemberRepository memberRepository; + private final TokenProvider tokenProvider; + + /** + * 로그인 메서드 - jwt 토큰 생성후 응답 + */ + @Transactional + @Override + public String memberLogin(GoogleLoginRequest request) { + Member existingMember = memberRepository.findByUid(request.getUid()); + + if (existingMember != null) { + if (existingMember.isActivated()) { + return handleExistingMemberLogin(existingMember); + } else { + throw new MemberNotActivatedException(); + } + } else { + return handleNewMemberLogin(request); + } + } + + + /** 기존 회원의 로그인 **/ + @Override + public String handleExistingMemberLogin(Member existingMember) { + String accessToken = tokenProvider.createAccessToken(existingMember.getUid()); + String refreshToken = tokenProvider.createRefreshToken(existingMember.getUid()); + return "기존 회원 로그인"; + } + + + + /** 신규 회원의 로그인 -> DB 저장 **/ + @Override + public String handleNewMemberLogin(GoogleLoginRequest request) { + Member newMember = Member.builder() + .uid(request.getUid()) + .loginType("google") + .build(); + memberRepository.save(newMember); + + String accessToken = tokenProvider.createAccessToken(newMember.getUid()); + String refreshToken = tokenProvider.createRefreshToken(newMember.getUid()); + + return "신규 회원 로그인"; + } + + + /** + * 회원가입 - 신규 유저의 경우 추가 정보 저장 + */ + @Transactional + @Override + public void signUp(SignUpRequest signUpRequest, String memberUid) { + Member findMember = memberRepository.findByUid(memberUid); + if (findMember == null) { + throw new MemberNotFoundException(); + } + + signUpRequest.toEntity(findMember); + memberRepository.save(findMember); + } + + + /** + * 토큰 재발행 + */ + @Transactional + @Override + public ResponseEntity authRecreate(AuthRecreateRequest authRecreateRequest) { + + if (!tokenProvider.validateRefreshToken(authRecreateRequest.getRefreshToken())) { + throw new AuthenticationFailedException(); + } + String uid = tokenProvider.getUid(authRecreateRequest.getRefreshToken()); + Member member = memberRepository.findByUidAndActivatedIsTrue(uid); + if (member == null) { + throw new MemberNotFoundException(); + } + String accessToken = tokenProvider.createAccessToken(member.getUid()); + String refreshToken = tokenProvider.createRefreshToken(member.getUid()); + + return ResponseEntity.ok() + .header("Access-Token", accessToken) + .header("Refresh-Token", refreshToken) + .body(null); + } + + + /** + * 멤버 정보 조회 + */ + @Override + public MemberDetailResponse getMemberInfo(String uid) { + + Member findMember = memberRepository.findByUid(uid); + if (findMember == null) { + throw new MemberNotFoundException(); + } + + return (MemberDetailResponse.fromEntity(findMember)); + } + + +} diff --git a/backend/src/main/java/com/isp/backend/domain/receipt/controller/ReceiptController.java b/backend/src/main/java/com/isp/backend/domain/receipt/controller/ReceiptController.java index b6bdfd89..afed05a8 100644 --- a/backend/src/main/java/com/isp/backend/domain/receipt/controller/ReceiptController.java +++ b/backend/src/main/java/com/isp/backend/domain/receipt/controller/ReceiptController.java @@ -5,7 +5,7 @@ import org.springframework.web.bind.annotation.RestController; @RestController -@RequestMapping("/api/receipts") +@RequestMapping("/receipts") @RequiredArgsConstructor public class ReceiptController { diff --git a/backend/src/main/java/com/isp/backend/domain/schedule/controller/ScheduleController.java b/backend/src/main/java/com/isp/backend/domain/schedule/controller/ScheduleController.java index bd4f4234..b3852f1a 100644 --- a/backend/src/main/java/com/isp/backend/domain/schedule/controller/ScheduleController.java +++ b/backend/src/main/java/com/isp/backend/domain/schedule/controller/ScheduleController.java @@ -4,7 +4,7 @@ import com.isp.backend.domain.schedule.dto.ScheduleRequestDTO; import com.isp.backend.domain.schedule.dto.ScheduleResponseDTO; import com.isp.backend.domain.schedule.dto.ScheduleSaveRequestDTO; -import com.isp.backend.domain.schedule.service.ScheduleService; +import com.isp.backend.domain.schedule.service.ScheduleServiceImpl; import com.isp.backend.global.security.CustomUserDetails; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; @@ -14,11 +14,11 @@ import java.util.List; @RestController -@RequestMapping("/api/schedules") +@RequestMapping("/schedules") @RequiredArgsConstructor public class ScheduleController { - private final ScheduleService scheduleService; + private final ScheduleServiceImpl scheduleServiceImpl; /** * 여행 일정 생성형 API @@ -26,7 +26,7 @@ public class ScheduleController { @PostMapping("/") public ResponseEntity createSchedule(@RequestBody ScheduleRequestDTO scheduleRequestDTO) { - ScheduleResponseDTO scheduleResponseDTO = scheduleService.createSchedule(scheduleRequestDTO); + ScheduleResponseDTO scheduleResponseDTO = scheduleServiceImpl.createSchedule(scheduleRequestDTO); return ResponseEntity.ok(scheduleResponseDTO); } @@ -37,7 +37,7 @@ public ResponseEntity createSchedule(@RequestBody ScheduleR @PostMapping("/save") public ResponseEntity saveSchedule(@AuthenticationPrincipal CustomUserDetails customUserDetails, @RequestBody ScheduleSaveRequestDTO requestDTO) { - scheduleService.saveSchedule(customUserDetails.getUsername(), requestDTO); + scheduleServiceImpl.saveSchedule(customUserDetails.getUsername(), requestDTO); return ResponseEntity.ok().build(); } @@ -48,7 +48,7 @@ public ResponseEntity saveSchedule(@AuthenticationPrincipal CustomUserDeta @GetMapping("/list") public ResponseEntity> getScheduleList(@AuthenticationPrincipal CustomUserDetails userDetails) { String uid = userDetails.getUsername(); - List scheduleList = scheduleService.getScheduleList(uid); + List scheduleList = scheduleServiceImpl.getScheduleList(uid); return ResponseEntity.ok(scheduleList); } @@ -59,7 +59,7 @@ public ResponseEntity> getScheduleList(@Authentica public ResponseEntity getScheduleDetail(@AuthenticationPrincipal CustomUserDetails userDetails, @PathVariable Long scheduleId) { String uid = userDetails.getUsername(); - ScheduleSaveRequestDTO scheduleDetail = scheduleService.getScheduleDetail(uid, scheduleId); + ScheduleSaveRequestDTO scheduleDetail = scheduleServiceImpl.getScheduleDetail(uid, scheduleId); return ResponseEntity.ok(scheduleDetail); } @@ -70,7 +70,7 @@ public ResponseEntity getScheduleDetail(@AuthenticationP public ResponseEntity deleteSchedule(@AuthenticationPrincipal CustomUserDetails userDetails, @PathVariable Long scheduleId) { String uid = userDetails.getUsername(); - scheduleService.deleteSchedule(uid, scheduleId); + scheduleServiceImpl.deleteSchedule(uid, scheduleId); return ResponseEntity.ok().build(); } @@ -82,7 +82,7 @@ public ResponseEntity deleteSchedule(@AuthenticationPrincipal CustomUserDe public ResponseEntity updateSchedule(@AuthenticationPrincipal CustomUserDetails userDetails, @PathVariable Long scheduleId, @RequestBody ScheduleSaveRequestDTO requestDTO) { - ScheduleSaveRequestDTO updatedSchedule = scheduleService.updateSchedule(userDetails.getUsername(), scheduleId, requestDTO); + ScheduleSaveRequestDTO updatedSchedule = scheduleServiceImpl.updateSchedule(userDetails.getUsername(), scheduleId, requestDTO); // return ResponseEntity.ok().build(); == public void로 return ResponseEntity.ok(updatedSchedule); } diff --git a/backend/src/main/java/com/isp/backend/domain/schedule/repository/ScheduleRepository.java b/backend/src/main/java/com/isp/backend/domain/schedule/repository/ScheduleRepository.java index 948fb907..17c69cb4 100644 --- a/backend/src/main/java/com/isp/backend/domain/schedule/repository/ScheduleRepository.java +++ b/backend/src/main/java/com/isp/backend/domain/schedule/repository/ScheduleRepository.java @@ -5,11 +5,9 @@ import org.springframework.data.jpa.repository.JpaRepository; import java.util.List; -import java.util.Optional; public interface ScheduleRepository extends JpaRepository { - // List findByMember(Member findmember); - Optional findByIdAndActivatedIsTrue(Long scheduleId); + Schedule findByIdAndActivatedIsTrue(Long scheduleId); List findByMemberAndActivatedIsTrue(Member findmember); } diff --git a/backend/src/main/java/com/isp/backend/domain/schedule/service/ScheduleService.java b/backend/src/main/java/com/isp/backend/domain/schedule/service/ScheduleService.java index de5ed1ff..a2a46963 100644 --- a/backend/src/main/java/com/isp/backend/domain/schedule/service/ScheduleService.java +++ b/backend/src/main/java/com/isp/backend/domain/schedule/service/ScheduleService.java @@ -1,197 +1,32 @@ package com.isp.backend.domain.schedule.service; import com.isp.backend.domain.country.entity.Country; -import com.isp.backend.domain.country.repository.CountryRepository; import com.isp.backend.domain.member.entity.Member; -import com.isp.backend.domain.member.repository.MemberRepository; import com.isp.backend.domain.schedule.dto.ScheduleListResponseDTO; import com.isp.backend.domain.schedule.dto.ScheduleRequestDTO; import com.isp.backend.domain.schedule.dto.ScheduleResponseDTO; import com.isp.backend.domain.schedule.dto.ScheduleSaveRequestDTO; import com.isp.backend.domain.schedule.entity.Schedule; -import com.isp.backend.domain.schedule.mapper.ScheduleMapper; -import com.isp.backend.domain.schedule.repository.ScheduleRepository; -import com.isp.backend.domain.scheduleDetail.entity.ScheduleDetail; -import com.isp.backend.domain.scheduleDetail.repository.ScheduleDetailRepository; -import com.isp.backend.global.exception.member.MemberNotFoundException; -import com.isp.backend.global.exception.schedule.CountryNotFoundException; -import com.isp.backend.global.exception.schedule.NotYourScheduleException; -import com.isp.backend.global.exception.schedule.ScheduleNotFoundException; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; import java.util.List; -import java.util.stream.Collectors; -@Slf4j -@RequiredArgsConstructor -@Service -public class ScheduleService { +public interface ScheduleService { - private final ScheduleRepository scheduleRepository; - private final ScheduleDetailRepository scheduleDetailRepository; - private final CountryRepository countryRepository; - private final MemberRepository memberRepository; - private final ScheduleMapper scheduleMapper; + void saveSchedule(String uid, ScheduleSaveRequestDTO scheduleSaveRequestDTO); + List getScheduleList(String uid); - /** - * 여행 일정 생성형 API - */ - @Transactional - public ScheduleResponseDTO createSchedule(ScheduleRequestDTO scheduleRequestDTO) { - // 프롬프트 생성하고 - // schedule 일정 생성하기 openai 써서 - return null; - } + ScheduleSaveRequestDTO getScheduleDetail(String uid, Long scheduleId); + void deleteSchedule(String uid, Long scheduleId); - /** - * 여행 일정 저장 API - */ - @Transactional - public void saveSchedule(String uid, ScheduleSaveRequestDTO scheduleSaveRequestDTO) { - // 유저 정보 확인 - Member findmember = memberRepository.findByUid(uid) - .orElseThrow(MemberNotFoundException::new); + ScheduleSaveRequestDTO updateSchedule(String uid, Long scheduleId, ScheduleSaveRequestDTO updateRequestDTO); - // 여행할 국가 확인 - Country findCountry = countryRepository.findIdByCity(scheduleSaveRequestDTO.getCountry()); - if (findCountry == null) { - throw new CountryNotFoundException(); - } + void calculateTotalPrice(Schedule schedule); - // 여행 일정 저장 - Schedule schedule = scheduleMapper.toSchedulesEntity(scheduleSaveRequestDTO, findmember, findCountry); - - // 여행 전체 일정 총 경비 저장 - calculateTotalPrice(schedule); - - scheduleRepository.save(schedule); - } - - - /** - * 여행 일정 목록 조회 API - */ - @Transactional(readOnly = true) - public List getScheduleList(String uid) { - // 유저 정보 확인 - Member findmember = memberRepository.findByUid(uid) - .orElseThrow(MemberNotFoundException::new); - - // 내가 쓴 일정 불러오기 - List scheduleList = scheduleRepository.findByMemberAndActivatedIsTrue(findmember); - - return scheduleList.stream() - .map(scheduleMapper::toScheduleListResponseDTO) - .collect(Collectors.toList()); - } - - - /** - * 여행 일정 상세 조회 API - */ - @Transactional(readOnly = true) - public ScheduleSaveRequestDTO getScheduleDetail(String uid, Long scheduleId) { - // 유저 정보 확인 - Member findmember = memberRepository.findByUid(uid) - .orElseThrow(MemberNotFoundException::new); - - // 여행 일정 확인 - Schedule findSchedule = scheduleRepository.findByIdAndActivatedIsTrue(scheduleId) - .orElseThrow(ScheduleNotFoundException::new); - - return scheduleMapper.toScheduleResponseDTO(findSchedule); - } - - - /** - * 여행 일정 삭제 API - */ - @Transactional - public void deleteSchedule(String uid, Long scheduleId) { - // 유저 정보 확인 - Member findmember = memberRepository.findByUid(uid) - .orElseThrow(MemberNotFoundException::new); - - // 여행 일정 확인 - Schedule findSchedule = scheduleRepository.findByIdAndActivatedIsTrue(scheduleId) - .orElseThrow(ScheduleNotFoundException::new); - - // 자신의 여행 일정인지 확인 - if (!findSchedule.getMember().equals(findmember)) { - throw new NotYourScheduleException(); - } - - // ScheduleDetail 테이블 데이터 삭제 - scheduleDetailRepository.deleteBySchedule(findSchedule); - - // Schedule 테이블의 activated 값을 false로 설정하여 삭제 표시 - findSchedule.setActivated(false); - scheduleRepository.save(findSchedule); - } - - - /** - * 여행 일정 수정 API - */ - @Transactional - public ScheduleSaveRequestDTO updateSchedule(String uid, Long scheduleId, ScheduleSaveRequestDTO updateRequestDTO) { - // 유저 정보 확인 - Member findMember = memberRepository.findByUid(uid) - .orElseThrow(MemberNotFoundException::new); - - // 여행 일정 확인 - Schedule findSchedule = scheduleRepository.findByIdAndActivatedIsTrue(scheduleId) - .orElseThrow(ScheduleNotFoundException::new); - - // 자신의 여행 일정인지 확인 - if (!findSchedule.getMember().equals(findMember)) { - throw new NotYourScheduleException(); - } - - // 여행할 국가 확인 - Country findCountry = countryRepository.findIdByCity(updateRequestDTO.getCountry()); - if (findCountry == null) { - throw new CountryNotFoundException(); - } - - // 기존 일정 세부 정보 삭제 - scheduleDetailRepository.deleteBySchedule(findSchedule); - - // 기존의 일정 엔티티를 수정 - findSchedule.setScheduleName(updateRequestDTO.getScheduleName()); - findSchedule.setCountry(findCountry); - findSchedule.setStartDate(updateRequestDTO.getStartDate()); - findSchedule.setEndDate(updateRequestDTO.getEndDate()); - - // 새로운 일정 세부 정보 추가 - List scheduleDetails = scheduleMapper.updateSchedulesEntity(updateRequestDTO, findSchedule); - findSchedule.setScheduleDetails(scheduleDetails); - - // 여행 전체 일정 총 경비 재계산 - calculateTotalPrice(findSchedule); - - // 수정된 일정 엔티티 저장 - scheduleRepository.save(findSchedule); - - // 수정된 일정을 반환 -- 없애도 됨 public void fh - return updateRequestDTO; - } - - - /* - * 여행 일정 총 경비 계산 - */ - private void calculateTotalPrice(Schedule schedule) { - double totalPrice = schedule.getScheduleDetails().stream() - .mapToDouble(ScheduleDetail::getBudget) - .sum(); - schedule.setTotalPrice(totalPrice); - } + Member validateUserCheck(String uid); + Schedule validateSchedule(Long scheduleId); + Country validateCountry(String countryName); } diff --git a/backend/src/main/java/com/isp/backend/domain/schedule/service/ScheduleServiceImpl.java b/backend/src/main/java/com/isp/backend/domain/schedule/service/ScheduleServiceImpl.java new file mode 100644 index 00000000..a13bf10e --- /dev/null +++ b/backend/src/main/java/com/isp/backend/domain/schedule/service/ScheduleServiceImpl.java @@ -0,0 +1,200 @@ +package com.isp.backend.domain.schedule.service; + +import com.isp.backend.domain.country.entity.Country; +import com.isp.backend.domain.country.repository.CountryRepository; +import com.isp.backend.domain.member.entity.Member; +import com.isp.backend.domain.member.repository.MemberRepository; +import com.isp.backend.domain.schedule.dto.ScheduleListResponseDTO; +import com.isp.backend.domain.schedule.dto.ScheduleRequestDTO; +import com.isp.backend.domain.schedule.dto.ScheduleResponseDTO; +import com.isp.backend.domain.schedule.dto.ScheduleSaveRequestDTO; +import com.isp.backend.domain.schedule.entity.Schedule; +import com.isp.backend.domain.schedule.mapper.ScheduleMapper; +import com.isp.backend.domain.schedule.repository.ScheduleRepository; +import com.isp.backend.domain.scheduleDetail.entity.ScheduleDetail; +import com.isp.backend.domain.scheduleDetail.repository.ScheduleDetailRepository; +import com.isp.backend.global.exception.member.MemberNotFoundException; +import com.isp.backend.global.exception.schedule.CountryNotFoundException; +import com.isp.backend.global.exception.schedule.NotYourScheduleException; +import com.isp.backend.global.exception.schedule.ScheduleNotFoundException; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.stream.Collectors; + +@Slf4j +@RequiredArgsConstructor +@Transactional(readOnly = true) +@Service +public class ScheduleServiceImpl implements ScheduleService { + + private final ScheduleRepository scheduleRepository; + private final ScheduleDetailRepository scheduleDetailRepository; + private final CountryRepository countryRepository; + private final MemberRepository memberRepository; + private final ScheduleMapper scheduleMapper; + + + /** + * 여행 일정 생성형 API + */ + @Transactional + public ScheduleResponseDTO createSchedule(ScheduleRequestDTO scheduleRequestDTO) { + // 프롬프트 생성하고 + // schedule 일정 생성하기 openai 써서 + return null; + } + + + /** + * 여행 일정 저장 API + */ + @Transactional + @Override + public void saveSchedule(String uid, ScheduleSaveRequestDTO scheduleSaveRequestDTO) { + Member findMember = validateUserCheck(uid); + Country findCountry = validateCountry(scheduleSaveRequestDTO.getCountry()); + // 여행 일정 저장 + Schedule schedule = scheduleMapper.toSchedulesEntity(scheduleSaveRequestDTO, findMember, findCountry); + // 여행 전체 일정 총 경비 저장 + calculateTotalPrice(schedule); + + scheduleRepository.save(schedule); + } + + + /** + * 여행 일정 목록 조회 API + */ + @Override + public List getScheduleList(String uid) { + Member findMember = validateUserCheck(uid); + // 내가 쓴 일정 불러오기 + List scheduleList = scheduleRepository.findByMemberAndActivatedIsTrue(findMember); + + return scheduleList.stream() + .map(scheduleMapper::toScheduleListResponseDTO) + .collect(Collectors.toList()); + } + + + /** + * 여행 일정 상세 조회 API + */ + @Override + public ScheduleSaveRequestDTO getScheduleDetail(String uid, Long scheduleId) { + Member findMember = validateUserCheck(uid); + Schedule findSchedule = validateSchedule(scheduleId); + + return scheduleMapper.toScheduleResponseDTO(findSchedule); + } + + + /** + * 여행 일정 삭제 API + */ + @Transactional + @Override + public void deleteSchedule(String uid, Long scheduleId) { + Member findMember = validateUserCheck(uid); + Schedule findSchedule = validateSchedule(scheduleId); + + // 자신의 여행 일정인지 확인 + if (!findSchedule.getMember().equals(findMember)) { + throw new NotYourScheduleException(); + } + + // ScheduleDetail 테이블 데이터 삭제 + scheduleDetailRepository.deleteBySchedule(findSchedule); + findSchedule.setActivated(false); + + scheduleRepository.save(findSchedule); + } + + + /** + * 여행 일정 수정 API + */ + @Transactional + @Override + public ScheduleSaveRequestDTO updateSchedule(String uid, Long scheduleId, ScheduleSaveRequestDTO updateRequestDTO) { + Member findMember = validateUserCheck(uid); + Country findCountry = validateCountry(updateRequestDTO.getCountry()); + Schedule findSchedule = validateSchedule(scheduleId); + + // 자신의 여행 일정인지 확인 + if (!findSchedule.getMember().equals(findMember)) { + throw new NotYourScheduleException(); + } + + scheduleDetailRepository.deleteBySchedule(findSchedule); + + // 기존의 일정 엔티티를 수정 + findSchedule.setScheduleName(updateRequestDTO.getScheduleName()); + findSchedule.setCountry(findCountry); + findSchedule.setStartDate(updateRequestDTO.getStartDate()); + findSchedule.setEndDate(updateRequestDTO.getEndDate()); + + // 새로운 일정 세부 정보 추가 + List scheduleDetails = scheduleMapper.updateSchedulesEntity(updateRequestDTO, findSchedule); + findSchedule.setScheduleDetails(scheduleDetails); + + // 총경비 재 계산 후 저장 + calculateTotalPrice(findSchedule); + scheduleRepository.save(findSchedule); + + // 수정된 일정을 반환 -- 없애도 됨 public void fh + return updateRequestDTO; + } + + + /** 여행 일정 총 경비 계산 **/ + @Override + public void calculateTotalPrice(Schedule schedule) { + double totalPrice = schedule.getScheduleDetails().stream() + .mapToDouble(ScheduleDetail::getBudget) + .sum(); + schedule.setTotalPrice(totalPrice); + } + + + /** 유저 정보 확인 **/ + @Override + public Member validateUserCheck(String uid) { + Member findMember = memberRepository.findByUid(uid); + if (findMember == null) { + throw new MemberNotFoundException(); + } + return findMember; + } + + + /** 여행 일정 검증 **/ + @Override + public Schedule validateSchedule(Long scheduleId) { + // 여행 일정 찾기 + Schedule findSchedule = scheduleRepository.findByIdAndActivatedIsTrue(scheduleId); + if (findSchedule == null) { + throw new ScheduleNotFoundException(); + } + return findSchedule; + } + + + /** 여행 국가 검증 **/ + @Override + public Country validateCountry(String countryName) { + Country findCountry = countryRepository.findIdByCity(countryName); + if (findCountry == null) { + throw new CountryNotFoundException(); + } + return findCountry; + } + + + + +} diff --git a/backend/src/main/java/com/isp/backend/global/s3/S3Controller.java b/backend/src/main/java/com/isp/backend/global/s3/S3Controller.java index 16dd31a6..4872ecac 100644 --- a/backend/src/main/java/com/isp/backend/global/s3/S3Controller.java +++ b/backend/src/main/java/com/isp/backend/global/s3/S3Controller.java @@ -12,7 +12,7 @@ @RequiredArgsConstructor @RestController -@RequestMapping("/api") +@RequestMapping public class S3Controller { private final S3Service s3Service; diff --git a/backend/src/main/java/com/isp/backend/global/security/CustomUserDetailsService.java b/backend/src/main/java/com/isp/backend/global/security/CustomUserDetailsService.java index 0917215f..dc0e0932 100644 --- a/backend/src/main/java/com/isp/backend/global/security/CustomUserDetailsService.java +++ b/backend/src/main/java/com/isp/backend/global/security/CustomUserDetailsService.java @@ -19,8 +19,10 @@ public class CustomUserDetailsService implements UserDetailsService { public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { // 유저 찾기 - Member member = memberRepository.findByUid(username) - .orElseThrow(MemberNotFoundException::new); + Member member = memberRepository.findByUid(username); + if (member == null) { + throw new MemberNotFoundException(); + } return new CustomUserDetails(member); diff --git a/backend/src/main/resources/application.yml b/backend/src/main/resources/application.yml index 256dc452..e4922ee4 100644 --- a/backend/src/main/resources/application.yml +++ b/backend/src/main/resources/application.yml @@ -11,6 +11,10 @@ spring: username: ${DB_USERNAME} password: ${DB_PASSWORD} +server: + servlet: + context-path: /api + jwt: secret: ${JWT_SECRET_KEY} From 6207311cc45f003f9945bd59213bb89ef05cb125 Mon Sep 17 00:00:00 2001 From: Dayeon-Hong Date: Sat, 9 Mar 2024 01:35:24 +0900 Subject: [PATCH 2/2] =?UTF-8?q?hotfix=20:=20DB=20+=20=EB=AA=A8=EB=93=88?= =?UTF-8?q?=ED=99=94=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../member/controller/MemberController.java | 2 +- .../domain/member/service/MemberService.java | 6 +++--- .../member/service/MemberServiceImpl.java | 20 +++++++++++++------ .../domain/schedule/entity/Schedule.java | 7 ------- .../schedule/service/ScheduleServiceImpl.java | 2 +- .../scheduleDetail/entity/ScheduleDetail.java | 2 +- .../global/security/WebSecurityConfig.java | 3 ++- 7 files changed, 22 insertions(+), 20 deletions(-) diff --git a/backend/src/main/java/com/isp/backend/domain/member/controller/MemberController.java b/backend/src/main/java/com/isp/backend/domain/member/controller/MemberController.java index 247cfdd1..9ee62b51 100644 --- a/backend/src/main/java/com/isp/backend/domain/member/controller/MemberController.java +++ b/backend/src/main/java/com/isp/backend/domain/member/controller/MemberController.java @@ -24,7 +24,7 @@ public class MemberController { * 로그인 API */ @PostMapping("/login") - public String memberLogin(@RequestBody GoogleLoginRequest request) { + public ResponseEntity memberLogin(@RequestBody GoogleLoginRequest request) { return memberService.memberLogin(request); } diff --git a/backend/src/main/java/com/isp/backend/domain/member/service/MemberService.java b/backend/src/main/java/com/isp/backend/domain/member/service/MemberService.java index d8743687..0837d8ec 100644 --- a/backend/src/main/java/com/isp/backend/domain/member/service/MemberService.java +++ b/backend/src/main/java/com/isp/backend/domain/member/service/MemberService.java @@ -8,13 +8,13 @@ import org.springframework.http.ResponseEntity; public interface MemberService { - String memberLogin(GoogleLoginRequest request); + ResponseEntity memberLogin(GoogleLoginRequest request); void signUp(SignUpRequest signUpRequest, String memberUid); - String handleExistingMemberLogin(Member existingMember); + ResponseEntity handleExistingMemberLogin(Member existingMember); - String handleNewMemberLogin(GoogleLoginRequest request); + ResponseEntity handleNewMemberLogin(GoogleLoginRequest request); ResponseEntity authRecreate(AuthRecreateRequest authRecreateRequest); diff --git a/backend/src/main/java/com/isp/backend/domain/member/service/MemberServiceImpl.java b/backend/src/main/java/com/isp/backend/domain/member/service/MemberServiceImpl.java index d666db14..bc9659c2 100644 --- a/backend/src/main/java/com/isp/backend/domain/member/service/MemberServiceImpl.java +++ b/backend/src/main/java/com/isp/backend/domain/member/service/MemberServiceImpl.java @@ -30,7 +30,7 @@ public class MemberServiceImpl implements MemberService { */ @Transactional @Override - public String memberLogin(GoogleLoginRequest request) { + public ResponseEntity memberLogin(GoogleLoginRequest request) { Member existingMember = memberRepository.findByUid(request.getUid()); if (existingMember != null) { @@ -45,19 +45,24 @@ public String memberLogin(GoogleLoginRequest request) { } + /** 기존 회원의 로그인 **/ @Override - public String handleExistingMemberLogin(Member existingMember) { + public ResponseEntity handleExistingMemberLogin(Member existingMember) { String accessToken = tokenProvider.createAccessToken(existingMember.getUid()); String refreshToken = tokenProvider.createRefreshToken(existingMember.getUid()); - return "기존 회원 로그인"; + return ResponseEntity.ok() + .header("Access-Token", accessToken) + .header("Refresh-Token", refreshToken) + .body("기존 회원 로그인"); } + /** 신규 회원의 로그인 -> DB 저장 **/ @Override - public String handleNewMemberLogin(GoogleLoginRequest request) { + public ResponseEntity handleNewMemberLogin(GoogleLoginRequest request) { Member newMember = Member.builder() .uid(request.getUid()) .loginType("google") @@ -67,7 +72,10 @@ public String handleNewMemberLogin(GoogleLoginRequest request) { String accessToken = tokenProvider.createAccessToken(newMember.getUid()); String refreshToken = tokenProvider.createRefreshToken(newMember.getUid()); - return "신규 회원 로그인"; + return ResponseEntity.status(HttpStatus.CREATED) + .header("Access-Token", accessToken) + .header("Refresh-Token", refreshToken) + .body("신규 회원 로그인"); } @@ -99,6 +107,7 @@ public ResponseEntity authRecreate(AuthRecreateRequest authRecreateReque } String uid = tokenProvider.getUid(authRecreateRequest.getRefreshToken()); Member member = memberRepository.findByUidAndActivatedIsTrue(uid); + if (member == null) { throw new MemberNotFoundException(); } @@ -122,7 +131,6 @@ public MemberDetailResponse getMemberInfo(String uid) { if (findMember == null) { throw new MemberNotFoundException(); } - return (MemberDetailResponse.fromEntity(findMember)); } diff --git a/backend/src/main/java/com/isp/backend/domain/schedule/entity/Schedule.java b/backend/src/main/java/com/isp/backend/domain/schedule/entity/Schedule.java index 2ebae473..e05a00dc 100644 --- a/backend/src/main/java/com/isp/backend/domain/schedule/entity/Schedule.java +++ b/backend/src/main/java/com/isp/backend/domain/schedule/entity/Schedule.java @@ -52,12 +52,5 @@ public class Schedule extends BaseEntity { @Column(nullable = false) private boolean activated = true; -// // setScheduleDetails 메서드 추가 -// public void setScheduleDetails(List scheduleDetails) { -// this.scheduleDetails.clear(); -// if (scheduleDetails != null) { -// this.scheduleDetails.addAll(scheduleDetails); -// } -// } } diff --git a/backend/src/main/java/com/isp/backend/domain/schedule/service/ScheduleServiceImpl.java b/backend/src/main/java/com/isp/backend/domain/schedule/service/ScheduleServiceImpl.java index a13bf10e..d7d96204 100644 --- a/backend/src/main/java/com/isp/backend/domain/schedule/service/ScheduleServiceImpl.java +++ b/backend/src/main/java/com/isp/backend/domain/schedule/service/ScheduleServiceImpl.java @@ -27,7 +27,7 @@ @Slf4j @RequiredArgsConstructor -@Transactional(readOnly = true) +@Transactional @Service public class ScheduleServiceImpl implements ScheduleService { diff --git a/backend/src/main/java/com/isp/backend/domain/scheduleDetail/entity/ScheduleDetail.java b/backend/src/main/java/com/isp/backend/domain/scheduleDetail/entity/ScheduleDetail.java index e276882e..962b4995 100644 --- a/backend/src/main/java/com/isp/backend/domain/scheduleDetail/entity/ScheduleDetail.java +++ b/backend/src/main/java/com/isp/backend/domain/scheduleDetail/entity/ScheduleDetail.java @@ -36,7 +36,7 @@ public class ScheduleDetail { // Schedules 엔티티의 필드를 참조하도록 수정 @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(nullable = false) + @JoinColumn(name = "schedule_id" , nullable = false) private Schedule schedule; } diff --git a/backend/src/main/java/com/isp/backend/global/security/WebSecurityConfig.java b/backend/src/main/java/com/isp/backend/global/security/WebSecurityConfig.java index 8369d9ed..f1b9815c 100644 --- a/backend/src/main/java/com/isp/backend/global/security/WebSecurityConfig.java +++ b/backend/src/main/java/com/isp/backend/global/security/WebSecurityConfig.java @@ -25,8 +25,9 @@ public class WebSecurityConfig { private static final String[] AUTH_WHITE_LIST = { + "/members/login", "/api/members/login", - "/api/members/test", + "/members/test", "/error", "/h2-console/**" };