diff --git a/src/main/java/com/umc/hackaton/snapspot/savespot/controller/SaveSpotController.java b/src/main/java/com/umc/hackaton/snapspot/savespot/controller/SaveSpotController.java index f9c02ce..0262fef 100644 --- a/src/main/java/com/umc/hackaton/snapspot/savespot/controller/SaveSpotController.java +++ b/src/main/java/com/umc/hackaton/snapspot/savespot/controller/SaveSpotController.java @@ -1,4 +1,54 @@ package com.umc.hackaton.snapspot.savespot.controller; +import com.umc.hackaton.snapspot.savespot.dto.SpotSaveReqeustDto; +import com.umc.hackaton.snapspot.savespot.dto.SpotSaveResponseDto; +import com.umc.hackaton.snapspot.savespot.service.SpotSaveService; +import com.umc.hackaton.snapspot.savespot.service.UserFolderService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/v1/savespot") +@Slf4j public class SaveSpotController { + + private final SpotSaveService spotSaveService; + private final UserFolderService userFolderService; + + @PostMapping + public ResponseEntity saveSpotSave(@RequestBody SpotSaveReqeustDto spotSaveRequestDto) { + try { + spotSaveService.save(spotSaveRequestDto); + return ResponseEntity.ok().body("Userfolder에 Spot 저장 성공"); + } catch (Exception e) { + log.error("스팟 저장에 실패하였습니다.", e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Userfolder에 Spot 저장에 실패하였습니다."); + } + } + + @DeleteMapping + public ResponseEntity deleteSpotSave(@RequestParam Long spotSaveId) { + try { + spotSaveService.delete(spotSaveId); + return ResponseEntity.ok().body("Userfolder에 Spot 삭제 성공"); + } catch (Exception e) { + log.info("스팟 삭제에 실패하였습니다.", e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Userfolder에 Spot 삭제에 실패하였습니다."); + } + } + + @GetMapping("/{id}") + public ResponseEntity getSpotSave(@PathVariable("id") Long id) { + try { + SpotSaveResponseDto spotSaveList = spotSaveService.getSpotsByFolderId(id); + return ResponseEntity.ok().body(spotSaveList); + } catch (Exception e) { + log.info("스팟 조회에 실패하였습니다.", e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Userfolder에 Spot 조회에 실패하였습니다."); + } + } } diff --git a/src/main/java/com/umc/hackaton/snapspot/savespot/dto/SpotSaveReqeustDto.java b/src/main/java/com/umc/hackaton/snapspot/savespot/dto/SpotSaveReqeustDto.java new file mode 100644 index 0000000..55b353a --- /dev/null +++ b/src/main/java/com/umc/hackaton/snapspot/savespot/dto/SpotSaveReqeustDto.java @@ -0,0 +1,22 @@ +package com.umc.hackaton.snapspot.savespot.dto; + +import com.umc.hackaton.snapspot.savespot.entity.SpotSave; +import com.umc.hackaton.snapspot.savespot.entity.UserFolder; +import com.umc.hackaton.snapspot.spot.entity.Spot; +import jakarta.validation.constraints.NotNull; +import lombok.Builder; +import lombok.Getter; + +@Getter +public class SpotSaveReqeustDto { + @NotNull private Long folderId; + @NotNull private Long spotId; + + @Builder + public SpotSave toEntity(UserFolder userFolder, Spot spot){ + return SpotSave.builder() + .userFolder(userFolder) + .spot(spot) + .build(); + } +} diff --git a/src/main/java/com/umc/hackaton/snapspot/savespot/dto/SpotSaveResponseDto.java b/src/main/java/com/umc/hackaton/snapspot/savespot/dto/SpotSaveResponseDto.java new file mode 100644 index 0000000..7c0fcf9 --- /dev/null +++ b/src/main/java/com/umc/hackaton/snapspot/savespot/dto/SpotSaveResponseDto.java @@ -0,0 +1,23 @@ +package com.umc.hackaton.snapspot.savespot.dto; + +import com.umc.hackaton.snapspot.spot.entity.Spot; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Builder +@Getter +@Setter +public class SpotSaveResponseDto { + private Long folderId; + private List spots; + + public static SpotSaveResponseDto fromEntity(Long folderId, List spots) { + return SpotSaveResponseDto.builder() + .folderId(folderId) + .spots(spots) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/umc/hackaton/snapspot/savespot/entity/SpotSave.java b/src/main/java/com/umc/hackaton/snapspot/savespot/entity/SpotSave.java new file mode 100644 index 0000000..acda4f1 --- /dev/null +++ b/src/main/java/com/umc/hackaton/snapspot/savespot/entity/SpotSave.java @@ -0,0 +1,30 @@ +package com.umc.hackaton.snapspot.savespot.entity; + +import com.umc.hackaton.snapspot.config.entity.BaseEntity; +import com.umc.hackaton.snapspot.spot.entity.Spot; +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class SpotSave extends BaseEntity { + + @Id + @GeneratedValue(strategy = jakarta.persistence.GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.EAGER) + @JoinColumn(name = "userfolder_id") + private UserFolder userFolder; + + @ManyToOne(fetch = FetchType.EAGER) + @JoinColumn(name = "spot_id") + private Spot spot; + +} diff --git a/src/main/java/com/umc/hackaton/snapspot/savespot/repository/SpotSaveRepository.java b/src/main/java/com/umc/hackaton/snapspot/savespot/repository/SpotSaveRepository.java new file mode 100644 index 0000000..437e1e7 --- /dev/null +++ b/src/main/java/com/umc/hackaton/snapspot/savespot/repository/SpotSaveRepository.java @@ -0,0 +1,11 @@ +package com.umc.hackaton.snapspot.savespot.repository; + +import com.umc.hackaton.snapspot.savespot.dto.SpotSaveResponseDto; +import com.umc.hackaton.snapspot.savespot.entity.SpotSave; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface SpotSaveRepository extends JpaRepository { + List findAllByUserFolder_Id(Long userFolderId); +} diff --git a/src/main/java/com/umc/hackaton/snapspot/savespot/repository/UserFolderRepository.java b/src/main/java/com/umc/hackaton/snapspot/savespot/repository/UserFolderRepository.java index f7dc6ab..30114d7 100644 --- a/src/main/java/com/umc/hackaton/snapspot/savespot/repository/UserFolderRepository.java +++ b/src/main/java/com/umc/hackaton/snapspot/savespot/repository/UserFolderRepository.java @@ -1,10 +1,12 @@ package com.umc.hackaton.snapspot.savespot.repository; import com.umc.hackaton.snapspot.savespot.entity.UserFolder; +import com.umc.hackaton.snapspot.user.entity.User; import org.springframework.data.jpa.repository.JpaRepository; import java.util.List; public interface UserFolderRepository extends JpaRepository { List findAllByUserIdAndIsDeletedFalse(Long userId); + UserFolder findByUser(User user); } diff --git a/src/main/java/com/umc/hackaton/snapspot/savespot/service/SpotSaveService.java b/src/main/java/com/umc/hackaton/snapspot/savespot/service/SpotSaveService.java new file mode 100644 index 0000000..3f4b5b8 --- /dev/null +++ b/src/main/java/com/umc/hackaton/snapspot/savespot/service/SpotSaveService.java @@ -0,0 +1,53 @@ +package com.umc.hackaton.snapspot.savespot.service; + +import com.umc.hackaton.snapspot.savespot.dto.SpotSaveReqeustDto; +import com.umc.hackaton.snapspot.savespot.dto.SpotSaveResponseDto; +import com.umc.hackaton.snapspot.savespot.entity.SpotSave; +import com.umc.hackaton.snapspot.savespot.entity.UserFolder; +import com.umc.hackaton.snapspot.savespot.repository.SpotSaveRepository; +import com.umc.hackaton.snapspot.savespot.repository.UserFolderRepository; +import com.umc.hackaton.snapspot.spot.entity.Spot; +import com.umc.hackaton.snapspot.spot.repository.SpotRepository; +import com.umc.hackaton.snapspot.user.entity.User; +import com.umc.hackaton.snapspot.user.repository.UserRepository; +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.stream.Collectors; + +@RequiredArgsConstructor +@Service +public class SpotSaveService { + + private final SpotSaveRepository spotSaveRepository; + private final UserFolderRepository userFolderRepository; + private final SpotRepository spotRepository; + private final UserRepository userRepository; + + @Transactional + public SpotSaveResponseDto save(SpotSaveReqeustDto dto) { + UserFolder userFolder = userFolderRepository.findById(dto.getFolderId()) + .orElseThrow(() -> new IllegalArgumentException("Invalid folder ID")); + Spot spot = spotRepository.findById(dto.getSpotId()) + .orElseThrow(() -> new IllegalArgumentException("Invalid spot ID")); + SpotSave spotSave = dto.toEntity(userFolder, spot); + SpotSave savedSpotSave = spotSaveRepository.save(spotSave); + return SpotSaveResponseDto.fromEntity(userFolder.getId(), List.of(spot)); + } + + @Transactional + public void delete(Long spotSaveId) { + spotSaveRepository.deleteById(spotSaveId); + } + + @Transactional + public SpotSaveResponseDto getSpotsByFolderId(Long folderId) { + List spotSaves = spotSaveRepository.findAllByUserFolder_Id(folderId); + List spots = spotSaves.stream() + .map(SpotSave::getSpot) + .collect(Collectors.toList()); + return SpotSaveResponseDto.fromEntity(folderId, spots); + } +} diff --git a/src/main/java/com/umc/hackaton/snapspot/savespot/service/UserFolderService.java b/src/main/java/com/umc/hackaton/snapspot/savespot/service/UserFolderService.java index e7dc67e..2fd838b 100644 --- a/src/main/java/com/umc/hackaton/snapspot/savespot/service/UserFolderService.java +++ b/src/main/java/com/umc/hackaton/snapspot/savespot/service/UserFolderService.java @@ -1,8 +1,11 @@ package com.umc.hackaton.snapspot.savespot.service; import com.umc.hackaton.snapspot.savespot.dto.UserFolderRequestDto; +import com.umc.hackaton.snapspot.savespot.entity.SpotSave; import com.umc.hackaton.snapspot.savespot.entity.UserFolder; +import com.umc.hackaton.snapspot.savespot.repository.SpotSaveRepository; import com.umc.hackaton.snapspot.savespot.repository.UserFolderRepository; +import com.umc.hackaton.snapspot.spot.entity.Spot; import com.umc.hackaton.snapspot.user.entity.User; import com.umc.hackaton.snapspot.user.repository.UserRepository; import lombok.RequiredArgsConstructor; @@ -10,12 +13,14 @@ import org.springframework.transaction.annotation.Transactional; import java.util.List; +import java.util.stream.Collectors; @Service @RequiredArgsConstructor public class UserFolderService { private final UserFolderRepository userFolderRepository; private final UserRepository userRepository; + private final SpotSaveRepository spotSaveRepository; @Transactional public void save(UserFolderRequestDto userFolder) { @@ -39,4 +44,11 @@ public UserFolder update(Long folderId, UserFolderRequestDto userFolderRequestDt public List getAllFoldersByUserId(Long userId) { return userFolderRepository.findAllByUserIdAndIsDeletedFalse(userId); } + + public List getSpotsByFolderId(Long folderId) { + List spotSaves = spotSaveRepository.findAllByUserFolder_Id(folderId); + return spotSaves.stream() + .map(SpotSave::getSpot) + .collect(Collectors.toList()); + } } diff --git a/src/main/java/com/umc/hackaton/snapspot/spot/controller/SpotController.java b/src/main/java/com/umc/hackaton/snapspot/spot/controller/SpotController.java index 4d22abb..ef88f25 100644 --- a/src/main/java/com/umc/hackaton/snapspot/spot/controller/SpotController.java +++ b/src/main/java/com/umc/hackaton/snapspot/spot/controller/SpotController.java @@ -6,12 +6,10 @@ import com.umc.hackaton.snapspot.spot.service.SpotService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; -import java.util.List; @RequiredArgsConstructor @RestController @@ -23,15 +21,21 @@ public class SpotController { private final SpotService spotService; @PostMapping - public ResponseEntity upload(@RequestBody SpotRequestDto dto){ + public ResponseEntity upload(@RequestBody SpotRequestDto dto) { try { - spotService.upload(dto); - return ResponseEntity.ok().body("스팟 업로드 성공."); + Spot spot = spotService.upload(dto); + return ResponseEntity.ok().body(spot); } catch (Exception e) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("스팟 업로드에 실패하였습니다."); } } + @GetMapping("/list/{spotId}") + public Spot getSpotById(@PathVariable Long spotId) { + return spotService.getSpotById(spotId); + + } + @GetMapping("/{spotId}") public ResponseEntity showSpot( @PathVariable("spotId") Long spotId @@ -39,7 +43,7 @@ public ResponseEntity showSpot( try { Spot spot = spotService.getSpot(spotId); return ResponseEntity.ok().body(spot); - } catch (Exception e){ + } catch (Exception e) { log.info("스팟 조회에 실패하였습니다.", e); return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("스팟 조회에 실패하였습니다."); } @@ -52,13 +56,12 @@ public ResponseEntity deleteSpot( try { spotService.deleteSpot(spotId); return ResponseEntity.ok().body("success"); - } catch (Exception e){ + } catch (Exception e) { log.info("스팟 삭제에 실패하였습니다.", e); return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("스팟 삭제에 실패하였습니다."); } } - @PatchMapping("/{spotId}") public ResponseEntity patchSpot( @PathVariable("spotId") Long spotId, @@ -67,14 +70,19 @@ public ResponseEntity patchSpot( try { Spot spot = spotService.updateSpot(spotId, dto); return ResponseEntity.ok().body(spot); - } catch (Exception e){ + } catch (Exception e) { log.info("스팟 수정에 실패하였습니다.", e); return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("스팟 수정에 실패하였습니다."); } } - @GetMapping("list") - public ResponseEntity> readNearSpotList(@RequestParam("latitude") double latitude, @RequestParam("logitude") double logitude){ - return ResponseEntity.ok(spotService.readNearSpotList(latitude, logitude)); + public ResponseEntity> readNearSpotList(@RequestParam("latitude") double latitude, @RequestParam("longitude") double longitude){ + return ResponseEntity.ok(spotService.readNearSpotList(latitude, longitude)); } + + @GetMapping("list/category") + public ResponseEntity> readCategoryNearSpotList(@RequestParam("latitude") double latitude, @RequestParam("longitude") double longitude, @RequestParam("categoryId") Long categoryId){ + List list = spotService.readNearSpotList(latitude, longitude); + return ResponseEntity.ok(spotService.readCategoryNearSpotList(list, categoryId)); + } } diff --git a/src/main/java/com/umc/hackaton/snapspot/spot/entity/Spot.java b/src/main/java/com/umc/hackaton/snapspot/spot/entity/Spot.java index d07a61b..3cd75ef 100644 --- a/src/main/java/com/umc/hackaton/snapspot/spot/entity/Spot.java +++ b/src/main/java/com/umc/hackaton/snapspot/spot/entity/Spot.java @@ -34,7 +34,7 @@ public class Spot extends BaseEntity { @Column(name = "longitude", nullable = false) private Double longitude; - @Column(name = "img_url", nullable = false) + @Column(name = "img_url", nullable = false, length = 1000) private String imgUrl; @Column(name = "like_num") diff --git a/src/main/java/com/umc/hackaton/snapspot/spot/repository/SpotRepository.java b/src/main/java/com/umc/hackaton/snapspot/spot/repository/SpotRepository.java index 8bc7629..a033ccc 100644 --- a/src/main/java/com/umc/hackaton/snapspot/spot/repository/SpotRepository.java +++ b/src/main/java/com/umc/hackaton/snapspot/spot/repository/SpotRepository.java @@ -7,7 +7,6 @@ import org.springframework.data.repository.query.Param; import java.util.List; -import java.util.Optional; public interface SpotRepository extends JpaRepository { List findAllByUser(User user); diff --git a/src/main/java/com/umc/hackaton/snapspot/spot/service/SpotService.java b/src/main/java/com/umc/hackaton/snapspot/spot/service/SpotService.java index 0bfafb5..dcd003f 100644 --- a/src/main/java/com/umc/hackaton/snapspot/spot/service/SpotService.java +++ b/src/main/java/com/umc/hackaton/snapspot/spot/service/SpotService.java @@ -9,13 +9,11 @@ import com.umc.hackaton.snapspot.spot.dto.SpotRequestDto; import com.umc.hackaton.snapspot.spot.dto.SpotResponseDto; import com.umc.hackaton.snapspot.spot.entity.Spot; -import com.umc.hackaton.snapspot.user.entity.User; import com.umc.hackaton.snapspot.spot.repository.SpotRepository; +import com.umc.hackaton.snapspot.user.entity.User; import com.umc.hackaton.snapspot.user.repository.UserRepository; import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import java.util.ArrayList; @@ -31,7 +29,7 @@ public class SpotService { private final CategorySpotRepository categorySpotRepository; @Transactional - public void upload(SpotRequestDto dto) { + public Spot upload(SpotRequestDto dto) { User user = userRepository.findUserById(dto.getUserId()); @@ -59,7 +57,14 @@ public void upload(SpotRequestDto dto) { // CategorySpot 저장 categorySpotRepository.saveAll(categorySpots); + return savedSpot; + } + @Transactional + public Spot getSpotById(Long spotId) { + // spotId를 사용하여 Repository를 통해 Spot을 가져옴 + return spotRepository.findById(spotId) + .orElseThrow(() -> new RuntimeException("Spot not found with id: " + spotId)); } public Spot getSpot(Long spotId) {