公共部分的查询加上缓存处理,并将首页的文章列表做分页展示

master
barney 2 years ago
parent 74e514ee80
commit 2749754eb0
  1. 2
      src/main/java/cc/bnblogs/common/ArticleSearch.java
  2. 39
      src/main/java/cc/bnblogs/common/LRUCache.java
  3. 8
      src/main/java/cc/bnblogs/config/WebConfig.java
  4. 79
      src/main/java/cc/bnblogs/controller/IndexController.java
  5. 22
      src/main/java/cc/bnblogs/mapper/ArticleMapper.java
  6. 13
      src/main/java/cc/bnblogs/mapper/TagMapper.java
  7. 3
      src/main/java/cc/bnblogs/pojo/Article.java
  8. 13
      src/main/java/cc/bnblogs/pojo/Category.java
  9. 4
      src/main/java/cc/bnblogs/pojo/Tag.java
  10. 40
      src/main/java/cc/bnblogs/service/ArticleService.java
  11. 25
      src/main/java/cc/bnblogs/service/CategoryService.java
  12. 16
      src/main/java/cc/bnblogs/service/TagService.java
  13. 350
      src/main/resources/templates/category.html
  14. 37
      src/main/resources/templates/common.html
  15. 31
      src/main/resources/templates/index.html
  16. 41
      src/main/resources/templates/list.html
  17. 388
      src/main/resources/templates/tags.html

@ -25,6 +25,8 @@ public class ArticleSearch {
private Integer status;
//标题
private String title;
//搜索关键字
private String keyword;
//文章类型
private Integer type;
//页码

@ -0,0 +1,39 @@
package cc.bnblogs.common;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
/**
* @author zfp@bnblogs.cc
* @createTime: 2022/10/21
*/
public class LRUCache {
// 使用hashSet
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);
}
}

@ -1,7 +1,9 @@
package cc.bnblogs.config;
import cc.bnblogs.common.LRUCache;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@ -19,6 +21,8 @@ public class WebConfig implements WebMvcConfigurer {
@Value("${upload.base-dir}")
private String baseDir;
public static final Integer MAX_LRU_CACHE_SIZE = 20;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// 创建static目录到/static/的路由
@ -37,4 +41,8 @@ public class WebConfig implements WebMvcConfigurer {
// 记住在absolutePath前加一个'/',否则本地图片读取不出来(重要的事情说三遍)
registry.addResourceHandler("/upload/**").addResourceLocations("file://" + '/' + absolutePath);
}
@Bean
public LRUCache lruCache() {
return new LRUCache(MAX_LRU_CACHE_SIZE);
}
}

@ -1,7 +1,9 @@
package cc.bnblogs.controller;
import cc.bnblogs.common.ArticleSearch;
import cc.bnblogs.common.LRUCache;
import cc.bnblogs.common.PageHelper;
import cc.bnblogs.config.WebConfig;
import cc.bnblogs.pojo.Article;
import cc.bnblogs.pojo.Category;
import cc.bnblogs.pojo.Tag;
@ -13,7 +15,9 @@ import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.Objects;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author zfp@bnblogs.cc
@ -29,15 +33,20 @@ public class IndexController {
private final BannerService bannerService;
private final CategoryService categoryService;
private final LRUCache lruCache;
public IndexController(FriendsService friendsService, NavigationService navigationService,
TagService tagService, ArticleService articleService, BannerService bannerService, CategoryService categoryService) {
TagService tagService, ArticleService articleService, BannerService bannerService,
CategoryService categoryService, LRUCache lruCache) {
this.friendsService = friendsService;
this.navigationService = navigationService;
this.tagService = tagService;
this.articleService = articleService;
this.bannerService = bannerService;
this.categoryService = categoryService;
this.lruCache = lruCache;
}
@ -46,8 +55,19 @@ public class IndexController {
// todo 可以在这里定义这个controller公用的model的属性
model.addAttribute("friends",friendsService.list());
model.addAttribute("navigations",navigationService.show());
model.addAttribute("tags",tagService.show((int)tagService.count()));
// 标签云
model.addAttribute("tags",tagService.list((int)tagService.count()));
model.addAttribute("hots",articleService.hotList(5));
int size = lruCache.size();
List<String> keywords = lruCache.list();
Collections.reverse(keywords);
if (size < WebConfig.MAX_LRU_CACHE_SIZE) {
// 关键字不够时用标签来补充
keywords.addAll(tagService.list( WebConfig.MAX_LRU_CACHE_SIZE - size).stream()
.map(Tag::getName).collect(Collectors.toList()));
}
model.addAttribute("keywords",keywords);
}
@ -55,7 +75,7 @@ public class IndexController {
@GetMapping("/")
public String index(@RequestParam(required = false, defaultValue = "1") Integer pageNumber,Model model) {
pageNumber = pageNumber < 1 ? 1: pageNumber;
model.addAttribute("articlePage",articleService.search(ArticleSearch.indexSearch(pageNumber,1)));
model.addAttribute("articlePage",articleService.search(ArticleSearch.indexSearch(pageNumber,5)));
model.addAttribute("banners",bannerService.list());
return "index";
}
@ -83,6 +103,15 @@ public class IndexController {
return "list";
}
/**
* 对应分类的列表页
* 格式: http://localhost:8080/category/{id}.html?pageNumber=1
* @param id 分类id
* @param pageNumber 页号
* @param model model
* @return 分类列表页
*/
@GetMapping("/category/{id}.html")
public String categoryList(@PathVariable Integer id,
@RequestParam(required = false,defaultValue = "1") Integer pageNumber,
@ -94,16 +123,50 @@ public class IndexController {
articleSearch.setCid(id);
PageHelper<Article> articlePage = articleService.search(articleSearch);
model.addAttribute("articlePage",articlePage);
model.addAttribute("pageType","category");
return "list";
}
@GetMapping("/category")
public String category() {
/**
* 返回搜索到的文章
* @param pageNumber 页号
* @param keyword 搜索关键字(同时搜索标题和内容中是否包含该关键字)
* @param model model
* @return 搜索结果
*/
@GetMapping("/search.html")
public String search(@RequestParam(required = false,defaultValue = "1") Integer pageNumber,
String keyword,
Model model){
lruCache.add(keyword);
model.addAttribute("keyword",keyword);
ArticleSearch articleSearch = ArticleSearch.indexSearch(pageNumber,5);
articleSearch.setKeyword(keyword);
PageHelper<Article> articlePage = articleService.search(articleSearch);
model.addAttribute("articlePage",articlePage);
model.addAttribute("pageType","search");
return "list";
}
/**
* 前台分类列表页
* @param model model
* @return 所有分类
*/
@GetMapping("/category.html")
public String category(Model model) {
model.addAttribute("categories",categoryService.show());
return "category";
}
@GetMapping("/tags")
public String tags() {
/**
* 前台标签列表页
* @param model model
* @return 所有标签
*/
@GetMapping("/tag.html")
public String tag(Model model) {
model.addAttribute("tagList",tagService.show());
return "tags";
}

@ -1,10 +1,12 @@
package cc.bnblogs.mapper;
import cc.bnblogs.pojo.Article;
import cc.bnblogs.pojo.Category;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import java.util.Date;
import java.util.List;
/**
@ -12,6 +14,26 @@ import java.util.List;
* @createTime: 2022/10/17
*/
public interface ArticleMapper extends JpaRepository<Article,Integer>, JpaSpecificationExecutor<Article>{
/**
* 返回留言量最高的几篇文章
* @param limit 文章数
* @return 匹配的文章列表
*/
@Query(value = "select * from blog_article where type=1 and status=1 order by views limit ?1", nativeQuery = true)
List<Article> hotList(int limit);
/**
* 统计分类文章数
* @param category 分类
* @return 文章个数
*/
Long countByCategory(Category category);
/**
* 返回该分类下最后一次更新时间
* @param cid 分类id
* @return 最后一次更新时间
*/
@Query(value="SELECT updated FROM blog_article WHERE category_id=?1 ORDER BY updated DESC LIMIT 1",nativeQuery = true)
Date lastUpdated(Integer cid);
}

@ -12,6 +12,11 @@ import java.util.List;
* @createTime: 2022/10/17
*/
public interface TagMapper extends JpaRepository<Tag, Integer> {
/**
* 随机返回一定数量的标签
* @param limit 标签数上限
* @return 标签云
*/
@Query(value = "SELECT * FROM blog_tag\n" +
"WHERE\n" +
" id >= ( SELECT FLOOR(\n" +
@ -24,4 +29,12 @@ public interface TagMapper extends JpaRepository<Tag, Integer> {
" ) \n" +
"ORDER BY id LIMIT ?1",nativeQuery = true)
List<Tag> findRandom(int limit);
/**
* 统计该标签下的文章数
* @param tid 标签id
* @return 文章数量
*/
@Query(value = "SELECT COUNT(1) FROM blog_article_tags WHERE tags_id=?1",nativeQuery = true)
Long articleCountByTid(Integer tid);
}

@ -74,7 +74,8 @@ public class Article implements Serializable {
public static final Integer COMMENT_DISABLE = 2;
// 返回摘要
public String summary() {
return this.content.substring(0,Math.max(200,this.content.length()));
String summary = this.content.replaceAll("[^\\u4E00-\\u9FA5a-zA-Z]", " ");
return summary.substring(0,Math.min(200,summary.length()));
}
}

@ -7,6 +7,7 @@ import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
/**
* @author zfp@bnblogs.cc
@ -35,4 +36,16 @@ public class Category implements Serializable {
* 分类介绍
*/
private String summary;
/**
* 该分类的文章总数
*/
@Transient
private Long articleCount;
/**
* 该分类下文章最近一次更新时间
*/
@Transient
private Date lastUpdated;
}

@ -24,4 +24,8 @@ public class Tag implements Serializable {
private Integer id;
@Column(unique = true)
private String name;
// 该标签下的文章总数
@Transient
private Long articleCount;
}

@ -20,6 +20,7 @@ import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.thymeleaf.util.StringUtils;
import javax.persistence.criteria.JoinType;
@ -135,26 +136,49 @@ public class ArticleService {
// 按照创建时间的降序返回结果
Pageable pageable = PageRequest.of(search.getPageNum() - 1, search.getPageSize(), Sort.by(Sort.Direction.DESC,"created"));
Page<Article> articlePage = articleMapper.findAll((Specification<Article>) (root, query, builder) -> {
List<Predicate> predicateList = new ArrayList<>();
List<Predicate> predicateAdd = new ArrayList<>();
if (Objects.nonNull(search.getCid())) {
predicateList.add(builder.equal(root.get("category"), Category.builder().id(search.getCid()).build()));
/*
* 传入一个分类id,查询对应的文章列表
* SELECT * FROM blog_article WHERE category_id={id};
*/
predicateAdd.add(builder.equal(root.get("category"), Category.builder().id(search.getCid()).build()));
}
if (Objects.nonNull(search.getStatus())) {
predicateList.add(builder.equal(root.get("status"), search.getStatus()));
predicateAdd.add(builder.equal(root.get("status"), search.getStatus()));
}
if (Objects.nonNull(search.getType())) {
predicateList.add(builder.equal(root.get("type"), search.getType()));
predicateAdd.add(builder.equal(root.get("type"), search.getType()));
}
if (!StringUtils.isEmptyOrWhitespace(search.getTitle())) {
// 标题的模糊查询
predicateList.add(builder.like(root.get("title"), "%" + search.getTitle() + "%"));
predicateAdd.add(builder.like(root.get("title"), "%" + search.getTitle() + "%"));
}
if (Objects.nonNull(search.getTid())) {
// todo 这里涉及多表连接,再看一下
/*
* SELECT * FROM blog_article as article
* LEFT JOIN blog_article_tags bat on article.id = bat.article_id
* LEFT JOIN blog_tag bt on bt.id = bat.tags_id
* WHERE bt.id={ID}
*/
ListJoin<Article, Tag> join = root.join(root.getModel().getList("tags", Tag.class), JoinType.LEFT);
predicateList.add(builder.equal(join.get("id"), search.getTid()));
predicateAdd.add(builder.equal(join.get("id"), search.getTid()));
}
return builder.and(predicateList.toArray(new Predicate[predicateList.size()]));
List<Predicate> predicateOr = new ArrayList<>();
if (!StringUtils.isEmptyOrWhitespace(search.getKeyword())) {
// 后面可以考虑使用搜索引擎ElasticSearch
predicateOr.add(builder.like(root.get("title"),"%" + search.getKeyword() + "%"));
predicateOr.add(builder.like(root.get("content"),"%" + search.getKeyword() + "%"));
}
if (CollectionUtils.isEmpty(predicateOr)) {
// or条件为空时,直接返回与条件的搜索结果
return builder.and(predicateAdd.toArray(new Predicate[predicateAdd.size()]));
}
return query.where(
builder.and(predicateAdd.toArray(new Predicate[predicateAdd.size()])),
builder.or(predicateOr.toArray(new Predicate[predicateOr.size()])))
.getRestriction();
},pageable);
return PageHelper.<Article>builder().

@ -1,22 +1,30 @@
package cc.bnblogs.service;
import cc.bnblogs.mapper.ArticleMapper;
import cc.bnblogs.mapper.CategoryMapper;
import cc.bnblogs.pojo.Category;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author zfp@bnblogs.cc
* @createTime: 2022/10/16
*/
@Service
@CacheConfig(cacheNames = {"blog-cache"})
public class CategoryService {
private final CategoryMapper categoryMapper;
private final ArticleMapper articleMapper;
public CategoryService(CategoryMapper categoryMapper) {
public CategoryService(CategoryMapper categoryMapper, ArticleMapper articleMapper) {
this.categoryMapper = categoryMapper;
this.articleMapper = articleMapper;
}
/**
@ -48,6 +56,7 @@ public class CategoryService {
* 保存分类
* @param category 待保存的分类对象
*/
@CacheEvict(allEntries = true)
public void save(Category category) {
System.out.println(category);
categoryMapper.save(category);
@ -57,7 +66,21 @@ public class CategoryService {
* 根据id删除分类对象
* @param id 待删除分类的id
*/
@CacheEvict(allEntries = true)
public void delete(Integer id) {
categoryMapper.deleteById(id);
}
/**
* 返回文章数不为0的所有分类
* @return 有效分类
*/
@Cacheable
public List<Category> show() {
return categoryMapper.findAll().stream().peek(category -> {
// 返回该分类下的文章总数
category.setArticleCount(articleMapper.countByCategory(category));
category.setLastUpdated(articleMapper.lastUpdated(category.getId()));
}).filter(category -> category.getArticleCount() > 0).collect(Collectors.toList());
}
}

@ -1,5 +1,6 @@
package cc.bnblogs.service;
import cc.bnblogs.mapper.ArticleMapper;
import cc.bnblogs.mapper.TagMapper;
import cc.bnblogs.pojo.Tag;
import org.springframework.cache.annotation.CacheConfig;
@ -8,6 +9,7 @@ import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author zfp@bnblogs.cc
@ -19,7 +21,7 @@ public class TagService {
private final TagMapper tagMapper;
public TagService(TagMapper tagMapper) {
public TagService(TagMapper tagMapper, ArticleMapper articleMapper) {
this.tagMapper = tagMapper;
}
@ -76,7 +78,17 @@ public class TagService {
* @return 标签云
*/
@Cacheable
public List<Tag> show(int limit) {
public List<Tag> list(int limit) {
return tagMapper.findRandom(limit);
}
/**
* 返回文章数不为0的所有标签
* @return
*/
public List<Tag> show() {
return tagMapper.findAll().stream().peek(tag -> {
tag.setArticleCount(tagMapper.articleCountByTid(tag.getId()));
}).filter(tag -> tag.getArticleCount() > 0).collect(Collectors.toList());
}
}

@ -1,289 +1,113 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="/static/plugin/bootstrap/css/bootstrap.min.css">
<!-- 可选的 Bootstrap 主题文件(一般不用引入) -->
<link rel="stylesheet" href="/static/plugin/bootstrap/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="/static/plugin/font-awesome/css/font-awesome.min.css">
<!-- 自定义css文件 -->
<link rel="stylesheet" href="/static/css/style.css">
<html xmlns:th="http://www.thymeleaf.org" xmlns="http://www.w3.org/1999/html" lang="en">
<head th:replace="common::header(~{::title},~{},~{})">
<title th:text="${'分类云' + ' - ' + @webSite.title}"></title>
</head>
<body>
<nav class="lw-md-show">
<div class="lw-container lw-header lw-posr ">
<div class="lw-logo lw-fl">
<a href="/">
<img src="/static/image/logo.png" alt="冷文的个人博客">
</a>
</div>
<span>让崇拜从这里开始,用代码做点好玩的事件,让每一天都变的充实起来!</span>
<div class="lw-fr lw-linkme">
<a href="#"><i class="fa fa-qq" aria-hidden="true"></i></a>
<a href="#"><i class="fa fa-wechat" aria-hidden="true"></i></a>
<a href="#"><i class="fa fa-weibo" aria-hidden="true"></i></a>
<a href="#"><i class="fa fa-envelope" aria-hidden="true"></i></a>
</div>
<div class="lw-nav lw-posa">
<a href="/"><i class="fa fa-home" aria-hidden="true"></i>首页</a>
<a href="#">技术分享</a>
<a href="#">闲言碎语</a>
<a href="#">个人随笔</a>
<a href="#"><i class="fa fa-users" aria-hidden="true"></i>友情链接</a>
<a href="#"><i class="fa fa-user" aria-hidden="true"></i>关于我</a>
<a href="#"><i class="fa fa-edit" aria-hidden="true"></i>留言板</a>
<a href="javascript:void(0)" class="lw-fr lw-search-btn" style="padding: 0;">
<i class="fa fa-search" aria-hidden="true"></i>
</a>
</div>
</div>
</nav>
<div class="lw-md-hidden lw-phone-header">
<a href="javascript:void(0)" class="lw-posa lw-phone-topbtn lw-search-show lw-search-btn"><i
class="fa fa-search"></i></a>
<a class="lw-index" href="/"><h1>冷文学习者</h1></a>
</div>
<div class="lw-md-hidden" style="height: 100px;"></div>
<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>
<li class="active">分类云</li>
</ol>
<ul class="lw-category-list">
<li>
<a href=""><i class="fa fa-folder lw-mr5"></i>emlog相关 <span>(Total 5 Articles)</span></a>
<p>与emlog相关的主题及插件,也有少部分相关教程...</p>
<p class="lw-category-update">最后更新: 2021-12-20</p>
</li>
<li>
<a href=""><i class="fa fa-folder lw-mr5"></i>typecho相关 <span>(Total 5 Articles)</span></a>
<p>与typecho相关的主题及插件,同时也有不少我自己在用typecho时的心得以及技巧...</p>
<p class="lw-category-update">最后更新: 2021-12-20</p>
</li>
<li>
<a href=""><i class="fa fa-folder lw-mr5"></i> 网站相关 <span>(Total 5 Articles)</span></a>
<p>有一些网站源码和建站技巧,也有一些前端相关的知识,博主也还有学习中...</p>
<p class="lw-category-update">最后更新: 2021-12-20</p>
</li>
<li>
<a href=""><i class="fa fa-folder lw-mr5"></i> Linux学习 <span>(Total 5 Articles)</span></a>
<p>Linux常用命令的学习笔记,也有一些开发生产环境的搭建...</p>
<p class="lw-category-update">最后更新: 2021-12-20</p>
</li>
<li>
<a href=""><i class="fa fa-folder lw-mr5"></i> Mac相关 <span>(Total 5 Articles)</span></a>
<p>因为大部分情况下我用的都是MacBook,所有在使用Mac方面有不少的心得体会...</p>
<p class="lw-category-update">最后更新: 2021-12-20</p>
</li>
<li>
<a href=""><i class="fa fa-folder lw-mr5"></i> Freewind相关 <span>(Total 5 Articles)</span></a>
<p>这里就有我一直维护的typecho主题Freewind啦,里面有每次更新的内容及功能介绍、下载地址...</p>
<p class="lw-category-update">最后更新: 2021-12-20</p>
</li>
<li>
<a href=""><i class="fa fa-folder lw-mr5"></i> 个人随笔 <span>(Total 5 Articles)</span></a>
<p>除了写技术贴当然也要写一些文章记录一下心情和日常...</p>
<p class="lw-category-update">最后更新: 2021-12-20</p>
<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 style="color: #de2424">(共<th:block th:text="${category.getArticleCount()}"></th:block>篇文章)</span>
</a>
<p style="font-size: 16px;font-weight: bold;color:black" th:text="${category.summary}"></p>
<p class="lw-category-update">最后更新:
<th:block th:text="${#dates.format(category.getLastUpdated(),'yyyy-MM-dd')}">
</th:block>
</p>
</li>
</ul>
</div>
<div class="lw-right-list lw-md-show lw-posa">
<div class="lw-right-item lw-profile">
<div class="lw-avatar-content lw-posr"
style="background-image:url(/static/image/5-120601094K3-50.gif);">
<div class="lw-avatar lw-posa">
<img src="/static/image/avatar.jpeg" alt="">
<th:block th:fragment="right">
<div class="lw-right-item lw-profile">
<div class="lw-avatar-content lw-posr"
style="background-image:url(/static/image/5-120601094K3-50.gif);">
<div class="lw-avatar lw-posa">
<img th:src="${@webSite.avatar}" src="/static/image/avatar.jpeg" alt="">
</div>
</div>
<ul class="lw-info">
<li><span>博主</span>
<th:block th:text="${@webSite.nickname}"></th:block>
</li>
<li><span>坐标</span>
<th:block th:text="${T(java.lang.String).join(' ',@webSite.address)}"></th:block>
</li>
<li><span>标签</span>
<th:block th:text="${T(java.lang.String).join('、',@webSite.tags)}"></th:block>
</li>
</ul>
</div>
<ul class="lw-info">
<li><span>博主</span>Mr丶冷文</li>
<li><span>坐标</span>北京 昌平</li>
<li><span>标签</span>Java、Web设计、Python、大数据、爬虫</li>
</ul>
</div>
<div class="lw-right-item lw-right-hot">
<h4><i class="fa fa-fire lw-mr5" aria-hidden="true"></i>热门文章</h4>
<ul class="lw-hot-list">
<li>
<a href="#">
<div class="lw-hot-img">
<span class="label label-danger lw-posa">1</span>
<img src="/static/image/1.jpg" alt="">
</div>
<p class="lw-hot-title">Freewind主题编辑器展示</p>
<p class="lw-hot-info"><i class="fa-solid fa-fire-flame-curved"></i> 65580 </p>
</a>
</li>
<li>
<a href="#">
<div class="lw-hot-img">
<span class="label label-warning lw-posa">2</span>
<img src="/static/image/2.jpg" alt="">
</div>
<p class="lw-hot-title">Conda虚拟环境使用</p>
<p class="lw-hot-info"><i class="fa-solid fa-fire-flame-curved"></i> 56283 </p>
</a>
</li>
<li>
<a href="#">
<div class="lw-hot-img">
<span class="label label-info lw-posa">3</span>
<img src="/static/image/3.jpg" alt="">
</div>
<p class="lw-hot-title">纯 CSS 图片碎裂动画教程</p>
<p class="lw-hot-info"><i class="fa-solid fa-fire-flame-curved"></i> 52213 </p>
</a>
</li>
<li>
<a href="#">
<div class="lw-hot-img">
<span class="label label-default lw-posa">4</span>
<img src="/static/image/4.jpg" alt="">
</div>
<p class="lw-hot-title">Spring Boot 3.0 M1 发布</p>
<p class="lw-hot-info"><i class="fa-solid fa-fire-flame-curved"></i> 23132 </p>
</a>
</li>
<li>
<a href="#">
<div class="lw-hot-img">
<span class="label label-default lw-posa">5</span>
<img src="/static/image/5.jpg" alt="">
</div>
<p class="lw-hot-title">异步上传文件显示进度条</p>
<p class="lw-hot-info"><i class="fa-solid fa-fire-flame-curved"></i> 12322 </p>
</a>
</li>
</ul>
</div>
<div class="lw-right-item lw-tag-cloud">
<h4><i class="fa fa-tags lw-mr5" aria-hidden="true"></i>标签云</h4>
<a href="https://www.kevinlu98.cn/tag/freewind/" title="freewind">
freewind</a>
<a href="https://www.kevinlu98.cn/tag/typecho/" title="typecho">
typecho</a>
<a href="https://www.kevinlu98.cn/tag/%E6%8F%92%E4%BB%B6/" title="插件">
插件</a>
<a href="https://www.kevinlu98.cn/tag/emlog/" title="emlog">
emlog</a>
<a href="https://www.kevinlu98.cn/tag/java/" title="java">
java</a>
<a href="https://www.kevinlu98.cn/tag/%E4%B8%BB%E9%A2%98/" title="主题">
主题</a>
<a href="https://www.kevinlu98.cn/tag/%E8%87%AA%E7%94%B1%E4%B9%8B%E9%A3%8E/" title="自由之风">
自由之风</a>
<a href="https://www.kevinlu98.cn/tag/%E5%9B%BE%E5%BA%8A/" title="图床">
图床</a>
<a href="https://www.kevinlu98.cn/tag/%E5%86%B7%E6%96%87%E5%9B%BE%E5%BA%8A/" title="冷文图床">
冷文图床</a>
<a href="https://www.kevinlu98.cn/tag/markdown/" title="markdown">
markdown</a>
<a href="https://www.kevinlu98.cn/tag/gitee/" title="gitee">
gitee</a>
<a href="https://www.kevinlu98.cn/tag/springboot/" title="springboot">
springboot</a>
<a href="https://www.kevinlu98.cn/tag/linux/" title="linux">
linux</a>
<a href="https://www.kevinlu98.cn/tag/mac/" title="mac">
mac</a>
<a href="https://www.kevinlu98.cn/tag/%E5%AD%A6%E4%B9%A0/" title="学习">
学习</a>
<a href="https://www.kevinlu98.cn/tag/python/" title="python">
python</a>
<a href="https://www.kevinlu98.cn/tag/conda/" title="conda">
conda</a>
<a href="https://www.kevinlu98.cn/tag/%E7%9B%B8%E5%86%8C/" title="相册">
相册</a>
<a href="https://www.kevinlu98.cn/tag/jsDelivr/" title="jsDelivr">
jsDelivr</a>
<a href="https://www.kevinlu98.cn/tag/cdn/" title="cdn">
cdn</a>
<a href="https://www.kevinlu98.cn/tag/codemirror/" title="codemirror">
codemirror</a>
<a href="https://www.kevinlu98.cn/tag/freedom/" title="freedom">
freedom</a>
<a href="https://www.kevinlu98.cn/tag/%E8%85%BE%E8%AE%AFcos/" title="腾讯cos">
腾讯cos</a>
<a href="https://www.kevinlu98.cn/tag/cos/" title="cos">
cos</a>
<a href="https://www.kevinlu98.cn/tag/%E7%A7%81%E4%BA%BA%E5%9B%BE%E5%BA%8A/" title="私人图床">
私人图床</a>
<a href="https://www.kevinlu98.cn/tag/%E6%AC%A2%E8%BF%8E%E9%A1%B5/" title="欢迎页">
欢迎页</a>
<a href="https://www.kevinlu98.cn/tag/%E7%99%BB%E5%BD%95%E6%B3%A8%E5%86%8C/" title="登录注册">
登录注册</a>
<a href="https://www.kevinlu98.cn/tag/%E6%95%99%E7%A8%8B%E4%B8%8B%E8%BD%BD/" title="教程下载">
教程下载</a>
<a href="https://www.kevinlu98.cn/tag/itjc8/" title="itjc8">
itjc8</a>
<a href="https://www.kevinlu98.cn/tag/%E8%99%9A%E6%8B%9F%E6%9C%BA/" title="虚拟机">
虚拟机</a>
</div>
<div class="lw-right-item lw-right-hot">
<h4><i class="fa fa-fire lw-mr5" aria-hidden="true"></i>热门文章</h4>
<ul class="lw-hot-list">
<!--/*@thymesVar id="hots" type="java.util.List<cc.bnblogs.pojo.Article>"*/-->
<li th:each="hot,it:${hots}">
<a th:href="@{/{id}.html(id=${hot.id})}" target="_blank">
<div class="lw-hot-img">
<span class="label label-danger lw-posa" th:if="${it.index eq 0}">1</span>
<span class="label label-warning lw-posa" th:if="${it.index eq 1}">2</span>
<span class="label label-info lw-posa" th:if="${it.index eq 2}">3</span>
<span class="label label-default lw-posa" th:if="${it.index > 2}" th:text="${it.index+1}"></span>
<img th:src="${@defaultImages.cover(hot.cover)}" alt="">
</div>
<p class="lw-hot-title" th:text="${hot.title}"></p>
<p class="lw-hot-info"><i class="fa fa-eye lw-mr5"></i>
<th:block th:text="${hot.views}"></th:block>
</p>
</a>
</li>
</ul>
</div>
<div class="lw-right-item lw-tag-cloud">
<h4><i class="fa fa-tags lw-mr5" aria-hidden="true"></i>标签云</h4>
<!--/*@thymesVar id="tags" type="java.util.List<cc.bnblogs.pojo.Tag>"*/-->
<a th:each="tag:${tags}" th:href="@{/tag/{id}.html(id=${tag.id})}" th:title="${tag.name}" th:text="${tag.name}"></a>
</div>
</th:block>
</div>
</div>
<div class="lw-friend-link">
<div class="lw-container">
<h2>友情链接</h2>
<a href="">冷文学习者</a>
<a href="">冷文博客</a>
<a href="">冷文聊编程</a>
<a href="">GetHub</a>
<a href="">CSDN</a>
<a href="">百度一下</a>
<a href="">新浪微博</a>
<a href="">谷歌搜索</a>
<a href="">知乎</a>
<a href="">掘金</a>
<th:block th:fragment="footer">
<div class="lw-friend-link">
<div class="lw-container">
<h2>友情链接</h2>
<!--/*@thymesVar id="friends" type="java.util.List<cc.bnblogs.pojo.Friends>"*/-->
<a th:each="friend:${friends}" target="_blank" th:href="${friend.link}" th:text="${friend.title}"></a>
</div>
</div>
</div>
<footer>
<p>冷文学习者 版权所有 <span class="lw-mr5"></span>Copyright © www.kevinlu98.cn All Rights Reserved.</p>
<p>备案号:陕ICP备19024566-1号 京公网安备 11011402012109号</p>
</footer>
<div class="lw-mask" id="lw-search-box">
<div class="lw-search-conetnt">
<a href="javascript:void(0)" class="lw-search-close lw-posa"><i class="fa fa-close"></i></a>
<div class="lw-search-input lw-posr">
<form action="" method="post">
<input type="text" placeholder="请输入搜索关键字...">
<button class="lw-posa"><i class="fa fa-search lw-mr5"></i>搜索</button>
</form>
<footer th:utext="${@webSite.footer}"></footer>
<div class="lw-mask" id="lw-search-box">
<div class="lw-search-conetnt">
<a href="javascript:void(0)" class="lw-search-close lw-posa"><i class="fa fa-close"></i></a>
<div class="lw-search-input lw-posr">
<form th:action="@{/search.html}" method="get">
<input type="text" required 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>
</div>
<p>推荐关键字:
<a href="javascript:void (0)">独立下载</a>
<a href="javascript:void (0)">评论通知</a>
<a href="javascript:void (0)">点赞</a>
<a href="javascript:void (0)">非插件</a>
<a href="javascript:void (0)">tp5</a>
<a href="javascript:void (0)">ajax</a>
<a href="javascript:void (0)">json</a>
<a href="javascript:void (0)">IO模型</a>
<a href="javascript:void (0)">跨域</a>
<a href="javascript:void (0)">javascript</a>
<a href="javascript:void (0)">springboot</a>
<a href="javascript:void (0)">视频剪辑</a>
<a href="javascript:void (0)">后期</a>
<a href="javascript:void (0)">个人随笔</a>
</p>
</div>
</div>
<script src="/static/plugin/jquery/jquery-3.5.1.min.js"></script>
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="/static/plugin/bootstrap/js/bootstrap.min.js"></script>
<script src="/static/js/main.js"></script>
<script src="/static/plugin/jquery/jquery-3.5.1.min.js"></script>
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="/static/plugin/bootstrap/js/bootstrap.min.js"></script>
<script src="/static/plugin/swiper-bundle/swiper-bundle.min.js"></script>
<script src="/static/js/main.js"></script>
</th:block>
</body>
</html>

@ -42,7 +42,8 @@
<div class="lw-nav lw-posa">
<a th:href="@{/}"><i class="fa fa-home" aria-hidden="true"></i>首页</a>
<!--/*@thymesVar id="navigations" type="java.util.List<cc.bnblogs.pojo.Navigation>"*/-->
<a th:each="navigation:${navigations}" th:href="${navigation.link}" th:target="${navigation.linkMode} ? '_blank' : ''" >
<a th:each="navigation:${navigations}" th:href="${navigation.link}"
th:target="${navigation.linkMode} ? '_blank' : ''">
<i th:if="${navigation.icon.length() > 0}" th:class="${'fa fa-'+navigation.icon}"></i>
<th:block th:text="${navigation.name}"></th:block>
</a>
@ -90,7 +91,8 @@
<span class="label label-danger lw-posa" th:if="${it.index eq 0}">1</span>
<span class="label label-warning lw-posa" th:if="${it.index eq 1}">2</span>
<span class="label label-info lw-posa" th:if="${it.index eq 2}">3</span>
<span class="label label-default lw-posa" th:if="${it.index > 2}" th:text="${it.index+1}"></span>
<span class="label label-default lw-posa" th:if="${it.index > 2}"
th:text="${it.index+1}"></span>
<img th:src="${@defaultImages.cover(hot.cover)}" alt="">
</div>
<p class="lw-hot-title" th:text="${hot.title}"></p>
@ -104,7 +106,8 @@
<div class="lw-right-item lw-tag-cloud">
<h4><i class="fa fa-tags lw-mr5" aria-hidden="true"></i>标签云</h4>
<!--/*@thymesVar id="tags" type="java.util.List<cc.bnblogs.pojo.Tag>"*/-->
<a th:each="tag:${tags}" th:href="@{/tag/{id}.html(id=${tag.id})}" th:title="${tag.name}" th:text="${tag.name}"></a>
<a th:each="tag:${tags}" th:href="@{/tag/{id}.html(id=${tag.id})}" th:title="${tag.name}"
th:text="${tag.name}"></a>
</div>
</th:block>
@ -115,8 +118,9 @@
</div>
<div class="lw-article-info">
<h2>
<a class="lw-xs-hidden" th:href="@{/category/{id}.html(id=${article.category.id})}"><span class="lw-category"
th:text="${article.category.name}"></span></a>
<a class="lw-xs-hidden" th:href="@{/category/{id}.html(id=${article.category.id})}"><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>
@ -129,7 +133,8 @@
<th:block th:text="${article.commentCount}"></th:block>
<th:block th:if="${!article.tags.isEmpty()}">
<i class="fa fa-tag lw-ml10 lw-mr5"></i>
<a th:each="tag:${article.tags}" th:href="@{/tag/{id}.html(id=${tag.id})}" class="lw-mr5" th:title="${tag.name}" th:text="${tag.name +' '}"></a>
<a th:each="tag:${article.tags}" th:href="@{/tag/{id}.html(id=${tag.id})}" class="lw-mr5"
th:title="${tag.name}" th:text="${tag.name +' '}"></a>
</th:block>
</p>
@ -149,26 +154,14 @@
<div class="lw-search-conetnt">
<a href="javascript:void(0)" class="lw-search-close lw-posa"><i class="fa fa-close"></i></a>
<div class="lw-search-input lw-posr">
<form action="" method="post">
<input type="text" placeholder="请输入搜索关键字...">
<form th:action="@{/search.html}" method="get">
<input type="text" required name="keyword" placeholder="请输入搜索关键字...">
<button class="lw-posa"><i class="fa fa-search lw-mr5"></i>搜索</button>
</form>
</div>
<p>推荐关键字:
<a href="javascript:void (0)">独立下载</a>
<a href="javascript:void (0)">评论通知</a>
<a href="javascript:void (0)">点赞</a>
<a href="javascript:void (0)">非插件</a>
<a href="javascript:void (0)">tp5</a>
<a href="javascript:void (0)">ajax</a>
<a href="javascript:void (0)">json</a>
<a href="javascript:void (0)">IO模型</a>
<a href="javascript:void (0)">跨域</a>
<a href="javascript:void (0)">javascript</a>
<a href="javascript:void (0)">springboot</a>
<a href="javascript:void (0)">视频剪辑</a>
<a href="javascript:void (0)">后期</a>
<a href="javascript:void (0)">个人随笔</a>
<a class="lw-mr5" th:each="keyword:${keywords}" th:href="@{/search.html(keyword=${keyword})}"
th:text="${keyword}" th:title="${keyword}"></a>
</p>
</div>
</div>

@ -78,7 +78,36 @@
</div>
</div>
<th:block th:include="common::footer"></th:block>
<th:block th:fragment="footer">
<div class="lw-friend-link">
<div class="lw-container">
<h2>友情链接</h2>
<!--/*@thymesVar id="friends" type="java.util.List<cc.bnblogs.pojo.Friends>"*/-->
<a th:each="friend:${friends}" target="_blank" th:href="${friend.link}" th:text="${friend.title}"></a>
</div>
</div>
<footer th:utext="${@webSite.footer}"></footer>
<div class="lw-mask" id="lw-search-box">
<div class="lw-search-conetnt">
<a href="javascript:void(0)" class="lw-search-close lw-posa"><i class="fa fa-close"></i></a>
<div class="lw-search-input lw-posr">
<form th:action="@{/search.html}" method="get">
<input type="text" required 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>
</div>
</div>
<script src="/static/plugin/jquery/jquery-3.5.1.min.js"></script>
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="/static/plugin/bootstrap/js/bootstrap.min.js"></script>
<script src="/static/plugin/swiper-bundle/swiper-bundle.min.js"></script>
<script src="/static/js/main.js"></script>
</th:block>
<script>
$(function () {

@ -3,6 +3,7 @@
<head th:replace="common::header(~{::title},~{},~{})">
<title th:if="${pageType eq 'category'}" th:text="${category.name + ' - ' + @webSite.title}"></title>
<title th:if="${pageType eq 'tag'}" th:text="${tag.name + ' - ' + @webSite.title}"></title>
<title th:if="${pageType eq 'search'}" th:text="${keyword + ' - ' + @webSite.title}"></title>
</head>
<body>
@ -12,11 +13,13 @@
<div class="lw-left-list">
<ol class="breadcrumb lw-crumb">
<li><a href="/">首页</a></li>
<li th:if="${pageType eq 'category'}"><a th:href="@{/category/{id}.html(id=${category.id})}">所有分类</a>
<li th:if="${pageType eq 'category'}"><a th:href="@{/category.html}">分类</a>
</li>
<li th:if="${pageType eq 'tag'}"><a th:href="@{/tag/{id}.html(id=${tag.id})}">所有标签</a></li>
<li th:if="${pageType eq 'tag'}"><a th:href="@{/tag.html}">标签</a></li>
<li th:if="${pageType eq 'category'}" class="active" th:text="${category.name}"></li>
<li th:if="${pageType eq 'tag'}" class="active" th:text="${tag.name}"></li>
<li th:if="${pageType eq 'search'}" class="active" th:text="${'包含关键字'+ '<' + keyword + '>'+'的文章'}"></li>
</ol>
<div class="lw-article-list">
<th:block th:include="common::article(${articlePage.rows})"></th:block>
@ -46,6 +49,20 @@
</li>
<li th:text="${'共 ' + articlePage.totalPages + ' 页'}"></li>
</ul>
<ul th:if="${articlePage.totalPages > 1 and pageType eq 'search'}" class="lw-pagenation">
<li th:if="${articlePage.currentPage != 1}"><a th:href="@{search.html(keyword=${keyword})}">首页</a></li>
<li th:each="num:${#numbers.sequence((articlePage.currentPage - 2 > 0 ? articlePage.currentPage - 2 : 1),(articlePage.currentPage + 2 < articlePage.totalPages ? articlePage.currentPage + 2 : articlePage.totalPages))}">
<a th:class="${articlePage.currentPage eq num}?'lw-active':''"
th:href="@{search.html(keyword=${keyword},pageNumber=${num})}"
th:text="${num}"></a>
</li>
<li th:if="${articlePage.currentPage != articlePage.totalPages}">
<a th:href="@{search.html(keyword=${keyword},pageNumber=${articlePage.totalPages})}">尾页</a>
</li>
<li th:text="${'共 ' + articlePage.totalPages + ' 页'}"></li>
</ul>
</div>
<div class="lw-right-list lw-md-show lw-posa">
<th:block th:fragment="right">
@ -113,26 +130,14 @@
<div class="lw-search-conetnt">
<a href="javascript:void(0)" class="lw-search-close lw-posa"><i class="fa fa-close"></i></a>
<div class="lw-search-input lw-posr">
<form action="" method="post">
<input type="text" placeholder="请输入搜索关键字...">
<form th:action="@{/search.html}" method="get">
<input type="text" required name="keyword" placeholder="请输入搜索关键字...">
<button class="lw-posa"><i class="fa fa-search lw-mr5"></i>搜索</button>
</form>
</div>
<p>推荐关键字:
<a href="javascript:void (0)">独立下载</a>
<a href="javascript:void (0)">评论通知</a>
<a href="javascript:void (0)">点赞</a>
<a href="javascript:void (0)">非插件</a>
<a href="javascript:void (0)">tp5</a>
<a href="javascript:void (0)">ajax</a>
<a href="javascript:void (0)">json</a>
<a href="javascript:void (0)">IO模型</a>
<a href="javascript:void (0)">跨域</a>
<a href="javascript:void (0)">javascript</a>
<a href="javascript:void (0)">springboot</a>
<a href="javascript:void (0)">视频剪辑</a>
<a href="javascript:void (0)">后期</a>
<a href="javascript:void (0)">个人随笔</a>
<a class="lw-mr5" th:each="keyword:${keywords}" th:href="@{/search.html(keyword=${keyword})}"
th:text="${keyword}" th:title="${keyword}"></a>
</p>
</div>
</div>

@ -1,315 +1,107 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="/static/plugin/bootstrap/css/bootstrap.min.css">
<!-- 可选的 Bootstrap 主题文件(一般不用引入) -->
<link rel="stylesheet" href="/static/plugin/bootstrap/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="/static/plugin/font-awesome/css/font-awesome.min.css">
<!-- 自定义css文件 -->
<link rel="stylesheet" href="/static/css/style.css">
<html xmlns:th="http://www.thymeleaf.org" xmlns="http://www.w3.org/1999/html" lang="en">
<head th:replace="common::header(~{::title},~{},~{})">
<title th:text="${'标签云' + ' - ' + @webSite.title}"></title>
</head>
<body>
<nav class="lw-md-show">
<div class="lw-container lw-header lw-posr ">
<div class="lw-logo lw-fl">
<a href="/">
<img src="/static/image/logo.png" alt="冷文的个人博客">
</a>
</div>
<span>让崇拜从这里开始,用代码做点好玩的事件,让每一天都变的充实起来!</span>
<div class="lw-fr lw-linkme">
<a href="#"><i class="fa fa-qq" aria-hidden="true"></i></a>
<a href="#"><i class="fa fa-wechat" aria-hidden="true"></i></a>
<a href="#"><i class="fa fa-weibo" aria-hidden="true"></i></a>
<a href="#"><i class="fa fa-envelope" aria-hidden="true"></i></a>
</div>
<div class="lw-nav lw-posa">
<a href="/"><i class="fa fa-home" aria-hidden="true"></i>首页</a>
<a href="#">技术分享</a>
<a href="#">闲言碎语</a>
<a href="#">个人随笔</a>
<a href="#"><i class="fa fa-users" aria-hidden="true"></i>友情链接</a>
<a href="#"><i class="fa fa-user" aria-hidden="true"></i>关于我</a>
<a href="#"><i class="fa fa-edit" aria-hidden="true"></i>留言板</a>
<a href="javascript:void(0)" class="lw-fr lw-search-btn" style="padding: 0;">
<i class="fa fa-search" aria-hidden="true"></i>
</a>
</div>
</div>
</nav>
<div class="lw-md-hidden lw-phone-header">
<a href="javascript:void(0)" class="lw-posa lw-phone-topbtn lw-search-show lw-search-btn"><i
class="fa fa-search"></i></a>
<a class="lw-index" href="/"><h1>冷文学习者</h1></a>
</div>
<div class="lw-md-hidden" style="height: 100px;"></div>
<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>
<div class="lw-tag-list">
<a href="https://www.kevinlu98.cn/tag/freewind/" title="freewind">
freewind <span>12</span></a>
<a href="https://www.kevinlu98.cn/tag/typecho/" title="typecho">
typecho<span>31</span></a>
<a href="https://www.kevinlu98.cn/tag/%E6%8F%92%E4%BB%B6/" title="插件">
插件<span>32</span></a>
<a href="https://www.kevinlu98.cn/tag/emlog/" title="emlog">
emlog<span>15</span></a>
<a href="https://www.kevinlu98.cn/tag/java/" title="java">
java<span>2</span></a>
<a href="https://www.kevinlu98.cn/tag/%E4%B8%BB%E9%A2%98/" title="主题">
主题<span>99</span></a>
<a href="https://www.kevinlu98.cn/tag/%E8%87%AA%E7%94%B1%E4%B9%8B%E9%A3%8E/" title="自由之风">
自由之风<span>128</span></a>
<a href="https://www.kevinlu98.cn/tag/%E5%9B%BE%E5%BA%8A/" title="图床">
图床<span>24</span></a>
<a href="https://www.kevinlu98.cn/tag/%E5%86%B7%E6%96%87%E5%9B%BE%E5%BA%8A/" title="冷文图床">
冷文图床<span>64</span></a>
<a href="https://www.kevinlu98.cn/tag/markdown/" title="markdown">
markdown<span>98</span></a>
<a href="https://www.kevinlu98.cn/tag/gitee/" title="gitee">
gitee<span>44</span></a>
<a href="https://www.kevinlu98.cn/tag/springboot/" title="springboot">
springboot<span>32</span></a>
<a href="https://www.kevinlu98.cn/tag/linux/" title="linux">
linux<span>62</span></a>
<a href="https://www.kevinlu98.cn/tag/mac/" title="mac">
mac<span>1</span></a>
<a href="https://www.kevinlu98.cn/tag/%E5%AD%A6%E4%B9%A0/" title="学习">
学习<span>2</span></a>
<a href="https://www.kevinlu98.cn/tag/python/" title="python">
python<span>10</span></a>
<a href="https://www.kevinlu98.cn/tag/conda/" title="conda">
conda<span>9</span></a>
<a href="https://www.kevinlu98.cn/tag/%E7%9B%B8%E5%86%8C/" title="相册">
相册<span>18</span></a>
<a href="https://www.kevinlu98.cn/tag/jsDelivr/" title="jsDelivr">
jsDelivr<span>7</span></a>
<a href="https://www.kevinlu98.cn/tag/cdn/" title="cdn">
cdn<span>25</span></a>
<a href="https://www.kevinlu98.cn/tag/codemirror/" title="codemirror">
codemirror<span>1</span></a>
<a href="https://www.kevinlu98.cn/tag/freedom/" title="freedom">
freedom<span>9</span></a>
<a href="https://www.kevinlu98.cn/tag/%E8%85%BE%E8%AE%AFcos/" title="腾讯cos">
腾讯cos<span>23</span></a>
<a href="https://www.kevinlu98.cn/tag/cos/" title="cos">
cos<span>2</span></a>
<a href="https://www.kevinlu98.cn/tag/%E7%A7%81%E4%BA%BA%E5%9B%BE%E5%BA%8A/" title="私人图床">
私人图床<span>29</span></a>
<a href="https://www.kevinlu98.cn/tag/%E6%AC%A2%E8%BF%8E%E9%A1%B5/" title="欢迎页">
欢迎页<span>45</span></a>
<a href="https://www.kevinlu98.cn/tag/%E7%99%BB%E5%BD%95%E6%B3%A8%E5%86%8C/" title="登录注册">
登录注册<span>34</span></a>
<a href="https://www.kevinlu98.cn/tag/%E6%95%99%E7%A8%8B%E4%B8%8B%E8%BD%BD/" title="教程下载">
教程下载<span>2</span></a>
<a href="https://www.kevinlu98.cn/tag/itjc8/" title="itjc8">
itjc8<span>5</span></a>
<a href="https://www.kevinlu98.cn/tag/%E8%99%9A%E6%8B%9F%E6%9C%BA/" title="虚拟机">
虚拟机<span>1</span></a>
</div>
</div>
<div class="lw-right-list lw-md-show lw-posa">
<div class="lw-right-item lw-profile">
<div class="lw-avatar-content lw-posr"
style="background-image:url(/static/image/5-120601094K3-50.gif);">
<div class="lw-avatar lw-posa">
<img src="/static/image/avatar.jpeg" alt="">
<div class="lw-left-list">
<ol class="breadcrumb lw-crumb">
<li><a href="/">首页</a></li>
<li class="active">标签云</li>
</ol>
<div class="lw-tag-list">
<a th:each="tag:${tagList}" th:title="${tag.name}" th:href="@{/tag/{id}.html(id=${tag.getId()})}">
<th:block th:text="${tag.name}"></th:block>
<span><th:block th:text="${tag.getArticleCount()}"></th:block></span></a>
</div>
</div>
<ul class="lw-info">
<li><span>博主</span>Mr丶冷文</li>
<li><span>坐标</span>北京 昌平</li>
<li><span>标签</span>Java、Web设计、Python、大数据、爬虫</li>
</ul>
</div>
<div class="lw-right-item lw-right-hot">
<h4><i class="fa fa-fire lw-mr5" aria-hidden="true"></i>热门文章</h4>
<ul class="lw-hot-list">
<li>
<a href="#">
<div class="lw-hot-img">
<span class="label label-danger lw-posa">1</span>
<img src="/static/image/1.jpg" alt="">
</div>
<p class="lw-hot-title">Freewind主题编辑器展示</p>
<p class="lw-hot-info"><i class="fa-solid fa-fire-flame-curved"></i> 65580 </p>
</a>
</li>
<li>
<a href="#">
<div class="lw-hot-img">
<span class="label label-warning lw-posa">2</span>
<img src="/static/image/2.jpg" alt="">
</div>
<p class="lw-hot-title">Conda虚拟环境使用</p>
<p class="lw-hot-info"><i class="fa-solid fa-fire-flame-curved"></i> 56283 </p>
</a>
</li>
<li>
<a href="#">
<div class="lw-hot-img">
<span class="label label-info lw-posa">3</span>
<img src="/static/image/3.jpg" alt="">
<div class="lw-right-list lw-md-show lw-posa">
<th:block th:fragment="right">
<div class="lw-right-item lw-profile">
<div class="lw-avatar-content lw-posr"
style="background-image:url(/static/image/5-120601094K3-50.gif);">
<div class="lw-avatar lw-posa">
<img th:src="${@webSite.avatar}" src="/static/image/avatar.jpeg" alt="">
</div>
</div>
<ul class="lw-info">
<li><span>博主</span>
<th:block th:text="${@webSite.nickname}"></th:block>
</li>
<li><span>坐标</span>
<th:block th:text="${T(java.lang.String).join(' ',@webSite.address)}"></th:block>
</li>
<li><span>标签</span>
<th:block th:text="${T(java.lang.String).join('、',@webSite.tags)}"></th:block>
</li>
</ul>
</div>
<p class="lw-hot-title">纯 CSS 图片碎裂动画教程</p>
<p class="lw-hot-info"><i class="fa-solid fa-fire-flame-curved"></i> 52213 </p>
</a>
</li>
<li>
<a href="#">
<div class="lw-hot-img">
<span class="label label-default lw-posa">4</span>
<img src="/static/image/4.jpg" alt="">
<div class="lw-right-item lw-right-hot">
<h4><i class="fa fa-fire lw-mr5" aria-hidden="true"></i>热门文章</h4>
<ul class="lw-hot-list">
<!--/*@thymesVar id="hots" type="java.util.List<cc.bnblogs.pojo.Article>"*/-->
<li th:each="hot,it:${hots}">
<a th:href="@{/{id}.html(id=${hot.id})}" target="_blank">
<div class="lw-hot-img">
<span class="label label-danger lw-posa" th:if="${it.index eq 0}">1</span>
<span class="label label-warning lw-posa" th:if="${it.index eq 1}">2</span>
<span class="label label-info lw-posa" th:if="${it.index eq 2}">3</span>
<span class="label label-default lw-posa" th:if="${it.index > 2}"
th:text="${it.index+1}"></span>
<img th:src="${@defaultImages.cover(hot.cover)}" alt="">
</div>
<p class="lw-hot-title" th:text="${hot.title}"></p>
<p class="lw-hot-info"><i class="fa fa-eye lw-mr5"></i>
<th:block th:text="${hot.views}"></th:block>
</p>
</a>
</li>
</ul>
</div>
<p class="lw-hot-title">Spring Boot 3.0 M1 发布</p>
<p class="lw-hot-info"><i class="fa-solid fa-fire-flame-curved"></i> 23132 </p>
</a>
</li>
<li>
<a href="#">
<div class="lw-hot-img">
<span class="label label-default lw-posa">5</span>
<img src="/static/image/5.jpg" alt="">
<div class="lw-right-item lw-tag-cloud">
<h4><i class="fa fa-tags lw-mr5" aria-hidden="true"></i>标签云</h4>
<!--/*@thymesVar id="tags" type="java.util.List<cc.bnblogs.pojo.Tag>"*/-->
<a th:each="tag:${tags}" th:href="@{/tag/{id}.html(id=${tag.id})}" th:title="${tag.name}"
th:text="${tag.name}"></a>
</div>
<p class="lw-hot-title">异步上传文件显示进度条</p>
<p class="lw-hot-info"><i class="fa-solid fa-fire-flame-curved"></i> 12322 </p>
</a>
</li>
</ul>
</th:block>
</div>
<div class="lw-right-item lw-tag-cloud">
<h4><i class="fa fa-tags lw-mr5" aria-hidden="true"></i>标签云</h4>
<a href="https://www.kevinlu98.cn/tag/freewind/" title="freewind">
freewind</a>
<a href="https://www.kevinlu98.cn/tag/typecho/" title="typecho">
typecho</a>
<a href="https://www.kevinlu98.cn/tag/%E6%8F%92%E4%BB%B6/" title="插件">
插件</a>
<a href="https://www.kevinlu98.cn/tag/emlog/" title="emlog">
emlog</a>
<a href="https://www.kevinlu98.cn/tag/java/" title="java">
java</a>
<a href="https://www.kevinlu98.cn/tag/%E4%B8%BB%E9%A2%98/" title="主题">
主题</a>
<a href="https://www.kevinlu98.cn/tag/%E8%87%AA%E7%94%B1%E4%B9%8B%E9%A3%8E/" title="自由之风">
自由之风</a>
<a href="https://www.kevinlu98.cn/tag/%E5%9B%BE%E5%BA%8A/" title="图床">
图床</a>
<a href="https://www.kevinlu98.cn/tag/%E5%86%B7%E6%96%87%E5%9B%BE%E5%BA%8A/" title="冷文图床">
冷文图床</a>
<a href="https://www.kevinlu98.cn/tag/markdown/" title="markdown">
markdown</a>
<a href="https://www.kevinlu98.cn/tag/gitee/" title="gitee">
gitee</a>
<a href="https://www.kevinlu98.cn/tag/springboot/" title="springboot">
springboot</a>
<a href="https://www.kevinlu98.cn/tag/linux/" title="linux">
linux</a>
<a href="https://www.kevinlu98.cn/tag/mac/" title="mac">
mac</a>
<a href="https://www.kevinlu98.cn/tag/%E5%AD%A6%E4%B9%A0/" title="学习">
学习</a>
<a href="https://www.kevinlu98.cn/tag/python/" title="python">
python</a>
<a href="https://www.kevinlu98.cn/tag/conda/" title="conda">
conda</a>
<a href="https://www.kevinlu98.cn/tag/%E7%9B%B8%E5%86%8C/" title="相册">
相册</a>
<a href="https://www.kevinlu98.cn/tag/jsDelivr/" title="jsDelivr">
jsDelivr</a>
<a href="https://www.kevinlu98.cn/tag/cdn/" title="cdn">
cdn</a>
<a href="https://www.kevinlu98.cn/tag/codemirror/" title="codemirror">
codemirror</a>
<a href="https://www.kevinlu98.cn/tag/freedom/" title="freedom">
freedom</a>
<a href="https://www.kevinlu98.cn/tag/%E8%85%BE%E8%AE%AFcos/" title="腾讯cos">
腾讯cos</a>
<a href="https://www.kevinlu98.cn/tag/cos/" title="cos">
cos</a>
<a href="https://www.kevinlu98.cn/tag/%E7%A7%81%E4%BA%BA%E5%9B%BE%E5%BA%8A/" title="私人图床">
私人图床</a>
<a href="https://www.kevinlu98.cn/tag/%E6%AC%A2%E8%BF%8E%E9%A1%B5/" title="欢迎页">
欢迎页</a>
<a href="https://www.kevinlu98.cn/tag/%E7%99%BB%E5%BD%95%E6%B3%A8%E5%86%8C/" title="登录注册">
登录注册</a>
<a href="https://www.kevinlu98.cn/tag/%E6%95%99%E7%A8%8B%E4%B8%8B%E8%BD%BD/" title="教程下载">
教程下载</a>
<a href="https://www.kevinlu98.cn/tag/itjc8/" title="itjc8">
itjc8</a>
<a href="https://www.kevinlu98.cn/tag/%E8%99%9A%E6%8B%9F%E6%9C%BA/" title="虚拟机">
虚拟机</a>
</div>
</div>
</div>
<div class="lw-friend-link">
<div class="lw-container">
<h2>友情链接</h2>
<a href="">冷文学习者</a>
<a href="">冷文博客</a>
<a href="">冷文聊编程</a>
<a href="">GetHub</a>
<a href="">CSDN</a>
<a href="">百度一下</a>
<a href="">新浪微博</a>
<a href="">谷歌搜索</a>
<a href="">知乎</a>
<a href="">掘金</a>
</div>
</div>
<footer>
<p>冷文学习者 版权所有 <span class="lw-mr5"></span>Copyright © www.kevinlu98.cn All Rights Reserved.</p>
<p>备案号:陕ICP备19024566-1号 京公网安备 11011402012109号</p>
</footer>
<div class="lw-mask" id="lw-search-box">
<div class="lw-search-conetnt">
<a href="javascript:void(0)" class="lw-search-close lw-posa"><i class="fa fa-close"></i></a>
<div class="lw-search-input lw-posr">
<form action="" method="post">
<input type="text" placeholder="请输入搜索关键字...">
<button class="lw-posa"><i class="fa fa-search lw-mr5"></i>搜索</button>
</form>
<th:block th:fragment="footer">
<div class="lw-friend-link">
<div class="lw-container">
<h2>友情链接</h2>
<!--/*@thymesVar id="friends" type="java.util.List<cc.bnblogs.pojo.Friends>"*/-->
<a th:each="friend:${friends}" target="_blank" th:href="${friend.link}" th:text="${friend.title}"></a>
</div>
</div>
<p>推荐关键字:
<a href="javascript:void (0)">独立下载</a>
<a href="javascript:void (0)">评论通知</a>
<a href="javascript:void (0)">点赞</a>
<a href="javascript:void (0)">非插件</a>
<a href="javascript:void (0)">tp5</a>
<a href="javascript:void (0)">ajax</a>
<a href="javascript:void (0)">json</a>
<a href="javascript:void (0)">IO模型</a>
<a href="javascript:void (0)">跨域</a>
<a href="javascript:void (0)">javascript</a>
<a href="javascript:void (0)">springboot</a>
<a href="javascript:void (0)">视频剪辑</a>
<a href="javascript:void (0)">后期</a>
<a href="javascript:void (0)">个人随笔</a>
</p>
</div>
</div>
<footer th:utext="${@webSite.footer}"></footer>
<div class="lw-mask" id="lw-search-box">
<div class="lw-search-conetnt">
<a href="javascript:void(0)" class="lw-search-close lw-posa"><i class="fa fa-close"></i></a>
<div class="lw-search-input lw-posr">
<form th:action="@{/search.html}" method="get">
<input type="text" required 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>
</div>
</div>
<script src="/static/plugin/jquery/jquery-3.5.1.min.js"></script>
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="/static/plugin/bootstrap/js/bootstrap.min.js"></script>
<script src="/static/plugin/swiper-bundle/swiper-bundle.min.js"></script>
<script src="/static/js/main.js"></script>
</th:block>
<script src="/static/plugin/jquery/jquery-3.5.1.min.js"></script>
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="/static/plugin/bootstrap/js/bootstrap.min.js"></script>
<script src="/static/js/main.js"></script>
</body>
</html>
Loading…
Cancel
Save