因为之前没有记录,所以还要看代码进行寻找,比较费劲,所以今天记录一下:
1、后端
SysAnnouncementController
下面函数增加待办的几个显示内容给前端用
具体代码如下:
/** * @功能:补充用户数据,并返回系统消息 * @return */ @RequestMapping(value = "/listByUser", method = RequestMethod.GET) public Result<Map<String, Object>> listByUser(@RequestParam(required = false, defaultValue = "5") Integer pageSize) { Result<Map<String,Object>> result = new Result<Map<String,Object>>(); LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal(); String userId = sysUser.getId(); // 1.将系统消息补充到用户通告阅读标记表中 LambdaQueryWrapper<SysAnnouncement> querySaWrapper = new LambdaQueryWrapper<SysAnnouncement>(); querySaWrapper.eq(SysAnnouncement::getMsgType,CommonConstant.MSG_TYPE_ALL); // 全部人员 querySaWrapper.eq(SysAnnouncement::getDelFlag,CommonConstant.DEL_FLAG_0.toString()); // 未删除 querySaWrapper.eq(SysAnnouncement::getSendStatus, CommonConstant.HAS_SEND); //已发布 querySaWrapper.ge(SysAnnouncement::getEndTime, sysUser.getCreateTime()); //新注册用户不看结束通知 //update-begin--Author:liusq Date:20210108 for:[JT-424] 【开源issue】bug处理-------------------- querySaWrapper.notInSql(SysAnnouncement::getId,"select annt_id from sys_announcement_send where user_id='"+userId+"'"); //update-begin--Author:liusq Date:20210108 for: [JT-424] 【开源issue】bug处理-------------------- List<SysAnnouncement> announcements = sysAnnouncementService.list(querySaWrapper); if(announcements.size()>0) { for(int i=0;i<announcements.size();i++) { //update-begin--Author:wangshuai Date:20200803 for: 通知公告消息重复LOWCOD-759-------------------- //因为websocket没有判断是否存在这个用户,要是判断会出现问题,故在此判断逻辑 LambdaQueryWrapper<SysAnnouncementSend> query = new LambdaQueryWrapper<>(); query.eq(SysAnnouncementSend::getAnntId,announcements.get(i).getId()); query.eq(SysAnnouncementSend::getUserId,userId); SysAnnouncementSend one = sysAnnouncementSendService.getOne(query); if(null==one){ SysAnnouncementSend announcementSend = new SysAnnouncementSend(); announcementSend.setAnntId(announcements.get(i).getId()); announcementSend.setUserId(userId); announcementSend.setReadFlag(CommonConstant.NO_READ_FLAG); sysAnnouncementSendService.save(announcementSend); } //update-end--Author:wangshuai Date:20200803 for: 通知公告消息重复LOWCOD-759------------ } } // 2.查询用户未读的系统消息 Page<SysAnnouncement> anntMsgList = new Page<SysAnnouncement>(0, pageSize); anntMsgList = sysAnnouncementService.querySysCementPageByUserId(anntMsgList,userId,"1");//通知公告消息 Page<SysAnnouncement> sysMsgList = new Page<SysAnnouncement>(0, pageSize); sysMsgList = sysAnnouncementService.querySysCementPageByUserId(sysMsgList,userId,"2");//系统消息 Page<SysAnnouncement> todealMsgList = new Page<SysAnnouncement>(0, pageSize); todealMsgList = sysAnnouncementService.querySysCementPageByUserId(todealMsgList,userId,"3");//待办消息 Map<String,Object> sysMsgMap = new HashMap<String, Object>(); sysMsgMap.put("sysMsgList", sysMsgList.getRecords()); sysMsgMap.put("sysMsgTotal", sysMsgList.getTotal()); sysMsgMap.put("anntMsgList", anntMsgList.getRecords()); sysMsgMap.put("anntMsgTotal", anntMsgList.getTotal()); sysMsgMap.put("todealMsgList", todealMsgList.getRecords()); sysMsgMap.put("todealMsgTotal", todealMsgList.getTotal()); result.setSuccess(true); result.setResult(sysMsgMap); return result; }
2、前端
HeaderNotice.vue 文件
获取系统消息里增加待办内容
同时显示的地方做调整,包括样式与内容显示
消息通知弹出
具体代码如下:
<template> <a-popover trigger="click" placement="bottomRight" :autoAdjustOverflow="true" :arrowPointAtCenter="true" overlayClassName="header-notice-wrapper" @visibleChange="handleHoverChange" :overlayStyle="{ width: '400px', top: '50px' }"> <template slot="content"> <a-spin :spinning="loadding"> <a-tabs> <a-tab-pane :tab="msg1Title" key="1"> <!--<a-list> <a-list-item> <a-list-item-meta title="你收到了 14 份新周报" description="一年前"> <a-avatar style="background-color: white" slot="avatar" src="https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png"/> </a-list-item-meta> </a-list-item> <a-list-item> <a-list-item-meta title="你推荐的 IT大牛 已通过第三轮面试" description="一年前"> <a-avatar style="background-color: white" slot="avatar" src="https://gw.alipayobjects.com/zos/rmsportal/OKJXDXrmkNshAMvwtvhu.png"/> </a-list-item-meta> </a-list-item> <a-list-item> <a-list-item-meta title="这种模板可以区分多种通知类型" description="一年前"> <a-avatar style="background-color: white" slot="avatar" src="https://gw.alipayobjects.com/zos/rmsportal/kISTdvpyTAhtGxpovNWd.png"/> </a-list-item-meta> </a-list-item> </a-list>--> <a-list> <a-list-item :key="index" v-for="(record, index) in announcement1"> <div style="margin-left: 5%;width: 50%"> <p><a @click="showAnnouncement(record)">{{ record.titile }}</a></p> <p style="color: rgba(0,0,0,.45);margin-bottom: 0px">{{ record.createTime }} 发布</p> </div> <div style="text-align: right"> <a-tag @click="showAnnouncement(record)" v-if="record.priority === 'L'" color="blue">一般消息</a-tag> <a-tag @click="showAnnouncement(record)" v-if="record.priority === 'M'" color="orange">重要消息</a-tag> <a-tag @click="showAnnouncement(record)" v-if="record.priority === 'H'" color="red">紧急消息</a-tag> </div> </a-list-item> <div style="margin-top: 5px;text-align: center"> <a-button @click="toMyAnnouncement()" type="dashed" block>查看更多</a-button> </div> </a-list> </a-tab-pane> <a-tab-pane :tab="msg2Title" key="2"> <a-list> <a-list-item :key="index" v-for="(record, index) in announcement2"> <div style="margin-left: 5%;width: 50%"> <p><a @click="showAnnouncement(record)">{{ record.titile }}</a></p> <p style="color: rgba(0,0,0,.45);margin-bottom: 0px">{{ record.createTime }} 发布</p> </div> <div style="text-align: right"> <a-tag @click="showAnnouncement(record)" v-if="record.priority === 'L'" color="blue">一般消息</a-tag> <a-tag @click="showAnnouncement(record)" v-if="record.priority === 'M'" color="orange">重要消息</a-tag> <a-tag @click="showAnnouncement(record)" v-if="record.priority === 'H'" color="red">紧急消息</a-tag> </div> </a-list-item> <div style="margin-top: 5px;text-align: center"> <a-button @click="toMyAnnouncement()" type="dashed" block>查看更多</a-button> </div> </a-list> </a-tab-pane> <a-tab-pane :tab="msg3Title" key="3"> <a-list> <a-list-item :key="index" v-for="(record, index) in announcement3"> <div style="margin-left: 5%;width: 50%"> <p><a @click="showAnnouncement(record)">{{ record.titile }}</a></p> <p style="color: rgba(0,0,0,.45);margin-bottom: 0px">{{ record.createTime }} 发布</p> </div> <div style="text-align: right"> <a-tag @click="showAnnouncement(record)" v-if="record.priority === 'L'" color="blue">一般消息</a-tag> <a-tag @click="showAnnouncement(record)" v-if="record.priority === 'M'" color="orange">重要消息</a-tag> <a-tag @click="showAnnouncement(record)" v-if="record.priority === 'H'" color="red">紧急消息</a-tag> </div> </a-list-item> <div style="margin-top: 5px;text-align: center"> <a-button @click="toMyAnnouncement()" type="dashed" block>查看更多</a-button> </div> </a-list> </a-tab-pane> </a-tabs> </a-spin> </template> <span @click="fetchNotice" class="header-notice"> <a-badge :count="msgTotal"> <a-icon style="font-size: 16px; padding: 4px" type="bell" /> </a-badge> </span> <show-announcement ref="ShowAnnouncement" @ok="modalFormOk"></show-announcement> <dynamic-notice ref="showDynamNotice" :path="openPath" :formData="formData"/> </a-popover> </template> <script> import { getAction,putAction } from '@/api/manage' import ShowAnnouncement from './ShowAnnouncement' import store from '@/store/' import DynamicNotice from './DynamicNotice' export default { name: "HeaderNotice", components: { DynamicNotice, ShowAnnouncement, }, data () { return { loadding: false, url:{ listCementByUser:"/sys/annountCement/listByUser", editCementSend:"/sys/sysAnnouncementSend/editByAnntIdAndUserId", queryById:"/sys/annountCement/queryById", }, hovered: false, announcement1:[], announcement2:[], announcement3:[], msg1Count:"0", msg2Count:"0", msg3Count:"0", msg1Title:"通知(0)", msg2Title:"", msg3Title:"", stopTimer:false, websock: null, lockReconnect:false, heartCheck:null, formData:{}, openPath:'' } }, computed:{ msgTotal () { return parseInt(this.msg1Count)+parseInt(this.msg2Count)+parseInt(this.msg3Count); } }, mounted() { this.loadData(); //this.timerFun(); this.initWebSocket(); // this.heartCheckFun(); }, destroyed: function () { // 离开页面生命周期函数 this.websocketOnclose(); }, methods: { timerFun() { this.stopTimer = false; let myTimer = setInterval(()=>{ // 停止定时器 if (this.stopTimer == true) { clearInterval(myTimer); return; } this.loadData() },6000) }, loadData (){ try { // 获取系统消息 getAction(this.url.listCementByUser).then((res) => { if (res.success) { this.announcement1 = res.result.anntMsgList; this.msg1Count = res.result.anntMsgTotal; this.msg1Title = "通知(" + res.result.anntMsgTotal + ")"; this.announcement2 = res.result.sysMsgList; this.msg2Count = res.result.sysMsgTotal; this.msg2Title = "系统消息(" + res.result.sysMsgTotal + ")"; this.announcement3 = res.result.todealMsgList; this.msg3Count = res.result.todealMsgTotal; this.msg3Title = "待办消息(" + res.result.todealMsgTotal + ")"; } }).catch(error => { console.log("系统消息通知异常",error);//这行打印permissionName is undefined this.stopTimer = true; console.log("清理timer"); }); } catch (err) { this.stopTimer = true; console.log("通知异常",err); } }, fetchNotice () { if (this.loadding) { this.loadding = false return } this.loadding = true setTimeout(() => { this.loadding = false }, 200) }, showAnnouncement(record){ putAction(this.url.editCementSend,{anntId:record.id}).then((res)=>{ if(res.success){ this.loadData(); } }); this.hovered = false; if(record.openType==='component'){ this.openPath = record.openPage; this.formData = {id:record.busId}; this.$refs.showDynamNotice.detail(record.openPage); }else{ this.$refs.ShowAnnouncement.detail(record); } }, toMyAnnouncement(){ this.$router.push({ path: '/isps/userAnnouncement' }); }, modalFormOk(){ }, handleHoverChange (visible) { this.hovered = visible; }, initWebSocket: function () { // WebSocket与普通的请求所用协议有所不同,ws等同于http,wss等同于https var userId = store.getters.userInfo.id; var url = window._CONFIG['domianURL'].replace("https://","wss://").replace("http://","ws://")+"/websocket/"+userId; //console.log("url=",url); this.websock = new WebSocket(url); this.websock.onopen = this.websocketOnopen; this.websock.onerror = this.websocketOnerror; this.websock.onmessage = this.websocketOnmessage; this.websock.onclose = this.websocketOnclose; }, websocketOnopen: function () { console.log("WebSocket连接成功"); //心跳检测重置 //this.heartCheck.reset().start(); }, websocketOnerror: function (e) { console.log("WebSocket连接发生错误"); this.reconnect(); }, websocketOnmessage: function (e) { console.log("-----接收消息-------",e.data); var data = eval("(" + e.data + ")"); //解析对象 if(data.cmd == "topic"){ //系统通知 this.loadData(); this.$notification.open({ //websocket消息通知弹出 message: 'websocket消息通知', description: data.msgTxt, style: { width: '600px', marginLeft: `${335 - 600}px`, }, }); }else if(data.cmd == "user"){ //用户消息 this.loadData(); this.$notification.open({ message: 'websocket消息通知', description: data.msgTxt, style: { width: '600px', marginLeft: `${335 - 600}px`, }, }); } //心跳检测重置 //this.heartCheck.reset().start(); }, websocketOnclose: function (e) { console.log("connection closed (" + e + ")"); if(e){ console.log("connection closed (" + e.code + ")"); } this.reconnect(); }, websocketSend(text) { // 数据发送 try { this.websock.send(text); } catch (err) { console.log("send failed (" + err.code + ")"); } }, openNotification (data) { var text = data.msgTxt; const key = `open${Date.now()}`; this.$notification.open({ message: '消息提醒', placement:'bottomRight', description: text, key, btn: (h)=>{ return h('a-button', { props: { type: 'primary', size: 'small', }, on: { click: () => this.showDetail(key,data) } }, '查看详情') }, }); }, reconnect() { var that = this; if(that.lockReconnect) return; that.lockReconnect = true; //没连接上会一直重连,设置延迟避免请求过多 setTimeout(function () { console.info("尝试重连..."); that.initWebSocket(); that.lockReconnect = false; }, 5000); }, heartCheckFun(){ var that = this; //心跳检测,每20s心跳一次 that.heartCheck = { timeout: 20000, timeoutObj: null, serverTimeoutObj: null, reset: function(){ clearTimeout(this.timeoutObj); //clearTimeout(this.serverTimeoutObj); return this; }, start: function(){ var self = this; this.timeoutObj = setTimeout(function(){ //这里发送一个心跳,后端收到后,返回一个心跳消息, //onmessage拿到返回的心跳就说明连接正常 that.websocketSend("HeartBeat"); console.info("客户端发送心跳"); //self.serverTimeoutObj = setTimeout(function(){//如果超过一定时间还没重置,说明后端主动断开了 // that.websock.close();//如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次 //}, self.timeout) }, this.timeout) } } }, showDetail(key,data){ this.$notification.close(key); var id = data.msgId; getAction(this.url.queryById,{id:id}).then((res) => { if (res.success) { var record = res.result; this.showAnnouncement(record); } }) }, } } </script> <style lang="css"> .header-notice-wrapper { top: 50px !important; } </style> <style lang="less" scoped> .header-notice{ display: inline-block; transition: all 0.3s; span { vertical-align: initial; } } </style>