IM聊天功能优化
This commit is contained in:
@@ -22,12 +22,14 @@ import org.jeecg.modules.im.vo.SysImConversationVO;
|
||||
import org.jeecg.modules.im.vo.SysImMessageVO;
|
||||
import org.jeecg.modules.message.websocket.WebSocket;
|
||||
import org.jeecg.modules.system.entity.SysDepart;
|
||||
import org.jeecg.modules.system.entity.SysPermission;
|
||||
import org.jeecg.modules.system.entity.SysUser;
|
||||
import org.jeecg.modules.system.entity.SysUserDepart;
|
||||
import org.jeecg.modules.system.mapper.SysDepartMapper;
|
||||
import org.jeecg.modules.system.mapper.SysUserDepartMapper;
|
||||
import org.jeecg.modules.system.mapper.SysUserMapper;
|
||||
import org.jeecg.modules.system.mapper.SysUserTenantMapper;
|
||||
import org.jeecg.modules.system.service.ISysPermissionService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -50,7 +52,14 @@ public class SysImChatServiceImpl implements ISysImChatService {
|
||||
|
||||
private static final String CONV_TYPE_SINGLE = "single";
|
||||
private static final String MSG_TYPE_TEXT = "text";
|
||||
private static final String MSG_TYPE_IMAGE = "image";
|
||||
private static final String MSG_TYPE_BIZ_RECORD = "biz_record";
|
||||
private static final String MSG_IMAGE_PREVIEW = "[图片]";
|
||||
private static final String MSG_BIZ_RECORD_PREVIEW = "[业务数据]";
|
||||
private static final String IM_RECORD_QUERY_KEY = "imRecordId";
|
||||
|
||||
@Autowired
|
||||
private ISysPermissionService sysPermissionService;
|
||||
@Autowired
|
||||
private SysImConversationMapper conversationMapper;
|
||||
@Autowired
|
||||
@@ -169,13 +178,16 @@ public class SysImChatServiceImpl implements ISysImChatService {
|
||||
messageMapper.insert(message);
|
||||
|
||||
SysImConversation conversation = conversationMapper.selectById(dto.getConversationId());
|
||||
conversation.setLastContent(truncate(message.getContent(), 200));
|
||||
//update-begin---author:cursor ---date:20260528 for:【IM聊天-OA】图片消息会话摘要-----------
|
||||
conversation.setLastContent(truncate(resolveLastContent(message.getMsgType(), message.getContent()), 200));
|
||||
//update-end---author:cursor ---date:20260528 for:【IM聊天-OA】图片消息会话摘要-----------
|
||||
conversation.setLastTime(now);
|
||||
conversation.setUpdateTime(now);
|
||||
conversationMapper.updateById(conversation);
|
||||
|
||||
memberMapper.incrementUnreadExceptSender(dto.getConversationId(), userId);
|
||||
SysImMessageVO messageVo = toMessageVo(message, userId);
|
||||
fillBizRecordReceiverPermission(messageVo, message, userId, new HashMap<>(4));
|
||||
pushChatMessage(dto.getConversationId(), userId, messageVo);
|
||||
return messageVo;
|
||||
}
|
||||
@@ -376,8 +388,11 @@ public class SysImChatServiceImpl implements ISysImChatService {
|
||||
}
|
||||
}
|
||||
List<SysImMessageVO> result = new ArrayList<>(messages.size());
|
||||
Map<String, Boolean> receiverPermissionCache = new HashMap<>(16);
|
||||
for (SysImMessage message : messages) {
|
||||
result.add(toMessageVo(message, currentUserId, userMap));
|
||||
SysImMessageVO vo = toMessageVo(message, currentUserId, userMap);
|
||||
fillBizRecordReceiverPermission(vo, message, currentUserId, receiverPermissionCache);
|
||||
result.add(vo);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -401,6 +416,97 @@ public class SysImChatServiceImpl implements ISysImChatService {
|
||||
}
|
||||
return vo;
|
||||
}
|
||||
|
||||
//update-begin---author:xsl ---date:20260528 for:【IM聊天-OA】发送方提示接收方无功能权限-----------
|
||||
private void fillBizRecordReceiverPermission(SysImMessageVO vo, SysImMessage message, String currentUserId, Map<String, Boolean> cache) {
|
||||
if (!Boolean.TRUE.equals(vo.getMine()) || !MSG_TYPE_BIZ_RECORD.equals(vo.getMsgType())) {
|
||||
return;
|
||||
}
|
||||
String pagePath = extractBizRecordPagePath(vo.getContent());
|
||||
if (oConvertUtils.isEmpty(pagePath)) {
|
||||
return;
|
||||
}
|
||||
String peerUserId = resolvePeerUserId(message.getConversationId(), currentUserId);
|
||||
if (oConvertUtils.isEmpty(peerUserId)) {
|
||||
return;
|
||||
}
|
||||
String cacheKey = peerUserId + "|" + normalizeBizPagePath(pagePath);
|
||||
Boolean hasPermission = cache.get(cacheKey);
|
||||
if (hasPermission == null) {
|
||||
hasPermission = hasUserPagePathPermission(peerUserId, pagePath);
|
||||
cache.put(cacheKey, hasPermission);
|
||||
}
|
||||
vo.setReceiverHasBizPagePermission(hasPermission);
|
||||
}
|
||||
|
||||
private String resolvePeerUserId(String conversationId, String currentUserId) {
|
||||
List<SysImConversationMember> members = memberMapper.selectList(new LambdaQueryWrapper<SysImConversationMember>()
|
||||
.eq(SysImConversationMember::getConversationId, conversationId));
|
||||
if (members == null || members.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
for (SysImConversationMember member : members) {
|
||||
if (!currentUserId.equals(member.getUserId())) {
|
||||
return member.getUserId();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String extractBizRecordPagePath(String content) {
|
||||
if (oConvertUtils.isEmpty(content)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
JSONObject obj = JSONObject.parseObject(content);
|
||||
return obj.getString("pagePath");
|
||||
} catch (Exception e) {
|
||||
log.debug("解析业务明细 pagePath 失败: {}", e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private String normalizeBizPagePath(String pagePath) {
|
||||
if (oConvertUtils.isEmpty(pagePath)) {
|
||||
return "";
|
||||
}
|
||||
String path = pagePath.split("\\?")[0];
|
||||
if (path.contains("&" + IM_RECORD_QUERY_KEY + "=") || path.contains("?" + IM_RECORD_QUERY_KEY + "=")) {
|
||||
path = path.replaceAll("[?&]" + IM_RECORD_QUERY_KEY + "=[^&]*", "");
|
||||
if (path.endsWith("?") || path.endsWith("&")) {
|
||||
path = path.substring(0, path.length() - 1);
|
||||
}
|
||||
}
|
||||
if (path.endsWith("/") && path.length() > 1) {
|
||||
path = path.substring(0, path.length() - 1);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
private boolean hasUserPagePathPermission(String userId, String pagePath) {
|
||||
String targetPath = normalizeBizPagePath(pagePath);
|
||||
if (oConvertUtils.isEmpty(userId) || oConvertUtils.isEmpty(targetPath)) {
|
||||
return false;
|
||||
}
|
||||
List<SysPermission> permissions = sysPermissionService.queryByUser(userId);
|
||||
if (permissions == null || permissions.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
for (SysPermission permission : permissions) {
|
||||
if (permission == null || oConvertUtils.isEmpty(permission.getUrl())) {
|
||||
continue;
|
||||
}
|
||||
if (permission.getMenuType() != null && permission.getMenuType() == 2) {
|
||||
continue;
|
||||
}
|
||||
String url = normalizeBizPagePath(permission.getUrl());
|
||||
if (targetPath.equals(url)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//update-end---author:xsl ---date:20260528 for:【IM聊天-OA】发送方提示接收方无功能权限-----------
|
||||
//update-end---author:cursor ---date:20260528 for:【IM聊天-OA】消息列表批量填充发送人-----------
|
||||
|
||||
private void pushChatMessage(String conversationId, String senderId, SysImMessageVO messageVo) {
|
||||
@@ -433,4 +539,34 @@ public class SysImChatServiceImpl implements ISysImChatService {
|
||||
}
|
||||
return content.length() <= maxLen ? content : content.substring(0, maxLen);
|
||||
}
|
||||
|
||||
//update-begin---author:cursor ---date:20260528 for:【IM聊天-OA】图片消息会话摘要-----------
|
||||
private String resolveLastContent(String msgType, String content) {
|
||||
if (MSG_TYPE_IMAGE.equals(msgType)) {
|
||||
return MSG_IMAGE_PREVIEW;
|
||||
}
|
||||
//update-begin---author:xsl ---date:20260528 for:【IM聊天-OA】业务明细消息会话摘要-----------
|
||||
if (MSG_TYPE_BIZ_RECORD.equals(msgType)) {
|
||||
return resolveBizRecordPreview(content);
|
||||
}
|
||||
//update-end---author:xsl ---date:20260528 for:【IM聊天-OA】业务明细消息会话摘要-----------
|
||||
return content;
|
||||
}
|
||||
|
||||
private String resolveBizRecordPreview(String content) {
|
||||
if (oConvertUtils.isEmpty(content)) {
|
||||
return MSG_BIZ_RECORD_PREVIEW;
|
||||
}
|
||||
try {
|
||||
JSONObject obj = JSONObject.parseObject(content);
|
||||
String pageTitle = obj.getString("pageTitle");
|
||||
if (oConvertUtils.isNotEmpty(pageTitle)) {
|
||||
return MSG_BIZ_RECORD_PREVIEW + pageTitle;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.debug("解析业务明细消息摘要失败: {}", e.getMessage());
|
||||
}
|
||||
return MSG_BIZ_RECORD_PREVIEW;
|
||||
}
|
||||
//update-end---author:cursor ---date:20260528 for:【IM聊天-OA】图片消息会话摘要-----------
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@ public class SysImMessageVO {
|
||||
private String msgType;
|
||||
@Schema(description = "是否本人发送")
|
||||
private Boolean mine;
|
||||
@Schema(description = "业务明细接收方是否有对应功能权限(仅发送方可见)")
|
||||
private Boolean receiverHasBizPagePermission;
|
||||
@Schema(description = "发送时间")
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
|
||||
Reference in New Issue
Block a user