12.个人博客系统(Java项目基于spring和vue)

目录

 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进行安全管理,对前台输入的密码进行加密运算,然后与数据库中的进行比较。成功后才能登入后台系统。

  1. 博客管理功能

博客管理功能分为写博客和博客信息管理。写博客是博主用来发表编写博客的,需要博客标题,然后选择博客类型,最后将博客内容填入百度的富文本编辑器中,点击发布博客按钮即可发布博客。

  1. 博客类别管理系统

博主类别管理系统可以添加,修改和删除博客类型名称和排序序号。将会显示到首页的按日志类别区域。游客可以从这里查找相关的感兴趣的博客内容。

4.评论管理功能

评论管理功能分为评论审核和评论信息管理两部分。评论审核是当有游客或自己发表了评论之后,博主需要在后台管理系统中审核评论。若想将此评论显示在页面上则点击审核通过,否则点击审核不通过。

5.个人信息管理功能

在这里可以修改博主的个人信息,可以修改昵称,个性签名,可以添加个人头像,修改个人简介。

6.系统管理功能

这里的功能有友情链接管理,修改密码,刷新系统缓存和安全退出。

友情链接管理可以添加,修改,删除友情链接网址。

4.3 游客用例

图4-3游客用例图

用例一

用例名称:查询博客

参与者:游客

主要流程:

  1. 在查询搜索处填写所需的条件
  2. 点击查询
  3. 便会显示出符合条件的所有博客

用例二

用例名称:查看博客内容

参与者:游客

主要流程:

  1. 点击想要查看的博客,进入博客内容页面
  2. 观看博客内容信息

用例三

用例名称:查看博主个人信息

参与者:游客

主要流程:

  1. 点击关于博主,进入博主个人信息页面
  2. 可以看到博主的个人信息内容

用例四

用例名称:发表评论

参与者:游客

前置条件:首先要进入到博客内容页面

主要流程:

  1. 在发表评论的评论框中写入自己想要发表的评论
  2. 填入验证码
  3. 点击发表评论

用例五

用例名称:查看友情链接

参与者:游客

主要流程:

  1. 在每个页面的右下角可以看到友情链接
  2. 若想跳转到某个友情链接则点击相应的友情链接即可
  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系统用户)

email

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写博客页面

点击发布博客按钮,发布成功。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/899021.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HarmonyOS 模块化设计

1.HarmonyOS 模块化设计 模块化设计文档   应用程序包开发与使用文档 1.1. 概述 组件化一直是移动端比较流行的开发方式&#xff0c;有着编译运行快&#xff0c;业务逻辑分明&#xff0c;任务划分清晰等优点&#xff0c;HarmonyOs组件化的使用&#xff0c;有利于模块之间的解…

算法笔记day05

目录 1.最小公倍数 2.最长连续的子序列 3.字母收集 1.最小公倍数 求最小公倍数_牛客题霸_牛客网 算法思路&#xff1a; 这就是一道数学题&#xff0c;a,b的最小公倍数 a * b / 最大公约数。 使用辗转相除法&#xff0c;求a&#xff0c;b的最大公约数。 #include <iostre…

Cadence元件A属性和B属性相互覆盖

最近在使用第三方插件集成到Cadence,协助导出BOM到平台上&#xff0c;方便对BOM进行管理和修改&#xff0c;结果因为属性A和属性B不相同&#xff0c;导致导出的BOM错误。如下图&#xff1a; ​​ 本来我们需要导出Q12&#xff0c;结果给我们导出了Q13&#xff0c;或者反之&…

UNIX网络编程-传输层

概述 传输层主要包括&#xff1a;TCP、UDP、SCTP&#xff08;流控制传输协议&#xff09;&#xff01; 绝大多数客户端/服务器网络应用都使用TCP/UDP。SCTP是一个较新的协议&#xff0c;最初设计用于跨因特网传输电话信令。 这些传输协议都转而使用网络协议IP&#xff1a;或是…

VScode分文件编写报错 | 如何进行VScode分文件编写 | 小白也能轻松解决版

分文件编写遇到的问题 分文件编写例子如下所示&#xff1a; 但是直接使用 Run Code 或者 调试C/C文件 会报错如下&#xff1a; 正在执行任务: C/C: g.exe 生成活动文件 正在启动生成… cmd /c chcp 65001>nul && D:\Librarys\mingw64\bin\g.exe -fdiagnostics-col…

计算机网络——传输层服务

传输层会给段加上目标ip和目标端口号 应用层去识别报文的开始和结束

[Unity Demo]从零开始制作空洞骑士Hollow Knight第十五集:制作更多地图,更多敌人,更多可交互对象

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、第一个代表性场景 1.制作更多敌人2.制作更多可交互对象二、第二个代表性场景 1.制作更多敌人2.制作更多可交互对象三、第三个代表性场景 1.制作更多敌人2.制…

MongoDB安装配置及配置和启动服务

MongoDB 安装配置 附&#xff1a;MongoDB官网下载地址&#xff1a; https://www.mongodb.com/download-center/community 注&#xff1a; 官网可以下载最新版的MongoDB安装包&#xff0c;有MSI安装版和ZIP安装版。我们课堂上使用4.4.4的ZIP安装版。安装版参考博客&#xff1…

【redis】基础指令|数据结构总览|单线程架构分析

W...Y的主页 &#x1f60a; 代码仓库分享&#x1f495; 前言&#xff1a;redis系类博客都是以redis5.0版本为基础&#xff01;&#xff01;&#xff01; 目录 Redis常见命令 基本全局命令 KEYS EXISTS DEL EXPIRE TTL TYPE 数据结构和内部编码 单线程架构 Redis…

群控系统服务端开发模式-数据库设计图

根据整理的业务需求可以发现&#xff0c;本系统数据库针对1.0版本就分两种库。第一类是管理层的数据库&#xff0c;分别是管理员表、角色表、菜单表、部门表、级别表。分别对应控制权限及数据权限。 一、管理层数据库设计图 二、业务层数据库设计图

潜水定位通信系统的功能和使用方法_鼎跃安全

潜水定位通信系统是保障潜水安全与作业高效的关键设备。它利用先进的声呐、无线电等技术&#xff0c;可精准定位潜水员位置。在水下能实现潜水员之间以及与水面的双向通信&#xff0c;确保信息及时传递。具备高可靠性和稳定性&#xff0c;即使在复杂水环境中也能正常运行。 一、…

智能体能和人工智能有什么区别?

智能体与人工智能&#xff08;AI&#xff09;之间存在明显的区别&#xff0c;尽管两者在技术和应用上有一定的重叠。 一、定义与范畴 人工智能&#xff08;AI&#xff09; 人工智能是指通过模拟、延伸和扩展人的智能&#xff0c;使计算机或其他智能设备具有人类智能的一种技术…

Redis --- 第六讲 --- 关于持久化

前言 持久化&#xff1a;MySQL的事务&#xff0c;有四大比较核心的特性 1、原子性 2、一致性 3、持久性 》 把数据存储到硬盘上 》持久&#xff0c;把数据存储在内存上》持久化。重启进程/重启主机之后&#xff0c;数据是否存在。 4、隔离性 Redis是一个内存数据库&#…

如何在忘记密码的情况下解锁 iPhone? 6 种方法分享

您是否因为没有密码而无法解锁您的 iPhone&#xff1f; 别担心&#xff0c;这种情况比你想象的更常见&#xff01;忘记密码是 iPhone 用户面临的最常见问题之一&#xff0c;而且可能非常令人沮丧 - 但不要绝望。 在这篇文章中&#xff0c;我们将与您分享绕过 iPhone 屏幕密码…

No provider available from registry RegistryDirectory

【中】No provider available from registry RegistryDirectory Dubbo 3.2.9Nacos 2.1.0 最近在做配置文件升级&#xff0c;服务比较多&#xff0c;之前的Dubbo配置各个服务写的比较乱&#xff0c;有的用Nacos上的 data-id&#xff0c;有的又是在自己的服务引入配置 遂准备统一…

记录一次从nacos配置信息泄露到redis写计划任务接管主机

经典c段打点开局。使用dddd做快速的打点发现某系统存在nacos权限绕过 有点怀疑是蜜罐&#xff0c;毕竟nacos这实在是有点经典 nacos利用 老规矩见面先上nacos利用工具打一波看看什么情况 弱口令nacos以及未授权访问&#xff0c;看这记录估计被光顾挺多次了啊 手动利用Nacos-…

软件测试与软件缺陷的基础知识

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

秋招面试题记录_半结构化面试

c八股(可能问的多一点) 1.简单说说C11语法特性 答&#xff1a; 1.auto以及decltype自动类型推导&#xff0c;避免手动声明复杂类型&#xff0c;减少冗长代码提升了可读性和安全性。 2.智能指针 自动释放内存 (具体说说) 有shared和unique 差异主要体现在所有权、内存开销、…

Tesseract OCR 安装

Tesseract OCR 的安装步骤因操作系统的不同而有所区别。以下是针对 Windows、macOS 和 Linux 系统的详细安装指导。 1. Windows 步骤&#xff1a; 下载 Tesseract 安装程序 访问 Tesseract GitHub Release 页面。下载最新版本的安装程序&#xff08;例如 .exe 文件&#xff0…

【小趴菜前端实习日记5】

实习日记5 一、vue3中如何使用router&#xff08;获取this)二、ts中用object定义类型太宽泛导致Ts无法推断出正确类型三、动态设置日记封面失败vite动态引入静态资源1.方法一vue3父子组件生命周期执行顺序 2.方法二3.方法三 四、打包问题总结1.The import.meta meta-property i…