说明
首页我们前面几节课已经全部做完成了,而我们某个标签、分类、关键字下的文章我们都是会放到列表页统一展示,这节课我们就把列表页也处理一下,我们列表页的模板用list.html
就可以了
分页展示进阶
数据量大导致分页太多的情况下我们如何处理分页
- 可以只显示当前页最近的几页数据
<ul th:if="${articlePage.totalPage>1}" class="lw-pagenation">
<li th:if="${articlePage.current != 1}"><a th:href="@{/}">首页</a></li>
<li th:each="num:${#numbers.sequence((articlePage.current < 3?1: articlePage.current -2) ,(articlePage.current < articlePage.totalPage -2?articlePage.current+2: articlePage.totalPage))}">
<a th:class="${articlePage.current eq num}?'lw-active':''" th:href="@{/(pn=${num})}"
th:text="${num}"></a>
</li>
<li th:if="${articlePage.current != articlePage.totalPage}">
<a th:href="@{/(pn=${articlePage.totalPage})}">尾页</a>
</li>
<li th:text="${'共 '+ articlePage.totalPage +' 页'}"></li>
</ul>
- 加上页码框
上一页 1 / 9 下一页 跳转[]
步骤分析
定义路由,我们希望的路由格式如下
- 分类路由:
/category/{分类ID}.html
- 标签路由:
/tag/{标签ID}.html
- 搜索路由:
/search.html?keywords={关键定}
- 分类路由:
面包屑的构建
- 分类面包屑:首页 / 分类大全 / 分类名称
- 标签面包屑:首页 / 标签 / 标签名称
- 搜索面包屑:首页 / 包含关键字 XX 的文章
- 标题的构建:XX - 站点名称
- 调用search接口进行查询
- 分页渲染
代码实现
文章列表的抽取
<th:block th:fragment="article(articleList)">
<article th:each="article:${articleList}" class="lw-article-item lw-posr">
<div class="lw-article-cover lw-posa lw-xs-hidden">
<img th:src="${@defaultImage.cover(article.cover)}" alt="">
</div>
<div class="lw-article-info">
<h2>
<a class="lw-xs-hidden"><span class="lw-category" th:text="${article.category.name}"></span></a>
<a th:href="@{/{id}.html(id=${article.id})}" th:text="${article.title}"></a>
</h2>
<p class="lw-desc" th:text="${article.summary()}"></p>
<p class="lw-text-hidden lw-article-more">
<i class="fa fa-clock-o lw-mr5"></i>
<th:block th:text="${#dates.format(article.created,'yyyy-MM-dd HH:mm')}"></th:block>
<i class="fa fa-eye lw-mr5 lw-ml10"></i>
<th:block th:text="${article.views}"></th:block>
<i class="fa fa-comment lw-ml10 lw-mr5"></i>
<th:block th:text="${article.commentCount}"></th:block>
<i class="fa fa-tag lw-ml10 lw-mr5"></i>
<a th:each="tag:${article.tags}" href="#" class="lw-mr5" th:title="${tag.name}" th:text="${tag.name +','}"></a>
</p>
</div>
</article>
</th:block>
分类列表
- 定义对应的路由
@GetMapping("/category/{id}.html")
public String categoryList(@PathVariable Integer id, @RequestParam(required = false, defaultValue = "1") Integer pn, Model model) {
Category category = categoryService.detail(id);
//todo 如果这个分类不存在的时候我们要处理一下
model.addAttribute("category", category);
ArticleSearch articleSearch = ArticleSearch.indexShow(pn, 1);
articleSearch.setCid(id);
PageHelper<Article> articlePage = articleService.search(articleSearch);
model.addAttribute("articlePage", articlePage);
return "list";
}
- 分类已经在search接口中支持过了,所以我们直接调用即可
- 分页渲染
<ul th:if="${articlePage.totalPage>1 and pageType eq 'category'}" class="lw-pagenation">
<li th:if="${articlePage.current != 1}"><a th:href="@{/category/{id}.html(id=${category.id})}">首页</a></li>
<li th:each="num:${#numbers.sequence((articlePage.current < 3?1: articlePage.current -2) ,(articlePage.current < articlePage.totalPage -2?articlePage.current+2: articlePage.totalPage))}">
<a th:class="${articlePage.current eq num}?'lw-active':''" th:href="@{/category/{id}.html(id=${category.id},pn=${num})}"
th:text="${num}"></a>
</li>
<li th:if="${articlePage.current != articlePage.totalPage}">
<a th:href="@{/category/{id}.html(id=${category.id},pn=${articlePage.totalPage})}">尾页</a>
</li>
<li th:text="${'共 '+ articlePage.totalPage +' 页'}"></li>
</ul>
标签列表
- 定义对应的路由
@GetMapping("/tag/{id}.html")
public String tagList(@PathVariable Integer id, @RequestParam(required = false, defaultValue = "1") Integer pn, Model model) {
Tag tag = tagService.detail(id);
//todo 如果这个分类不存在的时候我们要处理一下
model.addAttribute("tag", tag);
ArticleSearch articleSearch = ArticleSearch.indexShow(pn, );
articleSearch.setTid(id);
PageHelper<Article> articlePage = articleService.search(articleSearch);
model.addAttribute("articlePage", articlePage);
model.addAttribute("pageType", "tag");
return "list";
}
- 利用JPA的
join
操作查询标签列表下的所有
if (Objects.nonNull(search.getTid())) {
ListJoin<Article, Tag> join = root.join(root.getModel().getList("tags", Tag.class), JoinType.LEFT);
predicateList.add(builder.equal(join.get("id"), search.getTid()));
}
- 分页渲染
<ul th:if="${articlePage.totalPage>1 and pageType eq 'tag'}" class="lw-pagenation">
<li th:if="${articlePage.current != 1}"><a th:href="@{/tag/{id}.html(id=${tag.id})}">首页</a></li>
<li th:each="num:${#numbers.sequence((articlePage.current < 3?1: articlePage.current -2) ,(articlePage.current < articlePage.totalPage -2?articlePage.current+2: articlePage.totalPage))}">
<a th:class="${articlePage.current eq num}?'lw-active':''" th:href="@{/tag/{id}.html(id=${tag.id},pn=${num})}"
th:text="${num}"></a>
</li>
<li th:if="${articlePage.current != articlePage.totalPage}">
<a th:href="@{/tag/{id}.html(id=${tag.id},pn=${articlePage.totalPage})}">尾页</a>
</li>
<li th:text="${'共 '+ articlePage.totalPage +' 页'}"></li>
</ul>
搜索列表
- 定义对应的路由
@GetMapping("/search.html")
public String tagList(@RequestParam(required = false, defaultValue = "1") Integer pn, String keyword, Model model) {
//todo 如果这个分类不存在的时候我们要处理一下
model.addAttribute("keyword", keyword);
ArticleSearch articleSearch = ArticleSearch.indexShow(pn, 8);
articleSearch.setKeyword(keyword);
PageHelper<Article> articlePage = articleService.search(articleSearch);
model.addAttribute("articlePage", articlePage);
model.addAttribute("pageType", "search");
return "list";
}
- 在搜索接口中加入模糊匹配
Page<Article> articlePage = mapper.findAll((Specification<Article>) (root, query, builder) -> {
List<Predicate> predicateAnd = new ArrayList<>();
if (Objects.nonNull(search.getCid())) {
predicateAnd.add(builder.equal(root.get("category"), Category.builder().id(search.getCid()).build()));
}
if (Objects.nonNull(search.getStatus())) {
predicateAnd.add(builder.equal(root.get("status"), search.getStatus()));
}
if (Objects.nonNull(search.getType())) {
predicateAnd.add(builder.equal(root.get("type"), search.getType()));
}
if (!StringUtils.isEmptyOrWhitespace(search.getTitle())) {
predicateAnd.add(builder.like(root.get("title"), "%" + search.getTitle() + "%"));
}
if (Objects.nonNull(search.getTid())) {
ListJoin<Article, Tag> join = root.join(root.getModel().getList("tags", Tag.class), JoinType.LEFT);
predicateAnd.add(builder.equal(join.get("id"), search.getTid()));
}
List<Predicate> predicateOr = new ArrayList<>();
if (!StringUtils.isEmptyOrWhitespace(search.getKeyword())) {
// todo 如果可以话后面给大家 出一期进阶课,把这里的搜索换顾EleasticSearch
predicateOr.add(builder.like(root.get("title"), "%" + search.getKeyword() + "%"));
predicateOr.add(builder.like(root.get("content"), "%" + search.getKeyword() + "%"));
}
if (CollectionUtils.isEmpty(predicateOr)) {
return builder.and(predicateAnd.toArray(new Predicate[predicateAnd.size()]));
}
return query.where(builder.and(predicateAnd.toArray(new Predicate[predicateAnd.size()])), builder.or(predicateOr.toArray(new Predicate[predicateOr.size()]))).getRestriction();
}, pageable);
- 分页渲染
<ul th:if="${articlePage.totalPage>1 and pageType eq 'search'}" class="lw-pagenation">
<li th:if="${articlePage.current != 1}"><a th:href="@{/search.html(keyword=${keyword})}">首页</a></li>
<li th:each="num:${#numbers.sequence((articlePage.current < 3?1: articlePage.current -2) ,(articlePage.current < articlePage.totalPage -2?articlePage.current+2: articlePage.totalPage))}">
<a th:class="${articlePage.current eq num}?'lw-active':''" th:href="@{search.html(keyword=${keyword},pn=${num})}"
th:text="${num}"></a>
</li>
<li th:if="${articlePage.current != articlePage.totalPage}">
<a th:href="@{search.html(keyword=${keyword},pn=${articlePage.totalPage})}">尾页</a>
</li>
<li th:text="${'共 '+ articlePage.totalPage +' 页'}"></li>
</ul>
看看
多谢大佬分享
强强强
感谢作者!
感谢!