19
19
import com .leets .xcellentbe .domain .article .dto .ArticleCreateRequestDto ;
20
20
import com .leets .xcellentbe .domain .article .dto .ArticleCreateResponseDto ;
21
21
import com .leets .xcellentbe .domain .article .dto .ArticleResponseDto ;
22
+ import com .leets .xcellentbe .domain .article .dto .ArticleStatsDto ;
22
23
import com .leets .xcellentbe .domain .article .dto .ArticlesResponseDto ;
23
24
import com .leets .xcellentbe .domain .article .dto .ArticlesWithMediaDto ;
24
25
import com .leets .xcellentbe .domain .article .exception .ArticleNotFoundException ;
25
- import com .leets .xcellentbe .domain .article .exception .DeleteForbiddenException ;
26
+ import com .leets .xcellentbe .domain .articleLike .domain .repository .ArticleLikeRepository ;
27
+ import com .leets .xcellentbe .domain .comment .domain .Comment ;
28
+ import com .leets .xcellentbe .domain .comment .dto .CommentStatsDto ;
29
+ import com .leets .xcellentbe .domain .commentLike .domain .repository .CommentLikeRepository ;
30
+ import com .leets .xcellentbe .global .error .exception .custom .DeleteForbiddenException ;
26
31
import com .leets .xcellentbe .domain .articleMedia .domain .ArticleMedia ;
27
32
import com .leets .xcellentbe .domain .articleMedia .domain .repository .ArticleMediaRepository ;
28
- import com .leets .xcellentbe .domain .articleMedia . exception . ArticleMediaNotFoundException ;
33
+ import com .leets .xcellentbe .domain .comment . domain . repository . CommentRepository ;
29
34
import com .leets .xcellentbe .domain .hashtag .HashtagService .HashtagService ;
30
35
import com .leets .xcellentbe .domain .hashtag .domain .Hashtag ;
31
36
import com .leets .xcellentbe .domain .user .domain .User ;
@@ -43,6 +48,9 @@ public class ArticleService {
43
48
private final ArticleRepository articleRepository ;
44
49
private final ArticleMediaRepository articleMediaRepository ;
45
50
private final UserRepository userRepository ;
51
+ private final CommentRepository commentRepository ;
52
+ private final ArticleLikeRepository articleLikeRepository ;
53
+ private final CommentLikeRepository commentLikeRepository ;
46
54
private final HashtagService hashtagService ;
47
55
private final S3UploadMediaService s3UploadMediaService ;
48
56
private final JwtService jwtService ;
@@ -149,15 +157,21 @@ public ArticleResponseDto getArticle(HttpServletRequest request, UUID articleId)
149
157
150
158
Article targetArticle = articleRepository .findById (articleId )
151
159
.orElseThrow (ArticleNotFoundException ::new );
152
-
153
- List <ArticleMedia > mediaList = articleMediaRepository .findByArticle_ArticleId (targetArticle .getArticleId ());
154
- if (mediaList .isEmpty ()) {
155
- throw new ArticleMediaNotFoundException ();
156
- }
160
+ ArticleStatsDto stats = findArticleStats (targetArticle );
157
161
targetArticle .updateViewCount ();
158
162
boolean isOwner = targetArticle .getWriter ().getUserId ().equals (user .getUserId ());
159
163
160
- return ArticleResponseDto .from (targetArticle , isOwner );
164
+ List <Comment > comments = commentRepository .findAllByArticleAndNotDeleted (targetArticle );
165
+ Map <UUID , CommentStatsDto > replyStatsMap = comments .stream ()
166
+ .collect (Collectors .toMap (
167
+ Comment ::getCommentId ,
168
+ reply -> {
169
+ long likeCount = commentLikeRepository .countLikesByComment (reply );
170
+ long replyCount = commentRepository .countRepliesByComment (reply );
171
+ return CommentStatsDto .from (likeCount , replyCount );
172
+ }
173
+ ));
174
+ return ArticleResponseDto .from (targetArticle , isOwner , stats , replyStatsMap );
161
175
}
162
176
163
177
//게시글 전체 조회
@@ -167,13 +181,17 @@ public List<ArticleResponseDto> getArticles(HttpServletRequest request, LocalDat
167
181
168
182
Pageable pageable = PageRequest .of (0 , size );
169
183
170
- List <Article > articles = cursor == null ?
184
+ List <Article > articles = ( cursor == null ) ?
171
185
articleRepository .findRecentArticles (pageable ) : // 처음 로드 시
172
186
articleRepository .findRecentArticles (cursor , pageable );
173
187
174
188
return articles
175
189
.stream ()
176
- .map (article -> ArticleResponseDto .from (article , article .getWriter ().getUserId ().equals (user .getUserId ())))
190
+ .map (article -> {
191
+ boolean isOwner = article .getWriter ().getUserId ().equals (user .getUserId ());
192
+ ArticleStatsDto stats = findArticleStats (article );
193
+ return ArticleResponseDto .fromWithoutComments (article , isOwner , stats );
194
+ })
177
195
.collect (Collectors .toList ());
178
196
}
179
197
@@ -185,8 +203,7 @@ public ArticleCreateResponseDto rePostArticle(HttpServletRequest request, UUID a
185
203
Article repostedArticle = articleRepository .findById (articleId )
186
204
.orElseThrow (ArticleNotFoundException ::new );
187
205
Article newArticle = Article .createArticle (writer , repostedArticle .getContent ());
188
- repostedArticle .addRepost (newArticle );
189
- repostedArticle .plusRepostCount ();
206
+ newArticle .addRepost (repostedArticle );
190
207
191
208
return ArticleCreateResponseDto .from (articleRepository .save (newArticle ));
192
209
}
@@ -197,12 +214,20 @@ public void deleteRepost(HttpServletRequest request, UUID articleId) {
197
214
User user = getUser (request );
198
215
Article targetArticle = articleRepository .findById (articleId )
199
216
.orElseThrow (ArticleNotFoundException ::new );
200
- if (!(targetArticle .getWriter ().getUserId ().equals (user .getUserId ()))) {
217
+ // 게시글 작성자와 현재 사용자 일치 여부 확인, 리포스트 ID가 있는 경우에만 삭제 가능
218
+ if ((!targetArticle .getWriter ().getUserId ().equals (user .getUserId ()))||(targetArticle .getRePost () == null )) {
201
219
throw new DeleteForbiddenException ();
202
- } else {
203
- targetArticle .deleteArticle ();
204
- targetArticle .getRePost ().minusRepostCount ();
205
220
}
221
+ // 리포스트 삭제 처리
222
+ targetArticle .deleteArticle ();
223
+ articleRepository .save (targetArticle );
224
+ }
225
+
226
+ public ArticleStatsDto findArticleStats (Article article ) {
227
+ long likeCount = articleLikeRepository .countLikesByArticleId (article .getArticleId ());
228
+ long commentCount = commentRepository .countCommentsByArticle (article );
229
+ long repostCount = articleRepository .countReposts (article );
230
+ return ArticleStatsDto .from (likeCount , commentCount , repostCount );
206
231
}
207
232
208
233
//JWT 토큰 기반 사용자 정보 반환 메소드
@@ -214,6 +239,5 @@ private User getUser(HttpServletRequest request) {
214
239
.orElseThrow (UserNotFoundException ::new );
215
240
216
241
return user ;
217
-
218
242
}
219
243
}
0 commit comments