Skip to content

Commit

Permalink
Merge pull request #17 from 9oormthon-univ/feature/#16
Browse files Browse the repository at this point in the history
[FEAT] 즐겨찾기 API 구현
  • Loading branch information
haeun1107 authored Nov 19, 2024
2 parents 936052e + aed7a40 commit 1594a9a
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package danpoong.soenter.domain.likes.controller;

import danpoong.soenter.base.ApiResponse;
import danpoong.soenter.domain.likes.dto.LikesDTO.LikesResponse.GetLikeResponse;
import danpoong.soenter.domain.likes.service.LikesService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/likes")
@RequiredArgsConstructor
@Tag(name = "Likes Controller", description = "즐겨찾기(좋아요) 관련 API")
public class LikesController {

private final LikesService likesService;

@PostMapping("/{enterpriseId}")
@Operation(summary = "즐겨찾기 추가 API", description = "특정 기업을 즐겨찾기에 추가합니다.")
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "COMMON200", description = "OK, 성공")
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "COMMON400", description = "잘못된 요청입니다.")
public ApiResponse<Void> addLike(@PathVariable Long enterpriseId, Authentication authentication) {
likesService.addLike(authentication.getName(), enterpriseId);
return ApiResponse.onSuccess(null);
}

@GetMapping
@Operation(summary = "즐겨찾기 조회 API", description = "사용자의 즐겨찾기 기업을 조회합니다.")
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "COMMON200", description = "OK, 성공")
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "COMMON400", description = "잘못된 요청입니다.")
public ApiResponse<List<GetLikeResponse>> getLikes(Authentication authentication) {
List<GetLikeResponse> response = likesService.getLikes(authentication.getName());
return ApiResponse.onSuccess(response);
}

@DeleteMapping("/{enterpriseId}")
@Operation(summary = "즐겨찾기 삭제 API", description = "특정 기업을 즐겨찾기에서 삭제합니다.")
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "COMMON200", description = "OK, 성공")
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "COMMON400", description = "잘못된 요청입니다.")
public ApiResponse<Void> removeLike(@PathVariable Long enterpriseId, Authentication authentication) {
likesService.removeLike(authentication.getName(), enterpriseId);
return ApiResponse.onSuccess(null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package danpoong.soenter.domain.likes.converter;

import danpoong.soenter.domain.enterprise.entity.Enterprise;
import danpoong.soenter.domain.likes.dto.LikesDTO.LikesResponse.GetLikeResponse;

public class LikesConverter {
public static GetLikeResponse toGetLikeResponse(Enterprise enterprise) {
return GetLikeResponse.builder()
.enterpriseId(enterprise.getEnterpriseId())
.enterpriseName(enterprise.getName())
.city(enterprise.getCity())
.district(enterprise.getDistrict())
.website(enterprise.getWebsite())
.build();
}
}
21 changes: 21 additions & 0 deletions src/main/java/danpoong/soenter/domain/likes/dto/LikesDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package danpoong.soenter.domain.likes.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

public class LikesDTO {

public static class LikesResponse {
@Getter
@Builder
public static class GetLikeResponse {
private Long enterpriseId;
private String enterpriseName;
private String city;
private String district;
private String website;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package danpoong.soenter.domain.likes.repository;

import danpoong.soenter.domain.enterprise.entity.Enterprise;
import danpoong.soenter.domain.likes.entity.Likes;
import danpoong.soenter.domain.user.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface LikesRepository extends JpaRepository<Likes, Long> {
List<Likes> findByUser(User user);
boolean existsByUserAndEnterprise(User user, Enterprise enterprise);
void deleteByUserAndEnterprise(User user, Enterprise enterprise);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package danpoong.soenter.domain.likes.service;

import danpoong.soenter.domain.likes.dto.LikesDTO.LikesResponse.GetLikeResponse;

import java.util.List;

public interface LikesService {
void addLike(String userId, Long enterpriseId);
List<GetLikeResponse> getLikes(String userId);
void removeLike(String userId, Long enterpriseId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package danpoong.soenter.domain.likes.service;

import danpoong.soenter.domain.enterprise.entity.Enterprise;
import danpoong.soenter.domain.enterprise.repository.EnterpriseRepository;
import danpoong.soenter.domain.likes.converter.LikesConverter;
import danpoong.soenter.domain.likes.dto.LikesDTO.LikesResponse.GetLikeResponse;
import danpoong.soenter.domain.likes.entity.Likes;
import danpoong.soenter.domain.likes.repository.LikesRepository;
import danpoong.soenter.domain.user.entity.User;
import danpoong.soenter.domain.user.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class LikesServiceImpl implements LikesService {

private final LikesRepository likesRepository;
private final UserRepository userRepository;
private final EnterpriseRepository enterpriseRepository;

@Transactional
public void addLike(String userId, Long enterpriseId) {
User user = userRepository.findById(Long.valueOf(userId))
.orElseThrow(() -> new RuntimeException("존재하지 않는 사용자입니다."));
Enterprise enterprise = enterpriseRepository.findById(enterpriseId)
.orElseThrow(() -> new RuntimeException("존재하지 않는 기업입니다."));

if (likesRepository.existsByUserAndEnterprise(user, enterprise)) {
throw new RuntimeException("이미 즐겨찾기에 추가된 기업입니다.");
}

Likes like = Likes.builder()
.user(user)
.enterprise(enterprise)
.build();

likesRepository.save(like);
}

@Transactional(readOnly = true)
public List<GetLikeResponse> getLikes(String userId) {
User user = userRepository.findById(Long.valueOf(userId))
.orElseThrow(() -> new RuntimeException("존재하지 않는 사용자입니다."));

List<Likes> likes = likesRepository.findByUser(user);

return likes.stream()
.map(like -> LikesConverter.toGetLikeResponse(like.getEnterprise()))
.collect(Collectors.toList());
}

@Transactional
public void removeLike(String userId, Long enterpriseId) {
User user = userRepository.findById(Long.valueOf(userId))
.orElseThrow(() -> new RuntimeException("존재하지 않는 사용자입니다."));
Enterprise enterprise = enterpriseRepository.findById(enterpriseId)
.orElseThrow(() -> new RuntimeException("존재하지 않는 기업입니다."));

likesRepository.deleteByUserAndEnterprise(user, enterprise);
}
}

0 comments on commit 1594a9a

Please sign in to comment.