Skip to content

Commit abce677

Browse files
authored
Merge pull request #93 from HaruHan-Mail/feat(90)
Feat(90)
2 parents d39c2c3 + 5688144 commit abce677

File tree

10 files changed

+208
-2
lines changed

10 files changed

+208
-2
lines changed

Dockerfile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,8 @@ ARG JAR_FILE=./build/libs/*-SNAPSHOT.jar
44

55
COPY ${JAR_FILE} haruhan.jar
66

7-
ENTRYPOINT ["java", "-jar", "/haruhan.jar"]
7+
# 시스템 시간대 설정
8+
ENV TZ=Asia/Seoul
9+
10+
# JVM 시간대 설정
11+
ENTRYPOINT ["java", "-Duser.timezone=Asia/Seoul", "-jar", "/haruhan.jar"]

src/main/java/com/haruhan/common/error/repository/ContentRepository.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,16 @@
22

33
import com.haruhan.common.error.entity.Content;
44
import org.springframework.data.jpa.repository.JpaRepository;
5+
import org.springframework.data.jpa.repository.Query;
6+
import org.springframework.data.repository.query.Param;
7+
8+
import java.util.List;
59

610
public interface ContentRepository extends JpaRepository<Content, Long> {
7-
}
11+
12+
@Query("SELECT c FROM Content c ORDER BY c.bookmark_count DESC LIMIT 3")
13+
List<Content> findTop5ByBookmarkCount();
14+
15+
@Query("SELECT c FROM Content c WHERE c.content_id <= :end ORDER BY c.content_id ASC")
16+
List<Content> findUpToLastContent(@Param("end") Long lastContentId);
17+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.haruhan.content.controller;
2+
3+
import com.haruhan.common.error.StatusCode;
4+
import com.haruhan.common.error.dto.Message;
5+
import com.haruhan.content.dto.ContentResDto;
6+
import com.haruhan.content.service.ContentService;
7+
import lombok.RequiredArgsConstructor;
8+
import org.springframework.http.ResponseEntity;
9+
import org.springframework.web.bind.annotation.*;
10+
11+
import java.util.List;
12+
13+
@RestController
14+
@RequestMapping("/api/content")
15+
@RequiredArgsConstructor
16+
@CrossOrigin
17+
public class ContentController {
18+
19+
private final ContentService contentService;
20+
21+
@GetMapping("/mine/{email}")
22+
public ResponseEntity<Message> getUserReceivedContent(@PathVariable String email) {
23+
List<ContentResDto> contentList = contentService.getUserReceivedContent(email);
24+
return ResponseEntity.ok(new Message(StatusCode.OK, contentList));
25+
}
26+
27+
@GetMapping("/top5")
28+
public ResponseEntity<Message> getTop5BookmarkedContent() {
29+
List<ContentResDto> top5Content = contentService.getTop5BookmarkedContent();
30+
return ResponseEntity.ok(new Message(StatusCode.OK, top5Content));
31+
}
32+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.haruhan.content.dto;
2+
3+
import java.util.List;
4+
5+
//사용자가 받은 컨텐츠 정보를 응답하는 DTO
6+
public record ContentResDto(
7+
Long id,
8+
String title,
9+
String summary,
10+
List<String> background,
11+
List<String> importance,
12+
List<String> tip,
13+
List<String> additionalResources
14+
) {}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.haruhan.content.entity;
2+
3+
import com.haruhan.common.error.entity.Content;
4+
import com.haruhan.user.entity.User;
5+
import jakarta.persistence.*;
6+
import lombok.Getter;
7+
import lombok.NoArgsConstructor;
8+
9+
import java.time.LocalDateTime;
10+
11+
@Entity
12+
@Getter
13+
@NoArgsConstructor
14+
@Table(name = "user_received_content")
15+
public class UserReceivedContent {
16+
17+
@Id
18+
@GeneratedValue(strategy = GenerationType.IDENTITY)
19+
private Long id;
20+
21+
@ManyToOne
22+
@JoinColumn(name = "user_id", nullable = false)
23+
private User user; // 사용자를 참조
24+
25+
@ManyToOne
26+
@JoinColumn(name = "content_id", nullable = false)
27+
private Content content; // 받은 컨텐츠를 참조
28+
29+
@Column(name = "received_at", nullable = false)
30+
private LocalDateTime receivedAt; // 받은 날짜
31+
32+
public UserReceivedContent(User user, Content content) {
33+
this.user = user;
34+
this.content = content;
35+
this.receivedAt = LocalDateTime.now();
36+
}
37+
}
38+
39+
//id를 pk로 할지, 복합키 쓸지 고민중
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.haruhan.content.repository;
2+
3+
import com.haruhan.content.entity.UserReceivedContent;
4+
import com.haruhan.user.entity.User;
5+
import org.springframework.data.jpa.repository.JpaRepository;
6+
import org.springframework.stereotype.Repository;
7+
8+
import java.util.List;
9+
10+
@Repository
11+
public interface UserReceivedContentRepository extends JpaRepository<UserReceivedContent, Long> {
12+
13+
List<UserReceivedContent> findByUser(User user);
14+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.haruhan.content.service;
2+
3+
import com.haruhan.content.dto.ContentResDto;
4+
5+
import java.util.List;
6+
7+
public interface ContentService {
8+
9+
List<ContentResDto> getUserReceivedContent(String email);
10+
List<ContentResDto> getTop5BookmarkedContent();
11+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package com.haruhan.content.service;
2+
3+
import com.haruhan.common.error.CustomException;
4+
import com.haruhan.common.error.StatusCode;
5+
import com.haruhan.common.error.entity.Content;
6+
import com.haruhan.common.error.repository.ContentRepository;
7+
import com.haruhan.content.dto.ContentResDto;
8+
import com.haruhan.user.entity.User;
9+
import com.haruhan.user.repository.UserRepository;
10+
import jakarta.transaction.Transactional;
11+
import lombok.RequiredArgsConstructor;
12+
import org.springframework.stereotype.Service;
13+
14+
import java.util.Arrays;
15+
import java.util.List;
16+
import java.util.stream.Collectors;
17+
18+
@Service
19+
@Transactional
20+
@RequiredArgsConstructor
21+
public class ContentServiceImpl implements ContentService {
22+
23+
private final UserRepository userRepository;
24+
private final ContentRepository contentRepository;
25+
26+
@Override
27+
public List<ContentResDto> getUserReceivedContent(String email) {
28+
User user = userRepository.findByEmail(email)
29+
.orElseThrow(() -> new CustomException(StatusCode.NOT_FOUND_USER));
30+
31+
Long lastContentId = user.getLastReceivedContentId();
32+
33+
if (lastContentId == null || lastContentId < 1) {
34+
throw new CustomException(StatusCode.NOT_FOUND);
35+
}
36+
37+
List<Content> contentList = contentRepository.findUpToLastContent(lastContentId);
38+
39+
return contentList.stream()
40+
.map(this::convertToDto)
41+
.collect(Collectors.toList());
42+
}
43+
44+
45+
@Override
46+
public List<ContentResDto> getTop5BookmarkedContent() {
47+
List<Content> top5Content = contentRepository.findTop5ByBookmarkCount();
48+
49+
return top5Content.stream()
50+
.map(this::convertToDto)
51+
.collect(Collectors.toList());
52+
}
53+
54+
55+
//문자열을 줄바꿈 기준으로 분리하여 리스트로 변환
56+
private List<String> splitByNewLine(String text) {
57+
return Arrays.stream(text.split("\n"))
58+
.map(String::trim)
59+
.filter(s -> !s.isEmpty())
60+
.collect(Collectors.toList());
61+
}
62+
63+
64+
//Content -> ContentResDto 변환
65+
private ContentResDto convertToDto(Content content) {
66+
return new ContentResDto(
67+
content.getContent_id(),
68+
content.getTitle(),
69+
content.getSummary(),
70+
splitByNewLine(content.getBackground()),
71+
splitByNewLine(content.getImportance()),
72+
splitByNewLine(content.getTip()),
73+
splitByNewLine(content.getAdditional_resources())
74+
);
75+
}
76+
}

src/main/java/com/haruhan/user/entity/User.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ public class User {
4343
//orphanRemoval : 연결이 끊어진(null이 된) 북마크 엔티티를 자동 삭제
4444
private List<Bookmark> bookmarks;
4545

46+
@Column(name = "last_received_content_id")
47+
private Long lastReceivedContentId = 0L; // 마지막으로 받은 콘텐츠 ID
48+
4649

4750
public User(String email, PreferedTime preferedTime, Boolean isDaily) {
4851
this.email = email;

src/main/resources/application.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ spring:
99
application:
1010
name: haruhan-mail
1111

12+
jackson:
13+
time-zone: Asia/Seoul
14+
1215
datasource:
1316
url: jdbc:mysql://${DB_HOST}:${DB_PORT}/${DB_NAME}
1417
username: ${DB_USERNAME}

0 commit comments

Comments
 (0)