目录
1.系统的受众说明
2.相关技术介绍
2.1 B/S 简介
2.2 JAVA 简介
2.3 vue简介
2.4 SSM和Springboot简介
3.可行性分析
3.1 技术可行性分析
3.2 经济可行性分析
3.3 操作可行性
4.系统设计
4.1 系统总流程
4.2 博主用例
4.3 游客用例
4.4 系统类
4.5 E-R图
4.6 系统表设计
5.系统实现
5.1 登录模块
5.1.1 博主登录
5.2 博客管理模块:
5.2.1 博客查询
5.2.2 博客新建
/*** 新增文章管理*/@PreAuthorize("@ss.hasPermi('cms:blog:add')")@Log(title = "文章管理", businessType = BusinessType.INSERT)@PostMappingpublic AjaxResult add(@RequestBody CmsBlog cmsBlog){ cmsBlog.setCreateBy(getUsername()); Long blogId = cmsBlogService.insertCmsBlog(cmsBlog); if (blogId==null){ return AjaxResult.error(); } return AjaxResult.success(blogId);}
5.2.3 博客修改
5.2.4 博客删除
5.3 博客类别管理模块
5.3.1 添加博客类别
5.3.2 修改博客类别
5.3.3 删除博客类别
5.3.4 显示博客类别
5.4 评论管理模块
5.4.1 评论
5.4.2 删除评论
6.系统测试
6.1 前台模块测试
6.2 后台模块测试
1.系统的受众说明
1 在校学习的学生,可用于日常学习使用或是毕业设计使用
2 毕业一到两年的开发人员,用于锻炼自己的独立功能模块设计能力,增强代码编写能力。
3 亦可以部署为商化项目使用。
4 需要完整资料及源码,请在文末获取联系方式领取。
2.相关技术介绍
2.1 B/S 简介
软件系统体系结构分为两种,是客户机/服务器结构和浏览器/服务器结构。其中的浏览器/服务器结构就是B/S结构。
C/s模式:是客户端/服务器(Client/Server)模式,主要指的是传统的桌面级的应用程序。比如我们经常用的信息管理系统。
B/S模式:是浏览器/服务器(Browser/Server)模式,主要指的是web应用程序,就像电子商务网站,如淘宝,阿里巴巴等。相对于C/S模式的应用程序来说,B/S模式最大的优势在于客户端只要有浏览器就可以运行。而C/S模式的应用程序需要在客户端进行安装,而且升级也不太方便。而B/S模式的应用程序对于客户端来说,永远都是最新版本的。
2.2 JAVA 简介
Java的前身是Oak,sun公司在1995年申请注册商标的时候,发现已经Oak已经被注册了,最终才另外取了一个名字叫JAVA(其中还有一个趣味故事,有兴趣的可以去查找看看),
要使用Java首先要到官网甲骨文官网上下载Java的软件开发工具包,其中分为windows版本和Linux版本,我使用的是Windows的。而在Windows上要使用Java,要设置JAVA的环境变量。设置环境变量的步骤如下:第一步,点击计算机属性中的高级系统设置,点击系统属性高级的环境变量。第二步,设置一个系统变量为JAVA_HOME,其中的值是你的Java安装目录。它的作用还在于一些使用Java的工具时候需要用到这个变量,否则打不开,例如eclipse.第三步,设置一个classpath系统变量,它的作用是在你写Java源文件导包的时候去查找的类路径。第三步,在Windows自有的系统变量path中加入Java安装目录下的bin路径。既可以写成%JAVA_HOME%/bin;这就将Java的运行环境搭配好了。
介绍一下Java的文件目录。首先最重要的bin目录下面包含的是一些JDK包含的一些开发工具执行文件,例如像编译器javac.exe.运行Java的java.exe等等都在这个目录下面。其中Java启动的虚拟机在Java目录的jre目录中。
2.3 vue简介
Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架(部分使用,不是全家桶)。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。vue是一款简单的mvvm(model-view-viewmodel)框架
它的中心思想就是数据驱动,不像jQuery是结构驱动 结构驱动:先获取HTML的结构,然后再修改数据更新结构
数据驱动:简单的理解就是直接将数据同步到结构上,视图管理抽象为数据管理,而不是管理dom结构 Vue.js 不支持 IE8及其以下版本,因为 Vue.js 使用了 IE8 不能模拟的 ECMAScript 5 特性。Vue.js 支持 所有兼容ECMAScript 5 的浏览器。
2.4 SSM和Springboot简介
SSM是Spring、SpringMVC、MyBatis三个开源框架的组合,是JavaEE企业级应用程序开发的基础框架。Spring是整个SSM框架的核心,主要负责管理整个应用的生命周期,用于管理应用的各种资源,为各个层提供服务。
SpringMVC是一个基于Java的实现MVC设计模式的请求驱动类型的轻量级Web框架,通过SpringMVC可以使项目的分层设计更加清晰,层与层之间的职责也更加明确。
MyBatis是一个优秀的持久层框架,它支持自定义SQL、存储过程以及高级映射,可以使用简单的XML或注解进行配置,与Spring可无缝集成,使开发者能够快速开发出高质量的数据库应用。
Spring Boot是基于Spring框架开发的全新框架,用来简化新Spring应用的初始化搭建和开发过程,可快速构建独立的Spring应用,直接嵌入Tomcat、Jetty和Undertow服务器(无需部署WAR文件),提供依赖启动器简化构建配置,极大程度的自动化配置Spring和第三方库,提供生产就绪功能,极少的代码生成和XML配置。
3.可行性分析
3.1 技术可行性分析
本系统管理项目和依赖使用的是Maven,数据库连接使用的是Mybatis,数据库使用的是Mysql,接受浏览器请求并处理的是使用Springmvc,他们都是经过市场检验的,都已经十分成熟了,在安全性、可用性、可靠性等方面都是可以值得肯定的
3.2 经济可行性分析
本系统使用的技术框架都是开源框架,比如Spring,Springmvc,Mybatis.Springboot,vue而使用的数据库也是开源免费的Mysql,使用的开发软件IntelliJ IDEA有学生免费,人员就本人一个也是免费的。所以在经济上消费很低,在经济可行性分析中是可以确定可行的。
3.3 操作可行性
个人博客系统开发结合个人需求而开发,能解决用户可以通过互联网来展现自己等诸多问题,因此该项目符合开发条件,具有成熟的基础,并且,从前面的分析来看,技术上的操作是十分成熟并且开源免费广为人们使用,从系统的操作上是可行的。
4.系统设计
4.1 系统总流程
图4-1 系统流程图
本个人博客系统分为两个角色,分别是博主和游客。只有博主才能登录后台管理系统,进行博客发表。
1.首先要通过用户名和密码登录后台管理系统,才能发布博客。
2.博主和游客都可以阅读博客。
3.博主和游客都可以发表评论。
4.经过博主的评论审核,评论才可以发布。
5.此时博主和游客才可以观看到评论。
4.2 博主用例
图4-2博主用例图
博主的功能简介:
1.登入功能
登入后台管理系统:首先进入登录页面,需要输入账号和密码。它会使用Shiro进行安全管理,对前台输入的密码进行加密运算,然后与数据库中的进行比较。成功后才能登入后台系统。
- 博客管理功能
博客管理功能分为写博客和博客信息管理。写博客是博主用来发表编写博客的,需要博客标题,然后选择博客类型,最后将博客内容填入百度的富文本编辑器中,点击发布博客按钮即可发布博客。
- 博客类别管理系统
博主类别管理系统可以添加,修改和删除博客类型名称和排序序号。将会显示到首页的按日志类别区域。游客可以从这里查找相关的感兴趣的博客内容。
4.评论管理功能
评论管理功能分为评论审核和评论信息管理两部分。评论审核是当有游客或自己发表了评论之后,博主需要在后台管理系统中审核评论。若想将此评论显示在页面上则点击审核通过,否则点击审核不通过。
5.个人信息管理功能
在这里可以修改博主的个人信息,可以修改昵称,个性签名,可以添加个人头像,修改个人简介。
6.系统管理功能
这里的功能有友情链接管理,修改密码,刷新系统缓存和安全退出。
友情链接管理可以添加,修改,删除友情链接网址。
4.3 游客用例
图4-3游客用例图
用例一 |
用例名称:查询博客 |
参与者:游客 |
主要流程:
|
用例二 |
用例名称:查看博客内容 |
参与者:游客 |
主要流程:
|
用例三 |
用例名称:查看博主个人信息 |
参与者:游客 |
主要流程:
|
用例四 |
用例名称:发表评论 |
参与者:游客 |
前置条件:首先要进入到博客内容页面 |
主要流程:
|
用例五 |
用例名称:查看友情链接 |
参与者:游客 |
主要流程:
|
4.4 系统类
图4-4博客类图
本系统主要功能和模块的JavaBean主要集中博客、博客类型、评论、友情链接这四个类。
一、博客类
1.功能
用于存储博主发表的博客的一些信息
2.属性
id; // 编号
title; // 博客标题
summary; // 摘要
leaseDate; // 发布日期
clickHit; // 查看次数
replyHit; // 回复次数
content; // 博客内容
contentNoTag; // 博客内容 无网页标签 Lucene分词用
blogType; // 博客类型
blogCount; // 博客数量 非博客实际属性,主要是 根据发布日期归档查询博客数量用
releaseDateStr; // 发布日期字符串 只取年和月 keyWord; // 关键字
3.方法
都是属性对应的setter,getter方法
二、博客类型类
1.功能:对博客进行分类,将博客分为几大类型
2.属性:
id; // 编号
userName; // 用户名
password; // 密码
nickName; // 昵称
sign; // 个性签名
proFile; // 个人简介
imageName; // 博主头像
3.方法:
对应的setter,getter方法,也可用lombok@data注解
三,评论类:
1.功能:对博客评论数据保存。
2,。属性:
id; // 编号
userIp; // 用户IP
content; // 评论内容
blog; // 被评论的博客
commentDate; // 评论日期
state; // 审核状态 0 待审核 1 审核通过 2 审核未通过
3.方法:
对应的setter,getter方法
四.友情链接类
1.功能:可以保存页面上的友情链接网址。
2.属性:
id; // 编号
linkName; // 链接名称
linkUrl; // 链接地址
orderNo; // 排序序号 从小到大排序
3.方法:
对应的setter,getter方法。
4.5 E-R图
博客类的关系模式如下(加下滑线的是主键):
博客(编号,博客标题,摘要,发布日期,查看次数,博客类型,关键字,博客内容)。
博主类的关系模式如下(加下滑线的是主键):
博主实体(编号,用户名,密码,昵称,个性签名,个人简介,博主头像)。
博客类型类的关系模式如下(加下滑线的是主键):
博客类型实体(编号,博客类型名称,数量,排序)。
评论类的关系模式如下(加下滑线的是主键):
评论实体(编号,用户IP,评论内容,被评论的博客,评论日期,审核状态)。
友情链接类的关系模式如下(加下滑线的是主键):
友情链接实体(编号,链接名称,链接地址,排序序号)。
图4-5博客E-R图
博客类的关系模式如下(加下滑线的是主键):
博客(编号,博客标题,摘要,发布日期,查看次数,博客类型,关键字,博客内容)。
4.6 系统表设计
博客系统主要表博客,用户,博客类别,评论,标签,留言的设计如下。
表4-1 cms_blog表
列名 | 数据类型 | 说明 | 允许空 |
id | bigint | ID | 否 |
create_by | varchar | 创建者 | |
create_time | datetime | 创建时间 | |
update_by | varchar | 更新者 | |
update_time | datetime | 更新时间 | |
title | varchar | 标题 | |
type | char | 类型 | |
content_type | char | 文本编辑器类型 | |
content | longblob | 内容 | |
content_markdown | longblob | Markdown格式内容 | |
Top | char | 置顶(0否 1是) | |
views | int | 阅读 | |
status | char | 状态(0暂存 1发布) | |
blog_pic_type | char | 首页图片类型(0地址 1上传) | |
blog_pic | varchar | 首页图片( 1上传) | |
blog_pic_link | varchar | 首页图片( 0地址) | |
blog_desc | varchar | 简介 | |
blog_files | text | 附件列表 |
表4-2 sys_user表
列名 | 数据类型 | 说明 | 允许空 |
user_id | bigint | 用户ID | 否 |
dept_id | bigint | 部门ID | |
user_name | varchar | 用户账号 | |
nick_name | varchar | 用户昵称 | |
user_type | varchar | 用户类型(00系统用户) | |
| varchar | 用户邮箱 | |
phonenumber | varchar | 手机号码 | |
sex | char | 用户性别(0男 1女 2未知) | |
avatar | varchar | 头像地址 | |
password | varchar | 密码 | |
status | char | 帐号状态(0正常 1停用) | |
del_flag | char | 删除标志(0代表存在 2代表删除) | |
login_ip | varchar | 最后登录IP | |
login_date | datetime | 最后登录时间 | |
create_by | varchar | 创建者 | |
create_time | datetime | 创建时间 | |
update_by | varchar | 更新者 | |
update_time | datetime | 更新时间 | |
remark | varchar | 备注 |
表4-3 cms_type表
列名 | 数据类型 | 说明 | 允许空 |
type_id | bigint | 分类ID | 否 |
create_by | varchar | 创建者 | |
create_time | datetime | 创建时间 | |
update_by | varchar | 更新者 | |
update_time | datetime | 更新时间 | |
type_name | varchar | 分类名称 | |
type_pic | varchar | 分类图像( 1上传) | |
type_pic_type | char | 分类图像类型(0地址 1上传) | |
type_pic_link | varchar | 分类图像( 0地址) |
表4-4 cms_comment表
列名 | 数据类型 | 说明 | 允许空 |
id | bigint | ID | 否 |
parent_id | bigint | 父评论id | |
main_id | bigint | 主评论id(第一级评论) | |
like_num | int | 点赞数量 | |
content | varchar | 内容 | |
type | char | 评论类型:对人评论,对项目评论,对资源评论 | |
blog_id | bigint | 被评论者id,可以是人、项目、资源 | |
del_flag | char | 删除标志(0代表存在 1代表删除) | |
user_id | bigint | 评论者id | |
create_by | varchar | 创建者 | |
create_time | datetime | 创建时间 | |
update_by | varchar | 更新者 | |
update_time | datetime | 更新时间 |
表4-5 cms_tag表
列名 | 数据类型 | 说明 | 允许空 |
tag_id | bigint | 标签ID | 否 |
create_by | varchar | 创建者 | |
create_time | datetime | 创建时间 | |
update_by | varchar | 更新者 | |
update_time | datetime | 更新时间 | |
tag_name | varchar | 标签名称 |
表4-6 cms_message表
列名 | 数据类型 | 说明 | 允许空 |
id | bigint | ID | 否 |
parent_id | bigint | 父留言id | |
main_id | bigint | 主留言id(第一级留言) | |
like_num | int | 点赞数量 | |
content | varchar | 内容 | |
type | char | 留言类型:对人评论,对项目评论,对资源评论(0代表留言 1代表回复) | |
blog_id | bigint | 被留言者id,可以是人、项目、资源 | |
del_flag | char | 删除标志(0代表存在 1代表删除) | |
user_id | bigint | 留言者id | |
create_by | varchar | 创建者 | |
create_time | datetime | 创建时间 | |
update_by | varchar | 更新者 | |
update_time | datetime | 更新时间 |
5.系统实现
5.1 登录模块
5.1.1 博主登录
登入系统后台管理登录页面,博主首先输入用户名和密码,它回去调用Controller层代码,然后进入业务层调用数据库的一些操作确认是否用户名密码正确,然后返回到前台就会登进去。
登录首页模块主要代码:
vue代码:
使用form表单提交到后台进行数据验证:
<template>
<div class="login">
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form">
<h3 class="title">若依后台管理系统</h3>
<el-form-item prop="username">
<el-input
v-model="loginForm.username"
type="text"
auto-complete="off"
placeholder="账号"
>
<svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" />
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
v-model="loginForm.password"
type="password"
auto-complete="off"
placeholder="密码"
@keyup.enter.native="handleLogin"
>
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
</el-input>
</el-form-item>
<el-form-item prop="code" v-if="captchaOnOff">
<el-input
v-model="loginForm.code"
auto-complete="off"
placeholder="验证码"
style="width: 63%"
@keyup.enter.native="handleLogin"
>
<svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" />
</el-input>
<div class="login-code">
<img :src="codeUrl" @click="getCode" class="login-code-img"/>
</div>
</el-form-item>
<el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">记住密码</el-checkbox>
<el-form-item style="width:100%;">
<el-button
:loading="loading"
size="medium"
type="primary"
style="width:100%;"
@click.native.prevent="handleLogin"
>
<span v-if="!loading">登 录</span>
<span v-else>登 录 中...</span>
</el-button>
<div style="float: right;" v-if="register">
<router-link class="link-type" :to="'/register'">立即注册</router-link>
</div>
</el-form-item>
</el-form>
<!-- 底部 -->
<div class="el-login-footer">
<span>Copyright © 2018-2021 ruoyi.vip All Rights Reserved.</span>
</div>
</div>
</template>
<script>
import { getCodeImg } from "@/api/login";
import Cookies from "js-cookie";
import { encrypt, decrypt } from '@/utils/jsencrypt'
export default {
name: "Login",
data() {
return {
codeUrl: "",
loginForm: {
username: "admin",
password: "admin123",
rememberMe: false,
code: "",
uuid: ""
},
loginRules: {
username: [
{ required: true, trigger: "blur", message: "请输入您的账号" }
],
password: [
{ required: true, trigger: "blur", message: "请输入您的密码" }
],
code: [{ required: true, trigger: "change", message: "请输入验证码" }]
},
loading: false,
// 验证码开关
captchaOnOff: true,
// 注册开关
register: false,
redirect: undefined
};
},
watch: {
$route: {
handler: function(route) {
this.redirect = route.query && route.query.redirect;
},
immediate: true
}
},
created() {
this.getCode();
this.getCookie();
},
methods: {
getCode() {
getCodeImg().then(res => {
this.captchaOnOff = res.captchaOnOff === undefined ? true : res.captchaOnOff;
if (this.captchaOnOff) {
this.codeUrl = "data:image/gif;base64," + res.img;
this.loginForm.uuid = res.uuid;
}
});
},
getCookie() {
const username = Cookies.get("username");
const password = Cookies.get("password");
const rememberMe = Cookies.get('rememberMe')
this.loginForm = {
username: username === undefined ? this.loginForm.username : username,
password: password === undefined ? this.loginForm.password : decrypt(password),
rememberMe: rememberMe === undefined ? false : Boolean(rememberMe)
};
},
handleLogin() {
this.$refs.loginForm.validate(valid => {
if (valid) {
this.loading = true;
if (this.loginForm.rememberMe) {
Cookies.set("username", this.loginForm.username, { expires: 30 });
Cookies.set("password", encrypt(this.loginForm.password), { expires: 30 });
Cookies.set('rememberMe', this.loginForm.rememberMe, { expires: 30 });
} else {
Cookies.remove("username");
Cookies.remove("password");
Cookies.remove('rememberMe');
}
this.$store.dispatch("Login", this.loginForm).then(() => {
this.$router.push({ path: this.redirect || "/" }).catch(()=>{});
}).catch(() => {
this.loading = false;
if (this.captchaOnOff) {
this.getCode();
}
});
}
});
}
}
};
</script>
java代码:使用MVC框架,对后台数据和前台form表单提交的数据进行交互
@Autowired
private SysLoginService loginService;
@Autowired
private ISysMenuService menuService;
@Autowired
private SysPermissionService permissionService;
/**
* 登录方法
*
* @param loginBody 登录信息
* @return 结果
*/
@PostMapping("/login")
public AjaxResult login(@RequestBody LoginBody loginBody)
{
AjaxResult ajax = AjaxResult.success();
// 生成令牌
String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
loginBody.getUuid());
ajax.put(Constants.TOKEN, token);
return ajax;
}
5.2 博客管理模块:
博客管理管理模块为个人博客系统的用户(即博主)提供写博客和博客信息管理功能。在个人博客系统的首页上的博客就是从这里进行发布的。博客管理包含
新建:対博客的新建,博客可以含有图片,视频,音频附件。新建博客必须要有博客标题,博客类别自己选择所需要的博客类别,然后填入博客内容,最后发表文章。
搜索:在博客信息管理中,可以输入自己想要搜索的博客信息,系统会自动筛选出适合的博客展现给用户。
修改: 点击你想要修改的博客,系统会弹出修改博客页面,之后博客的标题,所属的博客类型,博客内容等都可以修改。
删除: 该系统支持单个删除和批量删除。
5.2.1 博客查询
图4-1查询博客时序图
步骤 | 系统行为描述 |
1 | 博客信息管理页面点查询按钮 |
2 | 页面表单提交调用控制层控制层的list方法 |
3 | 控制层list方法中调用服务层的list方法 |
4 | 服务层调用持久层list方法返回博客集合 |
按条件查询博客,调用控制层的list方法,在其中调用服务层list方法,返回 blog集合:List<Blog> list。获得集合后使用方法把查询到符要求的数据传到前台,在前台对数据进行处理。中心代码如下:
/**
* 首页查询文章列表
*/
@GetMapping("/cms/cmsList")
public TableDataInfo cmsList(CmsBlog cmsBlog)
{
startPage();
//状态为发布
cmsBlog.setStatus("1");
List<CmsBlog> list = cmsBlogService.selectCmsBlogList(cmsBlog);
return getDataTable(list);
}
/**
* 首页获取文章详细信息
*/
@GetMapping(value = { "/cms/detail/", "/cms/detail/{id}" })
public AjaxResult getInfoDetail(@PathVariable(value = "id", required = false) Long id)
{
AjaxResult ajax = AjaxResult.success();
CmsType cmsType = new CmsType();
CmsTag cmsTag = new CmsTag();
ajax.put("types", cmsTypeService.selectCmsTypeList(cmsType));
ajax.put("tags", cmsTagService.selectCmsTagList(cmsTag));
if (StringUtils.isNotNull(id))
{
ajax.put(AjaxResult.DATA_TAG, cmsBlogService.selectCmsBlogById(id));
}
return ajax;
}
5.2.2 博客新建
图4-2 新建博客时序图
步骤 | 系统行为描述 |
1 | 博主在后台页面填写博客信息点击发布博客按钮 |
2 | form表单提交调用控制层controller的save方法 |
3 | 控制层save方法中调用service层的add方法 |
4 | 调用blogMapper持久层保存博客信息 |
5 | 添加索引 |
点击写博客进入博客发布界面,填写博客内容信息,点击发布博客,提交到控制层的save方法,传入参数:Blog,该参数包含了该博客所有信息内容,在提交的时候使用javascript对博客的内容进行校验。校验成功后便会调用控制层的方法,在控制层的save()方法中调用服务层的add()方法,对该博客进行保存,持久到数据库中。部分代码如下
/**
* 新增文章管理
*/
@PreAuthorize("@ss.hasPermi('cms:blog:add')")
@Log(title = "文章管理", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody CmsBlog cmsBlog)
{
cmsBlog.setCreateBy(getUsername());
Long blogId = cmsBlogService.insertCmsBlog(cmsBlog);
if (blogId==null){
return AjaxResult.error();
}
return AjaxResult.success(blogId);
}
5.2.3 博客修改
图4-3 修改博客时序图
步骤 | 系统行为描述 |
1 | 博主在博客信息管理页面选择需要修改的博客打开博客修改页面 |
2 | form表单提交调用控制层controller的save方法 |
3 | 控制层save方法中调用service层的update方法 |
4 | 调用blogMapper持久层保存修改后的博客信息 |
5 | 更新索引 |
进入博客修改页面,修改博客内容信息,点击发布博客,提交到控制层的save方法,传入参数:Blog,该参数包含了修改后的博客所有信息内容,在提交的时候使用javascript对博客的内容进行校验。校验成功后便会调用控制层的方法,在控制层的save()方法中调用服务层的update()方法,对该博客进行保存,持久到数据库中。部分代码如下
/**
* 修改文章管理
*/
@PreAuthorize("@ss.hasPermi('cms:blog:edit')")
@Log(title = "文章管理", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody CmsBlog cmsBlog)
{
cmsBlog.setUpdateBy(getUsername());
//删除原首图
CmsBlog oldBlog = cmsBlogService.selectCmsBlogById(cmsBlog.getId());
if (cmsBlog.getBlogPic().isEmpty()||!cmsBlog.getBlogPic().equals(oldBlog.getBlogPic())){
if(!oldBlog.getBlogPic().isEmpty()){
String blogPic = oldBlog.getBlogPic();
if (blogPic!=null&&!"".equals(blogPic)){
int newFileNameSeparatorIndex = blogPic.lastIndexOf("/");
String FileName = blogPic.substring(newFileNameSeparatorIndex + 1).toLowerCase();
sysFileInfoService.deleteSysFileInfoByFileObjectName(FileName);
}
}
}
return toAjax(cmsBlogService.updateCmsBlog(cmsBlog));
}
5.2.4 博客删除
图4-4 删除博客时序图
步骤 | 系统行为描述 |
1 | 博主在博客信息管理页面选择需要删除的博客(可以选择多条) |
2 | 调用控制层controller的delete方法 |
3 | 控制层delete方法中调用service层的delete方法 |
4 | 调用blogMapper持久层将对应的博客信息删除 |
5 | 删除对应博客的索引 |
在博客管理页面选择需要删除的博客,点击删除按钮,提交到控制层的delete方法,传入参数:需要删除博客的id,调用控制层的方法,在控制层的delete()方法中调用服务层的delete()方法,对该博客或多个博客进行删除,持久到数据库中。部分代码如下:
/**
* 删除文章管理
*/
@PreAuthorize("@ss.hasPermi('cms:blog:remove')")
@Log(title = "文章管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids)
{
//删除原首图
for (Long id : ids) {
CmsBlog oldBlog = cmsBlogService.selectCmsBlogById(id);
if(!oldBlog.getBlogPic().isEmpty()){
String blogPic = oldBlog.getBlogPic();
if (blogPic!=null&&!"".equals(blogPic)){
int newFileNameSeparatorIndex = blogPic.lastIndexOf("/");
String FileName = blogPic.substring(newFileNameSeparatorIndex + 1).toLowerCase();
sysFileInfoService.deleteSysFileInfoByFileObjectName(FileName);
}
}
}
return toAjax(cmsBlogService.deleteCmsBlogByIds(ids));
}
5.3 博客类别管理模块
5.3.1 添加博客类别
图4-5 添加博客类型时序图
步骤 | 系统行为描述 |
1 | 博主在博客类别信息管理页面点击添加按钮打开添加博客类别弹窗 |
2 | 调用blogType控制层controller的save方法 |
3 | 控制层save方法中调用service层的add方法 |
4 | 调用blogTypeMapper持久层将对应的博客类别信息添加 |
5 | 返回成功添加信息 |
在博客类别管理页面打开添加博客类别弹窗,填写博客类别名称和排序,点击保存按钮,提交到控制层的save方法,传入参数:需要添加的博客类型blogType,调用控制层的方法,在控制层的save()方法中调用服务层的add()方法,添加博客类别的相关信息,持久到数据库中。部分代码如下:
/**
* 新增分类管理
*/
@PreAuthorize("@ss.hasPermi('cms:type:add')")
@Log(title = "分类管理", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody CmsType cmsType)
{
cmsType.setCreateBy(getUsername());
return toAjax(cmsTypeService.insertCmsType(cmsType));
}
5.3.2 修改博客类别
图4-6 修改博客类型时序图
步骤 | 系统行为描述 |
1 | 博主在博客类别信息管理页面选择要修改的博客类别点击修改按钮弹出弹窗 |
2 | 调用blogType控制层controller的save方法 |
3 | 控制层save方法中调用service层的update方法 |
4 | 调用blogTypeMapper持久层将对应的博客类别信息修改 |
5 | 返回成功系修改信息 |
在博客类别管理页面先选择要修改的数据,点击修改按钮,打开修改博客类别弹窗,填写修改后博客类别名称和排序,点击保存按钮,提交到控制层的save方法,传入参数:需要添加的博客类型blogType,调用控制层的方法,在控制层的save()方法中调用服务层的update()方法,修改博客类别的相关信息,持久到数据库中。部分代码如下:
/**
* 修改分类管理
*/
@PreAuthorize("@ss.hasPermi('cms:type:edit')")
@Log(title = "分类管理", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody CmsType cmsType)
{
cmsType.setUpdateBy(getUsername());
return toAjax(cmsTypeService.updateCmsType(cmsType));
}
5.3.3 删除博客类别
图4-7 删除博客类型时序图
步骤 | 系统行为描述 |
1 | 博主在博客类别信息管理页面勾选上要删除的博客类别,点击删除按钮 |
2 | 调用blogType控制层controller的delete方法 |
3 | 控制层delete方法中调用service层的delete方法 |
4 | 调用blogTypeMapper持久层将对应的博客类别信息删除 |
5 | 返回成功删除信息 |
在博客类别管理页面先勾选上要删除的数据,点击删除按钮,提交到控制层的delete方法,传入参数:需要删除的博客类型的id(可以是多个),调用控制层的方法,在控制层的delete()方法中调用服务层的delete()方法,删除博客类别的相关信息,持久到数据库中。部分代码如下:
/**
* 删除博客类别信息
* @param ids
* @param response
* @return
* @throws Exception
*/
/**
* 删除分类管理
*/
@PreAuthorize("@ss.hasPermi('cms:type:remove')")
@Log(title = "分类管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{typeIds}")
public AjaxResult remove(@PathVariable Long[] typeIds)
{
return toAjax(cmsTypeService.deleteCmsTypeByTypeIds(typeIds));
}
5.3.4 显示博客类别
图4-8显示博客类型时序图
步骤 | 系统行为描述 |
1 | 博主在后台系统打开博客类别信息管理页面就会调用查询方法 |
2 | 调用blogType控制层controller的list方法 |
3 | 控制层list方法中调用service层的list方法 |
4 | 调用blogTypeMapper持久层查询所有的博客类别信息 |
5 | 返回查询到的博客类别信息 |
在打开博客类别管理页面时,调用控制层的list方法,传入参数:当前页数和每页数量,调用控制层的方法,在控制层的list()方法中调用服务层的list()方法,从数据库中查询到博客类别信息,然后将博客类别的相关数据渲染页面上。部分代码如下:
/**
* 查询分类管理列表
*/
@PreAuthorize("@ss.hasPermi('cms:type:list')")
@GetMapping("/list")
public TableDataInfo list(CmsType cmsType)
{
startPage();
// 角色集合
Set<String> roles = permissionService.getRolePermission(getLoginUser().getUser());
if (!SecurityUtils.isAdmin(getUserId())&&!roles.contains("admin")&&!roles.contains("cms")){
cmsType.setCreateBy(getUsername());
}
List<CmsType> list = cmsTypeService.selectCmsTypeList(cmsType);
return getDataTable(list);
}
5.4 评论管理模块
5.4.1 评论
图4-9审核评论时序图
博主在后台页面打开评论管理页面,选择需要审核的评论,点击审核通过按钮,调用controller层的review方法,controller层调用service层的update方法,将评论的状态字段改为对应的代表通过审核的1,如果点击不通过那就是2.然后调用dao层的update方法持久化到数据库中,相关的代码如下:
/**
* 首页新增留言
*/
@PostMapping("/cms/addMessage")
public AjaxResult addMessage(@RequestBody CmsMessage cmsMessage)
{
Long parentId = cmsMessage.getParentId();
if (parentId!=null){
CmsMessage message = cmsMessageService.selectCmsMessageById(parentId);
if (message.getMainId()!=null){
cmsMessage.setMainId(message.getMainId());
}else {
cmsMessage.setMainId(parentId);
}
}
return toAjax(cmsMessageService.insertCmsMessage(cmsMessage));
}
5.4.2 删除评论
图4-10删除评论时序图
博主在后台打开评论管理页面,选择需要删除的评论,点击删除按钮。调用controller层的delete方法,在其中的方法中调用业务逻辑层的实现方法,然后调用dao层的方法,最后持久化到数据库中,相关的代码如下:
/**
* 删除留言管理
*/
@PreAuthorize("@ss.hasPermi('cms:message:remove')")
@Log(title = "留言管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids)
{
return toAjax(cmsMessageService.deleteCmsMessageByIds(ids));
}
6.系统测试
6.1 前台模块测试
浏览器的网址输入框中输入正确的地址既可以看到系统前台页面:
图5-1前台展示页面
6.2 后台模块测试
在前台首页可以点击登录后台按钮可以登录到后台管理页面,在后台管理页面可以进行博客管理,博客类别管理,评论审核和个人信息管理还有系统管理。但是首先要获取用户名和密码,拥有博主权限才可以进入到后台管理页面,首先输入用户名:admin,然后输入密码: 123。结果有两种,一种是密码正确成功登录,另外一种是不成功,登录失败,若是失败,则会在页面上打出红色字体:用户名或密码错误。
如下图所示:
图5-2后台登录页面
登录成功后,可以进入到后台管理页面,在这个页面,博主可以管理博客,可以新增博客,可以删除修改博客,也可以管理评论等等。
图5-2后台管理页面
测试写博客:
图5-3写博客页面
点击发布博客按钮,发布成功。