Files
hexagonal/src/main/java/myblog/blog/article/controller/ArticleController.java
jinia91 9ab902808b #### 211119
- 기능 요구사항
__기본기능__
 v 권한 구분 관리자 권한 구현
 v 깃헙아이디, 구글아이디로 로그인 가능
 v 블로그 기본 CRUD
 v 연관글 등록
 v 이미지 삽입시 이미지서버에 선업로드 후 URL반환
 v 댓글과 대댓글 구현
 v  랜드화면은 무한스크롤 구현
 v 카테고리 화면에서는 일반 페이징
 v 토스트 에디터 사용
 v 게시물 조회수 순위별
 v 최근 게시물
 v 최근 코멘트 노출
 v 블로그 태그별 검색과 태그 보이기
 v 일반 검색기능

-----
 - 카테고리 목록 설정
 - 썸네일 링크로 추가
__추가기능__
 - TOC
 - 글 1분단위 자동저장
 - 새로운글 알람 보내기
 - RSS피드
 - 공유하기 기능
 - 글 포스팅시 자동 커밋 푸시
2021-11-19 17:27:52 +09:00

326 lines
13 KiB
Java

package myblog.blog.article.controller;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import myblog.blog.article.domain.Article;
import myblog.blog.article.dto.*;
import myblog.blog.article.service.ArticleService;
import myblog.blog.category.dto.CategoryForView;
import myblog.blog.category.dto.CategoryNormalDto;
import myblog.blog.category.service.CategoryService;
import myblog.blog.comment.domain.Comment;
import myblog.blog.comment.dto.CommentDto;
import myblog.blog.comment.dto.CommentDtoForSide;
import myblog.blog.comment.service.CommentService;
import myblog.blog.member.auth.PrincipalDetails;
import myblog.blog.member.dto.MemberDto;
import myblog.blog.tags.dto.TagsDto;
import myblog.blog.tags.service.TagsService;
import org.modelmapper.ModelMapper;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Slice;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.stream.Collectors;
@Controller
@RequiredArgsConstructor
@Slf4j
public class ArticleController {
private final ModelMapper modelMapper;
private final ArticleService articleService;
private final TagsService tagsService;
private final CategoryService categoryService;
private final CommentService commentService;
@GetMapping("article/write")
public String writeArticleForm(ArticleForm articleForm, Model model) {
List<CategoryNormalDto> categoryForInput =
categoryService
.findCategoryByTier(2)
.stream()
.map(c -> modelMapper.map(c, CategoryNormalDto.class))
.collect(Collectors.toList());
model.addAttribute("categoryInput", categoryForInput);
List<TagsDto> tagsForInput =
tagsService
.findAllTags()
.stream()
.map(c -> new TagsDto(c.getName()))
.collect(Collectors.toList());
model.addAttribute("tagsInput", tagsForInput);
CategoryForView categoryForView = categoryService.getCategoryForView();
model.addAttribute("category", categoryForView);
List<CommentDtoForSide> comments = commentService.recentCommentList()
.stream()
.map(comment ->
new CommentDtoForSide(comment.getId(), comment.getArticle().getId(), comment.getContent()))
.collect(Collectors.toList());
model.addAttribute("commentsList", comments);
model.addAttribute("articleDto", articleForm);
return "article/articleWriteForm";
}
@PostMapping("article/write")
@Transactional
public String writeArticle(@ModelAttribute ArticleForm articleForm, Authentication authentication) {
PrincipalDetails principal = (PrincipalDetails) authentication.getPrincipal();
articleForm.setMemberId(principal.getMemberId());
Long articleId = articleService.writeArticle(articleForm);
return "redirect:/article/view?articleId=" + articleId;
}
@Transactional
@GetMapping("article/list")
public String getArticlesList(@RequestParam String category,
@RequestParam Integer tier,
@RequestParam Integer page,
Model model) {
CategoryForView categoryForView = categoryService.getCategoryForView();
model.addAttribute("category", categoryForView);
List<CommentDtoForSide> comments = commentService.recentCommentList()
.stream()
.map(comment ->
new CommentDtoForSide(comment.getId(), comment.getArticle().getId(), comment.getContent()))
.collect(Collectors.toList());
model.addAttribute("commentsList", comments);
PagingBoxDto pagingBoxDto = PagingBoxDto.createOf(page, articleService.getTotalArticleCntByCategory(category, categoryForView));
model.addAttribute("pagingBox", pagingBoxDto);
Slice<ArticleDtoForMain> articleList = articleService.getArticles(category, tier, pagingBoxDto.getCurPageNum());
model.addAttribute("articleList", articleList);
return "article/articleList";
}
@Transactional
@GetMapping("article/list/tag/{tag}")
public String getArticlesListByTag(@RequestParam Integer page,
@PathVariable String tag,
Model model) {
CategoryForView categoryForView = categoryService.getCategoryForView();
model.addAttribute("category", categoryForView);
List<CommentDtoForSide> comments = commentService.recentCommentList()
.stream()
.map(comment ->
new CommentDtoForSide(comment.getId(), comment.getArticle().getId(), comment.getContent()))
.collect(Collectors.toList());
model.addAttribute("commentsList", comments);
Page<ArticleDtoForMain> articleList =
articleService.getArticlesByTag(tag, page)
.map(article ->
modelMapper.map(article, ArticleDtoForMain.class));
model.addAttribute("articleList", articleList);
PagingBoxDto pagingBoxDto = PagingBoxDto.createOf(page, articleList.getTotalPages());
model.addAttribute("pagingBox", pagingBoxDto);
return "article/articleListByTag";
}
@Transactional
@GetMapping("article/list/search/{keyword}")
public String getArticlesListByKeyword(@RequestParam Integer page,
@PathVariable String keyword,
Model model) {
CategoryForView categoryForView = categoryService.getCategoryForView();
model.addAttribute("category", categoryForView);
List<CommentDtoForSide> comments = commentService.recentCommentList()
.stream()
.map(comment ->
new CommentDtoForSide(comment.getId(), comment.getArticle().getId(), comment.getContent()))
.collect(Collectors.toList());
model.addAttribute("commentsList", comments);
Page<ArticleDtoForMain> articleList =
articleService.getArticlesByKeyword(keyword, page)
.map(article ->
modelMapper.map(article, ArticleDtoForMain.class));
model.addAttribute("articleList", articleList);
PagingBoxDto pagingBoxDto = PagingBoxDto.createOf(page, articleList.getTotalPages());
model.addAttribute("pagingBox", pagingBoxDto);
return "article/articleListByKeyword";
}
@GetMapping("/article/view")
public String readArticle(@RequestParam Long articleId,
Authentication authentication,
@CookieValue(required = false, name = "view") String cookie, HttpServletResponse response,
Model model) {
if (authentication != null) {
PrincipalDetails principal = (PrincipalDetails) authentication.getPrincipal();
MemberDto memberDto = modelMapper.map(principal.getMember(), MemberDto.class);
model.addAttribute("member", memberDto);
} else {
model.addAttribute("member", null);
}
CategoryForView categoryForView = categoryService.getCategoryForView();
model.addAttribute("category", categoryForView);
List<CommentDtoForSide> comments = commentService.recentCommentList()
.stream()
.map(comment ->
new CommentDtoForSide(comment.getId(), comment.getArticle().getId(), comment.getContent()))
.collect(Collectors.toList());
model.addAttribute("commentsList", comments);
Article article = articleService.findArticleById(articleId);
ArticleDtoForDetail articleDtoForDetail = modelMapper.map(article, ArticleDtoForDetail.class);
List<String> tags = article.getArticleTagLists()
.stream()
.map(tag -> tag.getTags().getName())
.collect(Collectors.toList());
articleDtoForDetail.setTags(tags);
model.addAttribute("article", articleDtoForDetail);
List<ArticleDtoByCategory> articleTitlesSortByCategory =
articleService
.getArticlesByCategory(article.getCategory())
.stream()
.map(article1 -> modelMapper.map(article1, ArticleDtoByCategory.class))
.collect(Collectors.toList());
model.addAttribute("articlesSortBycategory", articleTitlesSortByCategory);
addHitWithCookie(article, cookie, response);
return "article/articleView";
}
@GetMapping("/article/edit")
public String updateArticle(@RequestParam Long articleId,
Authentication authentication,
Model model) {
List<CategoryNormalDto> categoryForInput =
categoryService
.findCategoryByTier(2)
.stream()
.map(c -> modelMapper.map(c, CategoryNormalDto.class))
.collect(Collectors.toList());
model.addAttribute("categoryInput", categoryForInput);
List<TagsDto> tagsForInput =
tagsService
.findAllTags()
.stream()
.map(c -> modelMapper.map(c, TagsDto.class))
.collect(Collectors.toList());
model.addAttribute("tagsInput", tagsForInput);
Article article = articleService.getArticleForEdit(articleId);
ArticleDtoForEdit articleDto = modelMapper.map(article, ArticleDtoForEdit.class);
List<String> tagList = article.getArticleTagLists()
.stream()
.map(articleTag -> articleTag.getTags().getName())
.collect(Collectors.toList());
articleDto.setArticleTagList(tagList);
model.addAttribute("articleDto", articleDto);
CategoryForView categoryForView = categoryService.getCategoryForView();
model.addAttribute("category", categoryForView);
List<CommentDtoForSide> comments = commentService.recentCommentList()
.stream()
.map(comment ->
new CommentDtoForSide(comment.getId(), comment.getArticle().getId(), comment.getContent()))
.collect(Collectors.toList());
model.addAttribute("commentsList", comments);
return "article/articleEditForm";
}
@PostMapping("/article/delete")
@Transactional
public String deleteArticle(@RequestParam Long articleId,
Authentication authentication) {
articleService.deleteArticle(articleId);
return "redirect:/";
}
@PostMapping("/article/edit")
@Transactional
public String editArticle(@RequestParam Long articleId,
@ModelAttribute ArticleForm articleForm, Authentication authentication) {
PrincipalDetails principal = (PrincipalDetails) authentication.getPrincipal();
articleForm.setMemberId(principal.getMemberId());
articleService.editArticle(articleId, articleForm);
return "redirect:/article/view?articleId=" + articleId;
}
@GetMapping("/main/article/{pageNum}")
public @ResponseBody
List<ArticleDtoForMain> mainNextPage(@PathVariable int pageNum) {
return articleService.getArticles(pageNum).getContent();
}
private void addHitWithCookie(Article article, String cookie, HttpServletResponse response) {
Long articleId = article.getId();
if (cookie == null) {
Cookie viewCookie = new Cookie("view", articleId + "/");
viewCookie.setComment("게시물 조회 확인용");
viewCookie.setMaxAge(60 * 60);
articleService.addHit(article);
response.addCookie(viewCookie);
} else {
boolean isRead = false;
String[] viewCookieList = cookie.split("/");
for (String alreadyRead : viewCookieList) {
if (alreadyRead.equals(String.valueOf(articleId))) {
isRead = true;
break;
}
;
}
if (!isRead) {
cookie += articleId + "/";
articleService.addHit(article);
}
response.addCookie(new Cookie("view", cookie));
}
}
}