springboot+vue 实现系统公告页面

本文档展示了如何使用SpringBoot后端和Vue前端实现一个系统公告管理页面。功能包括公告录入、发布、查询和详情展示。前端通过表单输入、日期选择器和分页组件实现数据交互,后端提供了更新发布和撤销的操作接口,以及已发布公告的查询接口,数据按时间排序并支持分页。
摘要由CSDN通过智能技术生成

前言

                近期根据工作需求做了一个系统公告页面,这里我们通过springboot+vue实现这个系统公告页面,主要设计的功能有

  1. 公告录入

    这一块就是一个数据新增页面,前端获取的数据通过后端存储到数据库

  2. 公告发布

    公告录入时默认状态为未发布,即通过状态码实现公告的发布和实现 0:未发布,1:发布,2:撤销,页面上添加一个发布按钮,根据公告发布状态的值选择是否显示这个按钮,发布即执行数据更新操作,即将状态码更新为1

     

     

     

     

     

     

  3. 公告查询

    根据公告数据状态查询已发布数据,按时间排序,页面实现查询和分页

  4. 详情公告页

    这页面是通过通用详情页模板,传递参数实现公告详情展示

    前端vue代码


    <template>
      <a-card :bordered="false">
    
          <div class="page-recerive">
    
              <div  class="common_nav" >
                <h1  class="nav_title" >通知公告</h1>
    
              </div>
              <div class="content" >
                  <div class="title"><h2 >通知公告浏览</h2></div>
                <!--查询-->
                  <div data-v-47fc369c="" class="tool" style="margin-left: 25px;">
                    <div  class="search" style="position: relative;float: left;">
                      <input data-v-47fc369c="" type="text" v-bind:value="title" placeholder="请输入标题" @change="TitleInput" style="height: 36px;color: black;font-weight: bolder;">
    
                    </div>
    
                    <div  class="el-select " style="float: left;line-height: 34px;margin-left: 15px;  display: inline-block;position: relative;">
                      <a-date-picker  @change="DateInput" v-bind:value="time" style="color: black;font-weight: bolder;"/>
                    </div>
                    <div style="float: left;line-height: 34px;margin-left: 25px;    display: inline-block;position: relative;">
                      <a-button  style="background-color: #1a3c8e;border-color: #1a3c8e;" type="primary" @click="searchQuery" icon="search">查询</a-button>
                      <a-button style="background-color: #1a3c8e; margin-left: 15px;border-color: #1a3c8e;" type="primary" @click="searchReset" icon="reload" >重置</a-button>
                    </div>
                  </div>
                <!--数据-->
                <div class="result" >
                  <table>
                    <thead class="row-title" >
                    <td style="width: 40%">公告标题</td>
                    <td style="width: 20%">发布部门</td>
                    <td style="width: 10%">发布时间</td>
                    </thead>
                    <tbody v-for="item in dataList">
                    <tr class="row-body" >
                      <td ><router-link  style="color:black" target="_blank" :to="{path:'../CtNoticeDetail',query:{id:item.id,company:item.company_dictText}}"><span class="box">♦</span>{{item.title}}</router-link></td>
                      <td><p class="company" >{{item.company_dictText}}</p></td>
                      <td><p class="senddate" >{{item.senddate}}</p></td>
                    </tr>
                    </tbody>
                  </table>
                </div>
                <!--数据分页-->
                <div class="page-bar" style="margin:40px auto;margin-top: 50px;">
                  <ul>
                    <li v-if="cur>1"><a v-on:click="cur--,pageClick()">上一页</a></li>
                    <li v-if="cur==1"><a class="banclick">上一页</a></li>
                    <li v-for="index in indexs" v-bind:class="{ 'active': cur == index}">
                      <a v-on:click="btnClick(index)">{{ index }}</a>
                    </li>
                    <li v-if="cur!=all"><a v-on:click="cur++,pageClick()">下一页</a></li>
                    <li v-if="cur == all"><a class="banclick">下一页</a></li>
                    <li><a>共<i>{{all}}</i>页</a></li>
                  </ul>
                </div>
    
          </div>
        </div>
      </a-card>
    </template>
    
    <script>
    
      import '@/assets/less/TableExpand.less'
      import { mixinDevice } from '@/utils/mixin'
      import { JeecgListMixin } from '@/mixins/JeecgListMixin'
      import CtNoticeModal from './modules/CtNoticeModal'
      import {filterMultiDictText} from '@/components/dict/JDictSelectUtil'
      import {doRelease, doReovke} from '@/api/api'     //.set('@api', resolve('src/api')) 表示@api指的是“src/api”
      import {getAction} from "@/api/manage";
    
      export default {
        name: 'CtNoticeList',
        mixins:[JeecgListMixin, mixinDevice],
        components: {
          CtNoticeModal
        },
        data () {
          return {
            title:'',
            time:'',
            params:{
              pageNo: 1,
              pageSize: 10,
              title:"",
              senddate:"",
            },
            description: '公告查询页面',
            release_url:"/ctms/ctNotice/ReleaveData"  ,//公告地址
            dataList:"",
            all:"",  //总页数
            cur:"",  //当前页数
            totalpage:"" ,//当前条数
            url: {
              list: "/ctms/ctNotice/ReleaveData"
            },
            dictOptions:{},
            superFieldList:[],
          }
        },
    
        methods: {
    
          //请求数据
    
              loadData(){
                getAction(this.release_url,this.params).then((res)=>{
                  this.dataList=[];
                  for(let i=0;i<res.result.records.length;i++){
                    this.dataList.push(res.result.records[i])
                  }
                  this.all = res.result.pages;
                  this.cur = res.result.current;
                  this.totalpage = res.result.total;
    
                })
                },
          
          searchReset(){
    
              this.params.senddate='';
              this.params.title = '';
              this.params.pageNo = 1;
              this.params.pageSize = 10;
              this.title = '';
              this.time = '';
    
            getAction(this.release_url,this.params).then((res)=>{
              this.dataList=[];
              for(let i=0;i<res.result.records.length;i++){
                this.dataList.push(res.result.records[i])
              }
              this.all = res.result.pages;
              this.cur = res.result.current;
              this.totalpage = res.result.total;
    
            })
    
          },
          //查询值
          TitleInput(value){
            this.params.title = value.target.value;
            this.title = value.target.value;
    
          },
    
          //查询值
          DateInput(date, dateString){
            this.params.senddate = dateString;
            this.time = dateString;
    
          },
    
          //分页
          btnClick: function(data){//页码点击事件
            if(data != this.cur){
              this.cur = data
            }
          //根据点击页数请求数据
            this.params.pageNo = this.cur
            this.loadData();
          },
    
          pageClick: function(){
          //根据点击页数请求数据
            this.params.pageNo = this.cur
            this.loadData();
          }
    
    
        },
    
        computed: {
    //分页
          indexs: function(){
            var left = 1;
            var right = this.all;
            var ar = [];
            if(this.all>= 5){
              if(this.cur > 3 && this.cur < this.all-2){
                left = this.cur - 2
                right = this.cur + 2
              }else{
                if(this.cur<=3){
                  left = 1
                  right = 5
                }else{
                  right = this.all
                  left = this.all -4
                }
              }
            }
            while (left <= right){
              ar.push(left)
              left ++
            }
            return ar
          }
        },
        created() {
          //调用方法
          this.loadData();
        },
    
      }
    </script>
    <style scoped>
      @import '~@assets/less/common.less';
    
    
      /*公告浏览页面*/
      .page-recerive{
    
        width: 80%;
        height:650px;
        margin-left:10%;
        box-sizing: border-box;
        background: #fff;
        box-shadow: 0 0 20px;
    
      }
    
      /*右侧*/
      .common_nav{
    
        width: 165px;
        height: 100%;
        float: left;
        background: #393b5d;
    
      }
    
      .nav_title{
        padding: 30px 0 24px 24px;
        font-size: 20px;
        font-weight: 400;
        color: #fff;
        border: 0;
        background: #4b4d6e;
        outline: none;
      }
      .content{
        padding-bottom: 30px;
        margin-left: 170px;
        padding: 10px;
        height: 98%;
        position: relative;
    
      }
      .content .title h2{
        font-size: 16px;
        margin-top: 20px;
        font-weight: bold;
      }
      .content .result{
        height: calc(100% - 170px);
        margin-top: 5%;
      }
      .content .result .row-title{
        font-size: 18px;
        font-weight: bold;
        color: #1a3c8e;
        text-align: left;
        padding: 0 10px;
        line-height: 40px;
        border-bottom: 0.5px solid #1a3c8e;
      }
    
      .content .result .row-body{
        margin-left: 30px;
        color: black;
        font-size: 16px;
        border-bottom: 0.5px solid #ececec;
        align-items: center;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        background: #f3f6f9;
        margin-bottom: 6px;
        font-style: normal;
      }
    
      .content .result .row-body .box{
        color: #fff;
        display: inline-block;
        background: #5487c7;
        width: 24px;
        height: 24px;
        line-height: 24px;
        text-align: center;
        margin-right: 6px;
      }
    
    
      /*分页*/
      .page-bar{
        margin:40px auto;
        margin-top: 150px;
    
    
      }
      ul,li{
        margin: 0px;
        padding: 0px;
      }
      li{
        list-style: none
      }
      .page-bar li:first-child>a {
        margin-left: 0px
      }
      .page-bar a{
        border: 1px solid #ddd;
        text-decoration: none;
        position: relative;
        float: left;
        padding: 6px 12px;
        margin-left: -1px;
        line-height: 1.42857143;
        color: #5D6062;
        cursor: pointer;
        margin-right: 20px;
      }
      .page-bar a:hover{
        background-color: #eee;
      }
      .page-bar a.banclick{
        cursor:not-allowed;
      }
      .page-bar .active a{
        color: #fff;
        cursor: default;
        background-color: #1a3c8e;
        border-color: #1a3c8e;
      }
      .page-bar i{
        font-style:normal;
        color: #1a3c8e;
        margin: 0px 4px;
        font-size: 12px;
      }
    </style>

     java后端代码


    Controller的发布和查询部分
    /**
    	  *	 更新发布操作
    	  * @param id
    	  * @return
    	  */
    	 @RequestMapping(value = "/doRelease", method = RequestMethod.GET)
    	 public Result<CtNotice> doRelease(@RequestParam(name="id",required=true) String id, HttpServletRequest request) {
    		 Result<CtNotice> result = new Result<CtNotice>();
    		 CtNotice ctNotice = ctNoticeService.getById(id);
    		 if (ctNotice == null) {
    			 result.error500("未找到对应实体");
    		 } else {
    			 ctNotice.setSendStatus(CommonSendStatus.PUBLISHED_STATUS_1);//发布中
    			 ctNotice.setSenddate(new Date());
    			 String currentUserName = JwtUtil.getUserNameByToken(request);
    			 ctNotice.setCreateBy(currentUserName);
    			 boolean ok = ctNoticeService.updateById(ctNotice);
    			 if (ok) {
    				 result.success("公告发布成功");
    			 }
    		 }
    		 return result;
    
    	 }
    	 /**
    	  *	 更新撤销操作
    	  * @param id
    	  * @return
    	  */
    	 @RequestMapping(value = "/doReovke", method = RequestMethod.GET)
    	 public Result<CtNotice> doReovke(@RequestParam(name="id",required=true) String id, HttpServletRequest request) {
    		 Result<CtNotice> result = new Result<CtNotice>();
    		 CtNotice ctNotice = ctNoticeService.getById(id);
    		 if(ctNotice==null) {
    			 result.error500("未找到对应实体");
    		 }else {
    			 ctNotice.setSendStatus(CommonSendStatus.REVOKE_STATUS_2);//撤销发布
    //			 ctNotice.setCancelTime(new Date());
    			 boolean ok = ctNoticeService.updateById(ctNotice);
    			 if(ok) {
    				 result.success("公告撤销成功");
    			 }
    		 }
    
    		 return result;
    	 }
    
    //	 //获取已发布数据
    	 @RequestMapping(value = "/ReleaveData",method = RequestMethod.GET)
    	 public Result<?> testData(CtNotice ctNotice,
    			 @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
    			 @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
    			 HttpServletRequest req) {
    //		 QueryWrapper<CtNotice> queryWrapper = new QueryWrapper<>();
    		 QueryWrapper<CtNotice> queryWrapper = QueryGenerator.initQueryWrapper(ctNotice, req.getParameterMap());
    		 queryWrapper.eq("send_status","1");
    		 queryWrapper.orderByDesc("senddate");
    		 Page<CtNotice> page = new Page<CtNotice>(pageNo, pageSize);
    		 IPage<CtNotice> pageList = ctNoticeService.page(page, queryWrapper);
    		 System.out.println(pageList);
    		 return Result.OK(pageList);
    
    	 }
实现公告的功能需要前端和后端配合完成,在此我提供一种使用Spring BootVue.js实现公告的思路。 1. 后端实现 使用Spring Boot开发后端,需要定义公告的数据模型,如: ```java @Entity @Table(name = "announcement") public class Announcement { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String title; private String content; @Column(name = "create_time") private Date createTime; // getter 和 setter 方法 } ``` 然后,使用Spring Data JPA来访问数据库,定义对应的Repository: ```java public interface AnnouncementRepository extends JpaRepository<Announcement, Long> { List<Announcement> findAllByOrderByCreateTimeDesc(); } ``` 在Controller中,提供查询公告列表和新增公告的接口: ```java @RestController @RequestMapping("/api/announcement") public class AnnouncementController { @Autowired private AnnouncementRepository repository; @GetMapping("/list") public List<Announcement> list() { return repository.findAllByOrderByCreateTimeDesc(); } @PostMapping("/add") public Announcement add(@RequestBody Announcement announcement) { announcement.setCreateTime(new Date()); return repository.save(announcement); } } ``` 2. 前端实现 使用Vue.js开发前端,通过axios库访问后端API,实现公告的展示和添功能。 在Vue组件中,使用data属性存储公告列表和新增公告的表单数据: ```javascript data() { return { announcements: [], newAnnouncement: { title: '', content: '' } } }, ``` 在created钩子函数中,使用axios库获取公告列表: ```javascript created() { axios.get('/api/announcement/list').then(response => { this.announcements = response.data }) }, ``` 在模板中,使用v-for指令渲染公告列表: ```html <template> <div> <h2>公告列表</h2> <div v-for="announcement in announcements" :key="announcement.id"> <h3>{{ announcement.title }}</h3> <p>{{ announcement.content }}</p> <small>{{ announcement.createTime }}</small> </div> <h2>新增公告</h2> <form @submit.prevent="addAnnouncement"> <div> <label>标题:</label> <input v-model="newAnnouncement.title" type="text" /> </div> <div> <label>内容:</label> <textarea v-model="newAnnouncement.content"></textarea> </div> <button type="submit">提交</button> </form> </div> </template> ``` 在methods属性中,定义addAnnouncement方法,通过axios库向后端API发送POST请求,添公告: ```javascript methods: { addAnnouncement() { axios.post('/api/announcement/add', this.newAnnouncement).then(response => { this.announcements.unshift(response.data) this.newAnnouncement.title = '' this.newAnnouncement.content = '' }) } } ``` 以上就是使用Spring BootVue.js实现公告的思路,具体实现细节可以根据实际情况进行调整。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值