(六)文章管理准备工作
说明
文章管理相比于其它部分来说相对复杂一些,首先是文章管理的搜索,这里是一个多条件且带分页功能的查询,而且还涉及到多张表的操作,而且由于文章的属性比较多,所以我们不能像以前那样在弹窗中完成更新和删除的操作,而是在新打开的页面完成该操作,大家再看看演示项目中的新增文章的操作就知道了
实体及数据库
由于文章这次会涉及到分类表、标签表及评论表,所以我们这次就一次性把这些表全部都做一个创建
标签表
- 类名:Tag
- 表名:blog_tag
属性 | 类型 | 备注 |
---|---|---|
id | 整数 | 主键 |
name | 字符串 | 名称 |
评论表
- 类名:Comment
- 表名:blog_comment
属性 | 类型 | 备注 |
---|---|---|
id | 整数 | 主键 |
nickname | 字符串 | 评论者的昵称 |
字符串 | 评论者的邮箱 | |
url | 字符串 | 评论者的主页 |
content | 字符串 | 评论内容 |
view | 布尔型 | 是否已读 |
pid | 整数 | 评论的父评论 |
created | 时间 | 评论创建时间 |
文章表
- 类名:Article
- 表名:blog_article
属性 | 类型 | 备注 |
---|---|---|
id | 整数 | 主键 |
title | 字符串 | 标题 |
content | 字符串 | 文章内容 文章内容此时255的varchat可能就不够了,应该用数据库的text保存 |
cover | 字符串 | 缩略图 |
type | 整数 | 类型:1.文章;2.页面 |
status | 整数 | 状态:1.发布;2.草稿 |
allowComment | 整数 | 允许评论:1.允许;2.不允许 |
views | 整数 | 浏览量 |
created | 时间 | 创建时间 |
updated | 时间 | 更新时间 |
关联关系
关联关系
- 文章到标签是一个多对多的状态,标签到文章是一个多对多的状态
- 文章到分类是一个多对一的状态,分类到文章是一个一对多的状态
- 文章到评论是一个一对多的状态,评论到文章是一个多对一的状态
jpa的关联注解
@ManyToOne
:多对一@ManyToMany
:多对多@OneToMany
:一对多
教程用到的新注解
@Transient
:忽略属性为数据库的列@Temporal
:指定数据库列的时间类型@Lob
:将String
映射为数据库中的text
类型@Basic
:该数据什么时候加载
代码生成
标签
name----名称
评论
nickname----评论者的昵称 email----评论者的邮箱 url----评论者的主页 content----评论内容 view----是否已读 pid----评论的父评论 created----评论创建时间
文章
title----标题 content----文章内容 cover----缩略图 type----类型 status----状态 allowComment----允许评论 views----浏览量 created----创建时间 updated----更新时间
代码完善
给生成的代码加上关联关系
文章
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; //主键 private String title; //标题 @Lob @Basic(fetch = FetchType.LAZY) @ToString.Exclude private String content; //文章内容 private String cover; //缩略图 private Integer type; //类型 private Integer status; //状态 private Integer allowComment; //允许评论 private Integer views; //浏览量 @Temporal(TemporalType.TIMESTAMP) private Date created; //创建时间 @Temporal(TemporalType.TIMESTAMP) private Date updated; //更新时间 @ManyToMany @ToString.Exclude private List<Tag> tags; @ManyToOne private Category category;
评论
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; //主键 private String nickname; //评论者的昵称 private String email; //评论者的邮箱 private String url; //评论者的主页 private String content; //评论内容 private Boolean view; //是否已读 private Integer pid; //评论的父评论 //指定数据库列的类型为时间戳 @Temporal(TemporalType.TIMESTAMP) private Date created; //评论创建时间 @ManyToOne private Article article;
在删除文章管理页的多余的代码
$('#data-table').bootstrapTable({ url: '/admin/article/', responseHandler: function (res) { return res.data }, columns: [ { title: '序号', width: 50, align: 'center', formatter: function (value, row, index) { return index + 1 } }, { title: '标题', field: 'title' }, { title: '状态', field: 'status' }, { title: '分类', field: 'category', }, { title: '浏览量', field: 'views' }, { title: '创建时间', field: 'created' }, { field: 'id', title: '操作', width: 100, formatter: function (value) { return `<button type="button" data-id="${value}" class="btn btn-danger btn-sm lw-del-btn"><i class="fa fa-trash"></i> 删除</button>` } }, ] })
在文章管理页顶部加入多条件搜索的工具条
<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> </div> <form class="form-inline" style="float:right;"> <div class="form-group"> <label>分类</label> <select class="form-control" style="width: 100px;"> <option value="">全部</option> <option th:each="category:${categories}" th:value="${category.id}" th:text="${category.name}"></option> </select> </div> <div class="form-group"> <label>状态</label> <select class="form-control" style="width: 100px;"> <option value="">全部</option> <option value="1">发布</option> <option value="2">草稿</option> </select> </div> <div class="form-group"> <label>类型</label> <select class="form-control" style="width: 100px;"> <option value="">全部</option> <option value="1">文章</option> <option value="2">页面</option> </select> </div> <div class="form-group"> <label>关键字</label> <input type="text" class="form-control" placeholder="请输入关键字..."> </div> <button type="submit" class="btn btn-primary"><i class="fa fa-search"></i> 搜索</button> </form>
新增/编辑文章页
- 利用
Bootstrap
完成页面布局,为左右布局 - 在左侧完成标题与文章的输入
- 在右侧完成其它选项的输入
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" lang="en">
<head th:replace="admin/common::header(~{::title},~{},~{})">
<title>新增文章</title>
</head>
<body>
<th:block th:include="admin/common::nav('article')"></th:block>
<div class="container lw-main">
<div class="row">
<form class="form-horizontal">
<div class="col-md-9">
<h3 style="margin-bottom: 10px;">创建新的文章</h3>
<div class="form-group">
<label class="col-sm-1 control-label">标题</label>
<div class="col-sm-11">
<input type="text" class="form-control" placeholder="请输入标题...">
</div>
</div>
<div class="form-group">
<label class="col-sm-1 control-label">内容</label>
<div class="col-sm-11">
<textarea style="resize: none;height: 700px;" class="form-control"></textarea>
</div>
</div>
<div class="form-group">
<label class="col-sm-1 control-label"></label>
<a class="btn btn-info" href="javascript:void(0)">返回列表</a>
<button type="submit" class="btn btn-success">保存文章</button>
</div>
</div>
<div class="col-md-3" style="background-color:#eeeeee;padding: 20px;">
<div class="form-group" style="margin: 0;">
<label>缩略图</label>
<img style="width: 100%;border: 1px solid #cccccc;" src="/static/admin/image/default.png" alt="">
<div style="text-align: right;margin-top: 10px;">
<button class="btn btn-warning"><i class="fa fa-image"></i> 上传图片</button>
</div>
<input type="hidden" class="form-control">
<input type="file" style="display: none" class="form-control">
</div>
<div class="form-group" style="margin: 0;">
<label>分类</label>
<div class="radio" th:each="category:${categories}">
<label>
<input type="radio" th:value="${category.id}" > <th:block th:text="${category.name}"></th:block>
</label>
</div>
</div>
<div class="form-group" style="margin: 10px 0 0;">
<label>标签</label>
<input type="text" class="form-control">
</div>
<div class="form-group" style="margin: 10px 0 0;">
<label>其它设置</label>
<div class="has-error">
<div class="checkbox">
<label>
<input type="checkbox" value="option1">
允许评论
</label>
</div>
</div>
<div class="has-error">
<div class="checkbox">
<label>
<input type="checkbox" value="option1">
保存草稿
</label>
</div>
</div>
<div class="has-error">
<div class="checkbox">
<label>
<input type="checkbox" value="option1">
保存为页面
</label>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
<th:block th:include="admin/common::footer"></th:block>
</body>
</html>
看看
多谢大佬分享
强强强
感谢作者!
感谢!