4、编辑公告
打开公告的列表,我们在编辑的按钮上加上一个跳转到添加的页面上。
<el-button type="primary" size="mini" icon="el-icon-edit" @click="$router.push({name: 'AddNotice', params: { noticeId: scope.row.noticeId }})">编辑</el-button>
这里用到了一个$router.push路由传值 ,在我们点击编辑的时候,会跳转到添加页面上,通过带着公告id一起传过去。获取参数的两种常用方法:params和query。
这里需要注意的是:由于动态路由也是传递params的,所以在this.$router.push()方法中path不能和params一起使用,否则params将无效。需要用name来指定页面。及通过路由配置的name属性访问。
$router.push({name: 'AddNotice', params: { noticeId: scope.row.noticeId }})
这里面的name的值就是我们要跳转页面路由的名称,在router文件中我圈起来的name。
下面我们要去发布公告的add.vue中去接收处理。
在add.vue中,上边的表单我们不需要改动,只需要将接收过来的数据进行处理即可。
我们写一个生命周期函数钩子created(),一个Vue实例被生成后会调用这个函数。我们这里面写检查是否存在noticeId,如果有值则获取文章的信息,我们这里还差一个根据公告id获取公告内容的接口,我们先将这个方法完成,再去后端写这个接口。
import { addNotice, updateNotice, getNoticeById } from '@/api/notice' created() { const noticeId = this.$route.params.noticeId; if(noticeId) { getNoticeById(noticeId).then((res) => { this.notice = res.data; }); } },
先将修改和根据id查询公告的接口引入进来,我们后端还没实现这个接口,我先把这个说完再去写,api的文件中还要添加一下接口。
我们根据this.$route.params.noticeId获取到点击编辑传过来的id,然后如果不为空的话,则去调getNoticeById接口,获取公告信息。
我们再去api/notice.js
文件中添加这接口。
export function getNoticeById(id){ return request({ url: '/notice/info/' + id, method: 'get' }) }
好啦,我们去后端将这个接口实现一下。
对于现在的我们来说,写个接口已经是轻车熟路了,先写service接口层
/** * 根据公告id获取公告 * @param noticeId * @return */ Notice getNoticeById(Integer noticeId);
实现类:
@Override public Notice getNoticeById(Integer noticeId) { Notice notice = noticeMapper.getNoticeById(noticeId); return notice; }
数据接口dao层
/** * 获取公告 * @param id * @return */ Notice getNoticeById(Integer id);
mybatis的xml
<select id="getNoticeById" resultMap="BaseResultMap"> select * from person_notice where notice_id = #{noticeId} </select>
最后写一下Controller层
@GetMapping("/info/{id}") @ApiOperation("根据id查询公告信息") @OperationLogSys(desc = "查询公告", operationType = OperationType.SELECT) public JsonResult<Object> getNotice(@PathVariable Integer id) { Notice notice = noticeService.getNoticeById(id); return JsonResult.success(notice); }
后端完成之后,我们再去写一下前端的发布公告的功能。在return的方法中再加一个noticeId
data() { return { showDialog: false, notice: { noticeContent: "", noticeTitle: "", noticeType: "", noticeStatus: true, noticeId: "" } } },
由于我们添加和修改使用的是同一个方法,所以我们在提交发布公告的时候要去判断一下我们是更新还是添加公告,这个和之前的分类功能基本上差不多。
handleSubmit() { this.showDialog = true; var body = this.notice; if(this.notice.noticeId) { updateNotice(body).then((res) => { this.$notify({ title: "提示", message: `公告《${this.notice.noticeTitle}》更新成功`, type: "success", }); this.$router.push("/notice/list"); }); } else { addNotice(body).then((response) => { this.$notify({ title: "提示", message: `公告《${this.notice.noticeTitle}》发布成功`, type: "success", }); this.$router.push("/notice/list"); }) } },
到这里我们的公告基本上写完了,我们来测试一下功能。点击编辑完之后,这边数据就会自动填充过来了,说明获取数据没有问题点击发布公告这边数据也都有了,我们修改一下类型改成通知。好啦,此时已经修改好了,我们的公告管理也实现了。
5、修改bug
在查看公告列表的时候,我发现公告的状态始终是关闭的状态,是由于我们在写列表的时候字段还没修改,所以我们去修改一下展示的字段。
<el-table-column align="center" label="状态" > <template slot-scope="scope"> <span>{{ noticeStatus(scope.row.noticeStatus) }}</span> </template> </el-table-column>
noticeStatus方法也要修改一下
noticeStatus(val) { if (val) { return "正常"; } else { return "关闭"; } },
这时我们再去看一下页面,修改一下状态可以发现完美实现了。设置公告的状态是关闭还是打开,这个主要是关乎到公告是否在前端页面展示,我们这个是后台的管理系统,对公告可以控制页面展不展示该公告。
list.vue文件的完整代码:
<template> <el-card class="box-card"> <!-- 设置标题公告管理 --> <div slot="header" class="clearfix"> <span>公告列表</span> </div> <el-table v-loading="listLoading" :data="list" fit highlight-current-row style="width: 98%; margin-top:30px;"> <el-table-column align="center" label="ID" > <template slot-scope="scope"> <span>{{ scope.row.noticeId }}</span> </template> </el-table-column> <el-table-column align="center" label="公告标题" > <template slot-scope="scope"> <span>{{ scope.row.noticeTitle }}</span> </template> </el-table-column> <el-table-column align="center" label="公告类型" > <template slot-scope="scope"> <span>{{filterStatus( scope.row.noticeType )}}</span> </template> </el-table-column> <el-table-column align="center" label="状态" > <template slot-scope="scope"> <span>{{ noticeStatus(scope.row.noticeStatus) }}</span> </template> </el-table-column> <el-table-column align="center" label="创建者" > <template slot-scope="scope"> <span>{{ scope.row.createBy }}</span> </template> </el-table-column> <el-table-column align="center" label="创建时间" > <template slot-scope="scope"> <i class="el-icon-time" style="margin-right:5px" /> <span>{{ scope.row.createTime }}</span> </template> </el-table-column> <el-table-column align="center" label="更新时间" > <template slot-scope="scope"> <i class="el-icon-time" style="margin-right:5px" /> <span>{{ scope.row.updateTime }}</span> </template> </el-table-column> <el-table-column align="center" label="操作" width="180"> <template slot-scope="scope"> <el-button type="primary" size="mini" icon="el-icon-edit" @click="$router.push({name: 'AddNotice', params: { noticeId: scope.row.noticeId }})">编辑</el-button> <el-button type="danger" size="small" icon="el-icon-delete" @click="deleteNoticeById(scope.row.noticeId)" >删除</el-button> </template> </el-table-column> </el-table> <!-- 分页 --> <el-pagination class="pagination-container" background @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="this.listQuery.pageNum" :page-size="this.listQuery.pageSize" :total="count" :page-sizes="[10, 20, 30]" layout="total, sizes, prev, pager, next, jumper" /> </el-card> </template> <script> import { noticeList, deleteNotice } from '@/api/notice' export default { name: 'noticeList', created() { this.getList() }, data() { return { list: null, listLoading: true, count: 0, listQuery: { pageNum: 1, pageSize: 10 }, } }, methods: { getList() { this.listLoading = true var body = this.listQuery; noticeList({body}).then(response => { this.list = response.data.result this.count = response.data.totalSize this.listLoading = false }) }, handleSizeChange(pageSize) { this.listQuery.pageSize = pageSize this.getList() }, handleCurrentChange(pageNum) { this.listQuery.pageNum = pageNum this.getList() }, filterStatus(val) { if (val == "0") { return "公告"; } else if (val == "1") { return "通知"; } else { return "提醒"; } }, noticeStatus(val) { if (val) { return "正常"; } else { return "关闭"; } }, deleteNoticeById (id) { this.$confirm('此操作将永久删除该公告, 是否继续?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { deleteNotice(id).then(response => { this.$message({ type: 'success', message: '删除成功!' }) this.getList() }).catch(() => { console.log('error') }) }).catch(() => { this.$message({ type: 'error', message: '你已经取消删除该公告!' }) }) }, }, } </script> <style rel="stylesheet/scss" lang="scss" scoped> .pagination-container { float: right; margin-top: 1.25rem; margin-bottom: 1.25rem; } .box-card { width: 98%; margin: 1%; } .clearfix:before, .clearfix:after { display: table; content: ""; } .clearfix:after { clear: both } .clearfix span { font-weight: 600; } </style>
add.vue文件的完整代码:
<template> <el-card class="box-card"> <!-- 设置标题公告管理 --> <div slot="header" class="clearfix"> <span>添加公告</span> </div> <!-- 发布文章 --> <div class="article-title-container"> <el-input size="medium" v-model="notice.noticeTitle" placeholder="输入公告标题"/> <el-button type="danger" size="medium" @click="openDialog" style="margin-left:10px">发布公告</el-button> </div> <!-- 公告内容 --> <mavon-editor ref="md" v-model="notice.noticeContent" style="height:calc(100vh - 260px)"/> <!-- 填写信息弹出框 --> <el-dialog :title="`发布公告:${notice.noticeTitle}`" :visible.sync="showDialog" width="30%"> <el-form label-position="left" label-width="80px"> <el-form-item label="公告类型"> <el-select v-model="notice.noticeType" placeholder="请选择公告类型"> <el-option label="公告" :value="0"></el-option> <el-option label="通知" :value="1"></el-option> <el-option label="提醒" :value="2"></el-option> </el-select> </el-form-item> <el-form-item label="状态"> <el-switch v-model="notice.noticeStatus"></el-switch> </el-form-item> </el-form> <span slot="footer"> <el-button @click="handleCancel">取 消</el-button> <el-button type="primary" @click="handleSubmit">发布</el-button> </span> </el-dialog> </el-card> </template> <script> import { addNotice, updateNotice, getNoticeById } from '@/api/notice' export default { name: 'Addnotice', created() { const noticeId = this.$route.params.noticeId; if(noticeId) { getNoticeById(noticeId).then((res) => { this.notice = res.data; }); } }, data() { return { showDialog: false, notice: { noticeContent: "", noticeTitle: "", noticeType: "", noticeStatus: true, noticeId: "" } } }, methods: { assertNotEmpty(target, msg) { if (!target) { this.$message({ message: msg, type: "warning", }); return false; } return true; }, // 打开文章信息填写框 openDialog() { if ( this.assertNotEmpty(this.notice.noticeTitle, "请填写公告标题") && this.assertNotEmpty(this.notice.noticeContent, "请填写公告内容") ) { this.showDialog = true; } }, handleSubmit() { this.showDialog = true; var body = this.notice; if(this.notice.noticeId) { updateNotice(body).then((res) => { this.$notify({ title: "提示", message: `公告《${this.notice.noticeTitle}》更新成功`, type: "success", }); this.$router.push("/notice/list"); }); } else { addNotice(body).then((response) => { this.$notify({ title: "提示", message: `公告《${this.notice.noticeTitle}》发布成功`, type: "success", }); this.$router.push("/notice/list"); }) } }, handleCancel() { this.showDialog = false; }, } } </script> <style rel="stylesheet/scss" lang="scss" scoped> .article-title-container { display: flex; align-items: center; margin-bottom: 1.25rem; margin-top: 1.25rem; } .box-card { width: 98%; margin: 1%; } .clearfix:before, .clearfix:after { display: table; content: ""; } .clearfix:after { clear: both } .clearfix span { font-weight: 600; } </style>
三、标签管理
接下来我们再完成标签管理,标签管理基本上和分类差不多,我们可以参照分类进行编写,大家可以先去写再回过来看看我写的。这里基本上和分类一致,我不再一一的讲解了,我将代码贴出来,作为大家的参考代码。其中修改我们后端的请求方式是put,在前端的api中要以put方式请求,删除为delete请求,这个删除我们不再修改后端的代码,直接在请求地址后边拼接一个id即可,大家再写的时候注意一下,其余的没什么多余的了。
1、tag.js接口
import request from '@/utils/request' export function tagList(query) { return request({ url: '/tag/list', method: 'post', data: query }) } export function addTag(data) { return request({ url: '/tag/create', method: 'post', data }) } export function updateTag(data) { return request({ url: '/tag/update', method: 'put', data }) } export function deleteTag(id) { return request({ url: '/tag/delete/' + id, method: 'delete', }) }
2、list.vue页面
<template> <el-card class="box-card"> <el-button type="primary" size="small" icon="el-icon-plus" @click="transformation(null)">新增标签</el-button> <el-table v-loading="listLoading" :data="list" fit highlight-current-row style="width: 98%; margin-top:30px;"> <el-table-column align="center" label="ID" > <template slot-scope="scope"> <span>{{ scope.row.id }}</span> </template> </el-table-column> <el-table-column align="center" label="标签名称"> <template slot-scope="scope"> <span>{{ scope.row.tagName}}</span> </template> </el-table-column> <el-table-column align="center" label="创建时间"> <template slot-scope="scope"> <i class="el-icon-time" style="margin-right:5px" /> <span>{{ scope.row.createTime}}</span> </template> </el-table-column> <el-table-column align="center" label="更新时间"> <template slot-scope="scope"> <i class="el-icon-time" style="margin-right:5px" /> <span>{{ scope.row.updateTime}}</span> </template> </el-table-column> <el-table-column align="center" label="操作" width="180"> <template slot-scope="scope"> <el-button type="primary" size="mini" icon="el-icon-edit" @click="transformation(scope.row)">编辑</el-button> <el-button type="danger" size="small" icon="el-icon-delete" @click="deleteTagById(scope.row.id)">删除</el-button> </template> </el-table-column> </el-table> <!-- 分页 --> <el-pagination class="pagination-container" background @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="this.listQuery.pageNum" :page-size="this.listQuery.pageSize" :total="count" :page-sizes="[10, 20, 30]" layout="total, sizes, prev, pager, next, jumper" /> <!-- 添加或修改标签对话框 --> <el-dialog :visible.sync="addOrupdateDialogVisible" width="30%"> <div class="dialog-title-container" slot="title" ref="tagTitle" /> <el-form label-width="100px" size="medium" :model="tagForm"> <el-form-item label="标签名称:"> <el-input v-model="tagForm.tagName" style="width:220px" /> </el-form-item> </el-form> <div slot="footer"> <el-button @click="addOrupdateDialogVisible = false">取 消</el-button> <el-button type="primary" @click="addTag"> 确 定 </el-button> </div> </el-dialog> </el-card> </template> <script> import { tagList, addTag, updateTag, deleteTag } from '@/api/tag' export default { name: 'TagList', created() { this.getList() }, data() { return { list: null, listLoading: true, count: 0, listQuery: { pageNum: 1, pageSize: 10 }, addOrupdateDialogVisible: false, tagForm: { id: null, tagName: "" }, } }, methods: { getList() { this.listLoading = true var body = this.listQuery; tagList({body}).then(response => { this.list = response.data.result this.count = response.data.totalSize this.listLoading = false }) }, transformation(tag) { if (tag != null) { this.tagForm = JSON.parse(JSON.stringify(tag)); this.$refs.tagTitle.innerHTML = "修改标签"; } else { this.tagForm.id = null; this.tagForm.tagName = ""; this.$refs.tagTitle.innerHTML = "添加标签"; } this.addOrupdateDialogVisible = true; }, addTag() { if (this.tagForm.tagName.trim() == "") { this.$message.error("标签名不能为空"); return false; } var body = this.tagForm; if(body.id == null){ addTag(body).then(response => { this.$message({ type: 'success', message: '添加标签成功!' }) this.getList() }).catch(() => { console.log('error') }) } else { updateTag(body).then(response => { this.$message({ type: 'success', message: '修改标签成功!' }) this.getList() }).catch(() => { console.log('error') }) } this.addOrupdateDialogVisible = false; }, deleteTagById (id) { this.$confirm('此操作将永久删除该标签, 是否继续?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { deleteTag(id).then(response => { this.$message({ type: 'success', message: '删除成功!' }) this.getList() }).catch(() => { console.log('error') }) }).catch(() => { this.$message({ type: 'error', message: '你已经取消删除该标签!' }) }) }, handleSizeChange(pageSize) { this.listQuery.pageSize = pageSize this.getList() }, handleCurrentChange(pageNum) { this.listQuery.pageNum = pageNum this.getList() } } } </script> <style rel="stylesheet/scss" lang="scss" scoped> .pagination-container { float: right; margin-top: 1.25rem; margin-bottom: 1.25rem; } .box-card { width: 98%; margin: 1%; } .clearfix:before, .clearfix:after { display: table; content: ""; } .clearfix:after { clear: both } .clearfix span { font-weight: 600; } </style>
写完之后,跑起来测一下增删改查即可,如有bug大家给我留言。
四、总结
好啦!这次就写到这里吧,熬了几夜终于搞完了,大家打开自己的系统是不是有点成就感了,或许这就是梦想开始的起点。我们还有控制台、文章管理两大块没有写,下一篇基本是可以结束了,但不排除我再加点新的东西,哈哈。小伙伴们加油吧,走到这一步不容易,你会为你的坚持感到骄傲。