SpringBoot+Vue 博客系统(十一):博客后台管理

签名:但行好事,莫问前程。

SpringBoot+Vue 博客系统(连载系列)

在这里插入图片描述


YangCunle`s Blog 博客网址:http://www.yangcunle.com


SpringBoot+Vue 博客系统(一):个人网站的由来

SpringBoot+Vue 博客系统(二):个人博客的搭建

SpringBoot+Vue 博客系统(三):个人博客的设计

SpringBoot+Vue 博客系统(四):博客后端开发

SpringBoot+Vue 博客系统(五):整合阿里云OSS

SpringBoot+Vue 博客系统(六):整合Redis

SpringBoot+Vue 博客系统(七):Blog前端Vue项目的搭建

SpringBoot+Vue 博客系统(八):前端项目引入Element-UI

SpringBoot+Vue 博客系统(九):安装Axios处理跨域

SpringBoot+Vue 博客系统(十):VUE路由 vue-route

SpringBoot+Vue 博客系统(十一):博客后台管理

SpringBoot+Vue 博客系统(十二):博客前台展示

SpringBoot+Vue 博客系统(十三):项目打包部署到服务器



超级管理员登录账号进入后台管理页面,可以从管理后台对博客系统进行管理,其中包括:用户管理,博客管理,编辑添加博客,以及标签、留言、链接以及作者信息的管理,后台管理数据,给前台展示。


一、首页

首页展示日历
在这里插入图片描述

二、用户管理

在这里插入图片描述

<template>
  <div>
    <!--    搜索框-->
    <div style="height: 50px; margin-top: -10px;margin-bottom: -7px">
      <el-input v-model="username" placeholder="请输入姓名"
                suffix-icon="el-icon-search" style="width: 220px"
                @keyup.enter.native="queryByPage"></el-input>
      <el-button type="primary" style="margin-left: 5px" @click="queryByPage">查询</el-button>
      <el-button type="success" style="margin-left: 5px" @click="reset">重置</el-button>
      <el-button type="primary" style="margin-left: 5px" @click="toAddUser">添加</el-button>
    </div>
    <!--    列表展示-->
    <el-table :data="tableData"
              :header-cell-style="{ background: '#f3f6fd', color: '#555','text-align':'center' }"
              :cell-style="{'text-align':'center'}"
              border
              style="width: 100%"
    >
      <el-table-column prop="id" label="ID" width="60px">
      </el-table-column>
      <el-table-column prop="username" label="姓名" width="200px">
      </el-table-column>
      <el-table-column prop="phone" label="手机号" width="250px">
      </el-table-column>
      <el-table-column prop="email" label="邮箱" width="269px">
      </el-table-column>
      <el-table-column prop="age" label="年龄" width="100px">
      </el-table-column>
      <el-table-column prop="role" label="角色" width="200px">
        <template slot-scope="scope">
          <el-tag
            :type="scope.row.role === 1 ? 'danger' : 'success'"
            disable-transitions>{{ scope.row.role === 1 ? '超级管理员' : '普通用户' }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column prop="createTime" label="注册时间" width="250px">
      </el-table-column>
      <el-table-column prop="operate" label="操作" width="300px">
        <template slot-scope="scope">
          <el-button size="small" type="primary" @click="read(scope.row.id)">查看</el-button>
          <el-button size="small" type="success" @click="toUpdate(scope.row.id)">编辑</el-button>
          <el-button size="small" type="danger" slot="reference" @click="del(scope.row.id)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <!--    Pagination 分页-->
    <el-pagination
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="pageNum"
      :page-sizes="[10, 20, 30]"
      :page-size="pageSize"
      layout="total, sizes, prev, pager, next, jumper"
      :total="total"
    >
    </el-pagination>
    <!--    增加弹窗-->
    <el-dialog
      :title="title_show"
      :visible.sync="dialogVisible"
      :close-on-click-modal=false
      width="30%">
      <!--      表单-->
      <el-form ref="form" :rules="rules" :model="user" label-width="120px">
        <el-form-item label="姓名:" prop="username">
          <el-col :span="20">
            <el-input v-model="user.username" :disabled="disable"></el-input>
          </el-col>
        </el-form-item>
        <el-form-item label="密码:" prop="password">
          <el-col :span="20">
            <el-input v-model="user.password" type="password" :disabled="disable"></el-input>
          </el-col>
        </el-form-item>
        <el-form-item label="手机号:" prop="phone">
          <el-col :span="20">
            <el-input v-model="user.phone" :disabled="disable"></el-input>
          </el-col>
        </el-form-item>
        <el-form-item label="邮箱:" prop="email">
          <el-col :span="20">
            <el-input v-model="user.email" :disabled="disable"></el-input>
          </el-col>
        </el-form-item>
        <el-form-item label="角色:">
          <el-radio-group v-model="user.role" :disabled="disable">
            <el-radio :label=1>超级管理员</el-radio>
            <el-radio :label=2>普通用户</el-radio>
          </el-radio-group>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer" v-show="v_show_Button">
    <el-button @click="dialogVisible = false">取 消</el-button>
    <el-button type="primary" @click="saveOrUpdate">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
export default {
  name: 'UserManage',
  data () {
    return {
      tableData: [],
      pageNum: 1,
      pageSize: 10,
      total: 0,
      username: '',
      title_show: '',
      // 是否展示添加弹窗
      dialogVisible: false,
      disable: false,
      v_show_Button: true,
      // user对象
      user: {
        id: '',
        username: '',
        password: '',
        phone: '',
        email: '',
        age: 18,
        role: 2
      },
      rules: {
        username: [
          {required: true, message: '请输入姓名', trigger: 'blur'},
          {min: 2, max: 10, message: '长度在 2 到 10 个字符', trigger: 'blur'}
        ],
        password: [
          {required: true, message: '请输入密码', trigger: 'blur'},
        ],
        phone: [
          {required: true, message: '请输入手机号码', trigger: 'blur'},
          {
            required: true,
            pattern: /^[1][3,4,5,7,8,9][0-9]{9}$/,
            message: '请输入正确的手机号码',
            trigger: 'blur',
          },
        ],
        email: [{
          required: true,
          message: '电子信箱不能为空',
          trigger: 'blur'
        }, {
          validator: function (rule, value, callback) {
            if (
              /^\w{1,64}@[a-z0-9\-]{1,256}(\.[a-z]{2,6}){1,2}$/i.test(
                value
              ) == false
            ) {
              callback(new Error('邮箱格式错误'))
            } else {
              callback()
            }
          },
          trigger: 'blur'
        }]
      }
    }
  },
  methods: {
    // 打开添加弹窗
    toAddUser () {
      this.dialogVisible = true
      this.title_show = '添加用户'
      this.$nextTick(() => {
        // 重置form表单
        this.resetForm()
      })
      this.disable = false
      this.v_show_Button = true
    },
    // 重置from表单
    resetForm () {
      this.$refs.form.resetFields()
    },
    // 判断是添加还是修改
    saveOrUpdate () {
      this.$refs.form.validate((valid) => {
        if (valid) {
          console.log(this.user.id)
          if (this.user.id == '') {
            this.save()
          } else {
            this.update()
          }
        } else {
          return false
        }
      })
    },
    save () {
      this.$axios.post('/api/user/save', this.user).then(res => res.data).then(res => {
        if (res.code == 200) {
          // 关闭添加弹窗
          this.dialogVisible = false
          // 重新加载数据
          this.queryByPage()
          // 提示添加成功信息
          this.$message({
            message: res.message,
            type: 'success'
          })
        } else {
          // 关闭添加弹窗
          this.dialogVisible = false
          // 提示错误信息
          this.$message({
            message: res.message,
            type: 'warning'
          })
        }
      })
    },
    read (id) {
      this.$axios.get('/api/user/read?id=' + id).then(res => res.data).then(res => {
        if (res.code == 200) {
          this.dialogVisible = true
          this.title_show = '查看用户'
          this.user = res.data
          this.disable = true
          this.v_show_Button = false
        } else {
          this.$message({
            message: res.message,
            type: 'warning'
          })
        }
      })
    },
    toUpdate (id) {
      this.$axios.get('/api/user/read?id=' + id).then(res => res.data).then(res => {
        if (res.code == 200) {
          this.dialogVisible = true
          this.title_show = '编辑用户'
          this.user = res.data
          this.disable = false
          this.v_show_Button = true
        } else {
          this.$message({
            message: res.message,
            type: 'warning'
          })
        }
      })
    },
    update () {
      this.$axios.post('/api/user/update', this.user).then(res => res.data).then(res => {
        if (res.code == 200) {
          // 关闭添加弹窗
          this.dialogVisible = false
          // 重新加载数据
          this.queryByPage()
          // 提示添加成功信息
          this.$message({
            message: res.message,
            type: 'success'
          })
        } else {
          // 关闭添加弹窗
          this.dialogVisible = false
          // 提示错误信息
          this.$message({
            message: res.message,
            type: 'warning'
          })
        }
      })
    },
    del (id) {
      this.$confirm('是否删除?', '删除', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() =>{
        this.$axios.get('/api/user/delete?id=' + id).then(res => res.data).then(res => {
          if (res.code == 200) {
            // 重新加载数据
            this.queryByPage()
            // 提示添加成功信息
            this.$message({
              message: res.message,
              type: 'success'
            })
          } else {
            this.$message({
              message: res.message,
              type: 'warning'
            })
          }
        })
      }).catch(()=>{
        this.$message({
          type: 'info',
          message: '取消操作'
        })
      })
    },
    handleSizeChange (val) {
      console.log(`每页 ${val}`)
      this.pageNum = 1
      this.pageSize = val
      this.queryByPage()
    },
    handleCurrentChange (val) {
      console.log(`当前页: ${val}`)
      this.pageNum = val
      this.queryByPage()
    },
    // 重置
    reset () {
      this.username = ''
      this.queryByPage()
    },
    // 测试post获取后端数据
    queryByPage () {
      this.$axios.post('/api/user/queryByPage', {
        username: this.username,
        pageNum: this.pageNum,
        pageSize: this.pageSize
      }).then(res => res.data).then(res => {
        if (res.code == 200) {
          this.tableData = res.data.list
          this.pageNum = res.data.currentPage
          this.pageSize = res.data.pageSize
          this.total = res.data.total
        } else {
          this.$message({
            message: res.message,
            type: 'warning'
          })
        }
      })
    }
  },
  mounted () {
    this.queryByPage()
  }
}
</script>

<style scoped>

</style>


1、列表数据分页展示

<!--    列表展示-->
    <el-table :data="tableData"
              :header-cell-style="{ background: '#f3f6fd', color: '#555','text-align':'center' }"
              :cell-style="{'text-align':'center'}"
              border
              style="width: 100%"
    >
      <el-table-column prop="id" label="ID" width="60px">
      </el-table-column>
      <el-table-column prop="username" label="姓名" width="200px">
      </el-table-column>
      <el-table-column prop="phone" label="手机号" width="250px">
      </el-table-column>
      <el-table-column prop="email" label="邮箱" width="269px">
      </el-table-column>
      <el-table-column prop="age" label="年龄" width="100px">
      </el-table-column>
      <el-table-column prop="role" label="角色" width="200px">
        <template slot-scope="scope">
          <el-tag
            :type="scope.row.role === 1 ? 'danger' : 'success'"
            disable-transitions>{{ scope.row.role === 1 ? '超级管理员' : '普通用户' }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column prop="createTime" label="注册时间" width="250px">
      </el-table-column>
      <el-table-column prop="operate" label="操作" width="300px">
        <template slot-scope="scope">
          <el-button size="small" type="primary" @click="read(scope.row.id)">查看</el-button>
          <el-button size="small" type="success" @click="toUpdate(scope.row.id)">编辑</el-button>
          <el-button size="small" type="danger" slot="reference" @click="del(scope.row.id)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <!--    Pagination 分页-->
    <el-pagination
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="pageNum"
      :page-sizes="[10, 20, 30]"
      :page-size="pageSize"
      layout="total, sizes, prev, pager, next, jumper"
      :total="total"
    >

2、请求后台分页数据

// 测试post获取后端数据
    queryByPage () {
      this.$axios.post('/api/user/queryByPage', {
        username: this.username,
        pageNum: this.pageNum,
        pageSize: this.pageSize
      }).then(res => res.data).then(res => {
        if (res.code == 200) {
          this.tableData = res.data.list
          this.pageNum = res.data.currentPage
          this.pageSize = res.data.pageSize
          this.total = res.data.total
        } else {
          this.$message({
            message: res.message,
            type: 'warning'
          })
        }
      })
    }

3、添加用户

在这里插入图片描述

<!--    增加弹窗-->
    <el-dialog
      :title="title_show"
      :visible.sync="dialogVisible"
      :close-on-click-modal=false
      width="30%">
      <!--      表单-->
      <el-form ref="form" :rules="rules" :model="user" label-width="120px">
        <el-form-item label="姓名:" prop="username">
          <el-col :span="20">
            <el-input v-model="user.username" :disabled="disable"></el-input>
          </el-col>
        </el-form-item>
        <el-form-item label="密码:" prop="password">
          <el-col :span="20">
            <el-input v-model="user.password" type="password" :disabled="disable"></el-input>
          </el-col>
        </el-form-item>
        <el-form-item label="手机号:" prop="phone">
          <el-col :span="20">
            <el-input v-model="user.phone" :disabled="disable"></el-input>
          </el-col>
        </el-form-item>
        <el-form-item label="邮箱:" prop="email">
          <el-col :span="20">
            <el-input v-model="user.email" :disabled="disable"></el-input>
          </el-col>
        </el-form-item>
        <el-form-item label="角色:">
          <el-radio-group v-model="user.role" :disabled="disable">
            <el-radio :label=1>超级管理员</el-radio>
            <el-radio :label=2>普通用户</el-radio>
          </el-radio-group>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer" v-show="v_show_Button">
    <el-button @click="dialogVisible = false">取 消</el-button>
    <el-button type="primary" @click="saveOrUpdate">确 定</el-button>
      </span>
    </el-dialog>

4、修改用户信息

在这里插入图片描述

点击编辑,根据id查修详情,数据回显

    toUpdate (id) {
      this.$axios.get('/api/user/read?id=' + id).then(res => res.data).then(res => {
        if (res.code == 200) {
          this.dialogVisible = true
          this.title_show = '编辑用户'
          this.user = res.data
          this.disable = false
          this.v_show_Button = true
        } else {
          this.$message({
            message: res.message,
            type: 'warning'
          })
        }
      })
    },

编辑完成,点击确定,修改数据

update () {
      this.$axios.post('/api/user/update', this.user).then(res => res.data).then(res => {
        if (res.code == 200) {
          // 关闭添加弹窗
          this.dialogVisible = false
          // 重新加载数据
          this.queryByPage()
          // 提示添加成功信息
          this.$message({
            message: res.message,
            type: 'success'
          })
        } else {
          // 关闭添加弹窗
          this.dialogVisible = false
          // 提示错误信息
          this.$message({
            message: res.message,
            type: 'warning'
          })
        }
      })
    },

5、删除用户

在这里插入图片描述

del (id) {
      this.$confirm('是否删除?', '删除', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() =>{
        this.$axios.get('/api/user/delete?id=' + id).then(res => res.data).then(res => {
          if (res.code == 200) {
            // 重新加载数据
            this.queryByPage()
            // 提示添加成功信息
            this.$message({
              message: res.message,
              type: 'success'
            })
          } else {
            this.$message({
              message: res.message,
              type: 'warning'
            })
          }
        })
      }).catch(()=>{
        this.$message({
          type: 'info',
          message: '取消操作'
        })
      })
    },

三、博客标签

在这里插入图片描述

操作差不多,就不一一介绍

<template>
<div>
    <!--    搜索框-->
    <div style="height: 50px; margin-top: -10px;margin-bottom: -7px">
      <el-input v-model="tagName" placeholder="请输入标签名称"
                suffix-icon="el-icon-search" style="width: 220px"
                @keyup.enter.native="queryByPage"></el-input>
      <el-button type="primary" style="margin-left: 5px" @click="queryByPage">查询</el-button>
      <el-button type="success" style="margin-left: 5px" @click="reset">重置</el-button>
      <el-button type="primary" style="margin-left: 5px" @click="toAddTag">添加</el-button>
    </div>
    <!--    列表展示-->
    <el-table :data="tableData"
              :header-cell-style="{ background: '#f3f6fd', color: '#555','text-align':'center' }"
              :cell-style="{'text-align':'center'}"
              border
              style="width: 100%"
    >
      <el-table-column prop="id" label="ID" width="100px">
      </el-table-column>
      <el-table-column prop="tagName" label="标签名称" width="429px">
      </el-table-column>
      <el-table-column prop="createTime" label="添加时间" width="350px">
      </el-table-column>
      <el-table-column prop="updateTime" label="修改时间" width="350px">
      </el-table-column>
      <el-table-column prop="operate" label="操作" width="400px">
        <template slot-scope="scope">
          <el-button size="small" type="primary" @click="read(scope.row.id)">查看</el-button>
          <el-button size="small" type="success" @click="toUpdate(scope.row.id)">编辑</el-button>
          <el-button size="small" type="danger" slot="reference" @click="del(scope.row.id)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <!--    Pagination 分页-->
    <el-pagination
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="pageNum"
      :page-sizes="[10, 20, 30]"
      :page-size="pageSize"
      layout="total, sizes, prev, pager, next, jumper"
      :total="total"
    >
    </el-pagination>
    <!--    增加弹窗-->
    <el-dialog
      :title="title_show"
      :visible.sync="dialogVisible"
      :close-on-click-modal=false
      width="30%">
      <!--      表单-->
      <el-form ref="form" :rules="rules" :model="tag" label-width="120px">
        <el-form-item label="标签名称:" prop="tagName">
          <el-col :span="20">
            <el-input v-model="tag.tagName" :disabled="disable"></el-input>
          </el-col>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer" v-show="v_show_Button">
    <el-button @click="dialogVisible = false">取 消</el-button>
    <el-button type="primary" @click="saveOrUpdate">确 定</el-button>
      </span>
    </el-dialog>
</div>
</template>

<script>
export default {
  name: 'Tag',
  data () {
    return {
      tableData: [],
      pageNum: 1,
      pageSize: 10,
      total: 0,
      tagName: '',
      title_show: '',
      // 是否展示添加弹窗
      dialogVisible: false,
      disable: false,
      v_show_Button: true,
      // Tag对象
      tag: {
        id: '',
        tagName: ''
      },
      rules: {
        tagName: [
          {required: true, message: '请输入标签名称', trigger: 'blur'},
        ]
      }
    }
  },
  methods: {
    // 打开添加弹窗
    toAddTag () {
      this.dialogVisible = true
      this.title_show = '添加博客标签'
      this.$nextTick(() => {
        // 重置form表单
        this.resetForm()
      })
      this.disable = false
      this.v_show_Button = true
    },
    // 重置from表单
    resetForm () {
      this.$refs.form.resetFields()
    },
    // 判断是添加还是修改
    saveOrUpdate () {
      this.$refs.form.validate((valid) => {
        if (valid) {
          console.log(this.tag.id)
          if (this.tag.id == '') {
            this.save()
          } else {
            this.update()
          }
        } else {
          return false
        }
      })
    },
    save () {
      this.$axios.post('/api/tag/save', this.tag).then(res => res.data).then(res => {
        if (res.code == 200) {
          // 关闭添加弹窗
          this.dialogVisible = false
          // 重新加载数据
          this.queryByPage()
          // 提示添加成功信息
          this.$message({
            message: res.message,
            type: 'success'
          })
        } else {
          // 关闭添加弹窗
          this.dialogVisible = false
          // 提示错误信息
          this.$message({
            message: res.message,
            type: 'warning'
          })
        }
      })
    },
    read (id) {
      this.$axios.get('/api/tag/query?id=' + id).then(res => res.data).then(res => {
        console.log(res.data)
        if (res.code == 200) {
          this.dialogVisible = true
          this.title_show = '查看'
          this.tag = res.data
          this.disable = true
          this.v_show_Button = false
        } else {
          this.$message({
            message: res.message,
            type: 'warning'
          })
        }
      })
    },
    toUpdate (id) {
      this.$axios.get('/api/tag/query?id=' + id).then(res => res.data).then(res => {
        if (res.code == 200) {
          this.dialogVisible = true
          this.title_show = '编辑'
          this.tag = res.data
          this.disable = false
          this.v_show_Button = true
        } else {
          this.$message({
            message: res.message,
            type: 'warning'
          })
        }
      })
    },
    update () {
      this.$axios.post('/api/tag/update', this.tag).then(res => res.data).then(res => {
        if (res.code == 200) {
          // 关闭添加弹窗
          this.dialogVisible = false
          // 重新加载数据
          this.queryByPage()
          // 提示添加成功信息
          this.$message({
            message: res.message,
            type: 'success'
          })
        } else {
          // 关闭添加弹窗
          this.dialogVisible = false
          // 提示错误信息
          this.$message({
            message: res.message,
            type: 'warning'
          })
        }
      })
    },
    del (id) {
      this.$confirm('是否删除?', '删除', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() =>{
        this.$axios.get('/api/tag/delete?id=' + id).then(res => res.data).then(res => {
          if (res.code == 200) {
            // 重新加载数据
            this.queryByPage()
            // 提示添加成功信息
            this.$message({
              message: res.message,
              type: 'success'
            })
          } else {
            this.$message({
              message: res.message,
              type: 'warning'
            })
          }
        })
      }).catch(()=>{
        this.$message({
          type: 'info',
          message: '取消操作'
        })
      })
    },
    handleSizeChange (val) {
      console.log(`每页 ${val}`)
      this.pageNum = 1
      this.pageSize = val
      this.queryByPage()
    },
    handleCurrentChange (val) {
      console.log(`当前页: ${val}`)
      this.pageNum = val
      this.queryByPage()
    },
    // 重置
    reset () {
      this.tagName = ''
      this.queryByPage()
    },
    // 获取后端数据
    queryByPage () {
      this.$axios.post('/api/tag/queryByPage', {
        tagName: this.tagName,
        pageNum: this.pageNum,
        pageSize: this.pageSize
      }).then(res => res.data).then(res => {
        if (res.code == 200) {
          this.tableData = res.data.list
          this.pageNum = res.data.currentPage
          this.pageSize = res.data.pageSize
          this.total = res.data.total
        } else {
          this.$message({
            message: res.message,
            type: 'warning'
          })
        }
      })
    }
  },
  mounted () {
    this.queryByPage()
  }
}
</script>

<style scoped>

</style>

四、博客管理

在这里插入图片描述

<template>
  <div>
    <!--    搜索框-->
    <div style="height: 50px; margin-top: -10px;margin-bottom: -7px">
      <el-input v-model="title" placeholder="请输入标题名称"
                suffix-icon="el-icon-search" style="width: 220px"
                @keyup.enter.native="queryByPage"></el-input>
      <!--      下拉框-->
      <el-select v-model="tag" placeholder="请选择标签" style="margin-left: 5px">
        <el-option
          v-for="item in tagList"
          :key="item.value"
          :label="item.label"
          :value="item.value">
        </el-option>
      </el-select>
      <el-button type="primary" style="margin-left: 5px" @click="queryByPage">查询</el-button>
      <el-button type="success" style="margin-left: 5px" @click="reset">重置</el-button>
      <el-button type="primary" style="margin-left: 5px" @click="toAdd">添加</el-button>
    </div>
    <!--    列表展示-->
    <el-table :data="tableData"
              :header-cell-style="{ background: '#f3f6fd', color: '#555','text-align':'center' }"
              :cell-style="{'text-align':'center'}"
              border
              style="width: 100%"
    >
      <el-table-column prop="id" label="ID" width="60px">
      </el-table-column>
      <el-table-column prop="title" label="博客标题" width="300px">
      </el-table-column>
      <el-table-column prop="author" label="作者" width="150px">
      </el-table-column>
      <el-table-column label="博客封面图片" width="299px">
        <template slot-scope="scope">
          <el-image style="width: 80px; height: 80px" :src="scope.row.img" :preview-src-list="[scope.row.img]">
          </el-image>
        </template>
      </el-table-column>
      <el-table-column prop="tag" label="博客标签" width="200px">
      </el-table-column>
      <el-table-column prop="liked" label="点赞" width="100px">
      </el-table-column>
      <el-table-column prop="views" label="浏览量" width="100px">
      </el-table-column>
      <el-table-column prop="createTime" label="添加时间" width="200px">
      </el-table-column>
      <el-table-column prop="operate" label="操作" width="220px">
        <template slot-scope="scope">
          <el-button size="small" type="success" @click="toUpdate(scope.row.id)">编辑</el-button>
          <el-button size="small" type="danger" slot="reference" @click="del(scope.row.id)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <!--    Pagination 分页-->
    <el-pagination
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="pageNum"
      :page-sizes="[6, 10, 20, 30]"
      :page-size="pageSize"
      layout="total, sizes, prev, pager, next, jumper"
      :total="total"
    >
    </el-pagination>
  </div>
</template>

<script>
export default {
  name: 'BlogManage',
  data () {
    return {
      tableData: [],
      pageNum: 1,
      pageSize: 6,
      total: 0,
      title: '',
      tag:'',
      tagList: [],
      // Blog对象
      blog: {
        id: '',
        title: '',
        author: '',
        img: '',
        content: '',
        description: '',
        tag: '',
        liked: ''
      },
      rules: {
        title: [
          {required: true, message: '请输入标题名称', trigger: 'blur'},
        ]
      }
    }
  },
  methods: {
    // 打开添加页面
    toAdd () {
      // 跳转添加博客页面
      this.$router.push('/BlogAdd')
    },
    // 重置from表单
    resetForm () {
      this.$refs.form.resetFields()
    },
    // 判断是添加还是修改
    saveOrUpdate () {

    },
    save () {

    },
    read (id) {

    },
    // 去修改页面
    toUpdate (id) {
      this.$router.push({
        path: "/BlogUpdate",
        query: { id: id }
      });
    },
    update () {

    },
    del (id) {
      this.$confirm('是否删除?', '删除', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() =>{
        this.$axios.get('/api/blog/delete?id=' + id).then(res => res.data).then(res => {
          if (res.code == 200) {
            // 重新加载数据
            this.queryByPage()
            // 提示添加成功信息
            this.$message({
              message: res.message,
              type: 'success'
            })
          } else {
            this.$message({
              message: res.message,
              type: 'warning'
            })
          }
        })
      }).catch(()=>{
        this.$message({
          type: 'info',
          message: '取消操作'
        })
      })
    },
    handleSizeChange (val) {
      console.log(`每页 ${val}`)
      this.pageNum = 1
      this.pageSize = val
      this.queryByPage()
    },
    handleCurrentChange (val) {
      console.log(`当前页: ${val}`)
      this.pageNum = val
      this.queryByPage()
    },
    // 重置
    reset () {
      this.title = ''
      this.tag = ''
      this.queryByPage()
    },
    // 获取后端数据
    queryByPage () {
      this.$axios.post('/api/blog/queryByPage', {
        title: this.title,
        tag: this.tag,
        pageNum: this.pageNum,
        pageSize: this.pageSize
      }).then(res => res.data).then(res => {
        if (res.code == 200) {
          this.tableData = res.data.list
          this.pageNum = res.data.currentPage
          this.pageSize = res.data.pageSize
          this.total = res.data.total
        } else {
          this.$message({
            message: res.message,
            type: 'warning'
          })
        }
      })
    },
    // 查询标签列表
    queryTagList (){
      this.$axios.get('/api/tag/getTagList').then(res => res.data).then(res => {
        if (res.code == 200) {
          this.tagList = res.data
        }
      })
    },
  },

  mounted () {
    this.queryByPage()
    this.queryTagList()
  }
}
</script>

<style scoped>

</style>

添加博客

在这里插入图片描述

<template>
<div>
  <el-form ref="form" :rules="rules" :model="blog" label-width="120px">
    <el-form-item label="博客标题:" style="width: 500px">
      <el-input v-model="blog.title"></el-input>
    </el-form-item>

    <el-form-item label="作者:" style="width: 500px">
      <el-input v-model="blog.author"></el-input>
    </el-form-item>

    <el-form-item label="博客说明:" style="width: 500px">
      <el-input type="textarea" v-model="blog.description"></el-input>
    </el-form-item>

    <el-form-item label="博客标签:" style="width: 500px">
      <!--      下拉框-->
      <el-select v-model="blog.tag" placeholder="请选择标签" style="width: 380px">
        <el-option
          v-for="item in tagList"
          :key="item.value"
          :label="item.label"
          :value="item.value">
        </el-option>
      </el-select>
    </el-form-item>

    <el-form-item label="博客主图:" style="width: 500px">
      <el-upload
        :action="fileUploadUrl"
        :on-success="uploadSuccess"
        :on-preview="handlePreview"
        :on-remove="handleRemove"
        :file-list="fileList"
        :limit="1"
        list-type="picture"
        v-model="blog.img">
        <el-button size="small" type="primary">点击上传</el-button>
        <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
      </el-upload>
    </el-form-item>

    <el-form-item label="博客内容:">
      <quill-editor ref="text" v-model="blog.content" class="editor" :options="editorOption" style="height: 1000px"/>
    </el-form-item>

    <el-form-item style="padding-top: 40px">
      <el-button type="primary" @click="onSubmit">立即创建</el-button>
      <el-button @click="cancel">取消</el-button>
    </el-form-item>
  </el-form>
</div>
</template>

<script>
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
import Quill from 'quill'
import { ImageDrop } from 'quill-image-drop-module'
import ImageResize from 'quill-image-resize-module'
Quill.register('modules/imageDrop', ImageDrop)
Quill.register('modules/imageResize', ImageResize)
const toolbarOptions = [
  ['bold', 'italic', 'underline', 'strike'],        // toggled buttons
  ['blockquote', 'code-block'],

  [{'header': 1}, {'header': 2}],               // custom button values
  [{'list': 'ordered'}, {'list': 'bullet'}],
  [{'script': 'sub'}, {'script': 'super'}],      // superscript/subscript
  [{'indent': '-1'}, {'indent': '+1'}],          // outdent/indent
  [{'direction': 'rtl'}],                         // text direction

  [{'size': ['small', false, 'large', 'huge']}],  // custom dropdown
  [{'header': [1, 2, 3, 4, 5, 6, false]}],

  [{'color': []}, {'background': []}],          // dropdown with defaults from theme
  [{'font': []}],
  [{'align': []}],
  ['link', 'image', 'video'],
  ['clean']                                         // remove formatting button
];
export default {
  name: 'BlogAdd',
  data() {
    return {
      // 标签
      tagList: [],
      // 图片上传
      fileList: [],
      fileUploadUrl: '/api/blog/fileUpload',
      // 富文本编辑器选项
      editorOption:{
        placeholder: 'Insert text here ...',
        modules: {
          imageResize: {
            displayStyles: {
              backgroundColor: 'black',
              border: 'none',
              color: 'white'
            },
            modules: ['Resize', 'DisplaySize', 'Toolbar']
          },
          toolbar: {
            container: toolbarOptions,  // 工具栏
          }
        }
      },
      blog: {
        title: '',
        author: '',
        img: '',
        content: '',
        description: '',
        tag: '',
      },
        rules: {
          title: [
          {required: true, message: '请输入博客标题', trigger: 'blur'},
        ],
          author: [
            {required: true, message: '请输入作者名称', trigger: 'blur'},
          ],
          img: [
            {required: true, message: '请上传博客主图', trigger: 'blur'},
          ],
          content: [
            {required: true, message: '请输入博客内容', trigger: 'blur'},
          ],
          tag: [
            {required: true, message: '请选择博客标签', trigger: 'blur'},
          ],
      }
      }
  },
  methods: {
    // 图片上传成功的回调
    uploadSuccess(response, file, fileList) {
      this.blog.img = response
    },

    // 添加博客操作
    onSubmit() {
      console.log(this.blog);
      this.$refs.form.validate((valid) => {
        if (valid) {
          this.$axios.post('/api/blog/save', this.blog).then(res => res.data).then(res => {
            console.log(res.data)
            if (res.code == 200) {
              // 跳转到博客列表
              this.$router.replace('/BlogManage')
              // 提示添加成功信息
              this.$message({
                message: res.message,
                type: 'success'
              })
            } else {
              // 提示错误信息
              this.$message({
                message: res.message,
                type: 'warning'
              })
            }
          })
        } else {
          return false
        }
      })
    },
    // 取消操作
    cancel () {
      // 跳转到博客列表
      this.$router.replace('/BlogManage')
    },
    handleRemove (file, fileList) {
      console.log(file, fileList)
    },
    handlePreview (file) {
      console.log(file)
    },
    // 查询标签列表
    queryTagList (){
      this.$axios.get('/api/tag/getTagList').then(res => res.data).then(res => {
        if (res.code == 200) {
          this.tagList = res.data
        }
      })
    },
  },
  mounted () {
    this.queryTagList()
  }

}
</script>

<style scoped>

</style>

五、留言管理

在这里插入图片描述

这块也比较简单,直接附上代码

<template>
  <div>
    <!--    搜索框-->
    <div style="height: 50px; margin-top: -10px;margin-bottom: -7px">
      <el-input v-model="username" placeholder="请输入留言人姓名"
                suffix-icon="el-icon-search" style="width: 220px"
                @keyup.enter.native="queryByPage"></el-input>
      <el-button type="primary" style="margin-left: 5px" @click="queryByPage">查询</el-button>
    </div>
    <!--    列表展示-->
    <el-table :data="tableData"
              :header-cell-style="{ background: '#f3f6fd', color: '#555','text-align':'center' }"
              :cell-style="{'text-align':'center'}"
              border
              style="width: 100%"
    >
      <el-table-column prop="id" label="ID" width="60px">
      </el-table-column>
      <el-table-column prop="username" label="姓名" width="200px">
      </el-table-column>
      <el-table-column label="头像" width="200px">
        <template slot-scope="scope">
          <el-image style="width: 50px; height: 50px;border-radius: 50%" :src="scope.row.headImg" :preview-src-list="[scope.row.headImg]">
          </el-image>
        </template>
      </el-table-column>
      <el-table-column prop="message" label="留言内容" width="669px">
      </el-table-column>
      <el-table-column prop="createTime" label="留言时间" width="250px">
      </el-table-column>
      <el-table-column prop="operate" label="操作" width="250px">
        <template slot-scope="scope">
          <el-button size="small" type="primary" @click="read(scope.row.id)">查看</el-button>
          <el-button size="small" type="danger" slot="reference" @click="del(scope.row.id)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <!--    Pagination 分页-->
    <el-pagination
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="pageNum"
      :page-sizes="[10, 20, 30]"
      :page-size="pageSize"
      layout="total, sizes, prev, pager, next, jumper"
      :total="total"
    >
    </el-pagination>
    <!--    增加弹窗-->
    <el-dialog
      :title="title_show"
      :visible.sync="dialogVisible"
      :close-on-click-modal=false
      width="30%">
      <!--      表单-->
      <el-form ref="form" :model="message" label-width="120px">
        <el-form-item label="姓名:">
          <el-col :span="20">
            <el-input v-model="message.username"></el-input>
          </el-col>
        </el-form-item>
        <el-form-item label="头像:">
          <el-col :span="20">
              <el-image style="width: 40px; height: 40px;border-radius: 50%"
                        :src="message.headImg">
              </el-image>
          </el-col>
        </el-form-item>
        <el-form-item label="留言内容:">
          <el-col :span="20">
            <el-input  type="textarea" v-model="message.message" ></el-input>
          </el-col>
        </el-form-item>
        <el-form-item label="留言时间:">
          <el-col :span="20">
            <el-input v-model="message.createTime" ></el-input>
          </el-col>
        </el-form-item>
      </el-form>
    </el-dialog>
  </div>
</template>

<script>
export default {
  name: 'MsgManage',
  data () {
    return {
      tableData: [],
      pageNum: 1,
      pageSize: 10,
      total: 0,
      username: '',
      title_show: '',
      // 是否展示添加弹窗
      dialogVisible: false,
      // 对象
      message: {
        id: '',
        username: '',
        headImg: '',
        message: '',
        createTime: '',
      },
    }
  },
  methods: {

    // 重置from表单
    resetForm () {
      this.$refs.form.resetFields()
    },
    read (id) {
      this.$axios.get('/api/message/query?id=' + id).then(res => res.data).then(res => {
        console.log(res.data)
        if (res.code == 200) {
          this.dialogVisible = true
          this.title_show = '查看'
          this.message = res.data
        } else {
          this.$message({
            message: res.message,
            type: 'warning'
          })
        }
      })
    },
    del (id) {
      this.$confirm('是否删除?', '删除', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() =>{
        this.$axios.get('/api/message/delete?id=' + id).then(res => res.data).then(res => {
          if (res.code == 200) {
            // 重新加载数据
            this.queryByPage()
            // 提示添加成功信息
            this.$message({
              message: res.message,
              type: 'success'
            })
          } else {
            this.$message({
              message: res.message,
              type: 'warning'
            })
          }
        })
      }).catch(()=>{
        this.$message({
          type: 'info',
          message: '取消操作'
        })
      })
    },
    handleSizeChange (val) {
      console.log(`每页 ${val}`)
      this.pageNum = 1
      this.pageSize = val
      this.queryByPage()
    },
    handleCurrentChange (val) {
      console.log(`当前页: ${val}`)
      this.pageNum = val
      this.queryByPage()
    },
    // 重置
    reset () {
      this.tagName = ''
      this.queryByPage()
    },
    // 获取后端数据
    queryByPage () {
      this.$axios.post('/api/message/queryByPage', {
        username: this.username,
        pageNum: this.pageNum,
        pageSize: this.pageSize
      }).then(res => res.data).then(res => {
        if (res.code == 200) {
          this.tableData = res.data.list
          this.pageNum = res.data.currentPage
          this.pageSize = res.data.pageSize
          this.total = res.data.total
        } else {
          this.$message({
            message: res.message,
            type: 'warning'
          })
        }
      })
    }
  },
  mounted () {
    this.queryByPage()
  }
}
</script>

<style scoped>

</style>

六、链接管理

在这里插入图片描述

<template>
  <div>
    <!--    搜索框-->
    <div style="height: 50px; margin-top: -10px;margin-bottom: -7px">
      <el-input v-model="username" placeholder="请输入留言人姓名"
                suffix-icon="el-icon-search" style="width: 220px"
                @keyup.enter.native="queryByPage"></el-input>
      <el-button type="primary" style="margin-left: 5px" @click="queryByPage">查询</el-button>
    </div>
    <!--    列表展示-->
    <el-table :data="tableData"
              :header-cell-style="{ background: '#f3f6fd', color: '#555','text-align':'center' }"
              :cell-style="{'text-align':'center'}"
              border
              style="width: 100%"
    >
      <el-table-column prop="id" label="ID" width="60px">
      </el-table-column>
      <el-table-column prop="username" label="姓名" width="200px">
      </el-table-column>
      <el-table-column label="头像" width="200px">
        <template slot-scope="scope">
          <el-image style="width: 50px; height: 50px;border-radius: 50%" :src="scope.row.headImg" :preview-src-list="[scope.row.headImg]">
          </el-image>
        </template>
      </el-table-column>
      <el-table-column prop="message" label="留言内容" width="669px">
      </el-table-column>
      <el-table-column prop="createTime" label="留言时间" width="250px">
      </el-table-column>
      <el-table-column prop="operate" label="操作" width="250px">
        <template slot-scope="scope">
          <el-button size="small" type="primary" @click="read(scope.row.id)">查看</el-button>
          <el-button size="small" type="danger" slot="reference" @click="del(scope.row.id)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <!--    Pagination 分页-->
    <el-pagination
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="pageNum"
      :page-sizes="[10, 20, 30]"
      :page-size="pageSize"
      layout="total, sizes, prev, pager, next, jumper"
      :total="total"
    >
    </el-pagination>
    <!--    增加弹窗-->
    <el-dialog
      :title="title_show"
      :visible.sync="dialogVisible"
      :close-on-click-modal=false
      width="30%">
      <!--      表单-->
      <el-form ref="form" :model="message" label-width="120px">
        <el-form-item label="姓名:">
          <el-col :span="20">
            <el-input v-model="message.username"></el-input>
          </el-col>
        </el-form-item>
        <el-form-item label="头像:">
          <el-col :span="20">
              <el-image style="width: 40px; height: 40px;border-radius: 50%"
                        :src="message.headImg">
              </el-image>
          </el-col>
        </el-form-item>
        <el-form-item label="留言内容:">
          <el-col :span="20">
            <el-input  type="textarea" v-model="message.message" ></el-input>
          </el-col>
        </el-form-item>
        <el-form-item label="留言时间:">
          <el-col :span="20">
            <el-input v-model="message.createTime" ></el-input>
          </el-col>
        </el-form-item>
      </el-form>
    </el-dialog>
  </div>
</template>

<script>
export default {
  name: 'MsgManage',
  data () {
    return {
      tableData: [],
      pageNum: 1,
      pageSize: 10,
      total: 0,
      username: '',
      title_show: '',
      // 是否展示添加弹窗
      dialogVisible: false,
      // 对象
      message: {
        id: '',
        username: '',
        headImg: '',
        message: '',
        createTime: '',
      },
    }
  },
  methods: {

    // 重置from表单
    resetForm () {
      this.$refs.form.resetFields()
    },
    read (id) {
      this.$axios.get('/api/message/query?id=' + id).then(res => res.data).then(res => {
        console.log(res.data)
        if (res.code == 200) {
          this.dialogVisible = true
          this.title_show = '查看'
          this.message = res.data
        } else {
          this.$message({
            message: res.message,
            type: 'warning'
          })
        }
      })
    },
    del (id) {
      this.$confirm('是否删除?', '删除', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() =>{
        this.$axios.get('/api/message/delete?id=' + id).then(res => res.data).then(res => {
          if (res.code == 200) {
            // 重新加载数据
            this.queryByPage()
            // 提示添加成功信息
            this.$message({
              message: res.message,
              type: 'success'
            })
          } else {
            this.$message({
              message: res.message,
              type: 'warning'
            })
          }
        })
      }).catch(()=>{
        this.$message({
          type: 'info',
          message: '取消操作'
        })
      })
    },
    handleSizeChange (val) {
      console.log(`每页 ${val}`)
      this.pageNum = 1
      this.pageSize = val
      this.queryByPage()
    },
    handleCurrentChange (val) {
      console.log(`当前页: ${val}`)
      this.pageNum = val
      this.queryByPage()
    },
    // 重置
    reset () {
      this.tagName = ''
      this.queryByPage()
    },
    // 获取后端数据
    queryByPage () {
      this.$axios.post('/api/message/queryByPage', {
        username: this.username,
        pageNum: this.pageNum,
        pageSize: this.pageSize
      }).then(res => res.data).then(res => {
        if (res.code == 200) {
          this.tableData = res.data.list
          this.pageNum = res.data.currentPage
          this.pageSize = res.data.pageSize
          this.total = res.data.total
        } else {
          this.$message({
            message: res.message,
            type: 'warning'
          })
        }
      })
    }
  },
  mounted () {
    this.queryByPage()
  }
}
</script>

<style scoped>

</style>

七、关于作者

在这里插入图片描述

这里可以编辑作者信息

<template>
  <div>
    <h3 style="text-align: center ;padding-bottom: 20px">作者信息</h3>
    <el-form ref="form" :rules="rules" :model="author">
      <el-form-item>
        <quill-editor ref="text" v-model="author.content" class="editor" :options="editorOption" />
      </el-form-item>
      <el-form-item style="margin-top: 10px">
        <el-button type="primary" @click="onSubmit">保存</el-button>
        <el-button @click="cancel">取消</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
import Quill from 'quill'
import { ImageDrop } from 'quill-image-drop-module'
import ImageResize from 'quill-image-resize-module'
Quill.register('modules/imageDrop', ImageDrop)
Quill.register('modules/imageResize', ImageResize)
const toolbarOptions = [
  ['bold', 'italic', 'underline', 'strike'],        // toggled buttons
  ['blockquote', 'code-block'],

  [{'header': 1}, {'header': 2}],               // custom button values
  [{'list': 'ordered'}, {'list': 'bullet'}],
  [{'script': 'sub'}, {'script': 'super'}],      // superscript/subscript
  [{'indent': '-1'}, {'indent': '+1'}],          // outdent/indent
  [{'direction': 'rtl'}],                         // text direction

  [{'size': ['small', false, 'large', 'huge']}],  // custom dropdown
  [{'header': [1, 2, 3, 4, 5, 6, false]}],

  [{'color': []}, {'background': []}],          // dropdown with defaults from theme
  [{'font': []}],
  [{'align': []}],
  ['link', 'image', 'video'],
  ['clean']                                         // remove formatting button
];

export default {
  name: 'AuthorManage',
  data () {
    return {
      // 富文本编辑器选项
      editorOption:{
        placeholder: '作者简介',
        modules: {
          imageResize: {
            displayStyles: {
              backgroundColor: 'black',
              border: 'none',
              color: 'white'
            },
            modules: ['Resize', 'DisplaySize', 'Toolbar']
          },
          toolbar: {
            container: toolbarOptions,  // 工具栏
          }
        }
      },
      author: {
        id: '',
        content: ''
      },
      rules: {
        content: [
          {required: true, message: '请输入作者信息', trigger: 'blur'},
        ]
      }
    }
  },
  methods: {

    // 添加作者操作
    onSubmit () {
      console.log(this.author)
      this.$refs.form.validate((valid) => {
        if (valid) {
          this.$axios.post('/api/author/update', this.author).then(res => res.data).then(res => {
            if (res.code == 200) {
              // 提示添加成功信息
              this.$message({
                message: res.message,
                type: 'success'
              })
            } else {
              // 提示错误信息
              this.$message({
                message: res.message,
                type: 'warning'
              })
            }
          })
        } else {
          return false
        }
      })
    },
    // 取消操作
    cancel () {
      this.queryBlogById()
    },
    handleRemove (file, fileList) {
      console.log(file, fileList)
    },
    handlePreview (file) {
      console.log(file)
    },

    // 查询作者详情
    queryBlogById () {
      this.$axios.get('/api/author/query?id=' + 1).then(res => res.data).then(res => {
        if (res.code == 200) {
          this.author = res.data
        }
      })
    },
  },
  mounted () {
    this.queryBlogById()
  }
}
</script>

<style scoped>

</style>


总结

以上记录了博客后台管理各模块的编写,如果对你有所帮助,请一键三连。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值