概述
效果图

数据库设计
DROP TABLE IF EXISTS `announcement`;
CREATE TABLE `announcement` (
`announcementId` int(11) NOT NULL AUTO_INCREMENT,
`announcementTitle` varchar(255) DEFAULT NULL,
`announcementTime` varchar(255) DEFAULT NULL,
`announcementContent` longtext,
PRIMARY KEY (`announcementId`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;
实体类设计
public class Announcement implements Serializable {
private Integer announcementId;
private String announcementTitle;//标题
private String announcementTime;//时间
private String announcementContent;//内容
Mapper层开发
public interface AnnouncementMapper extends BaseMapper<Announcement> {
Service层开发
AnnouncementService
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jkw.pojo.Announcement;
public interface AnnouncementService {
void add(Announcement announcement);
void update(Announcement announcement);
Announcement findById(Integer id);
Page
search(String search, int page, int size);
AnnouncementServiceImpl
package jkw.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jkw.mapper.AnnouncementMapper;
import jkw.pojo.Announcement;
import jkw.service.AnnouncementService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
public class AnnouncementServiceImpl implements AnnouncementService {
private AnnouncementMapper announcementMapper;
public void add(Announcement announcement) {
announcementMapper.insert(announcement);
public void update(Announcement announcement) {
announcementMapper.updateById(announcement);
public void delete(Integer id) {
announcementMapper.deleteById(id);
public Announcement findById(Integer id) {
return announcementMapper.selectById(id);
public List<Announcement> findAll() {
return announcementMapper.selectList(null);
public Page<Announcement> search(String search, int page, int size) {
QueryWrapper queryWrapper = new QueryWrapper();
return announcementMapper.selectPage(new Page<>(page, size), queryWrapper);

控制层开发
AnnouncementCon
package jkw.controller.back;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jkw.pojo.Announcement;
import jkw.service.AnnouncementService;
import jkw.vo.BaseResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
@RequestMapping("/back/announcement")
public class AnnouncementCon {
private AnnouncementService announcementService;
@PreAuthorize("hasAnyAuthority('/website/announcement')")
public BaseResult add(Announcement announcement) {
announcementService.add(announcement);
@PreAuthorize("hasAnyAuthority('/website/announcement')")
public BaseResult update(Announcement announcement) {
announcementService.update(announcement);
@DeleteMapping("/delete")
@PreAuthorize("hasAnyAuthority('/website/announcement')")
public BaseResult delete(Integer announcementId) {
announcementService.delete(announcementId);
@PreAuthorize("hasAnyAuthority('/website/announcement')")
public BaseResult findById(Integer announcementId) {
Announcement announcement = announcementService.findById(announcementId);
return BaseResult.ok(announcement);
@PreAuthorize("hasAnyAuthority('/website/announcement')")
public BaseResult findAll() {
List<Announcement> all = announcementService.findAll();
return BaseResult.ok(all);
@PreAuthorize("hasAnyAuthority('/website/announcement')")
public BaseResult search(String search, int page, int size) {
Page<Announcement> brandPage = announcementService.search(search, page, size);
return BaseResult.ok(brandPage);

后台ui设计
<div class="data-container">
<div class="data-header">
<el-input class="input" @keyup.enter="searchHandle" v-model="searchInfo" size="large"
placeholder="请输入关键字"></el-input>
<el-button @click="searchHandle" class="button" size="large" type="primary" plain>搜索</el-button>
<el-button round @click="addHander" size="large" type="primary">
<el-table :data="dataList.list" style="width: 700px;">
<el-table-column show-overflow-tooltip label="标题" prop="announcementTitle" align="center"></el-table-column>
<el-table-column align="center" :formatter="value => detaFormater(Number(value.announcementTime))" prop="announcementTime" label="时间" width="100"/>
<el-table-column label="操作" align="center" width="220">
<template #default="scope">
<el-button size="small" type="primary" @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
<el-button size="small" type="danger" @click="handleDelete(scope.$index, scope.row)">删除</el-button>
<el-pagination background
layout="prev,pager,next,jumper"
:default-page-size="defaultPageSize"
@current-change="currentChangeHaddler"></el-pagination>
<el-dialog draggable destroy-on-close v-model="dialogAddVisible" title="添加" width="70%" center>
<el-form inline :model="addFormInfo" label-width="150px">
<el-form-item label="标题">
<el-input v-model="addFormInfo.announcementTitle"></el-input>
<el-form-item label="时间">
<el-date-picker value-format="x" v-model="addFormInfo.announcementTime" type="date"></el-date-picker>
<el-form-item label="内容">
<el-input type="textarea" rows="6" style="width: 800px" v-model="addFormInfo.announcementContent"></el-input>
<span class="dialog-footer">
<el-button @click="dialogAddVisible = false">取消</el-button>
<el-button type="primary" @click="sureHandler">确定</el-button>
<!--destroy-on-close:每次关闭对话框时直接销毁对话框,没有缓存-->
v-model="dialogEditorVisible"
<el-form inline :model="editorFormInfo" label-width="150px">
<el-form-item label="标题">
<el-input v-model="editorFormInfo.announcementTitle"></el-input>
<el-form-item label="时间">
<el-date-picker value-format="x" v-model="editorFormInfo.announcementTime" type="date"></el-date-picker>
<el-form-item label="内容">
<el-input type="textarea" rows="6" style="width: 800px" v-model="editorFormInfo.announcementContent"></el-input>
<span class="dialog-footer">
<el-button @click="dialogEditorVisible = false">取消</el-button>
<el-button type="primary" @click="sureEditorHandler">确定</el-button>
import axios from "../../api/index.js"
import {onMounted, reactive, ref} from "vue";
import {ElMessage} from "element-plus";
import {detaFormater} from "@/utils/utils.js"
const dataList = reactive({
const currentPage = ref(1)
const defaultPageSize = ref(10)
const searchInfo = ref("")
const dialogAddVisible = ref(false)
const addFormInfo = reactive({
const dialogEditorVisible = ref(false)
const editorFormInfo = reactive({
const http = (search, page, size) => {
axios.announcement_search({
if (res.data.code == 200) {
dataList.list = res.data.data.records
totalData.value = res.data.data.total
ElMessage.error(res.data.message)
http(searchInfo.value, currentPage.value, defaultPageSize.value)
const currentChangeHaddler = (nowPage) => {
http(searchInfo.value, nowPage, defaultPageSize.value)
currentPage.value = nowPage
const searchHandle = () => {
http(searchInfo.value, currentPage.value, defaultPageSize.value)
const addHander = () => {
dialogAddVisible.value = true
const sureHandler = () => {
announcementTitle: addFormInfo.announcementTitle,
announcementTime: addFormInfo.announcementTime,
announcementContent: addFormInfo.announcementContent,
if (res.data.code == 200) {
dialogAddVisible.value = false
http(searchInfo.value, currentPage.value, defaultPageSize.value)
ElMessage.error(res.data.message)
const handleEdit = (index, row) => {
dialogEditorVisible.value = true
axios.announcement_findById({
announcementId: row.announcementId
if (res.data.code == 200) {
editorFormInfo.announcementId = res.data.data.announcementId;
editorFormInfo.announcementTitle = res.data.data.announcementTitle;
editorFormInfo.announcementTime = res.data.data.announcementTime;
editorFormInfo.announcementContent = res.data.data.announcementContent;
ElMessage.error(res.data.data.message)
const sureEditorHandler = () => {
axios.announcement_update({
announcementId: editorFormInfo.announcementId,
announcementTitle: editorFormInfo.announcementTitle,
announcementTime: editorFormInfo.announcementTime,
announcementContent: editorFormInfo.announcementContent,
if (res.data.code == 200) {
dialogEditorVisible.value = false
http(searchInfo.value, currentPage.value, defaultPageSize.value)
ElMessage.error(res.data.message)
const handleDelete = (index, row) => {
axios.announcement_delete({
announcementId: row.announcementId
if (res.data.code == 200) {
http(searchInfo.value, currentPage.value, defaultPageSize.value)
message: res.data.message,
background: linear-gradient(left, rgb(89, 234, 233) 27%, rgb(131, 231, 218) 44%, rgb(69, 150, 216) 88%);
background: -o-linear-gradient(left, rgb(89, 234, 233) 27%, rgb(131, 231, 218) 44%, rgb(69, 150, 216) 88%);
background: -ms-linear-gradient(left, rgb(89, 234, 233) 27%, rgb(131, 231, 218) 44%, rgb(69, 150, 216) 88%);
background: -moz-linear-gradient(left, rgb(89, 234, 233) 27%, rgb(131, 231, 218) 44%, rgb(69, 150, 216) 88%);
background: -webkit-linear-gradient(left, rgb(89, 234, 233) 27%, rgb(131, 231, 218) 44%, rgb(69, 150, 216) 88%);
