카테고리 도메인 리아키텍쳐링
This commit is contained in:
@@ -13,14 +13,13 @@ import myblog.blog.article.application.port.response.ArticleResponseForCardBox;
|
||||
import myblog.blog.article.application.port.response.ArticleResponseForDetail;
|
||||
import myblog.blog.article.application.port.response.ArticleResponseForEdit;
|
||||
|
||||
import myblog.blog.category.service.CategoryService;
|
||||
import myblog.blog.category.dto.*;
|
||||
import myblog.blog.category.appliacation.port.incomming.CategoryUseCase;
|
||||
import myblog.blog.category.appliacation.port.response.CategoryViewForLayout;
|
||||
import myblog.blog.member.auth.PrincipalDetails;
|
||||
import myblog.blog.member.dto.MemberVo;
|
||||
import myblog.blog.shared.queries.LayoutRenderingQueries;
|
||||
|
||||
import org.jsoup.Jsoup;
|
||||
import org.modelmapper.ModelMapper;
|
||||
|
||||
import org.springframework.data.domain.*;
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||
@@ -33,7 +32,6 @@ 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;
|
||||
|
||||
import static myblog.blog.shared.utils.MarkdownUtils.*;
|
||||
|
||||
@@ -45,14 +43,13 @@ public class ArticleController {
|
||||
private final ArticleQueriesUseCase articleQueriesUseCase;
|
||||
private final TempArticleUseCase tempArticleUseCase;
|
||||
private final TagsQueriesUseCase tagsQueriesUseCase;
|
||||
private final CategoryService categoryService;
|
||||
private final CategoryUseCase categoryUseCase;
|
||||
private final LayoutRenderingQueries layoutRenderingQueries;
|
||||
private final ModelMapper modelMapper;
|
||||
|
||||
@GetMapping("article/write")
|
||||
String getArticleWriteForm(Model model) {
|
||||
layoutRenderingQueries.AddLayoutTo(model);
|
||||
model.addAttribute("categoryInput", getCategoryDtosForForm());
|
||||
model.addAttribute("categoryInput", categoryUseCase.findCategoryByTier(2));
|
||||
model.addAttribute("tagsInput", tagsQueriesUseCase.findAllTagDtos());
|
||||
model.addAttribute("articleDto", new ArticleForm());
|
||||
return "article/articleWriteForm";
|
||||
@@ -80,12 +77,11 @@ public class ArticleController {
|
||||
String updateArticle(@RequestParam Long articleId, Model model) {
|
||||
ArticleResponseForEdit articleDto = articleQueriesUseCase.getArticleForEdit(articleId);
|
||||
layoutRenderingQueries.AddLayoutTo(model);
|
||||
model.addAttribute("categoryInput", getCategoryDtosForForm());
|
||||
model.addAttribute("categoryInput", categoryUseCase.findCategoryByTier(2));
|
||||
model.addAttribute("tagsInput", tagsQueriesUseCase.findAllTagDtos());
|
||||
model.addAttribute("articleDto", articleDto);
|
||||
return "article/articleEditForm";
|
||||
}
|
||||
|
||||
/*
|
||||
- 아티클 수정 요청
|
||||
*/
|
||||
@@ -96,7 +92,6 @@ public class ArticleController {
|
||||
articleUseCase.editArticle(ArticleEditRequest.from(articleId, articleForm));
|
||||
return "redirect:/article/view?articleId=" + articleId;
|
||||
}
|
||||
|
||||
/*
|
||||
- 아티클 삭제 요청
|
||||
*/
|
||||
@@ -106,7 +101,6 @@ public class ArticleController {
|
||||
articleUseCase.deleteArticle(articleId);
|
||||
return "redirect:/";
|
||||
}
|
||||
|
||||
/*
|
||||
- 카테고리별 게시물 조회하기
|
||||
*/
|
||||
@@ -117,7 +111,7 @@ public class ArticleController {
|
||||
@RequestParam Integer page,
|
||||
Model model) {
|
||||
PagingBoxHandler pagingBoxHandler =
|
||||
PagingBoxHandler.createOf(page, getTotalArticleCntByCategory(category, categoryService.getCategoryForView()));
|
||||
PagingBoxHandler.createOf(page, getTotalArticleCntByCategory(category, categoryUseCase.getCategoryViewForLayout()));
|
||||
|
||||
Slice<ArticleResponseForCardBox> articleDtoList =
|
||||
articleQueriesUseCase.getArticlesByCategory(category, tier, pagingBoxHandler.getCurPageNum());
|
||||
@@ -132,7 +126,23 @@ public class ArticleController {
|
||||
|
||||
return "article/articleList";
|
||||
}
|
||||
private int getTotalArticleCntByCategory(String category, CategoryViewForLayout categorys) {
|
||||
|
||||
if (categorys.getTitle().equals(category)) {
|
||||
return categorys.getCount();
|
||||
} else {
|
||||
for (CategoryViewForLayout categoryCnt :
|
||||
categorys.getCategoryTCountList()) {
|
||||
if (categoryCnt.getTitle().equals(category))
|
||||
return categoryCnt.getCount();
|
||||
for (CategoryViewForLayout categoryCntSub : categoryCnt.getCategoryTCountList()) {
|
||||
if (categoryCntSub.getTitle().equals(category))
|
||||
return categoryCntSub.getCount();
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("'"+category+"' 라는 카테고리는 존재하지 않습니다.");
|
||||
}
|
||||
/*
|
||||
- 태그별 게시물 조회하기
|
||||
*/
|
||||
@@ -157,7 +167,6 @@ public class ArticleController {
|
||||
|
||||
return "article/articleListByTag";
|
||||
}
|
||||
|
||||
/*
|
||||
- 검색어별 게시물 조회하기
|
||||
*/
|
||||
@@ -183,7 +192,6 @@ public class ArticleController {
|
||||
return "article/articleListByKeyword";
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
- 아티클 상세 조회
|
||||
1. 로그인여부 검토
|
||||
@@ -240,7 +248,6 @@ public class ArticleController {
|
||||
|
||||
return "article/articleView";
|
||||
}
|
||||
|
||||
/*
|
||||
- 쿠키 추가 / 조회수 증가 검토
|
||||
*/
|
||||
@@ -269,36 +276,4 @@ public class ArticleController {
|
||||
return addHitAvailable;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
- 카테고리별 아티클 갯수 구하기
|
||||
*/
|
||||
private int getTotalArticleCntByCategory(String category, CategoryForView categorys) {
|
||||
|
||||
if (categorys.getTitle().equals(category)) {
|
||||
return categorys.getCount();
|
||||
} else {
|
||||
for (CategoryForView categoryCnt :
|
||||
categorys.getCategoryTCountList()) {
|
||||
if (categoryCnt.getTitle().equals(category))
|
||||
return categoryCnt.getCount();
|
||||
for (CategoryForView categoryCntSub : categoryCnt.getCategoryTCountList()) {
|
||||
if (categoryCntSub.getTitle().equals(category))
|
||||
return categoryCntSub.getCount();
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("'"+category+"' 라는 카테고리는 존재하지 않습니다.");
|
||||
}
|
||||
|
||||
/*
|
||||
- 아티클 폼에 필요한 카테고리 dtos
|
||||
*/
|
||||
private List<CategorySimpleView> getCategoryDtosForForm() {
|
||||
return categoryService
|
||||
.findCategoryByTier(2)
|
||||
.stream()
|
||||
.map(category -> modelMapper.map(category, CategorySimpleView.class))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ public class MainController {
|
||||
- 메인 화면 제어용 컨트롤러
|
||||
*/
|
||||
@GetMapping("/")
|
||||
public String main(Model model) {
|
||||
String main(Model model) {
|
||||
// Dto 전처리
|
||||
List<ArticleResponseForCardBox> popularArticles = articleQueriesUseCase.getPopularArticles();
|
||||
//
|
||||
@@ -37,13 +37,11 @@ public class MainController {
|
||||
- 최신 아티클 무한스크롤로 조회
|
||||
*/
|
||||
@GetMapping("/main/article/{lastArticleId}")
|
||||
public @ResponseBody
|
||||
List<ArticleResponseForCardBox> mainNextPage(@PathVariable(required = false) Long lastArticleId) {
|
||||
@ResponseBody List<ArticleResponseForCardBox> mainNextPage(@PathVariable(required = false) Long lastArticleId) {
|
||||
|
||||
// Entity to Dto
|
||||
List<ArticleResponseForCardBox> articles = articleQueriesUseCase.getRecentArticles(lastArticleId);
|
||||
|
||||
|
||||
// 화면렌더링을 위한 파싱
|
||||
for(ArticleResponseForCardBox article : articles){
|
||||
String content = Jsoup.parse(getHtmlRenderer().render(getParser().parse(article.getContent()))).text();
|
||||
@@ -52,7 +50,6 @@ public class MainController {
|
||||
}
|
||||
article.setContent(content);
|
||||
}
|
||||
|
||||
return articles;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ public class TempArticleController {
|
||||
public String autoSaveTemp(@RequestBody TempArticleResponse tempArticleResponse){
|
||||
|
||||
tempArticleService.saveTemp(new TempArticle(tempArticleResponse.getContent()));
|
||||
|
||||
return "저장성공";
|
||||
}
|
||||
|
||||
@@ -36,10 +35,8 @@ public class TempArticleController {
|
||||
TempArticleResponse getTempArticle(){
|
||||
|
||||
Optional<TempArticle> tempArticle = tempArticleService.getTempArticle();
|
||||
|
||||
TempArticleResponse tempArticleResponse = new TempArticleResponse();
|
||||
tempArticleResponse.setContent(tempArticle.orElse(new TempArticle()).getContent());
|
||||
|
||||
return tempArticleResponse;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ public class ArticleRepositoryAdapter implements ArticleRepositoryPort {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Slice<Article> findBySupCategoryOrderByIdDesc(Pageable pageable, String category) {
|
||||
public Slice<Article> findBySuperCategoryOrderByIdDesc(Pageable pageable, String category) {
|
||||
return jpaArticleRepository.findBySupCategoryOrderByIdDesc(pageable,category);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import myblog.blog.article.application.port.response.ArticleResponseByCategory;
|
||||
import myblog.blog.article.application.port.response.ArticleResponseForDetail;
|
||||
import myblog.blog.article.application.port.response.ArticleResponseForEdit;
|
||||
|
||||
import myblog.blog.category.service.CategoryService;
|
||||
import myblog.blog.category.appliacation.CategoryService;
|
||||
import org.modelmapper.ModelMapper;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.data.domain.Page;
|
||||
@@ -78,7 +78,7 @@ public class ArticleQueries implements ArticleQueriesUseCase {
|
||||
}
|
||||
if (tier.equals(1)) {
|
||||
articles = articleRepositoryPort
|
||||
.findBySupCategoryOrderByIdDesc(
|
||||
.findBySuperCategoryOrderByIdDesc(
|
||||
PageRequest.of(pageResolve(page), 5), category);
|
||||
}
|
||||
if (tier.equals(2)) {
|
||||
|
||||
@@ -13,7 +13,7 @@ import myblog.blog.article.domain.Article;
|
||||
import myblog.blog.category.domain.Category;
|
||||
import myblog.blog.member.doamin.Member;
|
||||
|
||||
import myblog.blog.category.service.CategoryService;
|
||||
import myblog.blog.category.appliacation.CategoryService;
|
||||
import myblog.blog.member.service.Oauth2MemberService;
|
||||
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
|
||||
@@ -16,7 +16,7 @@ public interface ArticleRepositoryPort {
|
||||
List<Article> findByOrderByIdDescWithList(Pageable pageable);
|
||||
List<Article> findByOrderByIdDesc(Long articleId, Pageable pageable);
|
||||
Slice<Article> findBySubCategoryOrderByIdDesc(Pageable pageable, String category);
|
||||
Slice<Article> findBySupCategoryOrderByIdDesc(Pageable pageable, String category);
|
||||
Slice<Article> findBySuperCategoryOrderByIdDesc(Pageable pageable, String category);
|
||||
Article findArticleByIdFetchCategoryAndTags(Long articleId);
|
||||
Page<Article> findAllByArticleTagsOrderById(Pageable pageable, String tag);
|
||||
Page<Article> findAllByKeywordOrderById(Pageable pageable, String keyword);
|
||||
|
||||
@@ -83,6 +83,14 @@ public class Article extends BasicEntity {
|
||||
this.hit = 0L;
|
||||
}
|
||||
|
||||
private String makeDefaultThumbOf(String thumbnailUrl) {
|
||||
String defaultThumbUrl = "https://cdn.pixabay.com/photo/2020/11/08/13/28/tree-5723734_1280.jpg";
|
||||
|
||||
if (thumbnailUrl == null || thumbnailUrl.equals("")) {
|
||||
thumbnailUrl = defaultThumbUrl;
|
||||
}
|
||||
return thumbnailUrl;
|
||||
}
|
||||
/*
|
||||
- 아티클 수정을 위한 로직
|
||||
*/
|
||||
@@ -95,22 +103,8 @@ public class Article extends BasicEntity {
|
||||
this.thumbnailUrl = getThumbnailUrl();
|
||||
}
|
||||
}
|
||||
/*
|
||||
- 아티클 조회수 증가
|
||||
*/
|
||||
|
||||
public void addHit(){
|
||||
this.hit++;
|
||||
}
|
||||
|
||||
/*
|
||||
- 썸네일 기본 작성
|
||||
*/
|
||||
private String makeDefaultThumbOf(String thumbnailUrl) {
|
||||
String defaultThumbUrl = "https://cdn.pixabay.com/photo/2020/11/08/13/28/tree-5723734_1280.jpg";
|
||||
|
||||
if (thumbnailUrl == null || thumbnailUrl.equals("")) {
|
||||
thumbnailUrl = defaultThumbUrl;
|
||||
}
|
||||
return thumbnailUrl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package myblog.blog.category.adapter.imcomming;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import myblog.blog.category.appliacation.port.incomming.CategoryUseCase;
|
||||
import myblog.blog.category.appliacation.port.response.CategoryViewForLayout;
|
||||
import myblog.blog.category.appliacation.port.response.CategorySimpleDto;
|
||||
import myblog.blog.comment.dto.CommentDtoForLayout;
|
||||
import myblog.blog.comment.service.CommentService;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.Errors;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Controller
|
||||
@RequiredArgsConstructor
|
||||
public class CategoryController {
|
||||
|
||||
private final CategoryUseCase categoryUseCase;
|
||||
private final CommentService commentService;
|
||||
private final CategoryListValidator categorylistValidator;
|
||||
|
||||
/*
|
||||
- 카테고리 수정폼 조회
|
||||
*/
|
||||
@GetMapping("/category/edit")
|
||||
public String editCategoryForm(Model model) {
|
||||
|
||||
List<CategorySimpleDto> categoryList = categoryUseCase.getCategorytCountList();
|
||||
List<CategorySimpleDto> copyList = new ArrayList<>(List.copyOf(categoryList));
|
||||
copyList.remove(0);
|
||||
CategoryViewForLayout categoryViewForLayout = CategoryViewForLayout.from(categoryList);
|
||||
List<CommentDtoForLayout> comments = commentService.recentCommentList();
|
||||
|
||||
model.addAttribute("categoryForEdit", copyList);
|
||||
model.addAttribute("category", categoryViewForLayout);
|
||||
model.addAttribute("commentsList", comments);
|
||||
|
||||
return "admin/categoryEdit";
|
||||
}
|
||||
/*
|
||||
- 카테고리 수정 요청
|
||||
*/
|
||||
@PostMapping("/category/edit")
|
||||
public @ResponseBody
|
||||
String editCategory(@RequestBody List<CategorySimpleDto> categoryList, Errors errors) {
|
||||
// List DTO 검증을 위한 커스텀 validator
|
||||
categorylistValidator.validate(categoryList, errors);
|
||||
categoryUseCase.changeCategory(categoryList);
|
||||
return "변경 성공";
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,14 @@
|
||||
package myblog.blog.shared.exception;
|
||||
package myblog.blog.category.adapter.imcomming;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import myblog.blog.shared.exception.CustomFormException;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.validation.Errors;
|
||||
import org.springframework.validation.Validator;
|
||||
import org.springframework.validation.beanvalidation.SpringValidatorAdapter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
/*
|
||||
@@ -14,7 +16,7 @@ import java.util.List;
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class ListValidator implements Validator {
|
||||
public class CategoryListValidator implements Validator {
|
||||
|
||||
private final SpringValidatorAdapter springValidatorAdapter;
|
||||
|
||||
@@ -28,5 +30,8 @@ public class ListValidator implements Validator {
|
||||
for(Object object : (List)target){
|
||||
springValidatorAdapter.validate(object,errors);
|
||||
}
|
||||
if (errors.hasErrors()) {
|
||||
throw new CustomFormException(Objects.requireNonNull(errors.getFieldError()).getDefaultMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package myblog.blog.category.adapter.outgoing.persistence;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import myblog.blog.category.appliacation.port.outgoing.CategoryRepositoryPort;
|
||||
import myblog.blog.category.appliacation.port.response.CategorySimpleDto;
|
||||
import myblog.blog.category.domain.Category;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class CategoryRepositoryAdapter implements CategoryRepositoryPort {
|
||||
|
||||
private final JpaCategoryRepository jpaCategoryRepository;
|
||||
private final MybatisCategoryRepository mybatisCategoryRepository;
|
||||
|
||||
|
||||
@Override
|
||||
public Optional<Category> findByTitle(String title) {
|
||||
return jpaCategoryRepository.findByTitle(title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Category> findAll() {
|
||||
return jpaCategoryRepository.findAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CategorySimpleDto> getCategoryCount() {
|
||||
return mybatisCategoryRepository.getCategoryCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Category> findAllByTierIs(int tier) {
|
||||
return jpaCategoryRepository.findAllByTierIs(tier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Category> findAllWithoutDummy() {
|
||||
return jpaCategoryRepository.findAllWithoutDummy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteAll(List<Category> categoryListFromDb) {
|
||||
jpaCategoryRepository.deleteAll(categoryListFromDb);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(Category category) {
|
||||
jpaCategoryRepository.save(category);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package myblog.blog.category.repository;
|
||||
package myblog.blog.category.adapter.outgoing.persistence;
|
||||
|
||||
import myblog.blog.category.domain.Category;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
@@ -7,7 +7,7 @@ import org.springframework.data.jpa.repository.Query;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public interface CategoryRepository extends JpaRepository<Category, Long> {
|
||||
public interface JpaCategoryRepository extends JpaRepository<Category, Long> {
|
||||
|
||||
/*
|
||||
- 카테고리 이름으로 카테고리 찾기
|
||||
@@ -1,6 +1,6 @@
|
||||
package myblog.blog.category.repository;
|
||||
package myblog.blog.category.adapter.outgoing.persistence;
|
||||
|
||||
import myblog.blog.category.dto.CategorySimpleView;
|
||||
import myblog.blog.category.appliacation.port.response.CategorySimpleDto;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.springframework.stereotype.Repository;
|
||||
@@ -9,7 +9,7 @@ import java.util.List;
|
||||
|
||||
@Mapper
|
||||
@Repository
|
||||
public interface NaCategoryRepository {
|
||||
public interface MybatisCategoryRepository {
|
||||
|
||||
/*
|
||||
- 카테고리별 아티클 갯수 통계 쿼리
|
||||
@@ -23,6 +23,6 @@ public interface NaCategoryRepository {
|
||||
" group by c.title, b.title with rollup) e\n" +
|
||||
" right join category f on (e.title = f.title)\n" +
|
||||
" order by pOrder, cOrder ")
|
||||
List<CategorySimpleView> getCategoryCount();
|
||||
List<CategorySimpleDto> getCategoryCount();
|
||||
|
||||
}
|
||||
@@ -1,65 +1,74 @@
|
||||
package myblog.blog.category.service;
|
||||
package myblog.blog.category.appliacation;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import myblog.blog.category.domain.Category;
|
||||
import myblog.blog.category.dto.CategorySimpleView;
|
||||
import myblog.blog.category.dto.CategoryForView;
|
||||
import myblog.blog.category.repository.CategoryRepository;
|
||||
import myblog.blog.category.repository.NaCategoryRepository;
|
||||
import myblog.blog.category.appliacation.port.incomming.CategoryUseCase;
|
||||
import myblog.blog.category.appliacation.port.outgoing.CategoryRepositoryPort;
|
||||
import myblog.blog.category.appliacation.port.response.CategorySimpleDto;
|
||||
import myblog.blog.category.appliacation.port.response.CategoryViewForLayout;
|
||||
|
||||
import org.modelmapper.ModelMapper;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@Transactional
|
||||
@RequiredArgsConstructor
|
||||
public class CategoryService {
|
||||
public class CategoryService implements CategoryUseCase {
|
||||
|
||||
private final CategoryRepository categoryRepository;
|
||||
private final NaCategoryRepository naCategoryRepository;
|
||||
private final CategoryRepositoryPort categoryRepositoryPort;
|
||||
private final ModelMapper modelMapper;
|
||||
|
||||
/*
|
||||
- 카테고리 이름으로 카테고리 찾기
|
||||
*/
|
||||
@Override
|
||||
public Category findCategory(String title) {
|
||||
return categoryRepository.findByTitle(title)
|
||||
return categoryRepositoryPort.findByTitle(title)
|
||||
.orElseThrow(() -> new IllegalArgumentException("NotFoundCategoryException"));
|
||||
}
|
||||
|
||||
/*
|
||||
- 카테고리 이름으로 카테고리 찾기
|
||||
*/
|
||||
@Override
|
||||
public List<Category> getAllCategories() {
|
||||
return categoryRepository.findAll();
|
||||
return categoryRepositoryPort.findAll();
|
||||
}
|
||||
|
||||
/*
|
||||
- 카테고리와 카테고리별 아티클 수 찾기
|
||||
*/
|
||||
public List<CategorySimpleView> getCategorytCountList() {
|
||||
return naCategoryRepository.getCategoryCount();
|
||||
@Override
|
||||
public List<CategorySimpleDto> getCategorytCountList() {
|
||||
return categoryRepositoryPort.getCategoryCount();
|
||||
}
|
||||
|
||||
/*
|
||||
- getCategorytCountList()의 캐싱을 위한 전처리 매핑 로직
|
||||
- 본래는 컨트롤러단에서 존재해야할 dto 매핑코드지만 캐싱을 위해 서비스단으로 이동
|
||||
- 레이아웃 렌더링 성능 향상을 위해 캐싱작업
|
||||
카테고리 변경 / 아티클 변경이 존재할경우 레이아웃 캐시 초기화
|
||||
*/
|
||||
@Cacheable(value = "layoutCaching", key = "0")
|
||||
public CategoryForView getCategoryForView() {
|
||||
return CategoryForView.createCategory(naCategoryRepository.getCategoryCount());
|
||||
@Override
|
||||
public CategoryViewForLayout getCategoryViewForLayout() {
|
||||
return CategoryViewForLayout.from(categoryRepositoryPort.getCategoryCount());
|
||||
}
|
||||
|
||||
/*
|
||||
- 티어별 카테고리 목록 찾기
|
||||
*/
|
||||
public List<Category> findCategoryByTier(int tier) {
|
||||
return categoryRepository.findAllByTierIs(tier);
|
||||
@Override
|
||||
public List<CategorySimpleDto> findCategoryByTier(int tier) {
|
||||
return categoryRepositoryPort.findAllByTierIs(tier)
|
||||
.stream()
|
||||
.map(category -> modelMapper.map(category, CategorySimpleDto.class))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -71,138 +80,114 @@ public class CategoryService {
|
||||
3-2 DB에 존재하지 않는경우 새로 생성
|
||||
3-3 DB에만 존재하는 카테고리는 삭제처리
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
@CacheEvict(value = {"layoutCaching", "seoCaching"}, allEntries = true)
|
||||
public void changeCategory(List<CategorySimpleView> categoryList) {
|
||||
public void changeCategory(List<CategorySimpleDto> categoryList) {
|
||||
|
||||
// 1.카테고리 리스트 순서 작성
|
||||
sortingOrder(categoryList);
|
||||
CategorySimpleDto.sortByOrder(categoryList);
|
||||
// 2. 기존 DB 저장된 카테고리 리스트 불러오기
|
||||
List<Category> categoryListFromDb = categoryRepository.findAllWithoutDummy();
|
||||
List<Category> categoryListFromDb = categoryRepositoryPort.findAllWithoutDummy();
|
||||
|
||||
// 3. 카테고리 변경 루프
|
||||
// 3. 카테고리 변경
|
||||
while (!categoryList.isEmpty()) {
|
||||
CategorySimpleView categorySimpleView = categoryList.get(0);
|
||||
CategorySimpleDto categorySimpleDto = categoryList.get(0);
|
||||
categoryList.remove(0);
|
||||
|
||||
// 부모카테고리인경우
|
||||
if (categorySimpleView.getTier() == 1) {
|
||||
|
||||
if (categorySimpleDto.getTier() == 1) {
|
||||
Category pCategory = null;
|
||||
|
||||
// 부모카테고리가 기존에 존재 x
|
||||
if (categorySimpleView.getId() == null) {
|
||||
pCategory = createNewCategory(categorySimpleView, null);
|
||||
// 신규 부모인경우
|
||||
if (categorySimpleDto.getId() == null) {
|
||||
pCategory = createNewCategory(categorySimpleDto, null);
|
||||
}
|
||||
// 부모카테고리가 기존에 존재 o
|
||||
// 기존 부모인경우
|
||||
else {
|
||||
for (int i = 0; i < categoryListFromDb.size(); i++) {
|
||||
if (categoryListFromDb.get(i).getId().equals(categorySimpleView.getId())) {
|
||||
if (categoryListFromDb.get(i).getId().equals(categorySimpleDto.getId())) {
|
||||
pCategory = categoryListFromDb.get(i);
|
||||
categoryListFromDb.remove(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
pCategory.updateCategory(
|
||||
categorySimpleView.getTitle(),
|
||||
categorySimpleView.getTier(),
|
||||
categorySimpleView.getPOrder(),
|
||||
categorySimpleView.getCOrder(),
|
||||
categorySimpleDto.getTitle(),
|
||||
categorySimpleDto.getTier(),
|
||||
categorySimpleDto.getPOrder(),
|
||||
categorySimpleDto.getCOrder(),
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
while (!categoryList.isEmpty()) {
|
||||
|
||||
CategorySimpleView subCategorySimpleView = categoryList.get(0);
|
||||
if (subCategorySimpleView.getTier() == 1) break;
|
||||
CategorySimpleDto subCategorySimpleDto = categoryList.get(0);
|
||||
if (subCategorySimpleDto.getTier() == 1) break;
|
||||
categoryList.remove(0);
|
||||
|
||||
// 자식 카테고리인경우
|
||||
Category cCategory = null;
|
||||
// 카테고리가 기존에 존재 x
|
||||
if (subCategorySimpleView.getId() == null) {
|
||||
cCategory = createNewCategory(subCategorySimpleView, pCategory.getTitle());
|
||||
if (subCategorySimpleDto.getId() == null) {
|
||||
cCategory = createNewCategory(subCategorySimpleDto, pCategory.getTitle());
|
||||
}
|
||||
// 카테고리가 기존에 존재 o
|
||||
else {
|
||||
for (int i = 0; i < categoryListFromDb.size(); i++) {
|
||||
if (categoryListFromDb.get(i).getId().equals(subCategorySimpleView.getId())) {
|
||||
if (categoryListFromDb.get(i).getId().equals(subCategorySimpleDto.getId())) {
|
||||
cCategory = categoryListFromDb.get(i);
|
||||
categoryListFromDb.remove(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
cCategory.updateCategory(
|
||||
subCategorySimpleView.getTitle(),
|
||||
subCategorySimpleView.getTier(),
|
||||
subCategorySimpleView.getPOrder(),
|
||||
subCategorySimpleView.getCOrder(),
|
||||
subCategorySimpleDto.getTitle(),
|
||||
subCategorySimpleDto.getTier(),
|
||||
subCategorySimpleDto.getPOrder(),
|
||||
subCategorySimpleDto.getCOrder(),
|
||||
pCategory);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 3-3 불일치 카테고리 전부 삭제
|
||||
categoryRepository.deleteAll(categoryListFromDb);
|
||||
categoryRepositoryPort.deleteAll(categoryListFromDb);
|
||||
}
|
||||
|
||||
/*
|
||||
- 새로운 카테고리 생성하기
|
||||
- 상위 카테고리 존재 유무 분기
|
||||
*/
|
||||
private Category createNewCategory(CategorySimpleView categorySimpleView, String parent) {
|
||||
private Category createNewCategory(CategorySimpleDto categorySimpleDto, String parent) {
|
||||
Category parentCategory = null;
|
||||
if (parent != null) {
|
||||
parentCategory = categoryRepository.findByTitle(parent)
|
||||
parentCategory = categoryRepositoryPort.findByTitle(parent)
|
||||
.orElseThrow(() -> new IllegalArgumentException("NotFoundCategoryException"));
|
||||
}
|
||||
|
||||
Category category = Category.builder()
|
||||
.title(categorySimpleView.getTitle())
|
||||
.pSortNum(categorySimpleView.getPOrder())
|
||||
.cSortNum(categorySimpleView.getCOrder())
|
||||
.tier(categorySimpleView.getTier())
|
||||
.title(categorySimpleDto.getTitle())
|
||||
.pSortNum(categorySimpleDto.getPOrder())
|
||||
.cSortNum(categorySimpleDto.getCOrder())
|
||||
.tier(categorySimpleDto.getTier())
|
||||
.parents(parentCategory)
|
||||
.build();
|
||||
categoryRepository.save(category);
|
||||
categoryRepositoryPort.save(category);
|
||||
return category;
|
||||
}
|
||||
|
||||
/*
|
||||
- 카테고리 변경을 위해 카테고리의 순번을 작성하는 로직
|
||||
*/
|
||||
private void sortingOrder(List<CategorySimpleView> categoryList) {
|
||||
int pOrderIndex = 0;
|
||||
int cOrderIndex = 0;
|
||||
|
||||
//티어별 트리구조로 순서 작성 로직
|
||||
for (CategorySimpleView categoryDto : categoryList) {
|
||||
|
||||
if (categoryDto.getTier() == 1) {
|
||||
cOrderIndex = 0;
|
||||
categoryDto.setPOrder(++pOrderIndex);
|
||||
categoryDto.setCOrder(cOrderIndex);
|
||||
} else {
|
||||
categoryDto.setPOrder(pOrderIndex);
|
||||
categoryDto.setCOrder(++cOrderIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
- 최초 필수 더미 카테고리 추가 코드
|
||||
*/
|
||||
// /*
|
||||
// - 최초 필수 더미 카테고리 추가 코드
|
||||
// */
|
||||
// @PostConstruct
|
||||
private void insertDummyCategory() {
|
||||
if(categoryRepository.findByTitle("total")==null) {
|
||||
Category category0 = Category.builder()
|
||||
.tier(0)
|
||||
.title("total")
|
||||
.pSortNum(0)
|
||||
.cSortNum(0)
|
||||
.build();
|
||||
categoryRepository.save(category0);
|
||||
}
|
||||
}
|
||||
// private void insertDummyCategory() {
|
||||
// if(categoryRepositoryPort.findByTitle("total")==null) {
|
||||
// Category category0 = Category.builder()
|
||||
// .tier(0)
|
||||
// .title("total")
|
||||
// .pSortNum(0)
|
||||
// .cSortNum(0)
|
||||
// .build();
|
||||
// categoryRepositoryPort.save(category0);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package myblog.blog.category.appliacation.port.incomming;
|
||||
|
||||
import myblog.blog.category.appliacation.port.response.CategorySimpleDto;
|
||||
import myblog.blog.category.appliacation.port.response.CategoryViewForLayout;
|
||||
import myblog.blog.category.domain.Category;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface CategoryUseCase {
|
||||
Category findCategory(String title);
|
||||
List<Category> getAllCategories();
|
||||
List<CategorySimpleDto> getCategorytCountList();
|
||||
CategoryViewForLayout getCategoryViewForLayout();
|
||||
List<CategorySimpleDto> findCategoryByTier(int tier);
|
||||
void changeCategory(List<CategorySimpleDto> categoryList);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package myblog.blog.category.appliacation.port.outgoing;
|
||||
|
||||
import myblog.blog.category.appliacation.port.response.CategorySimpleDto;
|
||||
import myblog.blog.category.domain.Category;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public interface CategoryRepositoryPort {
|
||||
Optional<Category> findByTitle(String title);
|
||||
List<Category> findAll();
|
||||
List<CategorySimpleDto> getCategoryCount();
|
||||
List<Category> findAllByTierIs(int tier);
|
||||
List<Category> findAllWithoutDummy();
|
||||
void deleteAll(List<Category> categoryListFromDb);
|
||||
void save(Category category);
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package myblog.blog.category.appliacation.port.response;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
- 범용 카테고리 DTO
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@ToString
|
||||
public class CategorySimpleDto implements Cloneable {
|
||||
|
||||
private Long id;
|
||||
@NotBlank(message = "카테고리명은 공백일 수 없습니다.")
|
||||
private String title;
|
||||
private int tier;
|
||||
private int count;
|
||||
private int pOrder;
|
||||
private int cOrder;
|
||||
|
||||
@Override
|
||||
public CategorySimpleDto clone() {
|
||||
try {
|
||||
return (CategorySimpleDto) super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
/*
|
||||
- 카테고리 변경을 위해 카테고리의 순번을 작성하는 로직
|
||||
*/
|
||||
static public void sortByOrder(List<CategorySimpleDto> categoryList) {
|
||||
int pOrderIndex = 0;
|
||||
int cOrderIndex = 0;
|
||||
|
||||
//티어별 트리구조로 순서 작성 로직
|
||||
for (CategorySimpleDto categorySimpleDto : categoryList) {
|
||||
if (categorySimpleDto.getTier() == 1) {
|
||||
cOrderIndex = 0;
|
||||
categorySimpleDto.setPOrder(++pOrderIndex);
|
||||
categorySimpleDto.setCOrder(cOrderIndex);
|
||||
} else {
|
||||
categorySimpleDto.setPOrder(pOrderIndex);
|
||||
categorySimpleDto.setCOrder(++cOrderIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package myblog.blog.category.appliacation.port.response;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
- 레이아웃용 트리구조 카테고리 리스트
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class CategoryViewForLayout {
|
||||
|
||||
private int count;
|
||||
private String title;
|
||||
private Long id;
|
||||
private int pOrder;
|
||||
private int cOrder;
|
||||
// 트리구조를 갖기 위한 리스트
|
||||
private List<CategoryViewForLayout> categoryTCountList = new ArrayList<>();
|
||||
|
||||
/*
|
||||
- 스태틱 생성 메서드
|
||||
*/
|
||||
public static CategoryViewForLayout from(List<CategorySimpleDto> crList) {
|
||||
return recursiveBuildFromCategoryDto(0, crList);
|
||||
}
|
||||
|
||||
/*
|
||||
- 재귀호출로 트리구조 생성
|
||||
1. DTO객체 생성후 소스를 큐처리로 순차적 매핑
|
||||
2. Depth 변화시 재귀 호출 / 재귀 탈출
|
||||
3. 탈출시 상위 카테고리 list로 삽입하여 트리구조 작성
|
||||
*/
|
||||
private static CategoryViewForLayout recursiveBuildFromCategoryDto(int tier, List<CategorySimpleDto> source) {
|
||||
|
||||
CategoryViewForLayout categoryViewForLayout = new CategoryViewForLayout();
|
||||
|
||||
while (!source.isEmpty()) {
|
||||
CategorySimpleDto cSource = source.get(0);
|
||||
|
||||
if (cSource.getTier() == tier) {
|
||||
if(categoryViewForLayout.getTitle() != null
|
||||
&& !categoryViewForLayout.getTitle().equals(cSource.getTitle())){
|
||||
return categoryViewForLayout;
|
||||
}
|
||||
categoryViewForLayout.setTitle(cSource.getTitle());
|
||||
categoryViewForLayout.setCount(cSource.getCount());
|
||||
categoryViewForLayout.setId(cSource.getId());
|
||||
categoryViewForLayout.setCOrder(cSource.getCOrder());
|
||||
categoryViewForLayout.setPOrder(cSource.getPOrder());
|
||||
source.remove(0);
|
||||
} else if (cSource.getTier() > tier) {
|
||||
CategoryViewForLayout sub = recursiveBuildFromCategoryDto(tier + 1, source);
|
||||
categoryViewForLayout.getCategoryTCountList().add(sub);
|
||||
} else {
|
||||
return categoryViewForLayout;
|
||||
}
|
||||
}
|
||||
return categoryViewForLayout;
|
||||
}
|
||||
|
||||
private CategoryViewForLayout() {
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
package myblog.blog.category.controller;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import myblog.blog.shared.exception.CustomFormException;
|
||||
import myblog.blog.shared.exception.ListValidator;
|
||||
import myblog.blog.category.dto.CategoryForView;
|
||||
import myblog.blog.category.dto.CategorySimpleView;
|
||||
import myblog.blog.category.service.CategoryService;
|
||||
import myblog.blog.comment.dto.CommentDtoForLayout;
|
||||
import myblog.blog.comment.service.CommentService;
|
||||
import org.modelmapper.ModelMapper;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.Errors;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Controller
|
||||
@RequiredArgsConstructor
|
||||
public class CategoryController {
|
||||
|
||||
private final CategoryService categoryService;
|
||||
private final CommentService commentService;
|
||||
private final ModelMapper modelMapper;
|
||||
private final ListValidator listValidator;
|
||||
|
||||
/*
|
||||
- 카테고리 수정폼 조회
|
||||
*/
|
||||
@GetMapping("/edit/category")
|
||||
public String editCategoryForm(Model model) {
|
||||
|
||||
// DTO 매핑 전처리
|
||||
List<CategorySimpleView> categoryList = categoryService.getCategorytCountList();
|
||||
List<CategorySimpleView> copyList = cloneList(categoryList);
|
||||
copyList.remove(0);
|
||||
CategoryForView categoryForView = CategoryForView.createCategory(categoryList);
|
||||
List<CommentDtoForLayout> comments = commentService.recentCommentList();
|
||||
//
|
||||
|
||||
model.addAttribute("categoryForEdit", copyList);
|
||||
model.addAttribute("category", categoryForView);
|
||||
model.addAttribute("commentsList", comments);
|
||||
|
||||
return "admin/categoryEdit";
|
||||
}
|
||||
|
||||
/*
|
||||
- 카테고리 수정 요청
|
||||
*/
|
||||
@PostMapping("/category/edit")
|
||||
public @ResponseBody
|
||||
String editCategory(@RequestBody List<CategorySimpleView> categoryList, Errors errors) {
|
||||
// List DTO 검증을 위한 커스텀 validator
|
||||
listValidator.validate(categoryList, errors);
|
||||
// 유효성 검사
|
||||
if (errors.hasErrors()) {
|
||||
throw new CustomFormException(Objects.requireNonNull(errors.getFieldError()).getDefaultMessage());
|
||||
}
|
||||
|
||||
categoryService.changeCategory(categoryList);
|
||||
return "변경 성공";
|
||||
}
|
||||
private List<CategorySimpleView> cloneList(List<CategorySimpleView> categoryList) {
|
||||
return categoryList
|
||||
.stream()
|
||||
.map(categoryNormalDto ->
|
||||
modelMapper.map(categoryNormalDto, CategorySimpleView.class))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,9 @@ package myblog.blog.category.domain;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import myblog.blog.article.domain.Article;
|
||||
|
||||
import myblog.blog.shared.BasicEntity;
|
||||
import myblog.blog.article.domain.Article;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
package myblog.blog.category.dto;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
- 레이아웃용 트리구조 카테고리 리스트
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class CategoryForView {
|
||||
|
||||
private int count;
|
||||
private String title;
|
||||
private Long id;
|
||||
private int pOrder;
|
||||
private int cOrder;
|
||||
// 트리구조를 갖기 위한 리스트
|
||||
private List<CategoryForView> categoryTCountList = new ArrayList<>();
|
||||
|
||||
/*
|
||||
- 스태틱 생성 메서드
|
||||
*/
|
||||
public static CategoryForView createCategory(List<CategorySimpleView> crList) {
|
||||
return recursiveBuildFromCategoryDto(0, crList);
|
||||
}
|
||||
|
||||
/*
|
||||
- 재귀호출로 트리구조 생성
|
||||
1. DTO객체 생성후 소스를 큐처리로 순차적 매핑
|
||||
2. Depth 변화시 재귀 호출 / 재귀 탈출
|
||||
3. 탈출시 상위 카테고리 list로 삽입하여 트리구조 작성
|
||||
*/
|
||||
private static CategoryForView recursiveBuildFromCategoryDto(int tier, List<CategorySimpleView> source) {
|
||||
|
||||
CategoryForView categoryForView = new CategoryForView();
|
||||
|
||||
while (!source.isEmpty()) {
|
||||
CategorySimpleView cSource = source.get(0);
|
||||
|
||||
if (cSource.getTier() == tier) {
|
||||
if(categoryForView.getTitle() != null
|
||||
&& !categoryForView.getTitle().equals(cSource.getTitle())){
|
||||
return categoryForView;
|
||||
}
|
||||
categoryForView.setTitle(cSource.getTitle());
|
||||
categoryForView.setCount(cSource.getCount());
|
||||
categoryForView.setId(cSource.getId());
|
||||
categoryForView.setCOrder(cSource.getCOrder());
|
||||
categoryForView.setPOrder(cSource.getPOrder());
|
||||
source.remove(0);
|
||||
} else if (cSource.getTier() > tier) {
|
||||
CategoryForView sub = recursiveBuildFromCategoryDto(tier + 1, source);
|
||||
categoryForView.getCategoryTCountList().add(sub);
|
||||
} else {
|
||||
return categoryForView;
|
||||
}
|
||||
}
|
||||
return categoryForView;
|
||||
}
|
||||
|
||||
private CategoryForView() {
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package myblog.blog.category.dto;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/*
|
||||
- 범용 카테고리 DTO
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@ToString
|
||||
public class CategorySimpleView {
|
||||
|
||||
private Long id;
|
||||
@NotBlank(message = "카테고리명은 공백일 수 없습니다.")
|
||||
private String title;
|
||||
private int tier;
|
||||
private int count;
|
||||
private int pOrder;
|
||||
private int cOrder;
|
||||
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
package myblog.blog.member.controller;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import myblog.blog.category.dto.CategoryForView;
|
||||
import myblog.blog.category.service.CategoryService;
|
||||
import myblog.blog.category.appliacation.port.response.CategoryViewForLayout;
|
||||
import myblog.blog.category.appliacation.CategoryService;
|
||||
import myblog.blog.comment.dto.CommentDtoForLayout;
|
||||
import myblog.blog.comment.service.CommentService;
|
||||
import org.springframework.stereotype.Controller;
|
||||
@@ -12,7 +11,6 @@ import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Controller
|
||||
@RequiredArgsConstructor
|
||||
@@ -34,11 +32,11 @@ public class MemberController {
|
||||
}
|
||||
|
||||
// 레이아웃 DTO 전처리
|
||||
CategoryForView categoryForView = categoryService.getCategoryForView();
|
||||
CategoryViewForLayout categoryViewForLayout = categoryService.getCategoryViewForLayout();
|
||||
List<CommentDtoForLayout> comments = commentService.recentCommentList();
|
||||
//
|
||||
|
||||
model.addAttribute("category",categoryForView);
|
||||
model.addAttribute("category", categoryViewForLayout);
|
||||
model.addAttribute("commentsList", comments);
|
||||
|
||||
return "login";
|
||||
|
||||
@@ -9,7 +9,7 @@ import lombok.RequiredArgsConstructor;
|
||||
|
||||
import myblog.blog.article.domain.Article;
|
||||
import myblog.blog.category.domain.Category;
|
||||
import myblog.blog.category.service.CategoryService;
|
||||
import myblog.blog.category.appliacation.CategoryService;
|
||||
import org.jdom2.*;
|
||||
import org.jdom2.output.*;
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package myblog.blog.shared.queries;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import myblog.blog.category.dto.CategoryForView;
|
||||
import myblog.blog.category.service.CategoryService;
|
||||
import myblog.blog.category.appliacation.port.response.CategoryViewForLayout;
|
||||
import myblog.blog.category.appliacation.CategoryService;
|
||||
import myblog.blog.comment.dto.CommentDtoForLayout;
|
||||
import myblog.blog.comment.service.CommentService;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -21,9 +21,9 @@ public class LayoutRenderingQueries {
|
||||
- 레이아웃에 필요한 모델 담기
|
||||
*/
|
||||
public void AddLayoutTo(Model model) {
|
||||
CategoryForView categoryForView = categoryService.getCategoryForView();
|
||||
CategoryViewForLayout categoryViewForLayout = categoryService.getCategoryViewForLayout();
|
||||
List<CommentDtoForLayout> comments = commentService.recentCommentList();
|
||||
model.addAttribute("category", categoryForView);
|
||||
model.addAttribute("category", categoryViewForLayout);
|
||||
model.addAttribute("commentsList", comments);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
<li class="border-top my-3"></li>
|
||||
<li class="mb-1 superCategory btn fs-5"><a th:href="@{/article/list(category=total,tier=0,page=1)}"
|
||||
th:text="|전체글(${category.getCount()})|">토탈</a></li>
|
||||
<a th:href="@{/edit/category}" sec:authorize="hasRole('ADMIN')" class="me-0 ps-0 btn"><i class="fas fa-pen"></i></a>
|
||||
<a th:href="@{/category/edit}" sec:authorize="hasRole('ADMIN')" class="me-0 ps-0 btn"><i class="fas fa-pen"></i></a>
|
||||
|
||||
<li class="mb-1" th:each="superCategory : ${category.getCategoryTCountList()}">
|
||||
<div class="btn-group">
|
||||
|
||||
@@ -4,7 +4,7 @@ import myblog.blog.article.domain.Article
|
||||
import myblog.blog.article.application.ArticleService
|
||||
import myblog.blog.seo.application.SiteMapService
|
||||
import myblog.blog.category.domain.Category
|
||||
import myblog.blog.category.service.CategoryService
|
||||
import myblog.blog.category.appliacation.CategoryService
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
//import org.junit.Test
|
||||
|
||||
Reference in New Issue
Block a user