'123'
This commit is contained in:
parent
e4bdf650bb
commit
9681fd1a48
|
@ -1,6 +1,14 @@
|
|||
package com.ruoyi.web.controller.system;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.ruoyi.common.constant.WebsocketConst;
|
||||
import com.ruoyi.framework.websocket.WebSocketServer;
|
||||
import com.ruoyi.framework.websocket.WebSocketUsers;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
@ -22,7 +30,7 @@ import com.ruoyi.system.service.ISysNoticeService;
|
|||
|
||||
/**
|
||||
* 公告 信息操作处理
|
||||
*
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@RestController
|
||||
|
@ -32,6 +40,9 @@ public class SysNoticeController extends BaseController
|
|||
@Autowired
|
||||
private ISysNoticeService noticeService;
|
||||
|
||||
@Autowired
|
||||
private WebSocketServer webSocketServer;
|
||||
|
||||
/**
|
||||
* 获取通知公告列表
|
||||
*/
|
||||
|
@ -63,6 +74,13 @@ public class SysNoticeController extends BaseController
|
|||
public AjaxResult add(@Validated @RequestBody SysNotice notice)
|
||||
{
|
||||
notice.setCreateBy(getUsername());
|
||||
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put(WebsocketConst.MSG_ID, notice.getNoticeId());
|
||||
obj.put(WebsocketConst.MSG_TITLE, notice.getNoticeTitle());
|
||||
obj.put(WebsocketConst.MSG_CONTENT, notice.getNoticeContent());
|
||||
WebSocketUsers.sendMessageToUsersByText(obj.toString());
|
||||
|
||||
return toAjax(noticeService.insertNotice(notice));
|
||||
}
|
||||
|
||||
|
@ -88,4 +106,21 @@ public class SysNoticeController extends BaseController
|
|||
{
|
||||
return toAjax(noticeService.deleteNoticeByIds(noticeIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* 导航面板 消息通知
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/navbarNoticelist")
|
||||
public Map<String, List<SysNotice>> navbarNoticelist()
|
||||
{
|
||||
List<SysNotice> list = noticeService.navbarNoticelist();
|
||||
Map<String, List<SysNotice>> groupedByNoticeType = list.stream()
|
||||
.collect(Collectors.groupingBy(SysNotice::getNoticeType));
|
||||
for(String key:groupedByNoticeType.keySet()){
|
||||
List<SysNotice> lt = groupedByNoticeType.get(key);
|
||||
lt.sort((t1, t2) -> t2.getCreateTime().compareTo(t1.getCreateTime()));
|
||||
}
|
||||
return groupedByNoticeType;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
package com.ruoyi.common.constant;
|
||||
|
||||
/**
|
||||
* 消息推送通用常量
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class WebsocketConst {
|
||||
/** 消息ID */
|
||||
public static final String MSG_ID = "noticeId";
|
||||
|
||||
/** 消息TITLE */
|
||||
public static final String MSG_TITLE = "noticeTitle";
|
||||
|
||||
/** 消息CONTENT */
|
||||
public static final String MSG_CONTENT = "noticeContent";
|
||||
}
|
|
@ -5,14 +5,14 @@ import com.ruoyi.system.domain.SysNotice;
|
|||
|
||||
/**
|
||||
* 通知公告表 数据层
|
||||
*
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public interface SysNoticeMapper
|
||||
{
|
||||
/**
|
||||
* 查询公告信息
|
||||
*
|
||||
*
|
||||
* @param noticeId 公告ID
|
||||
* @return 公告信息
|
||||
*/
|
||||
|
@ -20,7 +20,7 @@ public interface SysNoticeMapper
|
|||
|
||||
/**
|
||||
* 查询公告列表
|
||||
*
|
||||
*
|
||||
* @param notice 公告信息
|
||||
* @return 公告集合
|
||||
*/
|
||||
|
@ -28,7 +28,7 @@ public interface SysNoticeMapper
|
|||
|
||||
/**
|
||||
* 新增公告
|
||||
*
|
||||
*
|
||||
* @param notice 公告信息
|
||||
* @return 结果
|
||||
*/
|
||||
|
@ -36,7 +36,7 @@ public interface SysNoticeMapper
|
|||
|
||||
/**
|
||||
* 修改公告
|
||||
*
|
||||
*
|
||||
* @param notice 公告信息
|
||||
* @return 结果
|
||||
*/
|
||||
|
@ -44,7 +44,7 @@ public interface SysNoticeMapper
|
|||
|
||||
/**
|
||||
* 批量删除公告
|
||||
*
|
||||
*
|
||||
* @param noticeId 公告ID
|
||||
* @return 结果
|
||||
*/
|
||||
|
@ -52,9 +52,15 @@ public interface SysNoticeMapper
|
|||
|
||||
/**
|
||||
* 批量删除公告信息
|
||||
*
|
||||
*
|
||||
* @param noticeIds 需要删除的公告ID
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteNoticeByIds(Long[] noticeIds);
|
||||
|
||||
/**
|
||||
* 消息推送信息获取
|
||||
* @return
|
||||
*/
|
||||
List<SysNotice> navbarNoticelist();
|
||||
}
|
||||
|
|
|
@ -5,14 +5,14 @@ import com.ruoyi.system.domain.SysNotice;
|
|||
|
||||
/**
|
||||
* 公告 服务层
|
||||
*
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public interface ISysNoticeService
|
||||
{
|
||||
/**
|
||||
* 查询公告信息
|
||||
*
|
||||
*
|
||||
* @param noticeId 公告ID
|
||||
* @return 公告信息
|
||||
*/
|
||||
|
@ -20,7 +20,7 @@ public interface ISysNoticeService
|
|||
|
||||
/**
|
||||
* 查询公告列表
|
||||
*
|
||||
*
|
||||
* @param notice 公告信息
|
||||
* @return 公告集合
|
||||
*/
|
||||
|
@ -28,7 +28,7 @@ public interface ISysNoticeService
|
|||
|
||||
/**
|
||||
* 新增公告
|
||||
*
|
||||
*
|
||||
* @param notice 公告信息
|
||||
* @return 结果
|
||||
*/
|
||||
|
@ -36,7 +36,7 @@ public interface ISysNoticeService
|
|||
|
||||
/**
|
||||
* 修改公告
|
||||
*
|
||||
*
|
||||
* @param notice 公告信息
|
||||
* @return 结果
|
||||
*/
|
||||
|
@ -44,17 +44,23 @@ public interface ISysNoticeService
|
|||
|
||||
/**
|
||||
* 删除公告信息
|
||||
*
|
||||
*
|
||||
* @param noticeId 公告ID
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteNoticeById(Long noticeId);
|
||||
|
||||
|
||||
/**
|
||||
* 批量删除公告信息
|
||||
*
|
||||
*
|
||||
* @param noticeIds 需要删除的公告ID
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteNoticeByIds(Long[] noticeIds);
|
||||
|
||||
/**
|
||||
* 导航面板 消息通知
|
||||
* @return
|
||||
*/
|
||||
List<SysNotice> navbarNoticelist();
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ import com.ruoyi.system.service.ISysNoticeService;
|
|||
|
||||
/**
|
||||
* 公告 服务层实现
|
||||
*
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Service
|
||||
|
@ -23,7 +23,7 @@ public class SysNoticeServiceImpl implements ISysNoticeService
|
|||
|
||||
/**
|
||||
* 查询公告信息
|
||||
*
|
||||
*
|
||||
* @param noticeId 公告ID
|
||||
* @return 公告信息
|
||||
*/
|
||||
|
@ -40,7 +40,7 @@ public class SysNoticeServiceImpl implements ISysNoticeService
|
|||
|
||||
/**
|
||||
* 查询公告列表
|
||||
*
|
||||
*
|
||||
* @param notice 公告信息
|
||||
* @return 公告集合
|
||||
*/
|
||||
|
@ -61,7 +61,7 @@ public class SysNoticeServiceImpl implements ISysNoticeService
|
|||
|
||||
/**
|
||||
* 新增公告
|
||||
*
|
||||
*
|
||||
* @param notice 公告信息
|
||||
* @return 结果
|
||||
*/
|
||||
|
@ -76,7 +76,7 @@ public class SysNoticeServiceImpl implements ISysNoticeService
|
|||
|
||||
/**
|
||||
* 修改公告
|
||||
*
|
||||
*
|
||||
* @param notice 公告信息
|
||||
* @return 结果
|
||||
*/
|
||||
|
@ -91,7 +91,7 @@ public class SysNoticeServiceImpl implements ISysNoticeService
|
|||
|
||||
/**
|
||||
* 删除公告对象
|
||||
*
|
||||
*
|
||||
* @param noticeId 公告ID
|
||||
* @return 结果
|
||||
*/
|
||||
|
@ -103,7 +103,7 @@ public class SysNoticeServiceImpl implements ISysNoticeService
|
|||
|
||||
/**
|
||||
* 批量删除公告信息
|
||||
*
|
||||
*
|
||||
* @param noticeIds 需要删除的公告ID
|
||||
* @return 结果
|
||||
*/
|
||||
|
@ -112,4 +112,13 @@ public class SysNoticeServiceImpl implements ISysNoticeService
|
|||
{
|
||||
return noticeMapper.deleteNoticeByIds(noticeIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导航面板 消息通知
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<SysNotice> navbarNoticelist() {
|
||||
return noticeMapper.navbarNoticelist();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,4 +86,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
</foreach>
|
||||
</delete>
|
||||
|
||||
<select id="navbarNoticelist" resultMap="SysNoticeResult">
|
||||
<include refid="selectNoticeVo"/>
|
||||
<where>
|
||||
CONVERT(date, create_time) = CONVERT(date, GETDATE())
|
||||
</where>
|
||||
order by create_time desc
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 查询业务消息
|
||||
export function getNoticeListTop3(query) {
|
||||
return request({
|
||||
url: '/system/notice/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
|
@ -41,4 +41,13 @@ export function delNotice(noticeId) {
|
|||
url: '/system/notice/' + noticeId,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 导航面板 消息通知
|
||||
export function navbarNoticelist(query) {
|
||||
return request({
|
||||
url: '/system/notice/navbarNoticelist',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
<ruo-yi-doc id="ruoyi-doc" class="right-menu-item hover-effect" />
|
||||
</el-tooltip>-->
|
||||
|
||||
<!--消息组件-->
|
||||
<NavbarNotice class="right-menu-item hover-effect"></NavbarNotice>
|
||||
<screenfull id="screenfull" class="right-menu-item hover-effect" />
|
||||
|
||||
<el-tooltip content="布局大小" effect="dark" placement="bottom">
|
||||
|
@ -57,18 +59,9 @@ import Search from '@/components/HeaderSearch'
|
|||
import RuoYiGit from '@/components/RuoYi/Git'
|
||||
import RuoYiDoc from '@/components/RuoYi/Doc'
|
||||
import settings from '@/settings'
|
||||
|
||||
import { getNoticeListTop3 } from "@/api/system/businessNotice";
|
||||
import NavbarNotice from "@/layout/components/NavbarNotice.vue";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
url: "ws://localhost:3334/websocket/message",
|
||||
message: "",
|
||||
text_content: "",
|
||||
ws: null,
|
||||
};
|
||||
},
|
||||
components: {
|
||||
Breadcrumb,
|
||||
TopNav,
|
||||
|
@ -77,7 +70,8 @@ export default {
|
|||
SizeSelect,
|
||||
Search,
|
||||
RuoYiGit,
|
||||
RuoYiDoc
|
||||
RuoYiDoc,
|
||||
NavbarNotice
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
|
@ -102,87 +96,7 @@ export default {
|
|||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
/** 消息推送 */
|
||||
this.notice();
|
||||
const wsuri = this.url;
|
||||
this.ws = new WebSocket(wsuri);
|
||||
const self = this;
|
||||
this.ws.onopen = function (event) {
|
||||
//self.text_content = self.text_content + "已经打开连接!" + "\n";
|
||||
};
|
||||
this.ws.onmessage = function (event) {
|
||||
//self.text_content = event.data + "\n";
|
||||
var messageBody = JSON.parse(event.data);
|
||||
Notification.info({
|
||||
title: "通知",
|
||||
dangerouslyUseHTMLString: true,
|
||||
message: messageBody.noticeContent,
|
||||
duration: 0,
|
||||
offset: 40,
|
||||
onClick: function () {
|
||||
//self.warnDetailByWarnid(messageBody.warnId); //自定义回调,message为传的参数
|
||||
// 点击跳转的页面
|
||||
},
|
||||
});
|
||||
};
|
||||
this.ws.onclose = function (event) {
|
||||
//self.text_content = self.text_content + "已经关闭连接!" + "\n";
|
||||
};
|
||||
/** 消息推送 */
|
||||
},
|
||||
methods: {
|
||||
/** 消息推送 */
|
||||
notice() {
|
||||
getNoticeListTop3().then(response => {
|
||||
for (let i = 0; i < response.length; i++) {
|
||||
let messageBody = response[i];
|
||||
setTimeout(() => {
|
||||
this.notificationInfo(messageBody);
|
||||
}, 100);
|
||||
}
|
||||
})
|
||||
},
|
||||
notificationInfo(messageBody) {
|
||||
Notification.info({
|
||||
title: "通知",
|
||||
dangerouslyUseHTMLString: true,
|
||||
message: messageBody.noticeContent,
|
||||
duration: 0,
|
||||
offset: 40,
|
||||
onClick: function () {
|
||||
//self.warnDetailByWarnid(messageBody.warnId); //自定义回调,message为传的参数
|
||||
// 点击跳转的页面
|
||||
},
|
||||
});
|
||||
},
|
||||
// join() {
|
||||
//
|
||||
// },
|
||||
exit() {
|
||||
if (this.ws) {
|
||||
this.ws.close();
|
||||
this.ws = null;
|
||||
}
|
||||
},
|
||||
send() {
|
||||
if (this.ws) {
|
||||
this.ws.send(this.message);
|
||||
} else {
|
||||
alert("未连接到服务器");
|
||||
}
|
||||
},
|
||||
warnDetailByWarnid(warnid) {
|
||||
// 跳转预警详情页面
|
||||
this.$router.push({
|
||||
path: "/XXX/XXX",
|
||||
query: {
|
||||
warnid: warnid,
|
||||
},
|
||||
});
|
||||
},
|
||||
/** 消息推送 */
|
||||
|
||||
toggleSideBar() {
|
||||
this.$store.dispatch('app/toggleSideBar')
|
||||
},
|
||||
|
|
|
@ -0,0 +1,175 @@
|
|||
<template>
|
||||
<!--(1通知 2公告)-->
|
||||
<el-dropdown>
|
||||
<span class="el-dropdown-link">
|
||||
<svg-icon icon-class="message" slot="reference" />
|
||||
<el-badge :value="noteTotal"></el-badge>
|
||||
</span>
|
||||
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-tabs v-model="activeName" @tab-click="handleClick" style="width:100%">
|
||||
<el-tab-pane label="系统通知" name="first">
|
||||
<el-dropdown-item v-for="(item,index) in noticeData" :key="index" >
|
||||
<el-link :underline="false" @click="clickNote(item)" :style="index==0?'': 'margin-top :15px'">{{item.noticeTitle}}</el-link>
|
||||
</el-dropdown-item>
|
||||
<el-link :underline="false" style="margin-top :15px" v-if="noticeData.length>5" type="primary">更多消息</el-link>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="系统公告" name="second">
|
||||
<el-dropdown-item v-for="(item,index) in sysLog" :key="index">
|
||||
<el-link :underline="false" @click="clickNote(item)" :style="index==0?'': 'margin-top :15px'">{{item.noticeTitle}}</el-link>
|
||||
</el-dropdown-item>
|
||||
<el-link v-if="sysLog.length>5" type="primary">更多消息</el-link>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-dropdown-menu>
|
||||
<!--<mode-dialog :visible="noteVisible" :noteType="noteType" :noticeId="noticeId" @close="closeMode"></mode-dialog>-->
|
||||
</el-dropdown>
|
||||
</template>
|
||||
<script>
|
||||
import { navbarNoticelist } from '@/api/system/notice'
|
||||
/*
|
||||
import ModeDialog from '@/components/ModeDialog'
|
||||
*/
|
||||
|
||||
export default {
|
||||
name: 'NavbarNotice',
|
||||
/*
|
||||
components: { ModeDialog },
|
||||
*/
|
||||
data() {
|
||||
return {
|
||||
activeName: 'first',
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 5,
|
||||
readFlag: '0'
|
||||
},
|
||||
noteTotal: '',
|
||||
// 公告
|
||||
sysLog: [],
|
||||
// 通知
|
||||
noticeData: [],
|
||||
websock: null,
|
||||
lockReconnect: false,
|
||||
heartCheck: null,
|
||||
noteVisible: false,
|
||||
noteType: 0,
|
||||
noticeId: 0
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// 初始化WebSocket
|
||||
this.initWebSocket()
|
||||
},
|
||||
destroyed: function() { // 离开页面生命周期函数
|
||||
this.websocketOnclose()
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
this.noticeData = []
|
||||
this.sysLog = []
|
||||
navbarNoticelist(this.queryParams).then(res => {
|
||||
console.log(res[1])
|
||||
this.noticeData = res[1]?res[1]:[];
|
||||
this.sysLog = res[2]?res[2]:[];
|
||||
|
||||
this.noteTotal = this.noticeData.length+this.sysLog.length;
|
||||
})
|
||||
},
|
||||
handleClick(tab, event) {
|
||||
},
|
||||
clickNote(data) {
|
||||
this.noteVisible = true
|
||||
this.noticeId = data.noticeId
|
||||
this.noteType = data.noticeType == '1' ? 0 : 1
|
||||
},
|
||||
closeMode() {
|
||||
this.getList()
|
||||
this.noteVisible = false
|
||||
},
|
||||
initWebSocket() {
|
||||
var userId = this.$store.getters.userId
|
||||
// WebSocket与普通的请求所用协议有所不同,ws等同于http,wss等同于https
|
||||
// VUE_APP_BASE_API_WS = 'ws://localhost:9696' 地址
|
||||
var url = 'ws://localhost:3334/websocket/message';
|
||||
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连接成功')
|
||||
},
|
||||
websocketOnerror: function(e) {
|
||||
console.log('WebSocket连接发生错误,第%s次', this.wsConnectErrorTime)
|
||||
this.wsConnectErrorTime = this.wsConnectErrorTime + 1
|
||||
if (this.wsConnectErrorTime > 5) {
|
||||
console.log('WebSocket连接错误超过5次,就不再重新连了!')
|
||||
this.lockReconnect = true
|
||||
return
|
||||
}
|
||||
this.reconnect()
|
||||
},
|
||||
websocketOnmessage: function(e) {
|
||||
console.log('-----接收消息-------', e.data)
|
||||
this.getList()
|
||||
},
|
||||
websocketOnclose: function(e) {
|
||||
console.log('connection closed (' + e + ')')
|
||||
if (e) {
|
||||
console.log('connection closed (' + e.code + ')')
|
||||
}
|
||||
this.reconnect()
|
||||
},
|
||||
reconnect() {
|
||||
var that = this
|
||||
if (that.lockReconnect) return
|
||||
that.lockReconnect = true
|
||||
//没连接上会一直重连,设置延迟避免请求过多
|
||||
setTimeout(function() {
|
||||
console.info('尝试重连...')
|
||||
that.initWebSocket()
|
||||
that.lockReconnect = false
|
||||
}, 2000)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.text-overflow {
|
||||
width: 160px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
margin: 2px 0;
|
||||
}
|
||||
|
||||
::v-deep .el-badge {
|
||||
top: -7px;
|
||||
}
|
||||
|
||||
::v-deep .el-badge__content.is-dot {
|
||||
position: relative;
|
||||
width: 11px;
|
||||
height: 11px;
|
||||
}
|
||||
|
||||
.el-tab-pane{
|
||||
width:300px
|
||||
}
|
||||
.el-dropdown-menu{
|
||||
width:250px
|
||||
}
|
||||
::v-deep .el-dropdown-menu {
|
||||
top: 28px;
|
||||
}
|
||||
|
||||
::v-deep .el-tabs {
|
||||
padding: 12px;
|
||||
width: 188px;
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue