diff --git a/src/main/java/store/itpick/backend/controller/DebateController.java b/src/main/java/store/itpick/backend/controller/DebateController.java index db083be..b68ead3 100644 --- a/src/main/java/store/itpick/backend/controller/DebateController.java +++ b/src/main/java/store/itpick/backend/controller/DebateController.java @@ -100,4 +100,14 @@ public BaseResponse> getDebateByKeyword( @RequestParam return new BaseResponse<>(debates); } + + @GetMapping("/recent") + public BaseResponse> getRecentViewedDebate(@RequestHeader("Authorization") String token) { + + String jwtToken = token.substring(7); + + List debateResponse = debateService.getRecentViewedDebate(jwtToken); + + return new BaseResponse<>(debateResponse); + } } diff --git a/src/main/java/store/itpick/backend/model/RecentViewedDebate.java b/src/main/java/store/itpick/backend/model/RecentViewedDebate.java new file mode 100644 index 0000000..b437811 --- /dev/null +++ b/src/main/java/store/itpick/backend/model/RecentViewedDebate.java @@ -0,0 +1,30 @@ +package store.itpick.backend.model; + +import jakarta.persistence.*; +import lombok.*; +import java.sql.Timestamp; + + +@Entity +@Table(name = "recent_viewed_debate") +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class RecentViewedDebate { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "recent_viewed_debate_id") + private Long id; + + @ManyToOne + @JoinColumn(name = "user_id", nullable = false) + private User user; + + @ManyToOne + @JoinColumn(name = "debate_id", nullable = false) + private Debate debate; + + @Column(name = "viewed_at", nullable = false) + private Timestamp viewedAt; +} diff --git a/src/main/java/store/itpick/backend/repository/RecentViewedDebateRepository.java b/src/main/java/store/itpick/backend/repository/RecentViewedDebateRepository.java new file mode 100644 index 0000000..93d656c --- /dev/null +++ b/src/main/java/store/itpick/backend/repository/RecentViewedDebateRepository.java @@ -0,0 +1,14 @@ +package store.itpick.backend.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; +import store.itpick.backend.model.RecentViewedDebate; + +import java.util.List; + +@Repository +public interface RecentViewedDebateRepository extends JpaRepository { + List findByUser_UserIdOrderByViewedAtDesc(Long userId); + +} + diff --git a/src/main/java/store/itpick/backend/service/DebateService.java b/src/main/java/store/itpick/backend/service/DebateService.java index 1b951eb..d532f8b 100644 --- a/src/main/java/store/itpick/backend/service/DebateService.java +++ b/src/main/java/store/itpick/backend/service/DebateService.java @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; +import java.util.stream.Collectors; import static store.itpick.backend.common.response.status.BaseExceptionResponseStatus.*; @@ -39,6 +40,7 @@ public class DebateService { private final VoteService voteService; private final JwtProvider jwtProvider; private final S3ImageBucketService s3ImageBucketService; + private final RecentViewedDebateRepository recentViewedDebateRepository; @Transactional public PostDebateResponse createDebate(PostDebateRequest postDebateRequest) { @@ -148,6 +150,11 @@ public GetDebateResponse getDebate(Long debateId, String token) { Debate debate = debateRepository.findById(debateId) .orElseThrow(() -> new DebateException(DEBATE_NOT_FOUND)); + + // 최근 본 토론 기록 생성 및 저장 + saveRecentViewedDebate(userId, debate); + + debate.setHits(debate.getHits() + 1); debateRepository.save(debate); @@ -224,7 +231,7 @@ public List GetDebatesByKeyword(Long keywordID, String sort) for (Debate debate : debates) { String title= debate.getTitle(); String content =debate.getContent(); - String mediaUrl =null; + String mediaUrl =debate.getImageUrl(); Long hit = debate.getHits(); Long comment = (long) debate.getComment().size(); debateList.add(new DebateByKeywordDTO(title,content,mediaUrl,hit,comment)); @@ -233,4 +240,39 @@ public List GetDebatesByKeyword(Long keywordID, String sort) return debateList; } + private void saveRecentViewedDebate(Long userId, Debate debate) { + User user = userRepository.findById(userId) + .orElseThrow(() -> new UserException(USER_NOT_FOUND)); + + RecentViewedDebate recentViewedDebate = new RecentViewedDebate(); + recentViewedDebate.setUser(user); + recentViewedDebate.setDebate(debate); + recentViewedDebate.setViewedAt(new Timestamp(System.currentTimeMillis())); // 시청 시간을 저장 + + recentViewedDebateRepository.save(recentViewedDebate); + } + + public List getRecentViewedDebate(String token){ + if (jwtProvider.isExpiredToken(token)) { + throw new JwtUnauthorizedTokenException(INVALID_TOKEN); + } + + Long userId = jwtProvider.getUserIdFromToken(token); + + List recentViewedDebates = recentViewedDebateRepository.findByUser_UserIdOrderByViewedAtDesc(userId); + + // Debate ID를 통해 Debate 엔티티를 조회 + List debateIds = recentViewedDebates.stream() + .map(recentViewedDebate -> recentViewedDebate.getDebate().getDebateId()) + .collect(Collectors.toList()); + + List debates = debateRepository.findAllById(debateIds); + + // Debate를 DTO로 변환 + return debates.stream() + .map(debate -> new DebateByKeywordDTO(debate.getTitle(), debate.getContent(), debate.getImageUrl(),debate.getHits(), (long) debate.getComment().size())) + .collect(Collectors.toList()); + + } + }