xiangpei
7 天以前 288ce585418550bbf2fd898fc01bc2ff9245f960
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
package cn.lili.modules.page.serviceimpl;
 
import cn.lili.cache.Cache;
import cn.lili.cache.CachePrefix;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.modules.page.entity.dos.Article;
import cn.lili.modules.page.entity.dos.ArticleCategory;
import cn.lili.modules.page.entity.enums.ArticleCategoryEnum;
import cn.lili.modules.page.entity.enums.ArticleEnum;
import cn.lili.modules.page.entity.vos.ArticleCategoryVO;
import cn.lili.modules.page.mapper.ArticleCategoryMapper;
import cn.lili.modules.page.service.ArticleCategoryService;
import cn.lili.modules.page.service.ArticleService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
 
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
 
/**
 * 文章分类业务层实现
 *
 * @author pikachu
 * @since 2020-05-5 15:10:16
 */
@Service
public class ArticleCategoryServiceImpl extends ServiceImpl<ArticleCategoryMapper, ArticleCategory> implements ArticleCategoryService {
 
    /**
     * 缓存
     */
    @Autowired
    private Cache cache;
    /**
     * 文章
     */
    @Autowired
    private ArticleService articleService;
    /**
     * 顶级父分类ID
     */
    private String parentId = "0";
    /**
     * 最大分类等级
     */
    private int maxLevel = 2;
 
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ArticleCategory saveArticleCategory(ArticleCategory articleCategory) {
        //非顶级分类
        if (articleCategory.getParentId() != null && !parentId.equals(articleCategory.getParentId())) {
            ArticleCategory parent = this.getById(articleCategory.getParentId());
            if (parent == null) {
                throw new ServiceException(ResultCode.ARTICLE_CATEGORY_PARENT_NOT_EXIST);
            }
            if (articleCategory.getLevel() >= maxLevel) {
                throw new ServiceException(ResultCode.ARTICLE_CATEGORY_BEYOND_TWO);
            }
        }
        articleCategory.setType(ArticleCategoryEnum.OTHER.name());
        this.save(articleCategory);
        //清除文章分类缓存
        this.clearCache();
        return articleCategory;
    }
 
 
    @Override
    public ArticleCategory updateArticleCategory(ArticleCategory articleCategory) {
        //非顶级分类校验是否存在
        if (!parentId.equals(articleCategory.getParentId())) {
            ArticleCategory parent = this.getById(articleCategory.getParentId());
            if (parent == null) {
                throw new ServiceException(ResultCode.ARTICLE_CATEGORY_PARENT_NOT_EXIST);
            }
            //替换catPath 根据path规则来匹配级别
            if (articleCategory.getLevel() >= maxLevel) {
                throw new ServiceException(ResultCode.ARTICLE_CATEGORY_BEYOND_TWO);
            }
        }
        //验证分类名称是否重复
        ArticleCategory category = this.getOne(
                new LambdaQueryWrapper<ArticleCategory>().eq(ArticleCategory::getArticleCategoryName, articleCategory.getArticleCategoryName()));
        if (category != null && !category.getId().equals(articleCategory.getId())) {
            throw new ServiceException(ResultCode.ARTICLE_CATEGORY_NAME_EXIST);
        }
        if (this.updateById(articleCategory)) {
            //清除文章分类
            this.clearCache();
            return category;
        }
        return null;
    }
 
    @Override
    public boolean deleteById(String id) {
 
        LambdaQueryWrapper<ArticleCategory> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(ArticleCategory::getParentId, id);
 
        //查看文章分类下是否有分类
        if (this.count(lambdaQueryWrapper) > 0) {
            throw new ServiceException(ResultCode.ARTICLE_CATEGORY_DELETE_ERROR);
        }
 
        //查看文章分类下是否有文章
        LambdaQueryWrapper<Article> articleLambdaQueryWrapper = new LambdaQueryWrapper<>();
        articleLambdaQueryWrapper.eq(Article::getCategoryId, id);
        if (articleService.count(articleLambdaQueryWrapper) > 0) {
            throw new ServiceException(ResultCode.ARTICLE_CATEGORY_HAS_ARTICLE);
        }
        //判断是否为默认的分类
        if (!this.getById(id).getType().equals(ArticleEnum.OTHER.name())) {
            throw new ServiceException(ResultCode.ARTICLE_CATEGORY_NO_DELETION);
        }
 
        //清除文章分类缓存
        this.clearCache();
        //删除文章分类
        return this.removeById(id);
    }
 
    @Override
    public List<ArticleCategoryVO> allChildren() {
        //从缓存取所有的分类
        Object all = cache.get(CachePrefix.ARTICLE_CATEGORY.getPrefix());
        List<ArticleCategoryVO> articleCategories;
        if (all == null) {
            //调用初始化分类缓存方法
            articleCategories = initCategory();
        } else {
            articleCategories = (List<ArticleCategoryVO>) all;
        }
        return articleCategories;
    }
 
    /**
     * 初始化所有文章分类
     *
     * @return 文章分类集合
     */
    private List<ArticleCategoryVO> initCategory() {
        List<ArticleCategory> articleCategories = this.list();
        List<ArticleCategoryVO> tree = new ArrayList<>();
        articleCategories.forEach(item -> {
            if (item.getLevel() == 0) {
                ArticleCategoryVO articleCategoryVO = new ArticleCategoryVO(item);
                initChild(articleCategoryVO, articleCategories);
                tree.add(articleCategoryVO);
            }
        });
        //对一级菜单排序
        tree.sort(new Comparator<ArticleCategoryVO>() {
            @Override
            public int compare(ArticleCategoryVO o1, ArticleCategoryVO o2) {
                return o1.getSort().compareTo(o2.getSort());
            }
        });
        cache.put(CachePrefix.ARTICLE_CATEGORY.getPrefix(), tree);
 
        return tree;
    }
 
    /**
     * 递归初始化子树
     *
     * @param tree              树结构
     * @param articleCategories 数据库对象集合
     */
    private void initChild(ArticleCategoryVO tree, List<ArticleCategory> articleCategories) {
        if (articleCategories == null) {
            return;
        }
        articleCategories.stream()
                .filter(item -> (item.getParentId().equals(tree.getId())))
                .forEach(child -> {
                    ArticleCategoryVO childTree = new ArticleCategoryVO(child);
                    initChild(childTree, articleCategories);
                    tree.getChildren().add(childTree);
                });
    }
 
    /**
     * 清除缓存中的文章分类
     */
    private void clearCache() {
        cache.remove(CachePrefix.ARTICLE_CATEGORY.getPrefix());
    }
 
 
    @Autowired
    public void setArticleService(ArticleService articleService) {
        this.articleService = articleService;
    }
}