阳光沙滩博客系统-门户文章模块

# 获取文章列表(条件查询)

门户,首页有比较多的内容,包括分类呀,文章列表,轮播图,广告之类的吧。

这个接口,可以获取到文章列表

/**
     * 获取文章列表
     * 权限,所有用户
     * 状态:必须已经发布的,置顶的由另外一个接口获取,其他的不可以从此接口获取
     *
     * @param page
     * @param size
     * @return
     */
@GetMapping("/list/{page}/{size}")
public ResponseResult listArticle(@PathVariable("page") int page, @PathVariable("size") int size) {
    return articleService.listArticles(page, size, null, null, Constants.Article.STATE_PUBLISH);
}
1
2
3
4
5
6
7
8
9
10
11
12
13

实现代码,这是公用代码了,管理中心的代码一样

@Override
public ResponseResult listArticlesByLabel(int page, int size, String label) {
    page = checkPage(page);
    size = checkSize(size);
    Sort sort = new Sort(Sort.Direction.DESC, "createTime");
    Pageable pageable = PageRequest.of(page - 1, size, sort);
    Page<ArticleNoContent> all = articleNoContentDao.findAll(new Specification<ArticleNoContent>() {
        @Override
        public Predicate toPredicate(Root<ArticleNoContent> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
            Predicate labelPre = criteriaBuilder.like(root.get("labels").as(String.class), "%" + label + "%");
            Predicate statePublishPre = criteriaBuilder.equal(root.get("state").as(String.class), Constants.Article.STATE_PUBLISH);
            Predicate stateTopPre = criteriaBuilder.equal(root.get("state").as(String.class), Constants.Article.STATE_TOP);
            Predicate or = criteriaBuilder.or(statePublishPre, stateTopPre);
            return criteriaBuilder.and(or, labelPre);
        }
    }, pageable);
    return ResponseResult.SUCCESS("获取文章列表成功.").setData(all);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 获取文章详情

这只可以获取到已经发表和置顶的文章

/**
     * 获取文章详情
     * 权限:任意用户
     * <p>
     * 内容过滤:只允许拿置顶的,或者已经发布的
     * 其他的获取:比如说草稿、只能对应用户获取。已经删除的,只有管理员才可以获取.
     *
     * @param articleId
     * @return
     */
@GetMapping("/{articleId}")
public ResponseResult getArticleDetail(@PathVariable("articleId") String articleId) {
    return articleService.getArticleById(articleId);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

实现:

/**
     * 如果有审核机制:审核中的文章-->只有管理员和作者自己可以获取
     * 有草稿、删除、置顶的、已经发布的
     * 删除的不能获取、其他都可以获取
     *
     * @param articleId
     * @return
     */
@Override
public ResponseResult getArticleById(String articleId) {
    //查询出文章
    Article article = articleDao.findOneById(articleId);
    if (article == null) {
        return ResponseResult.FAILED("文章不存在.");
    }
    //判断文章状态
    String state = article.getState();
    if (Constants.Article.STATE_PUBLISH.equals(state) ||
        Constants.Article.STATE_TOP.equals(state)) {
        //可以返回
        return ResponseResult.SUCCESS("获取文章成功.").setData(article);
    }
    //如果是删除/草稿,需要管理角色
    SobUser sobUser = userService.checkSobUser();
    if (sobUser == null || !Constants.User.ROLE_ADMIN.equals(sobUser.getRoles())) {
        return ResponseResult.PERMISSION_DENIED();
    }
    //返回结果
    return ResponseResult.SUCCESS("获取文章成功.").setData(article);
}

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

# 获取置顶文章

获取文章列表置顶,是因为我们希望不管用户切换到哪一页,置顶的内容还是在顶部。

@GetMapping("/top")
public ResponseResult getTopArticle() {
    return articleService.listTopArticles();
}
1
2
3
4

实现:

/**
     * 获取置顶文章
     * 跟权限无关
     * 状态必须置顶
     *
     * @return
     */
@Override
public ResponseResult listTopArticles() {
    List<Article> result = articleDao.findAll(new Specification<Article>() {
        @Override
        public Predicate toPredicate(Root<Article> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
            return criteriaBuilder.equal(root.get("state").as(String.class), Constants.Article.STATE_TOP);
        }
    });
    return ResponseResult.SUCCESS("获取置顶文章列表成功.").setData(result);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 获取标签列表

我们博客首页,需要有一个标签云,所以就有这个接口啦!

然后用户点击标签,就可以根据标签去后去对应的文章了。

API接口

/**
     * 获取标签云,用户点击标签,就会通过标签获取相关的文章列表
     * 任意用户
     *
     * @param size
     * @return
     */
@GetMapping("/label/{size}")
public ResponseResult getLabels(@PathVariable("size") int size) {
    return articleService.listLabels(size);
}
1
2
3
4
5
6
7
8
9
10
11

实现

@Override
public ResponseResult listLabels(int size) {
    size = this.checkSize(size);
    Sort sort = new Sort(Sort.Direction.DESC, "count");
    Pageable pageable = PageRequest.of(0, size, sort);
    Page<Label> all = labelDao.findAll(pageable);
    return ResponseResult.SUCCESS("获取标签列表成功.").setData(all);
}
1
2
3
4
5
6
7
8

# 根据标签获取文章列表

@GetMapping("/list/label/{label}/{page}/{size}")
public ResponseResult listArticleByLabel(@PathVariable("label") String label,
                                         @PathVariable("page") int page, @PathVariable("size") int size) {
    return articleService.listArticlesByLabel(page, size, label);
}
1
2
3
4
5

注意一下状态

@Override
public ResponseResult listArticlesByLabel(int page, int size, String label) {
    page = checkPage(page);
    size = checkSize(size);
    Sort sort = new Sort(Sort.Direction.DESC, "createTime");
    Pageable pageable = PageRequest.of(page - 1, size, sort);
    Page<ArticleNoContent> all = articleNoContentDao.findAll(new Specification<ArticleNoContent>() {
        @Override
        public Predicate toPredicate(Root<ArticleNoContent> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
            Predicate labelPre = criteriaBuilder.like(root.get("labels").as(String.class), "%" + label + "%");
            Predicate statePublishPre = criteriaBuilder.equal(root.get("state").as(String.class), Constants.Article.STATE_PUBLISH);
            Predicate stateTopPre = criteriaBuilder.equal(root.get("state").as(String.class), Constants.Article.STATE_TOP);
            Predicate or = criteriaBuilder.or(statePublishPre, stateTopPre);
            return criteriaBuilder.and(or, labelPre);
        }
    }, pageable);
    return ResponseResult.SUCCESS("获取文章列表成功.").setData(all);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 获取推荐文章

推荐文章,这里只是一个伪装的算法,不是真的。真的推荐同学们可以学习一下大数据。

接口

/**
     * 通过标签来计算这个匹配度
     * 标签:有一个,或者多个(5个以内,包含5个)
     * 从里面随机拿一个标签出来--->每一次获取的推荐文章,不那么雷同,种一样就雷同了
     * 通过标签去查询类似的文章,所包含此标签的文章
     * 如果没有相关文章,则从数据中获取最新的文章的
     *
     * @param articleId
     * @return
     */
@GetMapping("/recommend/{articleId}/{size}")
public ResponseResult getRecommendArticles(@PathVariable("articleId") String articleId, @PathVariable("size") int size) {
    return articleService.listRecommendArticle(articleId, size);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

实现代码:

/**
     * 获取推荐文章,通过标签来计算
     *
     * @param articleId
     * @param size
     * @return
     */
@Override
public ResponseResult listRecommendArticle(String articleId, int size) {
    //查询文章,不需要文章,只需要标签
    String labels = articleDao.listArticleLabelsById(articleId);
    //打散标签
    List<String> labelList = new ArrayList<>();
    if (!labels.contains("-")) {
        labelList.add(labels);
    } else {
        labelList.addAll(Arrays.asList(labels.split("-")));
    }
    //从列表中随即获取一标签,查询与此标签相似的文章
    String targetLabel = labelList.get(random.nextInt(labelList.size()));
    log.info("targetLabel == > " + targetLabel);
    List<ArticleNoContent> likeResultList = articleNoContentDao.listArticleByLikeLabel("%" + targetLabel + "%", articleId, size);
    //判断它的长度
    if (likeResultList.size() < size) {
        //说明不够数量,获取最新的文章作为补充
        int dxSize = size - likeResultList.size();
        List<ArticleNoContent> dxList = articleNoContentDao.listLastedArticleBySize(articleId, dxSize);
        //这个写法有一定的弊端,会把可能前面找到的也加进来,概率比较小,如果文章比较多
        likeResultList.addAll(dxList);
    }
    return ResponseResult.SUCCESS("获取推荐文章成功.").setData(likeResultList);
}

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

# 获取分类内容

@GetMapping("/categories")
public ResponseResult getCategories() {
    return categoryService.listCategories();
}
1
2
3
4

获取分类实现,这里注意一下,前端门户只能获取到普通状态的,如果已经禁用,或者删除的其他的不可以获取到哦。

管理中心可以获取到所有。

@Override
public ResponseResult listCategories() {
    //参数检查
    //创建条件
    Sort sort = new Sort(Sort.Direction.DESC, "createTime", "order");
    //判断用户角色,普通 用户/未登录用户,只能获取到正常的category
    //管理员帐户,可以拿到所有的分类.
    SobUser sobUser = userService.checkSobUser();
    List<Category> categories;
    if (sobUser == null || !Constants.User.ROLE_ADMIN.equals(sobUser.getRoles())) {
        //只能获取到正常的category
        categories = categoryDao.listCategoriesByState("1");
    } else {
        //查询
        categories = categoryDao.findAll(sort);
    }
    //返回结果
    return ResponseResult.SUCCESS("获取分类列表成功.").setData(categories);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 根据分类获取文章列表

@GetMapping("/list/{categoryId}/{page}/{size}")
public ResponseResult listArticleByCategoryId(@PathVariable("categoryId") String categoryId,
                                              @PathVariable("page") int page,
                                              @PathVariable("size") int size) {
    return articleService.listArticles(page, size, null, categoryId, Constants.Article.STATE_PUBLISH);
}
1
2
3
4
5
6

实现

@Override
public ResponseResult listArticlesByLabel(int page, int size, String label) {
    page = checkPage(page);
    size = checkSize(size);
    Sort sort = new Sort(Sort.Direction.DESC, "createTime");
    Pageable pageable = PageRequest.of(page - 1, size, sort);
    Page<ArticleNoContent> all = articleNoContentDao.findAll(new Specification<ArticleNoContent>() {
        @Override
        public Predicate toPredicate(Root<ArticleNoContent> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
            Predicate labelPre = criteriaBuilder.like(root.get("labels").as(String.class), "%" + label + "%");
            Predicate statePublishPre = criteriaBuilder.equal(root.get("state").as(String.class), Constants.Article.STATE_PUBLISH);
            Predicate stateTopPre = criteriaBuilder.equal(root.get("state").as(String.class), Constants.Article.STATE_TOP);
            Predicate or = criteriaBuilder.or(statePublishPre, stateTopPre);
            return criteriaBuilder.and(or, labelPre);
        }
    }, pageable);
    return ResponseResult.SUCCESS("获取文章列表成功.").setData(all);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
上次更新: 2022/03/28, 23:04:38