Mr丶冷文

文章 分类 评论
125 10 8391

站点介绍

冷文学习者(KEVINLU98.COM),记录一个北漂小码农的日常业余生活
友链申请地址(直接评论即可): 传送门

(十六)入口页的展示

MR丶冷文 2022-10-12 1143 0条评论 个人博客项目视频教程 javaspringboot个人博客博客项目

首页 / 正文
Freewind主题v1.5版本已发布,下载请移步Freewind 1.5,同时还有主题伴生插件Freewind Markdown,下载请移步 Freewind Markdown,有问题请在留言板,交换友链请直接在友链留言,我创建了一个主题交流群,有兴趣可以加下: 点此加入
报毒我说明一下,是因为我把主题的版权信息做了加密,其中用了eval,杀毒软件认为eval函数是一个危险的操作,这点介意的话请勿下载,我也没有强迫任何人去下载,也没有向大家收取一分钱的主题费用,所以也犯不着因为这些事情来喷我,喜欢就用,不喜欢就不用,就这么简单

发布于2022-10-28

说明

我们上节课处理了列表页,但我们还没有真正的入口页面到列表页面的跳转,比如分类列表、标签列表及搜索的入口,这节课我们就重点处理一下这里

处理描述信息中的非中英文字符

我们可以看到我们的列表页描述信息其实展示我是我们markdown的源代码,里面有大量的符号,而这些符号与我们的主要内容基本无关,所以我们可以把这些符号删除之后再展示摘要部分的内容

匹配中文的正则:\u4E00-\u9FA5

匹配英文的正则:a-zA-Z

public String summary() {
  String summary = this.content.replaceAll("[^\\u4E00-\\u9FA5a-zA-Z]", "");
  return summary.substring(0, Math.min(300, summary.length()));
}

分类列表

  • 模板:categroy.html
  • 路由:/category.html
  • 观察页面可以看到我们的分类列表需要如下信息

    • 分类名称(已有)
    • 分类描述(已有)
    • 分类下的文章数:可以查下count
    • 分类下文章的最后一次更新时间:可以查询文章列表后用updated进行排序
  • 代码实现
//articleMapper
Long countByCategory(Category category);

@Query(value = "select updated from blog_article where category_id=?1 order by updated desc limit 1", nativeQuery = true)
Date lastUpdated(Integer id);

// categoryService
@Cacheable
public List<Category> show() {
  return mapper.findAll().stream().peek(category -> {
    category.setArticleCount(articleMapper.countByCategory(category));
    category.setLastUpdated(articleMapper.lastUpdated(category.getId()));
  }).collect(Collectors.toList());
}
//IndexController
@GetMapping("/category.html")
public String category(Model model) {
  model.addAttribute("categories",categoryService.show());
  return "category";
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" lang="en">
  <head th:replace="common::header(~{::title},~{},~{})">
    <title th:text="${'分类大全 - '+@webSite.title}"></title>
  </head>
  <body>
    <th:block th:include="common::nav"></th:block>
    <div class="lw-container lw-main lw-posr">
      <div class="lw-left-list">
        <ol class="breadcrumb lw-crumb">
          <li><a href="/">首页</a></li>
          <li class="active">分类大全</li>
        </ol>
        <ul class="lw-category-list">
          <li th:each="category:${categories}">
            <a th:href="@{/category/{id}.html(id=${category.id})}">
              <i class="fa fa-folder lw-mr5"></i>
              <th:block th:text="${category.name}"></th:block>
              <span>(Total <th:block th:text="${category.articleCount}"></th:block> Articles)</span></a>
            <p th:text="${category.summary}"></p>
            <p class="lw-category-update">最后更新: <th:block th:text="${category.articleCount eq 0}?'1970-01-01':${#dates.format(category.lastUpdated,'yyyy-MM-dd')}"></th:block></p>
          </li>
        </ul>
      </div>
      <div class="lw-right-list lw-md-show lw-posa">
        <th:block th:include="common::right"></th:block>
      </div>
    </div>
    <th:block th:include="common::footer"></th:block>
  </body>
</html>

标签列表

  • 模板:tags.html
  • 路由:/tag.html
  • 观察页面可以看到我们的分类列表需要如下信息

    • 标签名称(已有)
    • 标签下的文章数:可以查下count
  • 代码实现
//tagMapper
@Query(value = "select count(1) from blog_article_tags where tags_id = ?1", nativeQuery = true)
Long articleCountByTid(Integer id);

//tagService
@Cacheable
public List<Tag> show() {
  return mapper.findAll().stream().peek(tag -> tag.setArticleCount(mapper.articleCountByTid(tag.getId()))).filter(tag -> tag.getArticleCount()>0).collect(Collectors.toList());
}
//IndexController
@GetMapping("/tag.html")
public String tag(Model model) {
  model.addAttribute("tagList", tagService.show());
  return "tags";
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" lang="en">
  <head th:replace="common::header(~{::title},~{},~{})">
    <title th:text="${'分类大全 - '+@webSite.title}"></title>
  </head>
  <body>
    <th:block th:include="common::nav"></th:block>
    <div class="lw-container lw-main lw-posr">
      <div class="lw-left-list">
        <ol class="breadcrumb lw-crumb">
          <li><a href="/static">首页</a></li>
          <li class="active">标签云</li>
        </ol>
        <div class="lw-tag-list">
          <a th:each="tag:${tagList}" th:href="@{/tag/{id}.html(id=${tag.id})}" th:title="${tag.name}">
            <th:block th:text="${tag.name}"></th:block>
            <span th:text="${tag.articleCount}"></span>
          </a>
        </div>
      </div>
      <div class="lw-right-list lw-md-show lw-posa">
        <th:block th:include="common::right"></th:block>
      </div>
    </div>
    <th:block th:include="common::footer"></th:block>
  </body>
</html>

搜索的入口

我们需要展示推荐关键字,这里我想的是用一个LRU做缓存展示20个最近使用的关键字,如果最近使用的关键字少于20个时我们用标签做补充

LRU:LRU中Least Recently Used 的缩写,这种算法认为最近使用过的数据是一个热门数据,下一次还有很大概率再次被使用,而最近很少被使用的数据,很大概率下次不会再使用了,当容器已经满了的时候把最近很少被使用的数据直接删除,这种算法最初是用于操作系统中的页面置换,现在也大多被使用于缓存过期策略

我们也认为最近被用户所搜索的关键字就是热门关键字,直接展示为推荐关键字

我们这里用LinkedHashSet做一个简单的LRU缓存

package cn.kevinlu98.common;


import java.util.ArrayList;
import java.util.LinkedHashSet;

import java.util.List;
import java.util.Set;

/**
 * Author: Mr丶冷文
 * Date: 2022/10/12 18:06
 * Email: kevinlu98@qq.com
 * Description:
 */
public class LRUCache {
  private final Set<String> cache = new LinkedHashSet<>();

  private final int limit;

  public LRUCache(int limit) {
    this.limit = limit;
  }

  public int size() {
    return cache.size();
  }

  public List<String> list() {
    return new ArrayList<>(cache);
  }

  public void add(String keyword) {
    while (cache.size() >= limit) {
      cache.remove(cache.stream().findFirst().orElse(null));
    }
    cache.remove(keyword);
    cache.add(keyword);
  }

}

Controller的变动

@ModelAttribute
private void indexModel(Model model) {
  // todo 可以在这里定义这个controller公用的model的属性
  model.addAttribute("friendlies", friendlyService.list());
  model.addAttribute("tags", tagService.list(30));
  model.addAttribute("navigations", navigationService.show());
  model.addAttribute("hots", articleService.hotList(5));
  int size = lruCache.size();
  List<String> keywords = lruCache.list();
  Collections.reverse(keywords);
  if (size < 10) {
    keywords.addAll(tagService.list(10 - size).stream().map(Tag::getName).collect(Collectors.toList()));
  }
  model.addAttribute("keywords", keywords);
}

@GetMapping("/search.html")
public String search(@RequestParam(required = false, defaultValue = "1") Integer pn, String keyword, Model model) {
  lruCache.add(keyword);
  //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";
}
<div class="lw-search-input lw-posr">
  <form th:action="@{/search.html}" method="get">
    <input required type="text" name="keyword" placeholder="请输入搜索关键字...">
    <button class="lw-posa"><i class="fa fa-search lw-mr5"></i>搜索</button>
  </form>
</div>
<p>推荐关键字:
  <a class="lw-mr5" th:each="keyword:${keywords}" th:href="@{/search.html(keyword=${keyword})}" th:text="${keyword}" th:title="${keyword}"></a>
</p>

评论(0)

热门文章

最新评论

  • 1

    看看

  • eeee

    多谢大佬分享

  • asdasd

    强强强

  • asdasd

    感谢作者!

  • asdasd

    感谢!

日历

2024年11月

     12
3456789
10111213141516
17181920212223
24252627282930

文章目录

站点公告
Freewind主题v1.5版本已发布,下载请移步Freewind 1.5,同时还有主题伴生插件Freewind Markdown,下载请移步 Freewind Markdown,有问题请在留言板,交换友链请直接在友链留言,我创建了一个主题交流群,有兴趣可以加下: 点此加入
报毒我说明一下,是因为我把主题的版权信息做了加密,其中用了eval,杀毒软件认为eval函数是一个危险的操作,这点介意的话请勿下载,我也没有强迫任何人去下载,也没有向大家收取一分钱的主题费用,所以也犯不着因为这些事情来喷我,喜欢就用,不喜欢就不用,就这么简单
点击小铃铛关闭