mirror of https://gitee.com/stylefeng/roses
parent
88c14e119f
commit
e6f887294d
|
@ -1,5 +1,6 @@
|
|||
package cn.stylefeng.roses.kernel.socket.api;
|
||||
|
||||
import cn.stylefeng.roses.kernel.socket.api.exception.SocketException;
|
||||
import cn.stylefeng.roses.kernel.socket.api.message.SocketMsgCallbackInterface;
|
||||
|
||||
/**
|
||||
|
@ -21,7 +22,7 @@ public interface SocketOperatorApi {
|
|||
* @author majianguo
|
||||
* @date 2021/6/11 下午2:19
|
||||
**/
|
||||
void sendMsgOfUserSessionBySessionId(String msgType, String sessionId, Object msg);
|
||||
void sendMsgOfUserSessionBySessionId(String msgType, String sessionId, Object msg) throws SocketException;
|
||||
|
||||
/**
|
||||
* 发送消息到指定用户的所有会话
|
||||
|
@ -34,7 +35,7 @@ public interface SocketOperatorApi {
|
|||
* @author majianguo
|
||||
* @date 2021/6/2 上午9:35
|
||||
**/
|
||||
void sendMsgOfUserSession(String msgType, String userId, Object msg);
|
||||
void sendMsgOfUserSession(String msgType, String userId, Object msg) throws SocketException;
|
||||
|
||||
/**
|
||||
* 发送消息到所有会话
|
||||
|
|
|
@ -25,7 +25,7 @@ import java.util.List;
|
|||
public class WebSocketOperator implements SocketOperatorApi {
|
||||
|
||||
@Override
|
||||
public void sendMsgOfUserSessionBySessionId(String msgType, String sessionId, Object msg) {
|
||||
public void sendMsgOfUserSessionBySessionId(String msgType, String sessionId, Object msg) throws SocketException {
|
||||
SocketSession<GettySocketOperator> session = SessionCenter.getSessionBySessionId(sessionId);
|
||||
if (ObjectUtil.isEmpty(session)) {
|
||||
throw new SocketException(SocketExceptionEnum.SESSION_NOT_EXIST);
|
||||
|
@ -37,7 +37,7 @@ public class WebSocketOperator implements SocketOperatorApi {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void sendMsgOfUserSession(String msgType, String userId, Object msg) {
|
||||
public void sendMsgOfUserSession(String msgType, String userId, Object msg) throws SocketException {
|
||||
// 根据用户ID获取会话
|
||||
List<SocketSession<GettySocketOperator>> socketSessionList = SessionCenter.getSessionByUserIdAndMsgType(userId);
|
||||
if (ObjectUtil.isEmpty(socketSessionList)) {
|
||||
|
|
|
@ -26,7 +26,9 @@ public class GettySocketOperator implements GettyChannelExpandInterFace {
|
|||
@Override
|
||||
public void writeAndFlush(Object obj) {
|
||||
try {
|
||||
socketChannel.getBasicRemote().sendText(JSON.toJSONString(obj));
|
||||
if (socketChannel.isOpen()) {
|
||||
socketChannel.getBasicRemote().sendText(JSON.toJSONString(obj));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -34,13 +36,17 @@ public class GettySocketOperator implements GettyChannelExpandInterFace {
|
|||
|
||||
@Override
|
||||
public void writeToChannel(Object obj) {
|
||||
socketChannel.getAsyncRemote().sendText(JSON.toJSONString(obj));
|
||||
if (socketChannel.isOpen()) {
|
||||
socketChannel.getAsyncRemote().sendText(JSON.toJSONString(obj));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
try {
|
||||
socketChannel.close();
|
||||
if (socketChannel.isOpen()) {
|
||||
socketChannel.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
|
|
@ -40,6 +40,31 @@ public class WebSocketServer {
|
|||
**/
|
||||
@OnOpen
|
||||
public void onOpen(Session session, @PathParam("userId") String userId) {
|
||||
// 操作api包装
|
||||
GettySocketOperator gettySocketOperator = new GettySocketOperator(session);
|
||||
|
||||
// 回复消息
|
||||
WebSocketMessageDTO replyMsg = new WebSocketMessageDTO();
|
||||
replyMsg.setServerMsgType(ServerMessageTypeEnum.SYS_REPLY_MSG_TYPE.getCode());
|
||||
replyMsg.setToUserId(userId);
|
||||
|
||||
try {
|
||||
// 设置回复内容
|
||||
replyMsg.setData(session.getId());
|
||||
|
||||
// 创建会话对象
|
||||
SocketSession<GettySocketOperator> socketSession = new SocketSession<>();
|
||||
socketSession.setSessionId(session.getId());
|
||||
socketSession.setUserId(userId);
|
||||
socketSession.setSocketOperatorApi(gettySocketOperator);
|
||||
socketSession.setConnectionTime(System.currentTimeMillis());
|
||||
|
||||
// 维护会话
|
||||
SessionCenter.addSocketSession(socketSession);
|
||||
} finally {
|
||||
// 回复消息
|
||||
gettySocketOperator.writeAndFlush(replyMsg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -68,13 +93,16 @@ public class WebSocketServer {
|
|||
// 转换为Java对象
|
||||
WebSocketMessageDTO WebSocketMessageDTO = JSON.parseObject(message, WebSocketMessageDTO.class);
|
||||
|
||||
// 维护通道是否已初始化
|
||||
SocketSession<GettySocketOperator> socketSession = SessionCenter.getSessionBySessionId(socketChannel.getId());
|
||||
|
||||
// 心跳包
|
||||
if (ClientMessageTypeEnum.USER_HEART.getCode().equals(WebSocketMessageDTO.getClientMsgType())) {
|
||||
if (ObjectUtil.isNotEmpty(socketSession) && ClientMessageTypeEnum.USER_HEART.getCode().equals(WebSocketMessageDTO.getClientMsgType())) {
|
||||
// 更新会话最后活跃时间
|
||||
SocketSession<GettySocketOperator> session = SessionCenter.getSessionBySessionId(socketChannel.getId());
|
||||
if (ObjectUtil.isNotEmpty(session)) {
|
||||
session.setLastActiveTime(System.currentTimeMillis());
|
||||
if (ObjectUtil.isNotEmpty(socketSession)) {
|
||||
socketSession.setLastActiveTime(System.currentTimeMillis());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 用户ID为空不处理直接跳过
|
||||
|
@ -82,40 +110,6 @@ public class WebSocketServer {
|
|||
return;
|
||||
}
|
||||
|
||||
// 维护通道是否已初始化
|
||||
SocketSession<GettySocketOperator> socketSession = SessionCenter.getSessionBySessionId(socketChannel.getId());
|
||||
if (ObjectUtil.isEmpty(socketSession) && ClientMessageTypeEnum.USER_CONNECTION_AUTHENTICATION.getCode().equals(WebSocketMessageDTO.getClientMsgType())) {
|
||||
// 操作api包装
|
||||
GettySocketOperator gettySocketOperator = new GettySocketOperator(socketChannel);
|
||||
|
||||
// 回复消息
|
||||
WebSocketMessageDTO replyMsg = new WebSocketMessageDTO();
|
||||
replyMsg.setServerMsgType(ServerMessageTypeEnum.SYS_REPLY_MSG_TYPE.getCode());
|
||||
replyMsg.setToUserId(WebSocketMessageDTO.getFormUserId());
|
||||
|
||||
try {
|
||||
// 校验token是否合法
|
||||
JwtContext.me().validateTokenWithException(WebSocketMessageDTO.getData().toString());
|
||||
|
||||
// 设置回复内容
|
||||
replyMsg.setData(socketChannel.getId());
|
||||
|
||||
// 创建会话对象
|
||||
socketSession = new SocketSession<>();
|
||||
socketSession.setSessionId(socketChannel.getId());
|
||||
socketSession.setUserId(WebSocketMessageDTO.getFormUserId());
|
||||
socketSession.setSocketOperatorApi(gettySocketOperator);
|
||||
socketSession.setConnectionTime(System.currentTimeMillis());
|
||||
|
||||
// 维护会话
|
||||
SessionCenter.addSocketSession(socketSession);
|
||||
} finally {
|
||||
// 回复消息
|
||||
gettySocketOperator.writeAndFlush(replyMsg);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 会话建立成功执行业务逻辑
|
||||
if (ObjectUtil.isNotEmpty(socketSession)) {
|
||||
|
||||
|
@ -143,7 +137,6 @@ public class WebSocketServer {
|
|||
**/
|
||||
@OnError
|
||||
public void onError(Session session, Throwable error) {
|
||||
log.error("发生错误");
|
||||
error.printStackTrace();
|
||||
log.error("session 发生错误:" + session.getId());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,8 +4,7 @@ import cn.hutool.core.util.ObjectUtil;
|
|||
import cn.stylefeng.roses.kernel.socket.api.session.pojo.SocketSession;
|
||||
import cn.stylefeng.roses.kernel.socket.business.websocket.operator.channel.GettySocketOperator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
|
@ -102,9 +101,13 @@ public class SessionCenter {
|
|||
* @date 2021/6/1 下午3:25
|
||||
**/
|
||||
public static void closed(String sessionId) {
|
||||
for (List<SocketSession<GettySocketOperator>> values : socketSessionMap.values()) {
|
||||
if (ObjectUtil.isNotEmpty(values)) {
|
||||
values.removeIf(item -> item.getSessionId().equals(sessionId));
|
||||
Set<Map.Entry<String, List<SocketSession<GettySocketOperator>>>> entrySet = socketSessionMap.entrySet();
|
||||
Iterator<Map.Entry<String, List<SocketSession<GettySocketOperator>>>> iterator = entrySet.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<String, List<SocketSession<GettySocketOperator>>> next = iterator.next();
|
||||
List<SocketSession<GettySocketOperator>> value = next.getValue();
|
||||
if (ObjectUtil.isNotEmpty(value)) {
|
||||
value.removeIf(gettySocketOperatorSocketSession -> gettySocketOperatorSocketSession.getSessionId().equals(sessionId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
<!--引入WebSocket模块-->
|
||||
<dependency>
|
||||
<groupId>cn.stylefeng.roses</groupId>
|
||||
<artifactId>socket-sdk-websocket</artifactId>
|
||||
<artifactId>socket-api</artifactId>
|
||||
<version>${roses.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ import cn.stylefeng.roses.kernel.message.db.service.SysMessageService;
|
|||
import cn.stylefeng.roses.kernel.rule.enums.YesOrNotEnum;
|
||||
import cn.stylefeng.roses.kernel.socket.api.SocketOperatorApi;
|
||||
import cn.stylefeng.roses.kernel.socket.api.enums.ServerMessageTypeEnum;
|
||||
import cn.stylefeng.roses.kernel.socket.api.exception.SocketException;
|
||||
import cn.stylefeng.roses.kernel.system.api.UserServiceApi;
|
||||
import cn.stylefeng.roses.kernel.system.api.pojo.user.request.SysUserRequest;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
|
@ -98,23 +99,28 @@ public class MessageDbServiceImpl implements MessageApi {
|
|||
}
|
||||
|
||||
Set<Long> userIdSet = new HashSet<>(userIds);
|
||||
SysMessage sysMessage = new SysMessage();
|
||||
BeanUtil.copyProperties(messageSendRequest, sysMessage);
|
||||
// 初始化默认值
|
||||
sysMessage.setReadFlag(MessageReadFlagEnum.UNREAD.getCode());
|
||||
sysMessage.setSendUserId(loginUser.getUserId());
|
||||
userIdSet.forEach(userId -> {
|
||||
for (Long userId : userIdSet) {
|
||||
// 判断用户是否存在
|
||||
if (userServiceApi.userExist(userId)) {
|
||||
SysMessage sysMessage = new SysMessage();
|
||||
BeanUtil.copyProperties(messageSendRequest, sysMessage);
|
||||
// 初始化默认值
|
||||
sysMessage.setReadFlag(MessageReadFlagEnum.UNREAD.getCode());
|
||||
sysMessage.setSendUserId(loginUser.getUserId());
|
||||
sysMessage.setReceiveUserId(userId);
|
||||
sendMsgList.add(sysMessage);
|
||||
}
|
||||
});
|
||||
}
|
||||
sysMessageService.saveBatch(sendMsgList);
|
||||
|
||||
// 给用户发送通知
|
||||
for (SysMessage item : sendMsgList) {
|
||||
socketOperatorApi.sendMsgOfUserSession(ServerMessageTypeEnum.SYS_NOTICE_MSG_TYPE.getCode(), item.getReceiveUserId().toString(), item);
|
||||
try {
|
||||
socketOperatorApi.sendMsgOfUserSession(ServerMessageTypeEnum.SYS_NOTICE_MSG_TYPE.getCode(), item.getReceiveUserId().toString(), item);
|
||||
} catch (SocketException socketException) {
|
||||
// 该用户不在线
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
package cn.stylefeng.roses.kernel.system.api;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 菜单api
|
||||
|
@ -52,4 +53,14 @@ public interface MenuServiceApi {
|
|||
*/
|
||||
List<String> getUserAppCodeList();
|
||||
|
||||
/**
|
||||
* 获取菜单所有的父级菜单ID
|
||||
*
|
||||
* @param menuIds 菜单列表
|
||||
* @return {@link java.util.Set<java.lang.Long>}
|
||||
* @author majianguo
|
||||
* @date 2021/6/22 上午10:11
|
||||
**/
|
||||
Set<Long> getMenuAllParentMenuId(Set<Long> menuIds);
|
||||
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ import cn.stylefeng.roses.kernel.auth.api.context.LoginContext;
|
|||
import cn.stylefeng.roses.kernel.auth.api.pojo.login.LoginUser;
|
||||
import cn.stylefeng.roses.kernel.auth.api.pojo.login.basic.SimpleRoleInfo;
|
||||
import cn.stylefeng.roses.kernel.db.api.DbOperatorApi;
|
||||
import cn.stylefeng.roses.kernel.rule.constants.RuleConstants;
|
||||
import cn.stylefeng.roses.kernel.rule.constants.SymbolConstant;
|
||||
import cn.stylefeng.roses.kernel.rule.constants.TreeConstants;
|
||||
import cn.stylefeng.roses.kernel.rule.enums.StatusEnum;
|
||||
|
@ -407,9 +408,7 @@ public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> impl
|
|||
|
||||
// 菜单查询条件
|
||||
LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(SysMenu::getStatusFlag, StatusEnum.ENABLE.getCode())
|
||||
.eq(SysMenu::getDelFlag, YesOrNotEnum.N.getCode())
|
||||
.orderByAsc(SysMenu::getMenuSort);
|
||||
queryWrapper.eq(SysMenu::getStatusFlag, StatusEnum.ENABLE.getCode()).eq(SysMenu::getDelFlag, YesOrNotEnum.N.getCode()).orderByAsc(SysMenu::getMenuSort);
|
||||
|
||||
// 如果应用编码不为空,则拼接应用编码
|
||||
if (StrUtil.isNotBlank(appCode)) {
|
||||
|
@ -463,6 +462,28 @@ public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> impl
|
|||
return list.stream().map(SysMenu::getAppCode).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Long> getMenuAllParentMenuId(Set<Long> menuIds) {
|
||||
Set<Long> parentMenuIds = new HashSet<>();
|
||||
|
||||
// 查询所有菜单信息
|
||||
List<SysMenu> sysMenus = this.listByIds(menuIds);
|
||||
if (ObjectUtil.isEmpty(sysMenus)) {
|
||||
return parentMenuIds;
|
||||
}
|
||||
|
||||
// 获取所有父菜单ID
|
||||
for (SysMenu sysMenu : sysMenus) {
|
||||
String menuPids = sysMenu.getMenuPids().replaceAll("\\[", "").replaceAll("\\]", "");
|
||||
String[] ids = menuPids.split(SymbolConstant.COMMA);
|
||||
for (String id : ids) {
|
||||
parentMenuIds.add(Long.parseLong(id));
|
||||
}
|
||||
}
|
||||
|
||||
return parentMenuIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取系统菜单
|
||||
*
|
||||
|
|
|
@ -40,6 +40,7 @@ import cn.stylefeng.roses.kernel.rule.enums.StatusEnum;
|
|||
import cn.stylefeng.roses.kernel.rule.enums.YesOrNotEnum;
|
||||
import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException;
|
||||
import cn.stylefeng.roses.kernel.rule.pojo.dict.SimpleDict;
|
||||
import cn.stylefeng.roses.kernel.system.api.MenuServiceApi;
|
||||
import cn.stylefeng.roses.kernel.system.api.UserServiceApi;
|
||||
import cn.stylefeng.roses.kernel.system.api.constants.SystemConstants;
|
||||
import cn.stylefeng.roses.kernel.system.api.exception.SystemModularException;
|
||||
|
@ -62,6 +63,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -91,6 +93,9 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||
@Resource
|
||||
private SysRoleMenuButtonService sysRoleMenuButtonService;
|
||||
|
||||
@Resource
|
||||
private MenuServiceApi menuServiceApi;
|
||||
|
||||
@Override
|
||||
public void add(SysRoleRequest sysRoleRequest) {
|
||||
|
||||
|
@ -219,9 +224,25 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||
List<Long> menuIdList = sysRoleMenuButtonRequest.getGrantMenuIdList();
|
||||
if (ObjectUtil.isNotEmpty(menuIdList)) {
|
||||
List<SysRoleMenu> sysRoleMenus = new ArrayList<>();
|
||||
|
||||
// 角色ID
|
||||
Long roleId = sysRoleMenuButtonRequest.getRoleId();
|
||||
|
||||
// 查询菜单的所有父菜单
|
||||
Set<Long> allParentMenuId = menuServiceApi.getMenuAllParentMenuId(new HashSet<>(menuIdList));
|
||||
|
||||
// 处理所有父菜单
|
||||
for (Long menuId : allParentMenuId) {
|
||||
SysRoleMenu item = new SysRoleMenu();
|
||||
item.setRoleId(roleId);
|
||||
item.setMenuId(menuId);
|
||||
sysRoleMenus.add(item);
|
||||
}
|
||||
|
||||
// 处理菜单本身
|
||||
for (Long menuId : menuIdList) {
|
||||
SysRoleMenu item = new SysRoleMenu();
|
||||
item.setRoleId(sysRoleMenuButtonRequest.getRoleId());
|
||||
item.setRoleId(roleId);
|
||||
item.setMenuId(menuId);
|
||||
sysRoleMenus.add(item);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue