一.下载layui社区的模版
https://fly.layui.com/store/FlyTemplate/
二.springboot热部署
参考(https://blog.youkuaiyun.com/panruola/article/details/87890234)
2.1导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
2.2Compiler,勾选 “Make project automatically”
3.3.快捷键 Shift+Ctrl+Alt+/ ,选择 “Registry” ,选中打勾 “compiler.automake.allow.when.app.running”
三.导入到springboot项目中(抽取片段)
我们可以抽取功能的片段:比如comment.html中公共的css样式(title不一样,我们可以通过参数传过来)
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:fragment="commentStyle">
<meta charset="utf-8">
<title th:text="${
title}">基于 layui 的极简社区页面模版</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="keywords" content="fly,layui,前端社区">
<meta name="description" content="Fly社区是模块化前端UI框架Layui的官网社区,致力于为web开发提供强劲动力">
<link rel="stylesheet" th:href="@{
/static/layui/css/layui.css}">
<link rel="stylesheet" th:href="@{
/static/css/global.css}">
</head>
<body>
引入:
<!--引入公共头部样式-->
<head th:replace="~{
inc/comment::commentStyle(title='首页')}">
四.controller中防止非整形访问该URL会报异常,所以通过id:\\d*来只允许整形通过
/*
博客详细页面
id:\d*只允许传的参数为整形
*/
@GetMapping("/post/{
id:\\d*}")
public String detail(@PathVariable("id") Long id){
return "post/detail";
}
五.导航栏的信息通过项目启动就存进容器中,这样项目一运行就查询数据库中的数据
1.创建一个类实现ApplicationRunner和ServletContextAware类
- ApplicationRunner用于在项目运行就执行
- ServletContextAware用于获取容器上下文
2.运行项目查询数据库中数据,并存进上下文
package com.wcy.eblog.config;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wcy.eblog.entity.MCategory;
import com.wcy.eblog.service.MCategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.web.context.ServletContextAware;
import javax.servlet.ServletContext;
import java.util.List;
/**
* ApplicationRunner 容器在启动的时候就会执行
* ServletContextAware获取上下文容器
* 把分类(导航栏)存进上下文容器中 (便于速度更快)
*/
@Component
public class ContextStartUp implements ApplicationRunner, ServletContextAware {
@Autowired
private MCategoryService mCategoryService;
ServletContext servletContext;
@Override
public void run(ApplicationArguments args) throws Exception {
//查询status=0的所有分类导航栏 若为1则不查询
List<MCategory> mCategoryList = mCategoryService.list(new QueryWrapper<MCategory>().eq("status",0));
//把查询到的数据存进容器中
servletContext.setAttribute("mCategoryList", mCategoryList);
}
@Override
public void setServletContext(ServletContext servletContext) {
this.servletContext=servletContext;
}
}
3.thymeleaf获取容器上下文的方法
<li th:each="category:${
#servletContext.getAttribute('mCategoryList')}">
<a th:href="@{
'/catalog/'+${
category.id}}">[[${
category.name}]]</a>
</li>
六.thymeleaf处理时间显示成几小时前
<!--对时间处理成几小时前-->
<span th:datetime="${#dates.format(postVo.created, 'yyyy-MM-dd HH:mm')}" class="time"></span>
<script src="https://cdn.bootcss.com/timeago.js/3.0.2/timeago.js"></script>
<script>
// 自动更新
var timeagoInstance = timeago();// 实例
timeagoInstance.render(document.querySelectorAll('.time'),'zh_CN');
</script>
七.注意layui分页的JS需要等页面加载完毕才执行
问题:防止layui分页消失,不会出现分页按钮
解决:
放到JQ的加载完毕才会执行的方法
$(function(){
});
八.实现博客七天回复量排行榜(redis实现)
1.实现逻辑:
- 查询数据库中前七天的博客以及博客的评论数
- 通过redis的zset有序集合key存关于天数的(博客创建的那一天 有序map),然后zset里面的key存博客id之类的,分数存评论数
比如:2020-7-2日有哪些博客创建了并且评论了,那么就会存进这个有序集合的key里面(见下图)
4. 因为web端需要展示博客的标题、评论数,所有还需要通过一个hash来存储这些数据。
5. 这些都需要设置一个过期时间 超出七天则清除
相关命令:
2.对应的service逻辑方法:
//初始化本周热议
@Override
public void initWeekRank() {
//1.查询七天内的博客
//DateUtil.offset(new Date(), DateField.DAY_OF_MONTH,-7)获取当前时间的第前七天的时间
List<MPost> mPosts = mPostMapper.selectList(new QueryWrapper<MPost>()
.ge("created", DateUtil.offset(new Date(), DateField.DAY_OF_MONTH,-7))
.gt("comment_count",0)//评论数大于0
);
//2.存进redis中
for(MPost mPost:mPosts){
String key="eblog:rank:time:"+DateUtil.format(mPost.getCreated(),"yyyy-MM-dd");
//2.1//存进zset中
redisUtil.zSet(key,mPost.getId(),mPost.getCommentCount());
//2.2.计算当前时间与博客创建时间差 7-(18-14)
long time=(7-DateUtil.between(new Date(),mPost.getCreated(), DateUnit.DAY))*24*60*60;
//2.3设置key消失时间
boolean expire = redisUtil.expire(key, time);
//2.4由于前端需要显示标题、评论数等信息
hashCachePostIdAndTitle(mPost);
}
//3.计算某七天的评论数并逆序排序
zUnionPost7DaysForWeekRand();
}
//计算七天内的评论数
private void zUnionPost7DaysForWeekRand() {
String newKey="eblog:rank:7week";
List<String> list=new ArrayList<>();
for(int i=-7;i<0;i++){
//这七天的key存进list里面 用户求并集
String timeKey="eblog:rank:time:"+ DateUtil.format(DateUtil.offsetDay(new Date(),i),"yyyy-MM-dd");
list.add(timeKey);
}
String key="eblog:rank:time:"+ DateUtil.format(new Date(),"yyyy-MM-dd");
redisUtil.zUnionAndStore(key,list,newKey);//timeKey
}
//把博客信息存进redis中
private void hashCachePostIdAndTitle(MPost mPost) {
//通过博客的ID来存储键
String key="eblog:rank:post:"+mPost.getId();
//计算当前时间与博客创建时间差 7-(18-14)
long time=(7-DateUtil.between(new Date(),mPost.getCreated(), DateUnit.DAY))*24*60*60;
//存进redis中并设置过期时间
redisUtil