Springboot3+vue3实现系统公告功能

创建系统公告表

CREATE TABLE `notice` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `title` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '公告标题',
  `content` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '公告内容',
  `time` datetime DEFAULT NULL COMMENT '发布时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='系统公告表';

Notice 管理页面 和 相关接口

页面 Notice.vue

<template>
  <div>
    <div class="card" style="margin-bottom: 5px">
      <el-input clearable @clear="load" style="width: 260px;margin-right: 5px" v-model="data.title" placeholder="请输入标题查询" :prefix-icon="Search"></el-input>
      <el-button type="primary" @click="load">查 询</el-button>
      <el-button @click="reset">重 置</el-button>
    </div>

    <div class="card" style="margin-bottom: 5px">
      <el-button type="primary" @click="handleAdd">新 增</el-button>
    </div>

    <div class="card" style="margin-bottom: 5px">
      <el-table :data="data.tableData" style="width: 100%" :header-cell-style="{color:'#333',backgroundColor:'#eaf4ff'}">
        <el-table-column prop="title" label="公告标题" />
        <el-table-column prop="content" label="公告内容" />
        <el-table-column prop="time" label="发布时间" />
        <el-table-column label="操作" width="100">
          <template #default="scope">
            <el-button type="primary" icon="Edit" circle @click="handleEdit(scope.row)"></el-button>
            <el-button type="danger" icon="Delete" circle @click="del(scope.row.id)"></el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>

    <el-dialog title="公告信息"  v-model="data.formVisible" width="30%" destroy-on-close>
      <el-form ref="formRef":model="data.form" :rules="data.rules" label-width="80px" style="padding: 20px 30px 10px 0">
        <el-form-item prop="title" label="公告标题">
          <el-input v-model="data.form.title" autocomplete="off" placeholder="请输入公告标题"/>
        </el-form-item>
        <el-form-item prop="content" label="公告内容">
          <el-input type="textarea" :rows="3" v-model="data.form.content" autocomplete="off" placeholder="请输入公告内容"/>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="data.formVisible = false">取 消</el-button>
          <el-button type="primary" @click="save">保 存</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import {Search} from "@element-plus/icons-vue";
import {reactive, ref} from "vue";
import request from "@/utils/request.js";
import {ElMessage, ElMessageBox} from "element-plus";


const formRef = ref()

const data = reactive({
  user: JSON.parse(localStorage.getItem('code_user') || '{}'),
  title: null,
  pageNum:1,
  pageSize:5,
  total:0,
  tableData:[],
  form:{},
  formVisible:false,
  rules:{
    title:[
      {required:true,message:'请填写公告标题',trigger:'blur'}
    ],
    content:[
      {required:true,message:'请填写公告内容',trigger:'blur'}
    ],
  }
})

const load = () => {
  request.get('/notice/selectPage',{
    params:{
      pageNum:data.pageNum,
      pageSize:data.pageSize,
      title:data.title
    }
  }).then(res => {
    if(res.code === '200'){
      data.tableData =res.data?.list//? 防止为空
      data.total = res.data?.total
    }else {
      ElMessage.error(res.msg)
    }
  })
}
load()

const handleAdd = () => {
  data.form = {}
  data.formVisible = true
}

const handleEdit = (row) => {
  data.form = JSON.parse(JSON.stringify(row))
  data.formVisible = true
}

const add = () => {
  request.post('/notice/add',data.form).then(res =>{
    if (res.code === '200'){
      ElMessage.success('新增成功')
      data.formVisible = false
      load()
    }else {
      ElMessage.error(res.msg)
    }
  })
}

const update = () => {
  request.put('notice/update',data.form).then(res => {
    if (res.code === '200'){
      ElMessage.success('更新成功')
      data.formVisible = false
      load()
    }else {
      ElMessage.error(res.msg)
    }
  })
}

const save = () => {
  formRef.value.validate(valid => {
    if(valid){
      data.form.id ? update() : add()
    }
  })
}

const del = (id) => {
  ElMessageBox.confirm('删除后无法恢复,您确认删除吗?','删除确认',{type:'warning'}).then(res => {
    request.delete('/notice/delete/'+ id).then(res => {
      if (res.code === '200') {
        ElMessage.success('删除成功')
        load()
      } else {
        ElMessage.error(res.msg)
      }
    })
  }).catch(err => {})
}
const reset = () => {
  data.title = null
  load()
}
</script>

相关接口

Notice.java

package com.example.entity;

/**
 * 系统公告信息
 */
public class Notice {
    private int id;
    private String title;
    private String content;
    private String time;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getTime() {
        return time;
    }

    public void setTime(String time) {
        this.time = time;
    }
}

NoticeController

package com.example.controller;

import com.example.common.Result;
import com.example.entity.Notice;
import com.example.service.NoticeService;
import com.github.pagehelper.PageInfo;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/notice")
public class NoticeController {

    @Resource
    NoticeService noticeService;

    @PostMapping("/add")
    public Result add(@RequestBody Notice notice) {//@RequestBody 接受前端传来的 json 参数
        noticeService.add(notice);
        return Result.success();
    }

    @PutMapping("/update")
    public Result update(@RequestBody Notice notice) {
        noticeService.update(notice);
        return Result.success();
    }

    @DeleteMapping("/delete/{id}")
    public Result delete(@PathVariable Integer id) {//@PathVariable 接受前端传来的路径参数
        noticeService.deleteById(id);
        return Result.success();
    }

    @GetMapping("/selectAll") //完整的请求路径: http:/ip:port/notice/selectAll
    public Result selectAll() {
        List<Notice> noticeList = noticeService.selectAll();
        return Result.success(noticeList);
    }

    /**
     * 分页查询
     * pageNum:当前的页码
     * pageSize:每页的个数
     */
    @GetMapping("/selectPage")
    public Result selectPage(@RequestParam(defaultValue = "1") Integer pageNum,
                             @RequestParam(defaultValue = "10") Integer pageSize,
                             Notice notice) {
       PageInfo<Notice> pageInfo = noticeService.selectPage(pageNum,pageSize,notice);
        return Result.success(pageInfo);//返回的是分页的对象
    }
}

NoticeService

package com.example.service;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.example.entity.Account;
import com.example.entity.Notice;
import com.example.exception.CustomerException;
import com.example.mapper.NoticeMapper;
import com.example.utils.TokenUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class NoticeService {
    @Resource
    NoticeMapper noticeMapper;


    public void add(Notice notice) {
        notice.setTime(DateUtil.now());
        noticeMapper.insert(notice);
    }

    public void update(Notice notice) {
        noticeMapper.updateById(notice);
    }

    public void deleteById(Integer id) {
        noticeMapper.deleteById(id);
    }



    public List<Notice> selectAll(){

        return noticeMapper.selectAll(null);
    }

    public PageInfo<Notice> selectPage(Integer pageNum, Integer pageSize,Notice notice) {
        //开启分页查询
        PageHelper.startPage(pageNum, pageSize);
        List<Notice> list = noticeMapper.selectAll(notice);
        return PageInfo.of(list);
    }
    
}

NoticeMapper

package com.example.mapper;

import com.example.entity.Notice;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface NoticeMapper {

    List<Notice> selectAll(Notice notice);

    void insert(Notice notice);

    void updateById(Notice notice);

    @Delete("delete  from `notice` where id = #{id}")
    void deleteById(Integer id);

    
}

NoticeMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.NoticeMapper">

    <select id="selectAll" resultType="com.example.entity.Notice">
        select * from `notice`
        <where>
            <if test="title != null">and title like concat('%', #{title}, '%')</if> <!-- 相当于 like '%1%'-->
        </where>
        order by id desc
    </select>

    <insert id="insert">
        insert into `notice` (title,content,time)
        values(#{title},#{content},#{time})
    </insert>

    <update id="updateById">
        update `notice` set title = #{title},content = #{content},time = #{time}
        where id = #{id}
    </update>
</mapper>

公告首页渲染

Home.vue

<template>
  <div>
    <div class="card">你好,同学</div>
    <div class="card" style="margin-top: 10px;">
      <div style="font-size: 16px;margin-bottom: 20px">系统公告</div>
      <el-timeline>
        <el-timeline-item :timestamp="item.time" placement="top" v-for="item in data.noticeData">
          <el-card>
            <h4>{{item.title}}</h4>
            <p>{{item.content}}</p>
          </el-card>
        </el-timeline-item>
      </el-timeline>
    </div>
  </div>
</template>
<script setup>

import {reactive} from "vue";
import {ElMessage} from "element-plus";
import request from "@/utils/request.js";

const data = reactive({
  user: JSON.parse(localStorage.getItem('code_user') || '{}'),
  noticeData:[]
})

const loadNotice = () => {
  request.get('notice/selectAll').then(res => {
    if (res.code === '200'){
      data.noticeData = res.data
      if (data.noticeData.length > 3){
        data.noticeData = data.noticeData.slice(0,3)
      }
    }else {
      ElMessage.error(res.msg)
    }
  })
}
loadNotice()
</script>
posted @ 2026-02-25 22:36  坚持努力学习ing  阅读(0)  评论(0)    收藏  举报