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..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 @@ -13,7 +13,7 @@ import org.springframework.web.bind.annotation.*; @RestController -@RequestMapping("/api/members") +@RequestMapping("/members") @RequiredArgsConstructor public class MemberController { @@ -29,6 +29,7 @@ public ResponseEntity memberLogin(@RequestBody GoogleLoginRequest reques } + /** * 회원가입 - 추가 정보 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..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 @@ -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 { + ResponseEntity memberLogin(GoogleLoginRequest request); -//import java.util.Optional; + void signUp(SignUpRequest signUpRequest, String memberUid); -@RequiredArgsConstructor -@Service + ResponseEntity 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)); - } + ResponseEntity 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..bc9659c2 --- /dev/null +++ b/backend/src/main/java/com/isp/backend/domain/member/service/MemberServiceImpl.java @@ -0,0 +1,138 @@ +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 ResponseEntity 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 ResponseEntity handleExistingMemberLogin(Member existingMember) { + String accessToken = tokenProvider.createAccessToken(existingMember.getUid()); + String refreshToken = tokenProvider.createRefreshToken(existingMember.getUid()); + return ResponseEntity.ok() + .header("Access-Token", accessToken) + .header("Refresh-Token", refreshToken) + .body("기존 회원 로그인"); + } + + + + + /** 신규 회원의 로그인 -> DB 저장 **/ + @Override + public ResponseEntity 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 ResponseEntity.status(HttpStatus.CREATED) + .header("Access-Token", accessToken) + .header("Refresh-Token", refreshToken) + .body("신규 회원 로그인"); + } + + + /** + * 회원가입 - 신규 유저의 경우 추가 정보 저장 + */ + @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/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/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..d7d96204 --- /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 +@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/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/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/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/**" }; 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}