This commit is contained in:
xd 2024-04-24 16:54:52 +08:00
parent ad34d7e219
commit b3a429204f
7 changed files with 208 additions and 25 deletions

View File

@ -1,13 +1,11 @@
package com.ruoyi.web.controller.system;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.constant.WebsocketConst;
import com.ruoyi.framework.websocket.OneToManyWebSocket;
import com.ruoyi.framework.websocket.WebSocketServer;
import com.ruoyi.framework.websocket.WebSocketUsers;
import com.ruoyi.system.domain.SysNoticeUser;
@ -45,7 +43,7 @@ public class SysNoticeController extends BaseController
private ISysNoticeService noticeService;
@Autowired
private WebSocketServer webSocketServer;
private OneToManyWebSocket oneToManyWebSocket;
/**
* 获取通知公告列表
@ -78,19 +76,28 @@ public class SysNoticeController extends BaseController
public AjaxResult add(@Validated @RequestBody SysNotice notice)
{
notice.setCreateBy(getUsername());
noticeService.insertNotice(notice);
List<SysNoticeUser> sysNoticeUsers = new ArrayList<SysNoticeUser>();
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());
if(!"3".equals(notice.getNoticeType())){//系统通知 通知公告
WebSocketUsers.sendMessageToUsersByText(obj.toString());
SysNoticeUser sysNoticeUser = new SysNoticeUser();
oneToManyWebSocket.sendMessage(obj.toString());
SysNoticeUser sysNoticeUser = null;
Map<String, Session> users = oneToManyWebSocket.getUsers();
for(String userId:users.keySet()){
sysNoticeUser = new SysNoticeUser();
sysNoticeUser.setNoticeId(notice.getNoticeId());
sysNoticeUser.setUserId(notice.getNoticeId());
sysNoticeUser.setUserId(Long.valueOf(userId));
sysNoticeUsers.add(sysNoticeUser);
}
noticeService.insertNoticeUserBatch(sysNoticeUsers);
}
return toAjax(noticeService.insertNotice(notice));
return success();
}
/**
@ -123,7 +130,8 @@ public class SysNoticeController extends BaseController
@GetMapping("/navbarNoticelist")
public Map<String, List<SysNotice>> navbarNoticelist()
{
List<SysNotice> list = noticeService.navbarNoticelist();
Long userId = getLoginUser().getUserId();//当前登陆者
List<SysNotice> list = noticeService.navbarNoticelist(userId);
Map<String, List<SysNotice>> groupedByNoticeType = list.stream()
.collect(Collectors.groupingBy(SysNotice::getNoticeType));
for(String key:groupedByNoticeType.keySet()){

View File

@ -0,0 +1,132 @@
package com.ruoyi.framework.websocket;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
/**
*
* 前后端交互的类实现消息的接收推送(自己发送给所有人(不包括自己))
*
*/
@ServerEndpoint(value = "/websocket/message/{userId}")
@Component
public class OneToManyWebSocket {
/**
* WebSocketUsers 日志控制器
*/
private static final Logger LOGGER = LoggerFactory.getLogger(WebSocketUsers.class);
/** 记录当前在线连接数 */
private static AtomicInteger onlineCount = new AtomicInteger(0);
/** 存放所有在线的客户端 key 为用户Id */
private static final Map<String, Session> clients = new ConcurrentHashMap<>();
/**
* 连接建立成功调用的方法
*/
@OnOpen
public void onOpen(Session session,@PathParam("userId") String userId) {
if(clients.containsKey(userId)){
clients.remove(userId);
clients.put(userId, session);
}else{
onlineCount.incrementAndGet(); // 在线数加1
clients.put(userId, session);
//sendMessage("你好啊客户端"+userId,session);
}
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose(Session session) {
for (String userId : clients.keySet()) {
if(clients.get(userId).equals(session)){
clients.remove(session);
onlineCount.decrementAndGet(); // 在线数减1
}
}
}
/**
* 收到客户端消息后调用的方法
*
* @param message
* 客户端发送过来的消息
*/
@OnMessage
public void onMessage(String message, Session session) {
LOGGER.info("服务端收到客户端[{}]的消息:{}", session.getId(), message);
//this.sendMessage(message, session);
}
@OnError
public void onError(Session session, Throwable error) {
LOGGER.error("发生错误");
error.printStackTrace();
}
/**
* 获取在线用户列表
*
* @return 返回用户集合
*/
public static Map<String, Session> getUsers()
{
return clients;
}
/**
* 群发消息
*
* @param message
*/
public static void sendMessage(String message) {
for (Map.Entry<String, Session> sessionEntry : clients.entrySet()) {
Session toSession = sessionEntry.getValue();
// 排除掉自己
//if (!fromSession.getId().equals(toSession.getId())) {
LOGGER.info("服务端给客户端[{}]发送消息{}", toSession.getId(), message);
toSession.getAsyncRemote().sendText(message);
//}
}
}
/**
* 群发消息
*
* @param message
* 消息内容
*/
public static void sendMessage(String message, List<String> ids) {
for (String id : ids) {
Session session = clients.get(id);
if(session!=null){
LOGGER.info("服务端给客户端[{}]发送消息{}", session.getId(), message);
try {
session.getAsyncRemote().sendText(message);
}catch (Exception e){
LOGGER.info("数据发送失败!疑似断开连接", session.getId(), message);
clients.remove(id);
}
}
}
}
public Session getUserSession(String userId){
return clients.get(userId);
}
}

View File

@ -2,6 +2,7 @@ package com.ruoyi.system.mapper;
import java.util.List;
import com.ruoyi.system.domain.SysNotice;
import com.ruoyi.system.domain.SysNoticeUser;
/**
* 通知公告表 数据层
@ -62,5 +63,11 @@ public interface SysNoticeMapper
* 消息推送信息获取
* @return
*/
List<SysNotice> navbarNoticelist();
List<SysNotice> navbarNoticelist(Long userId);
/**
* 批量插入消息-用户 中间表
* @param sysNoticeUsers
*/
void insertNoticeUserBatch(List<SysNoticeUser> sysNoticeUsers);
}

View File

@ -2,6 +2,7 @@ package com.ruoyi.system.service;
import java.util.List;
import com.ruoyi.system.domain.SysNotice;
import com.ruoyi.system.domain.SysNoticeUser;
/**
* 公告 服务层
@ -62,5 +63,11 @@ public interface ISysNoticeService
* 导航面板 消息通知
* @return
*/
List<SysNotice> navbarNoticelist();
List<SysNotice> navbarNoticelist(Long userId);
/**
* 批量插入消息-用户 中间表
* @param sysNoticeUsers
*/
void insertNoticeUserBatch(List<SysNoticeUser> sysNoticeUsers);
}

View File

@ -4,6 +4,7 @@ import java.nio.charset.StandardCharsets;
import java.util.List;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysNoticeUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.domain.SysNotice;
@ -118,7 +119,16 @@ public class SysNoticeServiceImpl implements ISysNoticeService
* @return
*/
@Override
public List<SysNotice> navbarNoticelist() {
return noticeMapper.navbarNoticelist();
public List<SysNotice> navbarNoticelist(Long userId) {
return noticeMapper.navbarNoticelist(userId);
}
/**
* 批量插入消息-用户 中间表
* @param sysNoticeUsers
*/
@Override
public void insertNoticeUserBatch(List<SysNoticeUser> sysNoticeUsers) {
noticeMapper.insertNoticeUserBatch(sysNoticeUsers);
}
}

View File

@ -42,7 +42,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</where>
</select>
<insert id="insertNotice" parameterType="SysNotice">
<insert id="insertNotice" parameterType="SysNotice" useGeneratedKeys="true" keyProperty="noticeId">
insert into sys_notice (
<if test="noticeTitle != null and noticeTitle != '' ">notice_title, </if>
<if test="noticeType != null and noticeType != '' ">notice_type, </if>
@ -87,11 +87,26 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</delete>
<select id="navbarNoticelist" resultMap="SysNoticeResult">
<include refid="selectNoticeVo"/>
select notice_id, notice_title, notice_type, notice_content, status, create_by, create_time, update_by, update_time, remark
from sys_notice a
inner join sys_user_notice b on a.notice_id = b.noticeId
<where>
CONVERT(date, create_time) = CONVERT(date, GETDATE())
and b.userId = #{userId}
and CONVERT(date, create_time) = CONVERT(date, GETDATE())
</where>
order by create_time desc
</select>
<insert id="insertNoticeUserBatch" parameterType="java.util.List">
insert into sys_user_notice
(noticeId,userId)
values
<foreach collection="list" item="item" index="index" separator=",">
(
#{item.noticeId,jdbcType=INTEGER},
#{item.userId,jdbcType=INTEGER}
)
</foreach>
</insert>
</mapper>

View File

@ -26,10 +26,11 @@
</el-dropdown>
</template>
<script>
import { navbarNoticelist } from '@/api/system/notice'
import { navbarNoticelist } from '@/api/system/notice';
/*
import ModeDialog from '@/components/ModeDialog'
*/
import { Notification } from 'element-ui';
export default {
name: 'NavbarNotice',
@ -54,10 +55,10 @@
},
mounted() {
// WebSocket
this.initWebSocket()
this.initWebSocket();
},
destroyed: function() { //
this.websocketOnclose()
this.websocketOnclose();
},
methods: {
getList() {
@ -85,10 +86,9 @@
this.noteVisible = false
},
initWebSocket() {
var userId = this.$store.getters.userId
var userId = this.$store.state.user.id;
// WebSocketwshttpwsshttps
// VUE_APP_BASE_API_WS = 'ws://localhost:9696'
var url = 'ws://localhost:3334/websocket/message';
var url = 'ws://localhost:3334/websocket/message/'+userId;
this.websock = new WebSocket(url)
this.websock.onopen = this.websocketOnopen
this.websock.onerror = this.websocketOnerror
@ -110,7 +110,11 @@
},
websocketOnmessage: function(e) {
console.log('-----接收消息-------', e.data)
this.getList()
this.getList();
Notification({
title: '消息',
message: JSON.parse(e.data).noticeTitle
})
},
websocketOnclose: function(e) {
console.log('connection closed (' + e + ')')