登录功能、后台控制台、评论功能完善、修复邮件异步发送bug

master
barney 2 years ago
parent 16e0687b4e
commit 901a6ee8a5
  1. 4
      .gitignore
  2. 0
      cache/.ehcache-diskstore.lock
  3. BIN
      cache/blog-cache.data
  4. 2
      src/main/java/cc/bnblogs/Application.java
  5. 2
      src/main/java/cc/bnblogs/common/MailHelper.java
  6. 5
      src/main/java/cc/bnblogs/common/WebSite.java
  7. 23
      src/main/java/cc/bnblogs/config/WebConfig.java
  8. 66
      src/main/java/cc/bnblogs/controller/AdminController.java
  9. 60
      src/main/java/cc/bnblogs/controller/CommentController.java
  10. 33
      src/main/java/cc/bnblogs/interceptor/LoginInterceptor.java
  11. 26
      src/main/java/cc/bnblogs/mapper/CommentMapper.java
  12. 33
      src/main/java/cc/bnblogs/service/CommentService.java
  13. 4
      src/main/java/cc/bnblogs/utils/CookieUtil.java
  14. 2
      src/main/resources/application.yml
  15. 7
      src/main/resources/templates/admin/article.html
  16. 12
      src/main/resources/templates/admin/banner.html
  17. 11
      src/main/resources/templates/admin/category.html
  18. 403
      src/main/resources/templates/admin/comment.html
  19. 15
      src/main/resources/templates/admin/common.html
  20. 10
      src/main/resources/templates/admin/friends.html
  21. 51
      src/main/resources/templates/admin/index.html
  22. 23
      src/main/resources/templates/admin/login.html
  23. 11
      src/main/resources/templates/admin/navigation.html
  24. 23
      src/test/java/cc/bnblogs/test/TestMd5Password.java

4
.gitignore vendored

@ -1,9 +1,13 @@
.idea/ .idea/
# 忽略生成的目标文件所在文件夹
target/ target/
# 忽略上传图片的文件夹 # 忽略上传图片的文件夹
upload/ upload/
# 忽略日志文件夹 # 忽略日志文件夹
logs/ logs/
# 忽略缓存文件夹
cache/
# Compiled class file # Compiled class file
*.class *.class

Binary file not shown.

@ -3,6 +3,7 @@ package cc.bnblogs;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.annotation.EnableCaching;
import org.springframework.scheduling.annotation.EnableAsync;
/** /**
@ -10,6 +11,7 @@ import org.springframework.cache.annotation.EnableCaching;
* @createTime: 2022/10/16 * @createTime: 2022/10/16
*/ */
@EnableCaching @EnableCaching
@EnableAsync
@SpringBootApplication @SpringBootApplication
public class Application { public class Application {
public static void main(String[] args) { public static void main(String[] args) {

@ -4,6 +4,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.mail.MessagingException; import javax.mail.MessagingException;
@ -31,6 +32,7 @@ public class MailHelper {
* @param subject 主题 * @param subject 主题
* @param text 内容 * @param text 内容
*/ */
@Async
public void sendMail(String toSend, String subject, String text) { public void sendMail(String toSend, String subject, String text) {
MimeMessage message = javaMailSender.createMimeMessage(); MimeMessage message = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message); MimeMessageHelper helper = new MimeMessageHelper(message);

@ -14,6 +14,7 @@ import java.util.List;
@Component @Component
@ConfigurationProperties(prefix = "website") @ConfigurationProperties(prefix = "website")
public class WebSite { public class WebSite {
public static final String LOGIN_SIGN = "login_sign";
// 站点名称 // 站点名称
private String title; private String title;
// SEO的关键字 // SEO的关键字
@ -22,6 +23,10 @@ public class WebSite {
private String description; private String description;
// 站长昵称 // 站长昵称
private String nickname; private String nickname;
// 管理员姓名
private String username;
// 管理员密码
private String password;
// 站长头像 // 站长头像
private String avatar; private String avatar;
// 站长坐标 // 站长坐标

@ -1,9 +1,9 @@
package cc.bnblogs.config; package cc.bnblogs.config;
import cc.bnblogs.common.LRUCache; import cc.bnblogs.common.LRUCache;
import cc.bnblogs.common.Result; import cc.bnblogs.interceptor.LoginInterceptor;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.server.ConfigurableWebServerFactory; import org.springframework.boot.web.server.ConfigurableWebServerFactory;
import org.springframework.boot.web.server.ErrorPage; import org.springframework.boot.web.server.ErrorPage;
@ -11,12 +11,10 @@ import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File; import java.io.File;
/** /**
@ -30,8 +28,23 @@ public class WebConfig implements WebMvcConfigurer {
@Value("${upload.base-dir}") @Value("${upload.base-dir}")
private String baseDir; private String baseDir;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册拦截器,添加拦截路由和放行路由
registry.addInterceptor(loginInterceptor)
.addPathPatterns("/admin/**")
.excludePathPatterns("/admin/login","/admin/logout","/admin/login.html");
}
private final LoginInterceptor loginInterceptor;
public static final Integer MAX_LRU_CACHE_SIZE = 20; public static final Integer MAX_LRU_CACHE_SIZE = 20;
public WebConfig(LoginInterceptor loginInterceptor) {
this.loginInterceptor = loginInterceptor;
}
@Override @Override
public void addResourceHandlers(ResourceHandlerRegistry registry) { public void addResourceHandlers(ResourceHandlerRegistry registry) {
// 创建static目录到/static/的路由 // 创建static目录到/static/的路由

@ -1,15 +1,24 @@
package cc.bnblogs.controller; package cc.bnblogs.controller;
import cc.bnblogs.common.ArticleSearch;
import cc.bnblogs.common.Result;
import cc.bnblogs.common.WebSite;
import cc.bnblogs.pojo.Article; import cc.bnblogs.pojo.Article;
import cc.bnblogs.pojo.Category; import cc.bnblogs.pojo.Category;
import cc.bnblogs.service.ArticleService; import cc.bnblogs.service.ArticleService;
import cc.bnblogs.service.CategoryService; import cc.bnblogs.service.CategoryService;
import cc.bnblogs.service.CommentService;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.thymeleaf.util.StringUtils;
import javax.servlet.http.HttpSession;
import java.nio.charset.StandardCharsets;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@ -22,14 +31,25 @@ import java.util.Objects;
public class AdminController { public class AdminController {
private final CategoryService categoryService; private final CategoryService categoryService;
private final ArticleService articleService; private final ArticleService articleService;
private final CommentService commentService;
public AdminController(CategoryService categoryService, ArticleService articleService) { private final WebSite webSite;
public AdminController(CategoryService categoryService, ArticleService articleService, CommentService commentService, WebSite webSite) {
this.categoryService = categoryService; this.categoryService = categoryService;
this.articleService = articleService; this.articleService = articleService;
this.commentService = commentService;
this.webSite = webSite;
} }
@GetMapping("/") @GetMapping("/")
public String index() { public String index(Model model) {
// 获取文章总数、分类总数、总评论数、未读评论数、最新的5篇文章、最新的5条评论
model.addAttribute("ArticleCount",articleService.count());
model.addAttribute("CategoryCount",categoryService.count());
model.addAttribute("CommentAll",commentService.count(null));
model.addAttribute("CommentNotReadCount",commentService.count(false));
model.addAttribute("NewArticleList",articleService.search(ArticleSearch.builder()
.type(Article.TYPE_ARTICLE).pageNum(1).pageSize(5).build()).getRows());
model.addAttribute("NewCommentList",commentService.list(null,1,5).getRows());
return "admin/index"; return "admin/index";
} }
@GetMapping("/category.html") @GetMapping("/category.html")
@ -56,7 +76,9 @@ public class AdminController {
} }
@GetMapping("/comment.html") @GetMapping("/comment.html")
public String comment() { public String comment(@RequestParam(required = false)Boolean view, Model model) {
// 给前端返回一个isView参数用来选中对应按扭
model.addAttribute("isView",view);
return "admin/comment"; return "admin/comment";
} }
@ -77,4 +99,40 @@ public class AdminController {
model.addAttribute("pageTitle", Objects.isNull(article.getId()) ? "创建新文章" : "编辑文章---" + article.getTitle()); model.addAttribute("pageTitle", Objects.isNull(article.getId()) ? "创建新文章" : "编辑文章---" + article.getTitle());
return "admin/write"; return "admin/write";
} }
/**
* 前台访问登陆页面
* @return
*/
@GetMapping("/login.html")
public String login() {
return "admin/login";
}
/**
* 登录校验
* @param username 用户名
* @param password 密码
* @return
*/
@PostMapping("/login")
public String login(String username, String password, Model model, HttpSession session) {
// 用户名和密码都一致,登录成功
if (StringUtils.equals(webSite.getPassword(), DigestUtils
.md5DigestAsHex(password.getBytes(StandardCharsets.UTF_8)))
&& StringUtils.equals(username,webSite.getUsername())) {
session.setAttribute(WebSite.LOGIN_SIGN,true);
return "redirect:/admin/";
}
else {
model.addAttribute("errorMsg","用户名或密码错误!");
return "admin/login";
}
}
@GetMapping("/logout")
public String logout(HttpSession session) {
session.removeAttribute(WebSite.LOGIN_SIGN);
return "admin/login";
}
} }

@ -1,9 +1,15 @@
package cc.bnblogs.controller; package cc.bnblogs.controller;
import cc.bnblogs.common.PageHelper;
import cc.bnblogs.common.Result; import cc.bnblogs.common.Result;
import cc.bnblogs.common.WebSite;
import cc.bnblogs.enums.ResultEnum; import cc.bnblogs.enums.ResultEnum;
import cc.bnblogs.pojo.Article;
import cc.bnblogs.pojo.Comment; import cc.bnblogs.pojo.Comment;
import cc.bnblogs.service.CommentService; import cc.bnblogs.service.CommentService;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.List; import java.util.List;
@ -17,18 +23,29 @@ import java.util.Objects;
@RequestMapping("/admin/comment") @RequestMapping("/admin/comment")
public class CommentController { public class CommentController {
private final CommentService commentService; private final CommentService commentService;
private final WebSite webSite;
public CommentController(CommentService commentService) {
public CommentController(CommentService commentService, WebSite webSite) {
this.commentService = commentService; this.commentService = commentService;
this.webSite = webSite;
} }
/** /**
* 请求所有评论的接口 * 根据评论是否已读返回分页后的评论列表
* @return 返回所有评论 * 按评论创建时间降序返回
* @param view 是否已读
* @param pageNumber 页号
* @param pageSize 页大小
* @return 分页后的评论
*/ */
@GetMapping("/") @GetMapping("/")
public Result<List<Comment>> list() { public Result<PageHelper<Comment>> list(@RequestParam(required = false) Boolean view,
return Result.success(commentService.list()); @RequestParam(required = false,defaultValue = "1") Integer pageNumber,
@RequestParam(required = false,defaultValue = "1")Integer pageSize) {
pageNumber = Math.max(1,pageNumber);
pageSize = Math.max(1,pageSize);
return Result.success(commentService.list(view,pageNumber,pageSize));
} }
/** /**
@ -67,4 +84,37 @@ public class CommentController {
commentService.delete(id); commentService.delete(id);
return Result.success(); return Result.success();
} }
/**
* 一键已读所有评论
*/
@GetMapping("/read")
public Result<String> readAll(){
commentService.readAll();
return Result.success();
}
/**
* 回复评论
* @param pid 父评论id
* @param aid 文章id
* @param message 回复内容
* @return 操作结果
*/
@PostMapping("/{pid}")
public Result<String> reply(@PathVariable Integer pid,Integer aid,String message) {
// 构造一个comment对象
// 填充站长的昵称、邮箱、网站地址、父评论id、文章id、回复内容
Comment comment = Comment.builder()
.article(Article.builder().id(aid).build())
.nickname(webSite.getNickname())
.email(webSite.getMail())
.url(webSite.getDomain())
.pid(pid)
.content(message)
.build();
// 保存评论
commentService.save(comment);
return Result.success();
}
} }

@ -0,0 +1,33 @@
package cc.bnblogs.interceptor;
import cc.bnblogs.common.WebSite;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Objects;
/**
* @author zfp@bnblogs.cc
* @createTime: 2022/10/23
* @description: 登录拦截器
*/
@Component
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
Boolean sign = (Boolean) session.getAttribute(WebSite.LOGIN_SIGN);
if (Objects.nonNull(sign) && sign) {
return true;
}
else {
request.setAttribute("errorMsg","请登录后再操作!");
// 当Session中没有登录信息时我们直接转发到登录页面并给出请登录后再进行操作的提示
request.getRequestDispatcher("/admin/login.html").forward(request,response);
return false;
}
}
}

@ -5,6 +5,9 @@ import cc.bnblogs.pojo.Comment;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.transaction.annotation.Transactional;
import java.util.List; import java.util.List;
@ -35,4 +38,27 @@ public interface CommentMapper extends JpaRepository<Comment,Integer> {
* @return 该父评论下的所有评论 * @return 该父评论下的所有评论
*/ */
List<Comment> findAllByPidOrderByCreatedDesc(Integer pid); List<Comment> findAllByPidOrderByCreatedDesc(Integer pid);
/**
* 将所有未读评论改为已读
*/
@Modifying
@Transactional(rollbackFor = {Exception.class})
@Query(value = "update blog_comment set view=true where view=false ", nativeQuery = true)
void readAll();
/**
* 根据view选择不同的评论
* @param view 是否已读
* @param pageable 分页器
* @return 评论列表
*/
Page<Comment> findAllByView(Boolean view, Pageable pageable);
/**
* 根据view的值统计评论数
* @param view 是否已读
* @return 评论个数
*/
Long countCommentByView(Boolean view);
} }

@ -10,7 +10,8 @@ import cc.bnblogs.pojo.Comment;
import cc.bnblogs.utils.UpdateUtil; import cc.bnblogs.utils.UpdateUtil;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.PageRequest;
import org.springframework.scheduling.annotation.Async; import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Date; import java.util.Date;
@ -48,12 +49,13 @@ public class CommentService {
} }
/** /**
* 获取评论总数 * 根据是否view的取值返回评论数(null:表示所有)
* * @param view 是否已读
* @return 评论 * @return 评论
*/ */
public long count() { public long count(Boolean view) {
return commentMapper.count(); return Objects.isNull(view) ?
commentMapper.count(): commentMapper.countCommentByView(view);
} }
/** /**
@ -87,7 +89,9 @@ public class CommentService {
comment.setPid(findCommentPid(comment.getPid())); comment.setPid(findCommentPid(comment.getPid()));
} }
commentMapper.save(comment); commentMapper.save(comment);
} else { }
// 修改评论内容
else {
Comment one = detail(comment.getId()); Comment one = detail(comment.getId());
UpdateUtil.copyNullProperties(comment, one); UpdateUtil.copyNullProperties(comment, one);
commentMapper.save(one); commentMapper.save(one);
@ -99,7 +103,6 @@ public class CommentService {
* *
* @param id 文章id * @param id 文章id
*/ */
@Async
public void sendMailToWebsite(Integer id) { public void sendMailToWebsite(Integer id) {
Article article = articleMapper.findById(id).orElse(null); Article article = articleMapper.findById(id).orElse(null);
if (Objects.isNull(article)) { if (Objects.isNull(article)) {
@ -119,7 +122,6 @@ public class CommentService {
* @param cid 被评论的评论id * @param cid 被评论的评论id
* @param reply 回复内容 * @param reply 回复内容
*/ */
@Async
public void sendMailToComment(Integer id, Integer cid, String reply) { public void sendMailToComment(Integer id, Integer cid, String reply) {
Article article = articleMapper.findById(id).orElse(null); Article article = articleMapper.findById(id).orElse(null);
if (Objects.isNull(article)) { if (Objects.isNull(article)) {
@ -170,4 +172,17 @@ public class CommentService {
// 评论内容-当前页数-评论总数-总页数 // 评论内容-当前页数-评论总数-总页数
return PageHelper.<Comment>builder().rows(page.getContent().stream().peek(x -> x.setChildren(commentMapper.findAllByPidOrderByCreatedDesc(x.getId()))).collect(Collectors.toList())).currentPage(pageNumber).total(page.getTotalElements()).totalPages(page.getTotalPages()).build(); return PageHelper.<Comment>builder().rows(page.getContent().stream().peek(x -> x.setChildren(commentMapper.findAllByPidOrderByCreatedDesc(x.getId()))).collect(Collectors.toList())).currentPage(pageNumber).total(page.getTotalElements()).totalPages(page.getTotalPages()).build();
} }
public void readAll() {
commentMapper.readAll();
}
public PageHelper<Comment> list(Boolean view, Integer pageNumber, Integer pageSize) {
Pageable pageable = PageRequest.of(pageNumber-1,pageSize, Sort.by(Sort.Direction.DESC,"created"));
Page<Comment> page = Objects.isNull(view) ? commentMapper.findAll(pageable) : commentMapper.findAllByView(view,pageable);
return PageHelper.<Comment>builder()
.rows(page.getContent())
.total(page.getTotalElements())
.build();
}
} }

@ -31,8 +31,8 @@ public class CookieUtil {
} }
public static void setCookie(HttpServletResponse response, String cookieName, String value) { public static void setCookie(HttpServletResponse response, String cookieName, String value) {
// 有效期为7 // 有效期为1
setCookie(response, cookieName, value, 7 * 24 * 60 * 60); setCookie(response, cookieName, value, 24 * 60 * 60);
} }
public static void deleteCookie(HttpServletResponse response, String cookieName) { public static void deleteCookie(HttpServletResponse response, String cookieName) {

@ -73,6 +73,8 @@ website:
domain: http://localhost:8080 #域名 domain: http://localhost:8080 #域名
avatar: https://hugo.bnblogs.cc/images/img/20220215001349.png avatar: https://hugo.bnblogs.cc/images/img/20220215001349.png
nickname: barney nickname: barney
username: admin
password: 0192023a7bbd73250516f069df18b500
address: 广东 广州 address: 广东 广州
tags: tags:
- java - java

@ -10,7 +10,7 @@
<div class="container lw-main lw-banner"> <div class="container lw-main lw-banner">
<div class="btn-group" role="group" style="margin-bottom: 20px;" aria-label="..."> <div class="btn-group" role="group" style="margin-bottom: 20px;" aria-label="...">
<a th:href="@{/admin/write.html}" class="btn btn-success"><i class="fa fa-plus"></i> 新增</a> <a th:href="@{/admin/write.html}" class="btn btn-success" style="outline: none;"><i class="fa fa-plus"></i> 新增</a>
</div> </div>
<form id="search-form" class="form-inline" style="float:right;"> <form id="search-form" class="form-inline" style="float:right;">
@ -41,8 +41,8 @@
<label>关键字</label> <label>关键字</label>
<input id="article-keywords" type="text" class="form-control" placeholder="请输入关键字..."> <input id="article-keywords" type="text" class="form-control" placeholder="请输入关键字...">
</div> </div>
<button type="reset" class="btn btn-default" id="reset-btn"><i class="fa fa-refresh"></i> 重置</button> <button style="outline: none;" type="reset" class="btn btn-default" id="reset-btn"><i class="fa fa-refresh"></i> 重置</button>
<button type="submit" class="btn btn-primary"><i class="fa fa-search"></i> 搜索</button> <button style="outline: none;" type="submit" class="btn btn-primary"><i class="fa fa-search"></i> 搜索</button>
</form> </form>
<table id="data-table" style="user-select: none"></table> <table id="data-table" style="user-select: none"></table>
</div> </div>
@ -60,6 +60,7 @@
pageSize: 5, // 每页5条数据 pageSize: 5, // 每页5条数据
pageList: [5, 10, 15], // 可选页大小 pageList: [5, 10, 15], // 可选页大小
responseHandler: function (res) { responseHandler: function (res) {
console.log(res.data);
return res.data return res.data
}, },
//这个是查询参数,就是bootstrap-table请求后端时携带的参数 //这个是查询参数,就是bootstrap-table请求后端时携带的参数

@ -10,10 +10,10 @@
<div class="container lw-main lw-banner"> <div class="container lw-main lw-banner">
<div class="btn-group" role="group" style="margin-bottom: 20px" aria-label="..."> <div class="btn-group" role="group" style="margin-bottom: 20px" aria-label="...">
<button type="button" id="create-banner-btn" class="btn btn-default"><i class="fa fa-plus"></i> <button type="button" style="outline: none;" id="create-banner-btn" class="btn btn-success"><i class="fa fa-plus"></i>
新增 新增
</button> </button>
<button type="button" id="refresh-banner-btn" class="btn btn-default"><i class="fa fa-refresh"></i> <button type="button" style="outline: none;" id="refresh-banner-btn" class="btn btn-primary"><i class="fa fa-refresh"></i>
保存顺序 保存顺序
</button> </button>
</div> </div>
@ -70,8 +70,8 @@
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button> <button style="outline: none;" type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
<button type="submit" class="btn btn-primary">保存</button> <button style="outline: none;" type="submit" class="btn btn-primary">保存</button>
</div> </div>
</form> </form>
</div> </div>
@ -135,8 +135,8 @@
align: "center", align: "center",
width: 180, width: 180,
formatter: function (value) { formatter: function (value) {
return `<button type="button" data-id="${value}" class="btn btn-info btn-sm banner-edit-btn"><i class="fa fa-edit"></i> 编辑</button> return `<button type="button" style="outline: none;" data-id="${value}" class="btn btn-info btn-sm banner-edit-btn"><i class="fa fa-edit"></i> 编辑</button>
<button type="button" data-id="${value}" class="btn btn-danger btn-sm banner-delete-btn"><i class="fa fa-trash"></i> 删除</button>` <button type="button" style="outline: none;" data-id="${value}" class="btn btn-danger btn-sm banner-delete-btn"><i class="fa fa-trash"></i> 删除</button>`
} }
} }
], ],

@ -8,7 +8,8 @@
<div class="container lw-main lw-banner"> <div class="container lw-main lw-banner">
<div class="btn-group" role="group" style="margin-bottom: 20px" aria-label="..."> <div class="btn-group" role="group" style="margin-bottom: 20px" aria-label="...">
<button type="button" id="create-category-btn" class="btn btn-default"><i class="fa fa-plus"></i> 新增</button> <button type="button" id="create-category-btn" style="outline: none;" class="btn btn-success">
<i class="fa fa-plus"></i> 新增</button>
</div> </div>
<table id="data-table"></table> <table id="data-table"></table>
</div> </div>
@ -36,8 +37,8 @@
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button> <button type="button" class="btn btn-default" style="outline: none;" data-dismiss="modal">关闭</button>
<button type="submit" class="btn btn-primary">保存</button> <button type="submit" class="btn btn-primary" style="outline: none;">保存</button>
</div> </div>
</form> </form>
</div> </div>
@ -75,8 +76,8 @@
align: "center", align: "center",
width: 180, width: 180,
formatter: function (value) { formatter: function (value) {
return `<button type="button" data-id="${value}" class="btn btn-info btn-sm category-edit-btn"><i class="fa fa-edit"></i> 编辑</button> return `<button type="button" style="outline: none;" data-id="${value}" class="btn btn-info btn-sm category-edit-btn"><i class="fa fa-edit"></i> 编辑</button>
<button type="button" data-id="${value}" class="btn btn-danger btn-sm category-delete-btn"><i class="fa fa-trash"></i> 删除</button>` <button type="button" style="outline: none;" data-id="${value}" class="btn btn-danger btn-sm category-delete-btn"><i class="fa fa-trash"></i> 删除</button>`
} }
} }
], ],

@ -1,232 +1,219 @@
<!DOCTYPE html> <!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" lang="en"> <html xmlns:th="http://www.thymeleaf.org" lang="en">
<head th:replace="admin/common::header(~{::title},~{},~{})"> <head th:replace="admin/common::header(~{::title},~{},~{::style})">
<title>评论管理</title> <title>评论管理</title>
<style>
#comment-content {
width: 400px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
</style>
</head> </head>
<body> <body>
<th:block th:include="admin/common::nav('comment')"></th:block> <th:block th:include="admin/common::nav('comment')"></th:block>
<div class="container lw-main lw-banner"> <div class="container lw-main lw-banner">
<div class="btn-group" role="group" style="margin-bottom: 20px" aria-label="..."> <div class="btn-group" role="group" style="margin-bottom: 20px" aria-label="...">
<button type="button" id="create-comment-btn" class="btn btn-default"><i class="fa fa-plus"></i> <button style="outline: none;" type="button" id="readAll-comment-btn" class="btn btn-default">
新增</button> <i class="fa fa-refresh"></i> 一键已读
</div> </button>
<table id="data-table" style="user-select: none"></table> </div>
</div>
<!-- 编辑窗口 --> <div class="btn-group" id="btn-selected-group" role="group" style="margin-bottom: 20px; float: right" aria-label="...">
<div class="modal fade" id="save-window" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"> <button type="button" style="outline: none;" th:class="${isView eq null}?'btn btn-primary':'btn btn-default'" data-view="">全部
<div class="modal-dialog" role="document"> </button>
<div class="modal-content"> <button type="button" style="outline: none;" th:class="${isView eq true}?'btn btn-primary':'btn btn-default'" data-view="true">已读
<form id="data-form"> </button>
<input type="hidden" name="id"> <button type="button" style="outline: none;" th:class="${isView eq false}?'btn btn-primary':'btn btn-default'" data-view="false">未读
<div class="modal-header"> </button>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="window-title">Modal Title</h4>
</div>
<div class="modal-body">
<div class="form-group">
<label>评论者的昵称</label>
<input type="text" name="nickname" class="form-control"
placeholder="请输入评论者的昵称...">
</div>
<div class="form-group">
<label>评论者的邮箱</label>
<input type="text" name="email" class="form-control"
placeholder="请输入评论者的邮箱...">
</div>
<div class="form-group">
<label>评论者的主页</label>
<input type="text" name="url" class="form-control"
placeholder="请输入评论者的主页...">
</div>
<div class="form-group">
<label>评论内容</label>
<input type="text" name="content" class="form-control"
placeholder="请输入评论内容...">
</div>
<div class="form-group">
<label>是否已读</label>
<input type="text" name="view" class="form-control"
placeholder="请输入是否已读...">
</div>
<div class="form-group">
<label>评论的父评论</label>
<input type="text" name="pid" class="form-control"
placeholder="请输入评论的父评论...">
</div>
<div class="form-group">
<label>评论创建时间</label>
<input type="text" name="created" class="form-control"
placeholder="请输入评论创建时间...">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
<button type="submit" class="btn btn-primary">保存</button>
</div>
</form>
</div> </div>
</div>
<table id="data-table" style="user-select: none"></table>
</div> </div>
<th:block th:include="admin/common::footer"></th:block> <th:block th:include="admin/common::footer"></th:block>
<script> <script>
$(function () { $(function () {
// 显示表单所有评论数据 // 点击已读、未读和全部
$('#data-table').bootstrapTable({ $('#btn-selected-group button').on('click',function () {
url: "/admin/comment/", // 点中哪个就把哪个按钮高亮
columns: [ $('#btn-selected-group .btn-primary').removeClass('btn-primary').addClass('btn-default')
{ $(this).removeClass('btn-default').addClass('btn-primary')
title: "序号", $('#data-table').bootstrapTable('refresh', {silent: true})
width: 50, })
align: 'center',
// 生成自增的序号
formatter: function (value, row, index) {
return index + 1
}
} ,
{
title: "评论者的昵称",
field: "nickname",
},
{
title: "评论者的邮箱",
field: "email",
},
{
title: "评论者的主页",
field: "url",
},
{
title: "评论内容",
field: "content",
},
{
title: "是否已读",
field: "view",
},
{
title: "评论的父评论",
field: "pid",
},
{
title: "评论创建时间",
field: "created",
},
{
field: "id",
title: '操作',
align: "center",
width: 180,
formatter: function (value) {
return `<button type="button" data-id="${value}" class="btn btn-info btn-sm comment-edit-btn"><i class="fa fa-edit"></i> 编辑</button>
<button type="button" data-id="${value}" class="btn btn-danger btn-sm comment-delete-btn"><i class="fa fa-trash"></i> 删除</button>`
}
}
],
responseHandler: function (res) {
return res.data
}
})
// 编辑对应评论
$("#data-table").on("click", ".comment-edit-btn", function () {
let id = $(this).data("id")
$.ajax({
url: "/admin/comment/" + id,
method: 'GET',
dataType: 'json',
success: res => {
if (res.code === 200) {
$("#window-title").text('编辑评论')
$("#data-form").initForm(res.data)
$('#save-window').modal('show')
}
else {
layer.msg(res.message, { icon: 2 })
}
}
})
})
// 新增评论
$("#create-comment-btn").on("click", function () {
$("#window-title").text('新增评论')
// 清空之前表单的数据
$("#data-form").initForm({id: "", nickname: "", email: "", url: "", content: "", view: "", pid: "", created: "",})
$('#save-window').modal('show')
})
// 显示表单所有评论数据
$('#data-table').bootstrapTable({
url: "/admin/comment/",
pagination: true, // 开启分页
sidePagination: 'server', // 使用服务端数据
pageNumber: 1, // 默认页码第一页
pageSize: 10, // 每页5条数据
pageList: [10, 20, 40], // 可选页大小
//这个是查询参数,就是bootstrap-table请求后端时携带的参数
// offset为数据的序号,limit为页大小
queryParams: function (params) {
return {
pageNumber: (params.offset / params.limit) + 1,
pageSize: params.limit,
view: $('#btn-selected-group .btn-primary').data('view'),
}
},
responseHandler: function (res) {
return res.data
},
onDblClickCell: function (field, value, row, $element) {
// 双击评论内容部分时可以编辑评论
let comment = $('#data-table .content');
comment.parent().html(comment.val());
if (field === 'content') {
$element.html(`<textarea class="form-control content">${value}</textarea>`);
$('.content').blur(function () {
// 获取评论id和评论内容
let data = {id: row.id, content: $(this).val()};
$.ajax({
url: '/admin/comment/',
method: 'POST',
data: data,
dataType: 'json',
success: res => {
if (res.code === 200) {
layer.msg("保存成功", {icon: 1, time: 700})
$('#data-table').bootstrapTable('refresh', {silent: true})
} else {
layer.msg(res.message, {icon: 2})
}
}
})
})
}
},
columns: [
{
title: "序号",
align: 'center',
// 生成自增的序号
formatter: function (value, row, index) {
return index + 1
}
},
{
title: "评论者",
field: "nickname",
align: "center",
formatter: (value, row) => {
let html = row.url ? `<a href="${row.url}" target="_blank">${value}</a>` : value;
return html + `<br>${row.email}`;
}
},
{
title: "评论内容",
field: "content",
formatter: value => {
return `<p id="comment-content">${value}</p>`
}
},
{
title: "是否已读",
field: "view",
align: "center",
formatter: value => {
return value ? "已读" : "未读";
}
},
{
title: "评论创建时间",
field: "created",
align: "center",
},
{
field: "id",
title: '操作',
align: "center",
formatter: function (value,row) {
return `<button type="button" data-id="${value}" data-aid="${row.article.id}" class="btn btn-success btn-sm comment-reply-btn"><i class="fa fa-comment"></i> 回复</button>
<button type="button" data-id="${value}" class="btn btn-danger btn-sm comment-delete-btn"><i class="fa fa-trash"></i> 删除</button>`
}
}
]
})
// 删除评论 // 删除评论
$("#data-table").on("click", ".comment-delete-btn", function () { $("#data-table").on("click", ".comment-delete-btn", function () {
let id = $(this).data('id') let id = $(this).data('id')
let idx = layer.confirm('是否要删除该数据?', { let idx = layer.confirm('是否要删除该数据?', {
btn: ['确认', '取消'] //按钮 btn: ['确认', '取消'] //按钮
}, function () { // 点击确认后删除 }, function () { // 点击确认后删除
$.ajax({ $.ajax({
url: '/admin/comment/' + id, url: '/admin/comment/' + id,
method: 'delete', method: 'delete',
dataType: 'json', dataType: 'json',
success: res => { success: res => {
if (res.code === 200) { if (res.code === 200) {
layer.msg("删除成功", { icon: 1, time: 700 }) layer.msg("删除成功", {icon: 1, time: 700})
$('#data-table').bootstrapTable('refresh', { silent: true }) $('#data-table').bootstrapTable('refresh', {silent: true})
} else { } else {
layer.msg(res.message, { icon: 2 }) layer.msg(res.message, {icon: 2})
} }
} }
})
layer.close(idx); // 关闭提示框
})
}) })
layer.close(idx); // 关闭提示框
})
})
// 更新评论数据 // 一键已读评论
$("#data-form").on("submit", function () { $('#readAll-comment-btn').on('click', function () {
let data = $(this).serialize(); $.ajax({
$.ajax({ url: "/admin/comment/read",
url: "/admin/comment/", type: 'GET',
method: "POST", dataType: 'json',
data: data, success(res) {
dataType: "json", if (res.code === 200) {
success: res => { layer.msg("操作成功", {icon: 1, time: 700})
if (res.code === 200) { $('#data-table').bootstrapTable('refresh', {silent: true})
// 显示成功信息 } else {
layer.msg("保存成功", { icon: 1, time: 600 }, function () { layer.msg(res.message, {icon: 2})
// 关闭模态框 }
$('#save-window').modal('hide') }
// 重载表格数据
$('#data-table').bootstrapTable('refresh', { silent: true })
}) })
} })
else {
layer.msg(res.message, { icon: 2 })
}
}
})
return false; // 阻止表单的提交行为
})
}) // 回复评论实现
$("#data-table").on('click', '.comment-reply-btn', function () {
// 获取目标资源id
let id = $(this).data('id')
let aid = $(this).data('aid')
layer.prompt({title: '回复', formType: 2}, function (text, index) {
layer.close(index);
$.ajax({
url: '/admin/comment/' + id,
method: 'POST',
data: {
aid: aid,
message: text
}, dataType: 'json',
success: res => {
if (res.code === 200) {
layer.msg("回复成功", {icon: 1})
console.log(res);
$('#data-table').bootstrapTable('refresh', {silent: true})
} else {
layer.msg(res.message, {icon: 2})
}
}
})
});
})
})
</script> </script>
</body> </body>

@ -31,7 +31,7 @@
<span class="icon-bar"></span> <span class="icon-bar"></span>
<span class="icon-bar"></span> <span class="icon-bar"></span>
</button> </button>
<a class="navbar-brand" href="#">博客后台</a> <span class="navbar-brand" style="user-select: none">博客后台</span>
</div> </div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav"> <ul class="nav navbar-nav">
@ -46,8 +46,8 @@
<li th:class="${active eq 'navigation'} ? 'active': ''"><a th:href="@{/admin/navigation.html}">导航管理</a></li> <li th:class="${active eq 'navigation'} ? 'active': ''"><a th:href="@{/admin/navigation.html}">导航管理</a></li>
</ul> </ul>
<ul class="nav navbar-nav navbar-right"> <ul class="nav navbar-nav navbar-right">
<li><a href="#">退出登录</a></li> <li><a href="/admin/logout">退出登录</a></li>
<li><a th:href="@{/}">网站前台</a></li> <li><a th:href="@{/}" target="_blank">网站前台</a></li>
</ul> </ul>
</div> </div>
</div> </div>
@ -58,13 +58,12 @@
<footer> <footer>
<div class="container lw-footer"> <div class="container lw-footer">
<p> <p>
© 2019-2020 <a href="/">冷文学习者</a> <a target="_blank" © 2019-2020 <a th:href="@{/}" th:text="${@webSite.nickname}"></a> <a target="_blank"
href="https://beian.miit.gov.cn">陕ICP备19024566-1号</a> href="https://beian.miit.gov.cn">赣ICP备2022002184号-1</a>
<a style="margin-left: 10px" target="_blank" <a style="margin-left: 10px" target="_blank"
href="http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=11011402012109">京公网安备 href="http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=36092202000146">赣公网安备 36092202000146号</a>
11011402012109号</a>
</p> </p>
<p>如果您有什么好的意见或建议请发邮件至 <a href="#">kevinlu98@qq.com</a></p> <p>如果您有什么好的意见或建议请发邮件至 <a href="http://mail.qq.com/cgi-bin/qm_share?t=qm_mailme&email=1337425156@qq.com" th:text="${@webSite.getMail()}"></a></p>
</div> </div>
</footer> </footer>
<script src="/static/plugin/jquery/jquery-3.5.1.min.js"></script> <script src="/static/plugin/jquery/jquery-3.5.1.min.js"></script>

@ -10,7 +10,7 @@
<div class="container lw-main lw-banner"> <div class="container lw-main lw-banner">
<div class="btn-group" role="group" style="margin-bottom: 20px" aria-label="..."> <div class="btn-group" role="group" style="margin-bottom: 20px" aria-label="...">
<button type="button" id="create-friends-btn" class="btn btn-default"><i class="fa fa-plus"></i> <button type="button" style="outline: none;" id="create-friends-btn" class="btn btn-success"><i class="fa fa-plus"></i>
新增 新增
</button> </button>
</div> </div>
@ -43,8 +43,8 @@
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button> <button type="button" style="outline: none;" class="btn btn-default" data-dismiss="modal">关闭</button>
<button type="submit" class="btn btn-primary">保存</button> <button type="submit" style="outline: none;" class="btn btn-primary">保存</button>
</div> </div>
</form> </form>
</div> </div>
@ -87,8 +87,8 @@
align: "center", align: "center",
width: 180, width: 180,
formatter: function (value) { formatter: function (value) {
return `<button type="button" data-id="${value}" class="btn btn-info btn-sm friends-edit-btn"><i class="fa fa-edit"></i> 编辑</button> return `<button type="button" style="outline: none;" data-id="${value}" class="btn btn-info btn-sm friends-edit-btn"><i class="fa fa-edit"></i> 编辑</button>
<button type="button" data-id="${value}" class="btn btn-danger btn-sm friends-delete-btn"><i class="fa fa-trash"></i> 删除</button>` <button type="button" style="outline: none;" data-id="${value}" class="btn btn-danger btn-sm friends-delete-btn"><i class="fa fa-trash"></i> 删除</button>`
} }
} }
], ],

@ -10,9 +10,9 @@
<div class="container lw-main"> <div class="container lw-main">
<div class="jumbotron"> <div class="jumbotron">
<h3>网站概要</h3> <h3>网站概要</h3>
<p>目前有 <i>83</i> 篇文章, 并有 <i>5010</i> 条关于你的评论在 <i>9</i> 个分类中.</p> <p>目前有 <i th:text="${ArticleCount}"></i> 篇文章, 并有 <i th:text="${CommentAll}"></i> 条关于你的评论在 <i th:text="${CategoryCount}"></i> 个分类中.</p>
<p>其中有 <i>12</i>条 评论未查看:</p> <p>其中有 <i th:text="${CommentNotReadCount}"></i>条 评论未查看:</p>
<p><a class="btn btn-primary btn-lg" href="#" role="button">点此查看</a></p> <p><a class="btn btn-primary btn-lg" th:href="@{/admin/comment.html(view=false)}" role="button">点此查看</a></p>
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
@ -20,25 +20,9 @@
<li class="list-group-item disabled"> <li class="list-group-item disabled">
<b>最新文章</b> <b>最新文章</b>
</li> </li>
<li class="list-group-item"> <li class="list-group-item" th:each="article:${NewArticleList}">
<span class="badge">09-28</span> <span class="badge" th:text="${#dates.format(article.created,'yyyy-MM-dd HH:mm')}"></span>
<a href="#"> Conda虚拟环境使用</a> <a th:href="@{/{id}.html(id=${article.id})}" target="_blank" th:text="${article.title}"></a>
</li>
<li class="list-group-item">
<span class="badge">05-26</span>
<a href="#"> 关于我这些年的经历</a>
</li>
<li class="list-group-item">
<span class="badge">04-28</span>
<a href="#"> 我曾是少年</a>
</li>
<li class="list-group-item">
<span class="badge">03-07</span>
<a href="#"> 迷茫</a>
</li>
<li class="list-group-item">
<span class="badge">02-10</span>
<a href="#"> Spring Boot 3.0 M1 发布</a>
</li> </li>
</ul> </ul>
</div> </div>
@ -47,26 +31,11 @@
<li class="list-group-item disabled"> <li class="list-group-item disabled">
<b>最新评论</b> <b>最新评论</b>
</li> </li>
<li class="list-group-item"> <li class="list-group-item" th:each="comment:${NewCommentList}">
<span class="badge">09-29</span> <span class="badge" th:text="${#dates.format(comment.created,'yyyy-MM-dd HH:mm')}"></span>
再度再度: 发现这个主题很特别! <a th:href="@{/{id}.html#comment-number(id=${comment.article.id})}" th:text="${comment.content}"></a>
</li>
<li class="list-group-item">
<span class="badge">09-29</span>
再度再度: 就OK间科技看
</li>
<li class="list-group-item">
<span class="badge">09-28</span>
duelex: 喜欢作者的这个风格,希望作者不断进步
</li>
<li class="list-group-item">
<span class="badge">09-27</span>
蜘蛛: 阿巴阿巴
</li>
<li class="list-group-item">
<span class="badge">09-10</span>
妄想: 需要插件
</li> </li>
</ul> </ul>
</div> </div>
</div> </div>

@ -1,5 +1,5 @@
<!doctype html> <!doctype html>
<html lang="en"> <html xmlns:th="http://www.thymeleaf.org" lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Title</title> <title>Title</title>
@ -7,29 +7,36 @@
<link rel="stylesheet" href="/static/plugin/font-awesome/css/font-awesome.min.css"> <link rel="stylesheet" href="/static/plugin/font-awesome/css/font-awesome.min.css">
<!-- 自定义css文件 --> <!-- 自定义css文件 -->
<link rel="stylesheet" href="/static/admin/css/login.css"> <link rel="stylesheet" href="/static/admin/css/login.css">
<style>
#error-msg {
color: red;
text-align: center;
font-size: 20px;
font-weight: bold;
}
</style>
</head> </head>
<body> <body>
<div class="lw-login-page"> <div class="lw-login-page">
<div class="lw-login-box"> <div class="lw-login-box">
<div class="lw-left"> <div class="lw-left">
<h1>欢迎登录</h1> <h1>欢迎登录</h1>
<p>冷文学习者-管理后台</p> <p><th:block th:text="${@webSite.nickname}"></th:block>-管理后台</p>
</div> </div>
<div class="lw-right"> <div class="lw-right">
<form> <div id="error-msg" th:if="${errorMsg!=null}" th:text="${errorMsg}"></div>
<form th:action="@{/admin/login}" method="post">
<div class="lw-input"> <div class="lw-input">
<input type="text" placeholder="用户名"> <input type="text" name="username" placeholder="用户名">
</div> </div>
<div class="lw-input"> <div class="lw-input">
<input type="password" placeholder="密码"> <input type="password" name="password" readonly onfocus="this.removeAttribute('readonly')" placeholder="密码">
</div> </div>
<div class="lw-input"> <div class="lw-input">
<button type="submit">登录后台</button> <button type="submit">登录后台</button>
</div> </div>
</form> </form>
<p>Copyright © www.kevinlu98.cn All Rights Reserved. <p>Copyright © <th:block th:text="${@webSite.title}"></th:block> All Rights Reserved.</p>
<br>
冷文学习者版权所有</p>
</div> </div>
</div> </div>
</div> </div>

@ -10,11 +10,11 @@
<div class="container lw-main lw-banner"> <div class="container lw-main lw-banner">
<div class="btn-group" role="group" style="margin-bottom: 20px" aria-label="..."> <div class="btn-group" role="group" style="margin-bottom: 20px" aria-label="...">
<button type="button" id="create-navigation-btn" class="btn btn-default"><i class="fa fa-plus"></i> <button type="button" id="create-navigation-btn" style="outline: none;" class="btn btn-success"><i class="fa fa-plus"></i>
新增 新增
</button> </button>
<button type="button" id="refresh-ordered-btn" class="btn btn-default"><i class="fa fa-refresh"></i> <button type="button" id="refresh-ordered-btn" style="outline: none;" class="btn btn-primary"><i class="fa fa-refresh"></i>
保存顺序 保存顺序
</button> </button>
</div> </div>
@ -74,8 +74,8 @@
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button> <button type="button" style="outline: none;" class="btn btn-default" data-dismiss="modal">关闭</button>
<button type="submit" class="btn btn-primary">保存</button> <button type="submit" style="outline: none;" class="btn btn-primary">保存</button>
</div> </div>
</form> </form>
</div> </div>
@ -150,7 +150,8 @@
align: "center", align: "center",
width: 180, width: 180,
formatter: function (value) { formatter: function (value) {
return `<button type="button" data-id="${value}" class="btn btn-info btn-sm navigation-edit-btn" style="margin-right: 10px"><i class="fa fa-edit"></i> 编辑</button><button type="button" data-id="${value}" class="btn btn-danger btn-sm navigation-delete-btn"><i class="fa fa-trash"></i> 删除</button>` return `<button style="outline: none;" type="button" data-id="${value}" class="btn btn-info btn-sm navigation-edit-btn" style="margin-right: 10px"><i class="fa fa-edit"></i> 编辑</button>
<button style="outline: none;" type="button" data-id="${value}" class="btn btn-danger btn-sm navigation-delete-btn"><i class="fa fa-trash"></i> 删除</button>`
} }
} }
] ]

@ -0,0 +1,23 @@
package cc.bnblogs.test;
import cc.bnblogs.Application;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.DigestUtils;
import java.nio.charset.StandardCharsets;
/**
* @author zfp@bnblogs.cc
* @createTime: 2022/10/23
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {Application.class}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class TestMd5Password {
@Test
public void testMd5() {
System.out.println(DigestUtils.md5DigestAsHex("admin123".getBytes(StandardCharsets.UTF_8)));
}
}
Loading…
Cancel
Save