-
Notifications
You must be signed in to change notification settings - Fork 21
/
ArticleService.java
226 lines (188 loc) · 7.82 KB
/
ArticleService.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
package myblog.blog.article.service;
import lombok.RequiredArgsConstructor;
import myblog.blog.article.domain.Article;
import myblog.blog.article.dto.ArticleDtoForMain;
import myblog.blog.category.domain.Category;
import myblog.blog.member.doamin.Member;
import myblog.blog.article.dto.ArticleForm;
import myblog.blog.article.repository.ArticleRepository;
import myblog.blog.article.repository.NaArticleRepository;
import myblog.blog.category.service.CategoryService;
import myblog.blog.tags.service.TagsService;
import org.kohsuke.github.GHRepository;
import org.kohsuke.github.GitHub;
import org.kohsuke.github.GitHubBuilder;
import org.modelmapper.ModelMapper;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Slice;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.factory.annotation.Value;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;
@Service
@Transactional
@RequiredArgsConstructor
public class ArticleService {
@Value("${git.gitToken}")
private String gitToken;
@Value("${git.repo}")
private String gitRepo;
private final TagsService tagsService;
private final CategoryService categoryService;
private final ArticleRepository articleRepository;
private final NaArticleRepository naArticleRepository;
private final ModelMapper modelMapper;
/*
- 아티클 작성 로직
- 글작성시 아티클 캐싱 초기화
*/
@CacheEvict(value = {"layoutCaching", "layoutRecentArticleCaching","seoCaching"}, allEntries = true)
public Long writeArticle(ArticleForm articleDto, Member writer) {
Article newArticle = articleFrom(articleDto, writer);
articleRepository.save(newArticle);
tagsService.createNewTagsAndArticleTagList(articleDto.getTags(), newArticle);
return newArticle.getId();
}
/*
- 아티클 수정 로직
- 글 수정시 아티클 캐싱 초기화
*/
@CacheEvict(value = {"layoutCaching", "layoutRecentArticleCaching","seoCaching"}, allEntries = true)
public void editArticle(Long articleId, ArticleForm articleForm) {
Article article = articleRepository.findById(articleId).get();
Category category = categoryService.findCategory(articleForm.getCategory());
tagsService.deleteArticleTags(article);
tagsService.createNewTagsAndArticleTagList(articleForm.getTags(), article);
// 더티 체킹으로 업데이트
article.editArticle(articleForm,category);
}
/*
- 아티클 삭제 로직
- 글 삭제시 아티클 캐싱 초기화
*/
@CacheEvict(value = {"layoutCaching", "layoutRecentArticleCaching","seoCaching"}, allEntries = true)
public void deleteArticle(Long articleId) {
naArticleRepository.deleteArticle(articleId);
}
/*
- 메인화면 위한 인기 아티클 6개 목록 가져오기
- 레이아웃 렌더링 성능 향상을 위해 캐싱작업
카테고리 변경 / 아티클 변경이 존재할경우 레이아웃 캐시 초기화
DTO 매핑 로직 서비스단에서 처리
*/
@Cacheable(value = "layoutCaching", key = "1")
public List<ArticleDtoForMain> getPopularArticles() {
return articleRepository.findTop6ByOrderByHitDesc()
.stream()
.map(article -> modelMapper.map(article, ArticleDtoForMain.class))
.collect(Collectors.toList());
}
/*
- 메인화면 위한 최신 아티클 페이징처리해서 가져오기
- 레이아웃 렌더링 성능 향상을 위해 캐싱작업
카테고리 변경 / 아티클 변경이 존재할경우 레이아웃 캐시 초기화
DTO 매핑 로직 서비스단에서 처리
*/
@Cacheable(value = "layoutRecentArticleCaching", key = "#page")
public Slice<ArticleDtoForMain> getRecentArticles(int page) {
return articleRepository
.findByOrderByIdDesc(PageRequest.of(page, 5))
.map(article -> modelMapper.map(article, ArticleDtoForMain.class));
}
/*
- 카테고리별 게시물 페이징 처리해서 가져오기
*/
public Slice<Article> getArticlesByCategory(String category, Integer tier, Integer page) {
Slice<Article> articles = null;
if (tier.equals(0)) {
articles = articleRepository
.findByOrderByIdDesc(
PageRequest.of(pageResolve(page), 5));
} else if (tier.equals(1)) {
articles = articleRepository
.findBySupCategoryOrderByIdDesc(
PageRequest.of(pageResolve(page), 5), category);
} else {
articles = articleRepository
.findBySubCategoryOrderByIdDesc(
PageRequest.of(pageResolve(page), 5), category);
}
return articles;
}
/*
- 아티클 읽기 위한 페치로 전체 가져오기
*/
public Article readArticle(Long id){
return articleRepository.findArticleByIdFetchCategoryAndTags(id);
}
/*
- 모든 게시물 조회
*/
public List<Article> getTotalArticle(){
return articleRepository.findAllByOrderByIdDesc();
}
/*
- 카테고리별 최신게시물 6개만 아티클 상세뷰 위해 가져오는로직
*/
public List<Article> getArticlesByCategoryForDetailView(Category category, Article article){
return articleRepository.findTop6ByCategoryOrderByIdDesc(category);
}
/*
- 태그별 게시물 페이징 처리해서 가져오기
*/
public Page<Article> getArticlesByTag(String tag, Integer page) {
return articleRepository
.findAllByArticleTagsOrderById(PageRequest.of(pageResolve(page), 5), tag);
}
/*
- 검색어별 게시물 페이징 처리해서 가져오기
*/
public Page<Article> getArticlesByKeyword(String keyword, Integer page) {
return articleRepository
.findAllByKeywordOrderById(PageRequest.of(pageResolve(page),5), keyword);
}
/*
- 깃헙에 아티클 푸시하기
*/
public void pushArticleToGithub(Long articleId) {
Article article = articleRepository.findById(articleId).get();
try {
GitHub gitHub = new GitHubBuilder().withOAuthToken(gitToken).build();
GHRepository repository = gitHub.getRepository(gitRepo);
repository.createContent()
.path(article.getCategory().getParents().getTitle()+"/"+article.getCategory().getTitle()+"/"+article.getTitle()+".md")
.content(article.getContent())
.message("test")
.branch("main")
.commit();
} catch (IOException e) {
e.printStackTrace();
}
}
/*
- 페이지 시작점 0~1변경 메서드
*/
private int pageResolve(Integer rawPage) {
if (rawPage == null || rawPage == 1) {
return 0;
} else return rawPage - 1;
}
/*
- 새로운 아티클 도메인 생성 메서드
*/
private Article articleFrom(ArticleForm articleDto, Member writer) {
return Article.builder()
.title(articleDto.getTitle())
.content(articleDto.getContent())
.toc(articleDto.getToc())
.member(writer)
.thumbnailUrl(articleDto.getThumbnailUrl())
.category(categoryService.findCategory(articleDto.getCategory()))
.build();
}
}