Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/me/bar")
Expand All @@ -30,4 +27,14 @@ public RsData<MyBarListResponseDto> getMyBarList(
MyBarListResponseDto body = myBarService.getMyBar(userId, page, pageSize);
return RsData.successOf(body); // code=200, message="success"
}

/** 킵 추가(생성/복원/재킵) */
@PostMapping("/{cocktailId}/keep")
public RsData<Void> keep(
@AuthenticationPrincipal(expression = "id") Long userId,
@PathVariable Long cocktailId
) {
myBarService.keep(userId, cocktailId);
return RsData.of(201, "kept"); // Aspect가 HTTP 201로 설정
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public class MyBarItemResponseDto {
private String cocktailName;
private String imageUrl;
private LocalDateTime createdAt;
private LocalDateTime keptAt;

public static MyBarItemResponseDto from(MyBar m) {
return MyBarItemResponseDto.builder()
Expand All @@ -22,6 +23,7 @@ public static MyBarItemResponseDto from(MyBar m) {
.cocktailName(m.getCocktail().getCocktailName())
.imageUrl(m.getCocktail().getCocktailImgUrl())
.createdAt(m.getCreatedAt())
.keptAt(m.getKeptAt())
.build();
}
}
4 changes: 4 additions & 0 deletions src/main/java/com/back/domain/mybar/entity/MyBar.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ public class MyBar {
@CreatedDate
private LocalDateTime createdAt;

/** 최근에 '킵'된 시각(생성/복원/재킵 시 갱신) — 목록 정렬에 사용 */
@Column(name = "kept_at", nullable = false)
private LocalDateTime keptAt;

/** 킵 해제 시각 (ACTIVE일 때는 null) */
private LocalDateTime deletedAt;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,19 @@
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.Optional;

@Repository
public interface MyBarRepository extends JpaRepository<MyBar, Long> {
/** 나만의 bar(킵) 목록: ACTIVE만, id desc */
Page<MyBar> findByUserIdAndStatusOrderByIdDesc(Long userId, KeepStatus status, Pageable pageable);
Page<MyBar> findByUser_IdAndStatusOrderByKeptAtDescIdDesc(Long userId, KeepStatus status, Pageable pageable);

/** 프로필/요약용: ACTIVE 개수 */
long countByUserIdAndStatus(Long userId, KeepStatus status);
long countByUser_IdAndStatus(Long userId, KeepStatus status);

/** 현재 킵 상태 확인(아이콘 등): ACTIVE 존재 여부 */
boolean existsByUser_IdAndCocktail_CocktailIdAndStatus(Long userId, Long cocktailId, KeepStatus status);

/** 복원/재킵을 위해 status 무시하고 한 건 찾기 (없으면 Optional.empty) */
Optional<MyBar> findByUser_IdAndCocktail_CocktailId(Long userId, Long cocktailId);
}
37 changes: 36 additions & 1 deletion src/main/java/com/back/domain/mybar/service/MyBarService.java
Original file line number Diff line number Diff line change
@@ -1,28 +1,34 @@
package com.back.domain.mybar.service;

import com.back.domain.cocktail.repository.CocktailRepository;
import com.back.domain.mybar.dto.MyBarItemResponseDto;
import com.back.domain.mybar.dto.MyBarListResponseDto;
import com.back.domain.mybar.entity.MyBar;
import com.back.domain.mybar.enums.KeepStatus;
import com.back.domain.mybar.repository.MyBarRepository;
import com.back.domain.user.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Service
@RequiredArgsConstructor
public class MyBarService {

private final MyBarRepository myBarRepository;
private final UserRepository userRepository;
private final CocktailRepository cocktailRepository;

@Transactional(readOnly = true)
public MyBarListResponseDto getMyBar(Long userId, int page, int pageSize) {
Page<MyBar> myBarPage = myBarRepository.findByUserIdAndStatusOrderByIdDesc(userId, KeepStatus.ACTIVE, PageRequest.of(page, pageSize));
Page<MyBar> myBarPage = myBarRepository.findByUser_IdAndStatusOrderByKeptAtDescIdDesc(userId, KeepStatus.ACTIVE, PageRequest.of(page, pageSize));

List<MyBar> myBars = myBarPage.getContent();
List<MyBarItemResponseDto> items = new ArrayList<>();
Expand All @@ -33,4 +39,33 @@ public MyBarListResponseDto getMyBar(Long userId, int page, int pageSize) {

return new MyBarListResponseDto(items, hasNext, nextPage);
}

@Transactional
public void keep(Long userId, Long cocktailId) {
Optional<MyBar> existingMyBar =
myBarRepository.findByUser_IdAndCocktail_CocktailId(userId, cocktailId);

LocalDateTime now = LocalDateTime.now();

if (existingMyBar.isPresent()) {
// 이미 행이 있으면: 최근에 다시 킵했다고 보고 keptAt만 갱신
MyBar myBar = existingMyBar.get();
myBar.setKeptAt(now);
if (myBar.getStatus() == KeepStatus.DELETED) {
// 해제돼 있던 건 복원
myBar.setStatus(KeepStatus.ACTIVE);
myBar.setDeletedAt(null);
}
return; // 이미 ACTIVE여도 keptAt 갱신으로 충분
}

// 없으면 새로 생성
MyBar myBar = new MyBar();
myBar.setUser(userRepository.getReferenceById(userId));
myBar.setCocktail(cocktailRepository.getReferenceById(cocktailId));
myBar.setStatus(KeepStatus.ACTIVE);
myBar.setKeptAt(now);

myBarRepository.save(myBar);
}
}