mirror of
https://gitee.com/dromara/RuoYi-Vue-Plus.git
synced 2026-04-04 01:33:23 +08:00
update 增加消息推送模块注释
This commit is contained in:
@@ -14,6 +14,7 @@ public interface ISysMessageService {
|
||||
|
||||
/**
|
||||
* 查询当前用户消息盒子数据
|
||||
* 按系统消息、通知公告、工作流消息分类返回
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 消息盒子数据
|
||||
@@ -23,69 +24,70 @@ public interface ISysMessageService {
|
||||
/**
|
||||
* 发送指定用户文本消息
|
||||
*
|
||||
* @param userId 目标用户
|
||||
* @param message 文本消息
|
||||
* @param userId 目标用户ID
|
||||
* @param message 文本消息内容
|
||||
*/
|
||||
void sendMessage(Long userId, String message);
|
||||
|
||||
/**
|
||||
* 广播文本消息
|
||||
* 全局广播文本消息
|
||||
*
|
||||
* @param message 文本消息
|
||||
* @param message 文本消息内容
|
||||
*/
|
||||
void sendMessage(String message);
|
||||
|
||||
/**
|
||||
* 发送指定用户消息
|
||||
* 发送指定用户自定义消息体
|
||||
*
|
||||
* @param userId 目标用户
|
||||
* @param payload 推送消息体
|
||||
* @param userId 目标用户ID
|
||||
* @param payload 消息推送体
|
||||
*/
|
||||
void sendMessage(Long userId, PushPayloadDTO payload);
|
||||
|
||||
/**
|
||||
* 广播消息
|
||||
* 全局广播自定义消息体
|
||||
*
|
||||
* @param payload 推送消息体
|
||||
* @param payload 消息推送体
|
||||
*/
|
||||
void sendMessage(PushPayloadDTO payload);
|
||||
|
||||
/**
|
||||
* 发布指定用户消息
|
||||
* 批量发布消息给指定用户列表
|
||||
*
|
||||
* @param userIds 用户ID列表
|
||||
* @param payload 推送消息体
|
||||
* @param userIds 用户ID集合
|
||||
* @param payload 消息推送体
|
||||
*/
|
||||
void publishMessage(List<Long> userIds, PushPayloadDTO payload);
|
||||
|
||||
/**
|
||||
* 发布广播文本消息
|
||||
* 发布全局广播文本消息
|
||||
*
|
||||
* @param message 文本消息
|
||||
* @param message 文本消息内容
|
||||
*/
|
||||
void publishAll(String message);
|
||||
|
||||
/**
|
||||
* 发布广播消息
|
||||
* 发布全局广播自定义消息体
|
||||
*
|
||||
* @param payload 推送消息体
|
||||
* @param payload 消息推送体
|
||||
*/
|
||||
void publishAll(PushPayloadDTO payload);
|
||||
|
||||
/**
|
||||
* 记录全局消息
|
||||
* 存储全局广播消息到数据库
|
||||
*
|
||||
* @param payload 推送消息体
|
||||
* @return 回填消息ID后的推送消息体
|
||||
* @param payload 消息推送体
|
||||
* @return 回填消息ID后的消息体
|
||||
*/
|
||||
PushPayloadDTO storeAll(PushPayloadDTO payload);
|
||||
|
||||
/**
|
||||
* 记录指定用户消息
|
||||
* 存储指定用户消息到数据库
|
||||
*
|
||||
* @param userIds 用户ID列表
|
||||
* @param payload 推送消息体
|
||||
* @return 回填消息ID后的推送消息体
|
||||
* @param userIds 用户ID集合
|
||||
* @param payload 消息推送体
|
||||
* @return 回填消息ID后的消息体
|
||||
*/
|
||||
PushPayloadDTO storeUsers(List<Long> userIds, PushPayloadDTO payload);
|
||||
|
||||
}
|
||||
|
||||
@@ -37,15 +37,45 @@ import java.util.concurrent.TimeUnit;
|
||||
@Service
|
||||
public class SysMessageServiceImpl implements ISysMessageService, MessageService {
|
||||
|
||||
/**
|
||||
* 全局广播用户标识(所有用户可见)
|
||||
*/
|
||||
private static final String GLOBAL_USER_IDS = "0";
|
||||
|
||||
/**
|
||||
* 消息分类:系统消息
|
||||
*/
|
||||
private static final String CATEGORY_SYSTEM = "system";
|
||||
|
||||
/**
|
||||
* 消息分类:通知公告
|
||||
*/
|
||||
private static final String CATEGORY_NOTICE = "notice";
|
||||
|
||||
/**
|
||||
* 消息分类:工作流
|
||||
*/
|
||||
private static final String CATEGORY_WORKFLOW = "workflow";
|
||||
|
||||
/**
|
||||
* 消息盒子每页展示最大条数
|
||||
*/
|
||||
private static final int BOX_LIMIT = 100;
|
||||
|
||||
/**
|
||||
* 消息盒子展示消息天数(仅展示30天内)
|
||||
*/
|
||||
private static final long BOX_DAYS = 30L;
|
||||
|
||||
private final SysMessageMapper baseMapper;
|
||||
|
||||
/**
|
||||
* 查询当前用户消息盒子数据
|
||||
* 按系统消息、通知公告、工作流消息分类返回
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 分类消息盒子数据
|
||||
*/
|
||||
@Override
|
||||
public SysMessageBoxVo queryMessageBox(Long userId) {
|
||||
SysMessageBoxVo box = new SysMessageBoxVo();
|
||||
@@ -55,51 +85,110 @@ public class SysMessageServiceImpl implements ISysMessageService, MessageService
|
||||
return box;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送指定用户文本消息
|
||||
*
|
||||
* @param userId 目标用户ID
|
||||
* @param message 文本消息内容
|
||||
*/
|
||||
@Override
|
||||
public void sendMessage(Long userId, String message) {
|
||||
PushHelper.sendMessage(userId, buildDefaultMessage(message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 全局广播文本消息
|
||||
*
|
||||
* @param message 文本消息内容
|
||||
*/
|
||||
@Override
|
||||
public void sendMessage(String message) {
|
||||
PushHelper.sendMessage(buildDefaultMessage(message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送指定用户自定义消息体
|
||||
*
|
||||
* @param userId 目标用户ID
|
||||
* @param payload 消息推送体
|
||||
*/
|
||||
@Override
|
||||
public void sendMessage(Long userId, PushPayloadDTO payload) {
|
||||
PushHelper.sendMessage(userId, payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* 全局广播自定义消息体
|
||||
*
|
||||
* @param payload 消息推送体
|
||||
*/
|
||||
@Override
|
||||
public void sendMessage(PushPayloadDTO payload) {
|
||||
PushHelper.sendMessage(payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量发布消息给指定用户列表
|
||||
*
|
||||
* @param userIds 用户ID集合
|
||||
* @param payload 消息推送体
|
||||
*/
|
||||
@Override
|
||||
public void publishMessage(List<Long> userIds, PushPayloadDTO payload) {
|
||||
PushHelper.publishMessage(userIds, storeUsers(userIds, payload));
|
||||
}
|
||||
|
||||
/**
|
||||
* 发布全局广播文本消息
|
||||
*
|
||||
* @param message 文本消息内容
|
||||
*/
|
||||
@Override
|
||||
public void publishAll(String message) {
|
||||
publishAll(buildDefaultMessage(message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 发布全局广播自定义消息体
|
||||
*
|
||||
* @param payload 消息推送体
|
||||
*/
|
||||
@Override
|
||||
public void publishAll(PushPayloadDTO payload) {
|
||||
PushHelper.publishAll(storeAll(payload));
|
||||
}
|
||||
|
||||
/**
|
||||
* 存储全局广播消息到数据库
|
||||
*
|
||||
* @param payload 消息推送体
|
||||
* @return 回填消息ID后的消息体
|
||||
*/
|
||||
@Override
|
||||
public PushPayloadDTO storeAll(PushPayloadDTO payload) {
|
||||
return storeMessage(null, payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* 存储指定用户消息到数据库
|
||||
*
|
||||
* @param userIds 用户ID集合
|
||||
* @param payload 消息推送体
|
||||
* @return 回填消息ID后的消息体
|
||||
*/
|
||||
@Override
|
||||
public PushPayloadDTO storeUsers(List<Long> userIds, PushPayloadDTO payload) {
|
||||
return storeMessage(userIds, payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* 统一消息存储逻辑
|
||||
* 判断是否需要存入消息盒子,需要则插入数据库
|
||||
*
|
||||
* @param userIds 用户ID集合(为null则全局广播)
|
||||
* @param payload 消息推送体
|
||||
* @return 回填消息ID后的消息体
|
||||
*/
|
||||
private PushPayloadDTO storeMessage(List<Long> userIds, PushPayloadDTO payload) {
|
||||
if (!supportsMessageBox(payload)) {
|
||||
return payload;
|
||||
@@ -110,20 +199,42 @@ public class SysMessageServiceImpl implements ISysMessageService, MessageService
|
||||
return payload;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据分类和用户ID查询消息列表
|
||||
* 仅查询30天内、最多100条、按时间倒序
|
||||
*
|
||||
* @param category 消息分类
|
||||
* @param userId 用户ID
|
||||
* @return 消息VO列表
|
||||
*/
|
||||
private List<SysMessageVo> selectMessageList(String category, Long userId) {
|
||||
LambdaQueryWrapper<SysMessage> lqw = Wrappers.lambdaQuery();
|
||||
// 分类匹配
|
||||
lqw.eq(SysMessage::getCategory, category);
|
||||
// 仅查询30天内消息
|
||||
lqw.ge(SysMessage::getCreateTime, new Date(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(BOX_DAYS)));
|
||||
// 全局消息 或 当前用户在接收人范围内
|
||||
lqw.and(wrapper -> wrapper.eq(SysMessage::getSendUserIds, GLOBAL_USER_IDS)
|
||||
.or()
|
||||
.apply(DataBaseHelper.findInSet(userId, "send_user_ids")));
|
||||
// 按创建时间+消息ID倒序
|
||||
lqw.orderByDesc(SysMessage::getCreateTime, SysMessage::getMessageId);
|
||||
// 分页查询(只查第一页,最多100条)
|
||||
List<SysMessage> list = baseMapper.selectList(new Page<>(1, BOX_LIMIT, false), lqw);
|
||||
// 转换为VO并返回
|
||||
return list.stream().map(this::buildVo).toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建消息实体(用于数据库存储)
|
||||
*
|
||||
* @param userIds 接收用户ID集合
|
||||
* @param payload 消息推送体
|
||||
* @return 系统消息实体
|
||||
*/
|
||||
private SysMessage buildMessage(List<Long> userIds, PushPayloadDTO payload) {
|
||||
SysMessage message = new SysMessage();
|
||||
// 设置消息ID(无则自动生成)
|
||||
message.setMessageId(payload.getMessageId() == null ? IdGeneratorUtil.nextLongId() : payload.getMessageId());
|
||||
message.setCategory(resolveCategory(payload));
|
||||
message.setType(payload.getType());
|
||||
@@ -133,20 +244,35 @@ public class SysMessageServiceImpl implements ISysMessageService, MessageService
|
||||
message.setContent(resolveContent(payload));
|
||||
message.setDataJson(JsonUtils.toJsonString(payload.getData()));
|
||||
message.setPath(payload.getPath());
|
||||
// 设置接收人(无则为全局广播)
|
||||
message.setSendUserIds(CollUtil.isEmpty(userIds) ? GLOBAL_USER_IDS : StringUtils.joinComma(userIds));
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* 消息实体转换为展示VO
|
||||
*
|
||||
* @param entity 消息实体
|
||||
* @return 消息展示VO
|
||||
*/
|
||||
private SysMessageVo buildVo(SysMessage entity) {
|
||||
SysMessageVo vo = MapstructUtils.convert(entity, SysMessageVo.class);
|
||||
vo.setData(parseData(entity.getDataJson()));
|
||||
return vo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断消息是否需要存入消息盒子
|
||||
* 仅系统消息、通知消息需要存入
|
||||
*
|
||||
* @param payload 消息推送体
|
||||
* @return 是否支持存入消息盒子
|
||||
*/
|
||||
private boolean supportsMessageBox(PushPayloadDTO payload) {
|
||||
if (payload == null) {
|
||||
return false;
|
||||
}
|
||||
// 仅消息/通知类型需要存入,排除LLM大模型消息
|
||||
if (StringUtils.equalsAny(payload.getType(), PushTypeEnum.MESSAGE.getType(), PushTypeEnum.NOTICE.getType())) {
|
||||
return !StringUtils.equalsAny(payload.getType(), PushTypeEnum.LLM.getType())
|
||||
&& !StringUtils.equalsAny(payload.getSource(), PushSourceEnum.LLM.getSource());
|
||||
@@ -154,6 +280,12 @@ public class SysMessageServiceImpl implements ISysMessageService, MessageService
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据消息类型/来源自动解析消息分类
|
||||
*
|
||||
* @param payload 消息推送体
|
||||
* @return 消息分类(system/notice/workflow)
|
||||
*/
|
||||
private String resolveCategory(PushPayloadDTO payload) {
|
||||
if (StringUtils.equalsAny(payload.getType(), PushTypeEnum.NOTICE.getType())
|
||||
|| StringUtils.equalsAny(payload.getSource(), PushSourceEnum.NOTICE.getSource())) {
|
||||
@@ -165,6 +297,12 @@ public class SysMessageServiceImpl implements ISysMessageService, MessageService
|
||||
return CATEGORY_SYSTEM;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据消息分类自动生成消息标题
|
||||
*
|
||||
* @param payload 消息推送体
|
||||
* @return 消息标题
|
||||
*/
|
||||
private String resolveTitle(PushPayloadDTO payload) {
|
||||
return switch (resolveCategory(payload)) {
|
||||
case CATEGORY_NOTICE -> "通知公告消息";
|
||||
@@ -173,6 +311,12 @@ public class SysMessageServiceImpl implements ISysMessageService, MessageService
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析消息内容(从data中提取noticeContent)
|
||||
*
|
||||
* @param payload 消息推送体
|
||||
* @return 消息内容
|
||||
*/
|
||||
private String resolveContent(PushPayloadDTO payload) {
|
||||
Object data = payload.getData();
|
||||
if (data instanceof Map<?, ?> map) {
|
||||
@@ -181,6 +325,12 @@ public class SysMessageServiceImpl implements ISysMessageService, MessageService
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析JSON数据字符串为对象
|
||||
*
|
||||
* @param dataJson JSON字符串
|
||||
* @return 解析后对象
|
||||
*/
|
||||
private Object parseData(String dataJson) {
|
||||
if (StringUtils.isBlank(dataJson)) {
|
||||
return null;
|
||||
@@ -188,6 +338,12 @@ public class SysMessageServiceImpl implements ISysMessageService, MessageService
|
||||
return JsonUtils.parseObject(dataJson, Object.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建默认格式的消息体
|
||||
*
|
||||
* @param message 消息内容
|
||||
* @return 默认消息体
|
||||
*/
|
||||
private PushPayloadDTO buildDefaultMessage(String message) {
|
||||
return PushPayloadDTO.of(PushTypeEnum.MESSAGE, PushSourceEnum.BACKEND, message, null);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user