Commit 3dd717939354799e4f3e97c7df8512209effa368

Authored by YunaiV
1 parent 210a8d5a

refactor: 扁平化 IM WebSocket 通知推送 API

- 将 WebSocket 推送入口统一为 userId/userIds + conversationType + contentType + payload
- 移除业务侧 ImNotificationWebSocketDTO 构造和无会话专用发送入口
- 收敛私聊、群聊、频道、好友、加群申请、RTC 通知调用路径
- 精简 ImNotificationWebSocketDTO,仅保留统一外壳字段
- 保留群消息 payload 的 receiptStatus、readCount、receiverUserIds
- 更新相关单元测试,覆盖群消息通知 payload 字段
Showing 101 changed files with 576 additions and 614 deletions

Too many changes.

To preserve performance only 100 of 101 files are displayed.

sql/mysql/ruoyi-vue-pro.sql
@@ -1396,39 +1396,39 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st @@ -1396,39 +1396,39 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st
1396 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3559, 1, '等待验证', '0', 'im_friend_request_handle_result', 0, 'warning', '', NULL, '1', '2026-05-04 02:43:41', '1', '2026-05-04 02:43:41', b'0'); 1396 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3559, 1, '等待验证', '0', 'im_friend_request_handle_result', 0, 'warning', '', NULL, '1', '2026-05-04 02:43:41', '1', '2026-05-04 02:43:41', b'0');
1397 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3560, 2, '已添加', '1', 'im_friend_request_handle_result', 0, 'success', '', NULL, '1', '2026-05-04 02:43:41', '1', '2026-05-04 02:43:41', b'0'); 1397 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3560, 2, '已添加', '1', 'im_friend_request_handle_result', 0, 'success', '', NULL, '1', '2026-05-04 02:43:41', '1', '2026-05-04 02:43:41', b'0');
1398 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3561, 3, '已拒绝', '2', 'im_friend_request_handle_result', 0, 'info', '', NULL, '1', '2026-05-04 02:43:41', '1', '2026-05-04 02:43:41', b'0'); 1398 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3561, 3, '已拒绝', '2', 'im_friend_request_handle_result', 0, 'info', '', NULL, '1', '2026-05-04 02:43:41', '1', '2026-05-04 02:43:41', b'0');
1399 -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3562, 101, '文本', '101', 'im_message_type', 0, '', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');  
1400 -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3563, 102, '图片', '102', 'im_message_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');  
1401 -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3564, 103, '语音', '103', 'im_message_type', 0, 'warning', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');  
1402 -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3565, 104, '视频', '104', 'im_message_type', 0, 'warning', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');  
1403 -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3566, 105, '文件', '105', 'im_message_type', 0, 'info', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');  
1404 -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3568, 2101, '撤回', '2101', 'im_message_type', 0, 'danger', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');  
1405 -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3569, 2200, '回执', '2200', 'im_message_type', 0, 'warning', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');  
1406 -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3570, 2201, '已读', '2201', 'im_message_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');  
1407 -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3571, 1501, '群创建', '1501', 'im_message_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');  
1408 -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3572, 1502, '群信息变更', '1502', 'im_message_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');  
1409 -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3573, 1503, '入群申请', '1503', 'im_message_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');  
1410 -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3574, 1504, '成员退群', '1504', 'im_message_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');  
1411 -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3575, 1505, '入群申请通过', '1505', 'im_message_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');  
1412 -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3576, 1506, '入群申请拒绝', '1506', 'im_message_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');  
1413 -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3577, 1507, '群主转让', '1507', 'im_message_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');  
1414 -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3578, 1508, '成员被移出', '1508', 'im_message_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');  
1415 -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3579, 1509, '成员加入', '1509', 'im_message_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');  
1416 -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3580, 1510, '自由进群', '1510', 'im_message_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');  
1417 -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3581, 1511, '群解散', '1511', 'im_message_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');  
1418 -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3582, 1512, '成员禁言', '1512', 'im_message_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');  
1419 -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3583, 1513, '成员取消禁言', '1513', 'im_message_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');  
1420 -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3584, 1514, '全群禁言', '1514', 'im_message_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');  
1421 -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3585, 1515, '全群取消禁言', '1515', 'im_message_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');  
1422 -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3586, 1516, '成员昵称变更', '1516', 'im_message_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');  
1423 -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3587, 1517, '添加管理员', '1517', 'im_message_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');  
1424 -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3588, 1518, '撤销管理员', '1518', 'im_message_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');  
1425 -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3589, 1519, '群公告变更', '1519', 'im_message_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');  
1426 -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3590, 1520, '群名变更', '1520', 'im_message_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');  
1427 -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3591, 1531, '群消息置顶', '1531', 'im_message_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');  
1428 -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3592, 1532, '群消息取消置顶', '1532', 'im_message_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');  
1429 -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3593, 1533, '群封禁变更', '1533', 'im_message_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');  
1430 -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3594, 1204, '新增好友', '1204', 'im_message_type', 0, 'success', '', NULL, 'admin', '2026-05-05 13:26:53', 'admin', '2026-05-05 13:26:53', b'0');  
1431 -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3595, 1205, '好友被删除', '1205', 'im_message_type', 0, 'warning', '', NULL, 'admin', '2026-05-05 13:26:53', 'admin', '2026-05-05 13:26:53', b'0'); 1399 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3562, 101, '文本', '101', 'im_content_type', 0, '', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
  1400 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3563, 102, '图片', '102', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
  1401 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3564, 103, '语音', '103', 'im_content_type', 0, 'warning', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
  1402 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3565, 104, '视频', '104', 'im_content_type', 0, 'warning', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
  1403 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3566, 105, '文件', '105', 'im_content_type', 0, 'info', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
  1404 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3568, 2101, '撤回', '2101', 'im_content_type', 0, 'danger', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
  1405 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3569, 2200, '回执', '2200', 'im_content_type', 0, 'warning', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
  1406 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3570, 2201, '已读', '2201', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
  1407 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3571, 1501, '群创建', '1501', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
  1408 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3572, 1502, '群信息变更', '1502', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
  1409 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3573, 1503, '入群申请', '1503', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
  1410 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3574, 1504, '成员退群', '1504', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
  1411 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3575, 1505, '入群申请通过', '1505', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
  1412 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3576, 1506, '入群申请拒绝', '1506', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
  1413 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3577, 1507, '群主转让', '1507', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
  1414 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3578, 1508, '成员被移出', '1508', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
  1415 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3579, 1509, '成员加入', '1509', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
  1416 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3580, 1510, '自由进群', '1510', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
  1417 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3581, 1511, '群解散', '1511', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
  1418 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3582, 1512, '成员禁言', '1512', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
  1419 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3583, 1513, '成员取消禁言', '1513', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
  1420 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3584, 1514, '全群禁言', '1514', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
  1421 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3585, 1515, '全群取消禁言', '1515', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
  1422 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3586, 1516, '成员昵称变更', '1516', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
  1423 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3587, 1517, '添加管理员', '1517', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
  1424 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3588, 1518, '撤销管理员', '1518', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
  1425 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3589, 1519, '群公告变更', '1519', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
  1426 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3590, 1520, '群名变更', '1520', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
  1427 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3591, 1531, '群消息置顶', '1531', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
  1428 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3592, 1532, '群消息取消置顶', '1532', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
  1429 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3593, 1533, '群封禁变更', '1533', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
  1430 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3594, 1204, '新增好友', '1204', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 13:26:53', 'admin', '2026-05-05 13:26:53', b'0');
  1431 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3595, 1205, '好友被删除', '1205', 'im_content_type', 0, 'warning', '', NULL, 'admin', '2026-05-05 13:26:53', 'admin', '2026-05-05 13:26:53', b'0');
1432 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3596, 1, '搜索', '1', 'im_group_add_source', 0, '', '', NULL, '', '2026-05-06 09:26:36', '', '2026-05-06 09:26:36', b'0'); 1432 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3596, 1, '搜索', '1', 'im_group_add_source', 0, '', '', NULL, '', '2026-05-06 09:26:36', '', '2026-05-06 09:26:36', b'0');
1433 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3597, 2, '邀请', '2', 'im_group_add_source', 0, '', '', NULL, '', '2026-05-06 09:26:36', '', '2026-05-06 09:26:36', b'0'); 1433 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3597, 2, '邀请', '2', 'im_group_add_source', 0, '', '', NULL, '', '2026-05-06 09:26:36', '', '2026-05-06 09:26:36', b'0');
1434 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3598, 3, '扫码', '3', 'im_group_add_source', 0, '', '', NULL, '', '2026-05-06 09:26:36', '', '2026-05-06 09:26:36', b'0'); 1434 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3598, 3, '扫码', '3', 'im_group_add_source', 0, '', '', NULL, '', '2026-05-06 09:26:36', '', '2026-05-06 09:26:36', b'0');
@@ -1474,9 +1474,9 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st @@ -1474,9 +1474,9 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st
1474 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061114, 3, '已拒绝', '30', 'im_rtc_participant_status', 0, 'warning', '', '接通前点拒接', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0'); 1474 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061114, 3, '已拒绝', '30', 'im_rtc_participant_status', 0, 'warning', '', '接通前点拒接', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0');
1475 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061115, 4, '未应答', '40', 'im_rtc_participant_status', 0, 'info', '', '通话已结束仍未应答', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0'); 1475 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061115, 4, '未应答', '40', 'im_rtc_participant_status', 0, 'info', '', '通话已结束仍未应答', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0');
1476 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061116, 5, '已离开', '50', 'im_rtc_participant_status', 0, 'success', '', '接通后挂断 / 离开', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0'); 1476 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061116, 5, '已离开', '50', 'im_rtc_participant_status', 0, 'success', '', '接通后挂断 / 离开', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0');
1477 -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061117, 1610, '通话开始', '1610', 'im_message_type', 0, 'info', '', '入消息流;私聊定向通知,群聊全员广播', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0');  
1478 -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061118, 1611, '通话结束', '1611', 'im_message_type', 0, 'info', '', '入消息流;私聊准气泡,群聊系统 tip', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0');  
1479 -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061119, 125, '素材', '125', 'im_message_type', 0, 'success', '', '频道运营推送的图文卡片消息', '1', '2026-05-18 13:14:34', '1', '2026-05-18 13:14:34', b'0'); 1477 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061117, 1610, '通话开始', '1610', 'im_content_type', 0, 'info', '', '入消息流;私聊定向通知,群聊全员广播', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0');
  1478 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061118, 1611, '通话结束', '1611', 'im_content_type', 0, 'info', '', '入消息流;私聊准气泡,群聊系统 tip', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0');
  1479 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061119, 125, '素材', '125', 'im_content_type', 0, 'success', '', '频道运营推送的图文卡片消息', '1', '2026-05-18 13:14:34', '1', '2026-05-18 13:14:34', b'0');
1480 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061120, 1, '富文本', '1', 'im_channel_material_type', 0, 'primary', '', '', '1', '2026-05-19 14:09:25', '1', '2026-05-19 14:09:25', b'0'); 1480 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061120, 1, '富文本', '1', 'im_channel_material_type', 0, 'primary', '', '', '1', '2026-05-19 14:09:25', '1', '2026-05-19 14:09:25', b'0');
1481 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061121, 2, '外链', '2', 'im_channel_material_type', 0, 'info', '', '', '1', '2026-05-19 14:09:25', '1', '2026-05-19 14:09:25', b'0'); 1481 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061121, 2, '外链', '2', 'im_channel_material_type', 0, 'info', '', '', '1', '2026-05-19 14:09:25', '1', '2026-05-19 14:09:25', b'0');
1482 COMMIT; 1482 COMMIT;
@@ -1689,7 +1689,7 @@ INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creat @@ -1689,7 +1689,7 @@ INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creat
1689 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2133, 'MES 销售退货单状态', 'mes_wm_return_sales_status', 0, 'MES 销售退货单状态枚举', '1', '2026-04-03 17:20:25', '1', '2026-04-05 15:05:39', b'0', NULL); 1689 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2133, 'MES 销售退货单状态', 'mes_wm_return_sales_status', 0, 'MES 销售退货单状态枚举', '1', '2026-04-03 17:20:25', '1', '2026-04-05 15:05:39', b'0', NULL);
1690 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2135, 'MES 上下工状态类型', 'mes_pro_work_record_type', 0, 'MES 上下工状态类型', '1', '2026-04-05 14:07:27', '1', '2026-04-05 14:07:27', b'0', NULL); 1690 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2135, 'MES 上下工状态类型', 'mes_pro_work_record_type', 0, 'MES 上下工状态类型', '1', '2026-04-05 14:07:27', '1', '2026-04-05 14:07:27', b'0', NULL);
1691 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2138, 'MES 生产入库单状态', 'mes_wm_product_produce_status', 0, 'MES 生产入库单状态', '1', '2026-04-05 15:53:46', '1', '2026-04-05 15:53:46', b'0', '1970-01-01 00:00:00'); 1691 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2138, 'MES 生产入库单状态', 'mes_wm_product_produce_status', 0, 'MES 生产入库单状态', '1', '2026-04-05 15:53:46', '1', '2026-04-05 15:53:46', b'0', '1970-01-01 00:00:00');
1692 -INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2200, 'IM 消息类型', 'im_message_type', 0, '对应 ImMessageTypeEnum', 'admin', '2026-04-30 11:35:07', 'admin', '2026-04-30 11:35:07', b'0', NULL); 1692 +INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2200, 'IM 内容类型', 'im_content_type', 0, '对应 ImContentTypeEnum', 'admin', '2026-04-30 11:35:07', 'admin', '2026-04-30 11:35:07', b'0', NULL);
1693 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2202, 'IM 消息回执状态', 'im_message_receipt_status', 0, '对应 ImMessageReceiptStatusEnum', 'admin', '2026-04-30 11:35:07', 'admin', '2026-04-30 11:35:07', b'0', NULL); 1693 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2202, 'IM 消息回执状态', 'im_message_receipt_status', 0, '对应 ImMessageReceiptStatusEnum', 'admin', '2026-04-30 11:35:07', 'admin', '2026-04-30 11:35:07', b'0', NULL);
1694 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2203, 'IM 好友状态', 'im_friend_status', 0, '0=正常 / 1=已删除', 'admin', '2026-04-30 11:35:07', 'admin', '2026-04-30 11:35:07', b'0', NULL); 1694 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2203, 'IM 好友状态', 'im_friend_status', 0, '0=正常 / 1=已删除', 'admin', '2026-04-30 11:35:07', 'admin', '2026-04-30 11:35:07', b'0', NULL);
1695 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2204, 'IM 群状态', 'im_group_status', 0, '0=正常 / 1=已解散', 'admin', '2026-04-30 11:35:07', 'admin', '2026-04-30 11:35:07', b'0', NULL); 1695 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2204, 'IM 群状态', 'im_group_status', 0, '0=正常 / 1=已解散', 'admin', '2026-04-30 11:35:07', 'admin', '2026-04-30 11:35:07', b'0', NULL);
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/message/vo/channel/ImChannelMessageRespVO.java
@@ -29,7 +29,7 @@ public class ImChannelMessageRespVO { @@ -29,7 +29,7 @@ public class ImChannelMessageRespVO {
29 private String materialCoverUrl; 29 private String materialCoverUrl;
30 30
31 @Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "125") 31 @Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "125")
32 - private Integer type; // 参见 ImMessageTypeEnum 枚举类 32 + private Integer type; // 参见 ImContentTypeEnum 枚举类
33 33
34 @Schema(description = "消息内容;payload JSON 快照") 34 @Schema(description = "消息内容;payload JSON 快照")
35 private String content; 35 private String content;
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/message/vo/group/ImGroupMessageManagerPageReqVO.java
@@ -22,7 +22,7 @@ public class ImGroupMessageManagerPageReqVO extends PageParam { @@ -22,7 +22,7 @@ public class ImGroupMessageManagerPageReqVO extends PageParam {
22 private Long senderId; 22 private Long senderId;
23 23
24 @Schema(description = "消息类型", example = "1") 24 @Schema(description = "消息类型", example = "1")
25 - private Integer type; // 参见 ImMessageTypeEnum 枚举类 25 + private Integer type; // 参见 ImContentTypeEnum 枚举类
26 26
27 @Schema(description = "消息内容", example = "你好") 27 @Schema(description = "消息内容", example = "你好")
28 private String content; 28 private String content;
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/message/vo/group/ImGroupMessageManagerRespVO.java
@@ -29,7 +29,7 @@ public class ImGroupMessageManagerRespVO { @@ -29,7 +29,7 @@ public class ImGroupMessageManagerRespVO {
29 private String senderNickname; 29 private String senderNickname;
30 30
31 @Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") 31 @Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
32 - private Integer type; // 参见 ImMessageTypeEnum 枚举类 32 + private Integer type; // 参见 ImContentTypeEnum 枚举类
33 33
34 @Schema(description = "消息内容(JSON 格式)", requiredMode = Schema.RequiredMode.REQUIRED) 34 @Schema(description = "消息内容(JSON 格式)", requiredMode = Schema.RequiredMode.REQUIRED)
35 private String content; 35 private String content;
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/message/vo/privates/ImPrivateMessageManagerPageReqVO.java
@@ -22,7 +22,7 @@ public class ImPrivateMessageManagerPageReqVO extends PageParam { @@ -22,7 +22,7 @@ public class ImPrivateMessageManagerPageReqVO extends PageParam {
22 private Long receiverId; 22 private Long receiverId;
23 23
24 @Schema(description = "消息类型", example = "1") 24 @Schema(description = "消息类型", example = "1")
25 - private Integer type; // 参见 ImMessageTypeEnum 枚举类 25 + private Integer type; // 参见 ImContentTypeEnum 枚举类
26 26
27 @Schema(description = "消息内容", example = "你好") 27 @Schema(description = "消息内容", example = "你好")
28 private String content; 28 private String content;
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/message/vo/privates/ImPrivateMessageManagerRespVO.java
@@ -28,7 +28,7 @@ public class ImPrivateMessageManagerRespVO { @@ -28,7 +28,7 @@ public class ImPrivateMessageManagerRespVO {
28 private String receiverNickname; 28 private String receiverNickname;
29 29
30 @Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") 30 @Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
31 - private Integer type; // 参见 ImMessageTypeEnum 枚举类 31 + private Integer type; // 参见 ImContentTypeEnum 枚举类
32 32
33 @Schema(description = "消息内容(JSON 格式)", requiredMode = Schema.RequiredMode.REQUIRED) 33 @Schema(description = "消息内容(JSON 格式)", requiredMode = Schema.RequiredMode.REQUIRED)
34 private String content; 34 private String content;
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/statistics/ImStatisticsManagerController.java
@@ -112,7 +112,7 @@ public class ImStatisticsManagerController { @@ -112,7 +112,7 @@ public class ImStatisticsManagerController {
112 } 112 }
113 113
114 @GetMapping("/message-type-distribution") 114 @GetMapping("/message-type-distribution")
115 - @Operation(summary = "获得消息类型分布(最近 30 天)") 115 + @Operation(summary = "获得内容类型分布(最近 30 天)")
116 @PreAuthorize("@ss.hasPermission('im:manager:statistics:query')") 116 @PreAuthorize("@ss.hasPermission('im:manager:statistics:query')")
117 public CommonResult<List<ImStatisticsManagerMessageTypeRespVO>> getMessageTypeDistribution() { 117 public CommonResult<List<ImStatisticsManagerMessageTypeRespVO>> getMessageTypeDistribution() {
118 LocalDateTime endTime = LocalDate.now().plusDays(1).atStartOfDay(); 118 LocalDateTime endTime = LocalDate.now().plusDays(1).atStartOfDay();
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/statistics/vo/ImStatisticsManagerMessageTypeRespVO.java
@@ -3,12 +3,12 @@ package cn.iocoder.yudao.module.im.controller.admin.manager.statistics.vo; @@ -3,12 +3,12 @@ package cn.iocoder.yudao.module.im.controller.admin.manager.statistics.vo;
3 import io.swagger.v3.oas.annotations.media.Schema; 3 import io.swagger.v3.oas.annotations.media.Schema;
4 import lombok.Data; 4 import lombok.Data;
5 5
6 -@Schema(description = "管理后台 - IM 数据看板消息类型分布项 Response VO") 6 +@Schema(description = "管理后台 - IM 数据看板内容类型分布项 Response VO")
7 @Data 7 @Data
8 public class ImStatisticsManagerMessageTypeRespVO { 8 public class ImStatisticsManagerMessageTypeRespVO {
9 9
10 @Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") 10 @Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
11 - private Integer type; // 参见 ImMessageTypeEnum 枚举类 11 + private Integer type; // 参见 ImContentTypeEnum 枚举类
12 12
13 @Schema(description = "消息数", requiredMode = Schema.RequiredMode.REQUIRED, example = "8000") 13 @Schema(description = "消息数", requiredMode = Schema.RequiredMode.REQUIRED, example = "8000")
14 private Long value; 14 private Long value;
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/group/ImGroupMessageSendReqVO.java
1 package cn.iocoder.yudao.module.im.controller.admin.message.vo.group; 1 package cn.iocoder.yudao.module.im.controller.admin.message.vo.group;
2 2
3 import cn.iocoder.yudao.framework.common.validation.InEnum; 3 import cn.iocoder.yudao.framework.common.validation.InEnum;
4 -import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum; 4 +import cn.iocoder.yudao.module.im.enums.ImContentTypeEnum;
5 import com.fasterxml.jackson.annotation.JsonIgnore; 5 import com.fasterxml.jackson.annotation.JsonIgnore;
6 import io.swagger.v3.oas.annotations.media.Schema; 6 import io.swagger.v3.oas.annotations.media.Schema;
7 import jakarta.validation.constraints.AssertTrue; 7 import jakarta.validation.constraints.AssertTrue;
@@ -28,7 +28,7 @@ public class ImGroupMessageSendReqVO { @@ -28,7 +28,7 @@ public class ImGroupMessageSendReqVO {
28 28
29 @Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") 29 @Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
30 @NotNull(message = "消息类型不能为空") 30 @NotNull(message = "消息类型不能为空")
31 - @InEnum(ImMessageTypeEnum.class) 31 + @InEnum(ImContentTypeEnum.class)
32 private Integer type; 32 private Integer type;
33 33
34 @Schema(description = "消息内容,JSON 格式", requiredMode = Schema.RequiredMode.REQUIRED, example = "{\"content\":\"你好\"}") 34 @Schema(description = "消息内容,JSON 格式", requiredMode = Schema.RequiredMode.REQUIRED, example = "{\"content\":\"你好\"}")
@@ -47,7 +47,7 @@ public class ImGroupMessageSendReqVO { @@ -47,7 +47,7 @@ public class ImGroupMessageSendReqVO {
47 @AssertTrue(message = "消息类型不允许") 47 @AssertTrue(message = "消息类型不允许")
48 @JsonIgnore 48 @JsonIgnore
49 public boolean isTypeNormal() { 49 public boolean isTypeNormal() {
50 - return type == null || ImMessageTypeEnum.validate(type).isNormal(); 50 + return type == null || ImContentTypeEnum.validate(type).isNormal();
51 } 51 }
52 52
53 } 53 }
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/privates/ImPrivateMessageSendReqVO.java
1 package cn.iocoder.yudao.module.im.controller.admin.message.vo.privates; 1 package cn.iocoder.yudao.module.im.controller.admin.message.vo.privates;
2 2
3 import cn.iocoder.yudao.framework.common.validation.InEnum; 3 import cn.iocoder.yudao.framework.common.validation.InEnum;
4 -import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum; 4 +import cn.iocoder.yudao.module.im.enums.ImContentTypeEnum;
5 import com.fasterxml.jackson.annotation.JsonIgnore; 5 import com.fasterxml.jackson.annotation.JsonIgnore;
6 import io.swagger.v3.oas.annotations.media.Schema; 6 import io.swagger.v3.oas.annotations.media.Schema;
7 import jakarta.validation.constraints.AssertTrue; 7 import jakarta.validation.constraints.AssertTrue;
@@ -26,7 +26,7 @@ public class ImPrivateMessageSendReqVO { @@ -26,7 +26,7 @@ public class ImPrivateMessageSendReqVO {
26 26
27 @Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") 27 @Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
28 @NotNull(message = "消息类型不能为空") 28 @NotNull(message = "消息类型不能为空")
29 - @InEnum(ImMessageTypeEnum.class) 29 + @InEnum(ImContentTypeEnum.class)
30 private Integer type; 30 private Integer type;
31 31
32 @Schema(description = "消息内容,JSON 格式", requiredMode = Schema.RequiredMode.REQUIRED, example = "{\"content\":\"你好\"}") 32 @Schema(description = "消息内容,JSON 格式", requiredMode = Schema.RequiredMode.REQUIRED, example = "{\"content\":\"你好\"}")
@@ -42,7 +42,7 @@ public class ImPrivateMessageSendReqVO { @@ -42,7 +42,7 @@ public class ImPrivateMessageSendReqVO {
42 @AssertTrue(message = "消息类型不允许") 42 @AssertTrue(message = "消息类型不允许")
43 @JsonIgnore 43 @JsonIgnore
44 public boolean isTypeNormal() { 44 public boolean isTypeNormal() {
45 - return type == null || ImMessageTypeEnum.validate(type).isNormal(); 45 + return type == null || ImContentTypeEnum.validate(type).isNormal();
46 } 46 }
47 47
48 } 48 }
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/ImChannelMessageDO.java
@@ -4,7 +4,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; @@ -4,7 +4,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler; 4 import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler;
5 import cn.iocoder.yudao.module.im.dal.dataobject.channel.ImChannelDO; 5 import cn.iocoder.yudao.module.im.dal.dataobject.channel.ImChannelDO;
6 import cn.iocoder.yudao.module.im.dal.dataobject.channel.ImChannelMaterialDO; 6 import cn.iocoder.yudao.module.im.dal.dataobject.channel.ImChannelMaterialDO;
7 -import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum; 7 +import cn.iocoder.yudao.module.im.enums.ImContentTypeEnum;
8 import com.baomidou.mybatisplus.annotation.KeySequence; 8 import com.baomidou.mybatisplus.annotation.KeySequence;
9 import com.baomidou.mybatisplus.annotation.TableField; 9 import com.baomidou.mybatisplus.annotation.TableField;
10 import com.baomidou.mybatisplus.annotation.TableId; 10 import com.baomidou.mybatisplus.annotation.TableId;
@@ -54,7 +54,7 @@ public class ImChannelMessageDO extends BaseDO { @@ -54,7 +54,7 @@ public class ImChannelMessageDO extends BaseDO {
54 /** 54 /**
55 * 消息类型 55 * 消息类型
56 * <p> 56 * <p>
57 - * 枚举 {@link ImMessageTypeEnum} 57 + * 枚举 {@link ImContentTypeEnum}
58 */ 58 */
59 private Integer type; 59 private Integer type;
60 /** 60 /**
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/ImGroupMessageDO.java
@@ -5,7 +5,7 @@ import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler; @@ -5,7 +5,7 @@ import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler;
5 import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupDO; 5 import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupDO;
6 import cn.iocoder.yudao.module.im.enums.message.ImMessageReceiptStatusEnum; 6 import cn.iocoder.yudao.module.im.enums.message.ImMessageReceiptStatusEnum;
7 import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum; 7 import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum;
8 -import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum; 8 +import cn.iocoder.yudao.module.im.enums.ImContentTypeEnum;
9 import com.baomidou.mybatisplus.annotation.KeySequence; 9 import com.baomidou.mybatisplus.annotation.KeySequence;
10 import com.baomidou.mybatisplus.annotation.TableField; 10 import com.baomidou.mybatisplus.annotation.TableField;
11 import com.baomidou.mybatisplus.annotation.TableId; 11 import com.baomidou.mybatisplus.annotation.TableId;
@@ -54,7 +54,7 @@ public class ImGroupMessageDO extends BaseDO { @@ -54,7 +54,7 @@ public class ImGroupMessageDO extends BaseDO {
54 /** 54 /**
55 * 消息类型 55 * 消息类型
56 * <p> 56 * <p>
57 - * 枚举 {@link ImMessageTypeEnum} 57 + * 枚举 {@link ImContentTypeEnum}
58 */ 58 */
59 private Integer type; 59 private Integer type;
60 /** 60 /**
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/ImPrivateMessageDO.java
@@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.im.dal.dataobject.message; @@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.im.dal.dataobject.message;
3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 import cn.iocoder.yudao.module.im.enums.message.ImMessageReceiptStatusEnum; 4 import cn.iocoder.yudao.module.im.enums.message.ImMessageReceiptStatusEnum;
5 import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum; 5 import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum;
6 -import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum; 6 +import cn.iocoder.yudao.module.im.enums.ImContentTypeEnum;
7 import com.baomidou.mybatisplus.annotation.KeySequence; 7 import com.baomidou.mybatisplus.annotation.KeySequence;
8 import com.baomidou.mybatisplus.annotation.TableId; 8 import com.baomidou.mybatisplus.annotation.TableId;
9 import com.baomidou.mybatisplus.annotation.TableName; 9 import com.baomidou.mybatisplus.annotation.TableName;
@@ -50,7 +50,7 @@ public class ImPrivateMessageDO extends BaseDO { @@ -50,7 +50,7 @@ public class ImPrivateMessageDO extends BaseDO {
50 /** 50 /**
51 * 消息类型 51 * 消息类型
52 * <p> 52 * <p>
53 - * 枚举 {@link ImMessageTypeEnum} 53 + * 枚举 {@link ImContentTypeEnum}
54 */ 54 */
55 private Integer type; 55 private Integer type;
56 /** 56 /**
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/message/AudioMessage.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/AudioMessage.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.message; 1 +package cn.iocoder.yudao.module.im.dal.dataobject.message.content;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 4
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/message/CardMessage.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/CardMessage.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.message; 1 +package cn.iocoder.yudao.module.im.dal.dataobject.message.content;
2 2
3 import cn.iocoder.yudao.module.im.enums.ImConversationTypeEnum; 3 import cn.iocoder.yudao.module.im.enums.ImConversationTypeEnum;
4 import lombok.Data; 4 import lombok.Data;
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/message/FaceMessage.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/FaceMessage.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.message; 1 +package cn.iocoder.yudao.module.im.dal.dataobject.message.content;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 4
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/message/FileMessage.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/FileMessage.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.message; 1 +package cn.iocoder.yudao.module.im.dal.dataobject.message.content;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 4
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/message/ImageMessage.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/ImageMessage.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.message; 1 +package cn.iocoder.yudao.module.im.dal.dataobject.message.content;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 4
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/message/LocationMessage.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/LocationMessage.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.message; 1 +package cn.iocoder.yudao.module.im.dal.dataobject.message.content;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 4
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/message/MaterialMessage.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/MaterialMessage.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.message; 1 +package cn.iocoder.yudao.module.im.dal.dataobject.message.content;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 import lombok.experimental.Accessors; 4 import lombok.experimental.Accessors;
@@ -6,7 +6,7 @@ import lombok.experimental.Accessors; @@ -6,7 +6,7 @@ import lombok.experimental.Accessors;
6 /** 6 /**
7 * 频道素材消息 payload 7 * 频道素材消息 payload
8 * <p> 8 * <p>
9 - * 对应 {@link cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum#MATERIAL}(type=125)。 9 + * 对应 {@link cn.iocoder.yudao.module.im.enums.ImContentTypeEnum#MATERIAL}(type=125)。
10 * 客户端按本字段集渲染图文卡片; 10 * 客户端按本字段集渲染图文卡片;
11 * 富文本正文不在本 payload 中传递,点击详情时另调 /im/channel/material/get-content?id= 按需拉取。 11 * 富文本正文不在本 payload 中传递,点击详情时另调 /im/channel/material/get-content?id= 按需拉取。
12 */ 12 */
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/message/MergeMessage.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/MergeMessage.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.message; 1 +package cn.iocoder.yudao.module.im.dal.dataobject.message.content;
2 2
3 -import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum; 3 +import cn.iocoder.yudao.module.im.enums.ImContentTypeEnum;
4 import lombok.Data; 4 import lombok.Data;
5 5
6 import java.util.List; 6 import java.util.List;
@@ -47,7 +47,7 @@ public class MergeMessage { @@ -47,7 +47,7 @@ public class MergeMessage {
47 /** 47 /**
48 * 消息类型 48 * 消息类型
49 * <p> 49 * <p>
50 - * 枚举 {@link ImMessageTypeEnum} 50 + * 枚举 {@link ImContentTypeEnum}
51 */ 51 */
52 private Integer type; 52 private Integer type;
53 /** 53 /**
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/message/QuoteMessage.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/QuoteMessage.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.message; 1 +package cn.iocoder.yudao.module.im.dal.dataobject.message.content;
2 2
3 -import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum; 3 +import cn.iocoder.yudao.module.im.enums.ImContentTypeEnum;
4 import lombok.Data; 4 import lombok.Data;
5 import lombok.experimental.Accessors; 5 import lombok.experimental.Accessors;
6 6
@@ -39,7 +39,7 @@ public class QuoteMessage { @@ -39,7 +39,7 @@ public class QuoteMessage {
39 /** 39 /**
40 * 被引用消息类型 40 * 被引用消息类型
41 * <p> 41 * <p>
42 - * 枚举 {@link ImMessageTypeEnum} 42 + * 枚举 {@link ImContentTypeEnum}
43 */ 43 */
44 private Integer type; 44 private Integer type;
45 /** 45 /**
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/message/RecallMessage.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/RecallMessage.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.message; 1 +package cn.iocoder.yudao.module.im.dal.dataobject.message.content;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 import lombok.experimental.Accessors; 4 import lombok.experimental.Accessors;
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/message/TextMessage.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/TextMessage.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.message; 1 +package cn.iocoder.yudao.module.im.dal.dataobject.message.content;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 4
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/message/VideoMessage.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/content/VideoMessage.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.message; 1 +package cn.iocoder.yudao.module.im.dal.dataobject.message.content;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 4
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/statistics/ImStatisticsManagerMapper.java
@@ -154,7 +154,7 @@ public interface ImStatisticsManagerMapper { @@ -154,7 +154,7 @@ public interface ImStatisticsManagerMapper {
154 @Param("endTime") LocalDateTime endTime); 154 @Param("endTime") LocalDateTime endTime);
155 155
156 /** 156 /**
157 - * 区间内消息类型分布(私聊+群聊合并) 157 + * 区间内内容类型分布(私聊+群聊合并)
158 * 158 *
159 * @return [{type: 0, count: 123}, ...] 159 * @return [{type: 0, count: 123}, ...]
160 */ 160 */
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/enums/message/ImMessageTypeEnum.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/enums/ImContentTypeEnum.java
1 -package cn.iocoder.yudao.module.im.enums.message; 1 +package cn.iocoder.yudao.module.im.enums;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.lang.Assert; 4 import cn.hutool.core.lang.Assert;
@@ -11,13 +11,13 @@ import java.util.Arrays; @@ -11,13 +11,13 @@ import java.util.Arrays;
11 import java.util.Set; 11 import java.util.Set;
12 12
13 /** 13 /**
14 - * IM 消息类型枚举 14 + * IM 内容类型枚举
15 * 15 *
16 * @author 芋道源码 16 * @author 芋道源码
17 */ 17 */
18 @Getter 18 @Getter
19 @RequiredArgsConstructor 19 @RequiredArgsConstructor
20 -public enum ImMessageTypeEnum implements ArrayValuable<Integer> { 20 +public enum ImContentTypeEnum implements ArrayValuable<Integer> {
21 21
22 // ========== 用户聊天消息(101-105 直接复用 OpenIM 段位编号) ========== 22 // ========== 用户聊天消息(101-105 直接复用 OpenIM 段位编号) ==========
23 /** 23 /**
@@ -335,7 +335,7 @@ public enum ImMessageTypeEnum implements ArrayValuable&lt;Integer&gt; { @@ -335,7 +335,7 @@ public enum ImMessageTypeEnum implements ArrayValuable&lt;Integer&gt; {
335 */ 335 */
336 GROUP_BANNED(1533, "群封禁变更", true, false); 336 GROUP_BANNED(1533, "群封禁变更", true, false);
337 337
338 - public static final Integer[] ARRAYS = Arrays.stream(values()).map(ImMessageTypeEnum::getType).toArray(Integer[]::new); 338 + public static final Integer[] ARRAYS = Arrays.stream(values()).map(ImContentTypeEnum::getType).toArray(Integer[]::new);
339 339
340 private static final Set<Integer> FRIEND_NOTIFICATION_TYPES = CollUtil.newHashSet( 340 private static final Set<Integer> FRIEND_NOTIFICATION_TYPES = CollUtil.newHashSet(
341 FRIEND_REQUEST_APPROVED.type, 341 FRIEND_REQUEST_APPROVED.type,
@@ -392,8 +392,8 @@ public enum ImMessageTypeEnum implements ArrayValuable&lt;Integer&gt; { @@ -392,8 +392,8 @@ public enum ImMessageTypeEnum implements ArrayValuable&lt;Integer&gt; {
392 * @param type 消息类型 392 * @param type 消息类型
393 * @return 枚举实例 393 * @return 枚举实例
394 */ 394 */
395 - public static ImMessageTypeEnum validate(Integer type) {  
396 - ImMessageTypeEnum result = ArrayUtil.firstMatch(item -> item.type.equals(type), values()); 395 + public static ImContentTypeEnum validate(Integer type) {
  396 + ImContentTypeEnum result = ArrayUtil.firstMatch(item -> item.type.equals(type), values());
397 Assert.notNull(result, "未注册的消息类型 type={}", type); 397 Assert.notNull(result, "未注册的消息类型 type={}", type);
398 return result; 398 return result;
399 } 399 }
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/enums/ImConversationTypeEnum.java
@@ -16,6 +16,7 @@ import java.util.Objects; @@ -16,6 +16,7 @@ import java.util.Objects;
16 @Getter 16 @Getter
17 public enum ImConversationTypeEnum implements ArrayValuable<Integer> { 17 public enum ImConversationTypeEnum implements ArrayValuable<Integer> {
18 18
  19 + NONE(0, "无会话"), // 无会话
19 PRIVATE(1, "私聊"), // 私聊 20 PRIVATE(1, "私聊"), // 私聊
20 GROUP(2, "群聊"), // 群聊 21 GROUP(2, "群聊"), // 群聊
21 CHANNEL(3, "频道"); // 频道 / 公众号 22 CHANNEL(3, "频道"); // 频道 / 公众号
@@ -36,6 +37,10 @@ public enum ImConversationTypeEnum implements ArrayValuable&lt;Integer&gt; { @@ -36,6 +37,10 @@ public enum ImConversationTypeEnum implements ArrayValuable&lt;Integer&gt; {
36 return ARRAYS; 37 return ARRAYS;
37 } 38 }
38 39
  40 + public static boolean isNone(Integer type) {
  41 + return Objects.equals(NONE.type, type);
  42 + }
  43 +
39 public static boolean isPrivate(Integer type) { 44 public static boolean isPrivate(Integer type) {
40 return Objects.equals(PRIVATE.type, type); 45 return Objects.equals(PRIVATE.type, type);
41 } 46 }
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/friend/ImFriendRequestServiceImpl.java
@@ -17,10 +17,9 @@ import cn.iocoder.yudao.module.im.enums.friend.ImFriendStateEnum; @@ -17,10 +17,9 @@ import cn.iocoder.yudao.module.im.enums.friend.ImFriendStateEnum;
17 import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum; 17 import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum;
18 import cn.iocoder.yudao.module.im.framework.config.ImProperties; 18 import cn.iocoder.yudao.module.im.framework.config.ImProperties;
19 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService; 19 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService;
20 -import cn.iocoder.yudao.module.im.service.websocket.dto.ImPrivateMessageDTO;  
21 -import cn.iocoder.yudao.module.im.service.websocket.dto.notification.friend.FriendRequestApprovedNotification;  
22 -import cn.iocoder.yudao.module.im.service.websocket.dto.notification.friend.FriendRequestNotification;  
23 -import cn.iocoder.yudao.module.im.service.websocket.dto.notification.friend.FriendRequestRejectedNotification; 20 +import cn.iocoder.yudao.module.im.service.websocket.notification.friend.FriendRequestApprovedNotification;
  21 +import cn.iocoder.yudao.module.im.service.websocket.notification.friend.FriendRequestNotification;
  22 +import cn.iocoder.yudao.module.im.service.websocket.notification.friend.FriendRequestRejectedNotification;
24 import cn.iocoder.yudao.module.system.api.user.AdminUserApi; 23 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
25 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; 24 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
26 import jakarta.annotation.Resource; 25 import jakarta.annotation.Resource;
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupRequestServiceImpl.java
@@ -17,11 +17,10 @@ import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum; @@ -17,11 +17,10 @@ import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum;
17 import cn.iocoder.yudao.module.im.service.message.ImGroupMessageService; 17 import cn.iocoder.yudao.module.im.service.message.ImGroupMessageService;
18 import cn.iocoder.yudao.module.im.service.message.dto.ImGroupMessageSendDTO; 18 import cn.iocoder.yudao.module.im.service.message.dto.ImGroupMessageSendDTO;
19 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService; 19 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService;
20 -import cn.iocoder.yudao.module.im.service.websocket.dto.ImPrivateMessageDTO;  
21 -import cn.iocoder.yudao.module.im.service.websocket.dto.notification.group.BaseGroupNotification;  
22 -import cn.iocoder.yudao.module.im.service.websocket.dto.notification.group.GroupRequestApprovedNotification;  
23 -import cn.iocoder.yudao.module.im.service.websocket.dto.notification.group.GroupRequestReceivedNotification;  
24 -import cn.iocoder.yudao.module.im.service.websocket.dto.notification.group.GroupRequestRejectedNotification; 20 +import cn.iocoder.yudao.module.im.service.websocket.notification.group.BaseGroupNotification;
  21 +import cn.iocoder.yudao.module.im.service.websocket.notification.group.GroupRequestApprovedNotification;
  22 +import cn.iocoder.yudao.module.im.service.websocket.notification.group.GroupRequestReceivedNotification;
  23 +import cn.iocoder.yudao.module.im.service.websocket.notification.group.GroupRequestRejectedNotification;
25 import cn.iocoder.yudao.module.system.api.user.AdminUserApi; 24 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
26 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; 25 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
27 import jakarta.annotation.Resource; 26 import jakarta.annotation.Resource;
@@ -97,7 +96,7 @@ public class ImGroupRequestServiceImpl implements ImGroupRequestService { @@ -97,7 +96,7 @@ public class ImGroupRequestServiceImpl implements ImGroupRequestService {
97 // 3. 情况二:群开启了审批,创建或复用一条主动申请记录 96 // 3. 情况二:群开启了审批,创建或复用一条主动申请记录
98 ImGroupRequestDO request = createOrResetApplyRequest(groupId, userId, reqVO); 97 ImGroupRequestDO request = createOrResetApplyRequest(groupId, userId, reqVO);
99 98
100 - // 4. 1503 私聊定向推群主 + 全部管理员(多端同步);payload 携带申请方昵称 / 头像 99 + // 4. 1503 定向推群主 + 全部管理员(多端同步);payload 携带申请方昵称 / 头像
101 AdminUserRespDTO applyUser = adminUserApi.getUser(userId); 100 AdminUserRespDTO applyUser = adminUserApi.getUser(userId);
102 GroupRequestReceivedNotification payload = buildRequestNotification(group, request, applyUser); 101 GroupRequestReceivedNotification payload = buildRequestNotification(group, request, applyUser);
103 for (Long receiverUserId : getGroupMemberListByOwnerAndAdminUserIds(group)) { 102 for (Long receiverUserId : getGroupMemberListByOwnerAndAdminUserIds(group)) {
@@ -139,12 +138,12 @@ public class ImGroupRequestServiceImpl implements ImGroupRequestService { @@ -139,12 +138,12 @@ public class ImGroupRequestServiceImpl implements ImGroupRequestService {
139 groupMemberService.addGroupMember(request.getGroupId(), request.getUserId(), 138 groupMemberService.addGroupMember(request.getGroupId(), request.getUserId(),
140 ImGroupMemberRoleEnum.NORMAL.getRole(), request.getAddSource(), request.getInviterUserId()); 139 ImGroupMemberRoleEnum.NORMAL.getRole(), request.getAddSource(), request.getInviterUserId());
141 140
142 - // 5.1 1505 私聊推送给申请人 + 群主 + 全部管理员(每端单推) 141 + // 5.1 1505 定向推送给申请人 + 群主 + 全部管理员(每端单推)
143 GroupRequestApprovedNotification payload = (GroupRequestApprovedNotification) new GroupRequestApprovedNotification() 142 GroupRequestApprovedNotification payload = (GroupRequestApprovedNotification) new GroupRequestApprovedNotification()
144 .setRequestId(request.getId()).setGroupId(request.getGroupId()).setUserId(request.getUserId()) 143 .setRequestId(request.getId()).setGroupId(request.getGroupId()).setUserId(request.getUserId())
145 .setOperatorUserId(userId); 144 .setOperatorUserId(userId);
146 broadcastToOwnerAdminsAndApplicant(request.getGroupId(), request.getUserId(), payload, 145 broadcastToOwnerAdminsAndApplicant(request.getGroupId(), request.getUserId(), payload,
147 - ImMessageTypeEnum.GROUP_REQUEST_APPROVED.getType(), userId); 146 + ImContentTypeEnum.GROUP_REQUEST_APPROVED.getType(), userId);
148 // 5.2 群事件:主动申请 → 1510 自由进群;被邀请 → 1509 成员加入 147 // 5.2 群事件:主动申请 → 1510 自由进群;被邀请 → 1509 成员加入
149 if (request.getInviterUserId() == null) { 148 if (request.getInviterUserId() == null) {
150 groupMessageService.sendGroupMessage(userId, 149 groupMessageService.sendGroupMessage(userId,
@@ -174,12 +173,12 @@ public class ImGroupRequestServiceImpl implements ImGroupRequestService { @@ -174,12 +173,12 @@ public class ImGroupRequestServiceImpl implements ImGroupRequestService {
174 throw exception(GROUP_REQUEST_HANDLED); 173 throw exception(GROUP_REQUEST_HANDLED);
175 } 174 }
176 175
177 - // 3. 1506 私聊推送给申请人 + 群主 + 全部管理员 176 + // 3. 1506 定向推送给申请人 + 群主 + 全部管理员
178 GroupRequestRejectedNotification payload = (GroupRequestRejectedNotification) new GroupRequestRejectedNotification() 177 GroupRequestRejectedNotification payload = (GroupRequestRejectedNotification) new GroupRequestRejectedNotification()
179 .setRequestId(request.getId()).setGroupId(request.getGroupId()).setUserId(request.getUserId()) 178 .setRequestId(request.getId()).setGroupId(request.getGroupId()).setUserId(request.getUserId())
180 .setHandleContent(handleContent).setOperatorUserId(userId); 179 .setHandleContent(handleContent).setOperatorUserId(userId);
181 broadcastToOwnerAdminsAndApplicant(request.getGroupId(), request.getUserId(), payload, 180 broadcastToOwnerAdminsAndApplicant(request.getGroupId(), request.getUserId(), payload,
182 - ImMessageTypeEnum.GROUP_REQUEST_REJECTED.getType(), userId); 181 + ImContentTypeEnum.GROUP_REQUEST_REJECTED.getType(), userId);
183 } 182 }
184 183
185 @Override 184 @Override
@@ -395,7 +394,7 @@ public class ImGroupRequestServiceImpl implements ImGroupRequestService { @@ -395,7 +394,7 @@ public class ImGroupRequestServiceImpl implements ImGroupRequestService {
395 } 394 }
396 395
397 /** 396 /**
398 - * 1505 / 1506 受众:申请人 + 群主 + 全部管理员;每端单独推一帧,前端按 receiver 是否申请人区分文案 397 + * 1505 / 1506 受众:申请人 + 群主 + 全部管理员
399 */ 398 */
400 private void broadcastToOwnerAdminsAndApplicant(Long groupId, Long applicantUserId, BaseGroupNotification payload, 399 private void broadcastToOwnerAdminsAndApplicant(Long groupId, Long applicantUserId, BaseGroupNotification payload,
401 Integer messageType, Long operatorUserId) { 400 Integer messageType, Long operatorUserId) {
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupServiceImpl.java
@@ -30,7 +30,7 @@ import cn.iocoder.yudao.module.im.dal.mysql.group.ImGroupMapper; @@ -30,7 +30,7 @@ import cn.iocoder.yudao.module.im.dal.mysql.group.ImGroupMapper;
30 import cn.iocoder.yudao.module.im.enums.group.ImGroupAddSourceEnum; 30 import cn.iocoder.yudao.module.im.enums.group.ImGroupAddSourceEnum;
31 import cn.iocoder.yudao.module.im.enums.group.ImGroupMemberRoleEnum; 31 import cn.iocoder.yudao.module.im.enums.group.ImGroupMemberRoleEnum;
32 import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum; 32 import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum;
33 -import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum; 33 +import cn.iocoder.yudao.module.im.enums.ImContentTypeEnum;
34 import cn.iocoder.yudao.module.im.framework.config.ImProperties; 34 import cn.iocoder.yudao.module.im.framework.config.ImProperties;
35 import cn.iocoder.yudao.module.im.service.friend.ImFriendService; 35 import cn.iocoder.yudao.module.im.service.friend.ImFriendService;
36 import cn.iocoder.yudao.module.im.service.message.ImGroupMessageService; 36 import cn.iocoder.yudao.module.im.service.message.ImGroupMessageService;
@@ -436,7 +436,7 @@ public class ImGroupServiceImpl implements ImGroupService { @@ -436,7 +436,7 @@ public class ImGroupServiceImpl implements ImGroupService {
436 if (message == null || ObjUtil.notEqual(message.getGroupId(), groupId)) { 436 if (message == null || ObjUtil.notEqual(message.getGroupId(), groupId)) {
437 throw exception(MESSAGE_NOT_IN_GROUP); 437 throw exception(MESSAGE_NOT_IN_GROUP);
438 } 438 }
439 - if (!ImMessageTypeEnum.validate(message.getType()).isNormal() 439 + if (!ImContentTypeEnum.validate(message.getType()).isNormal()
440 || ImMessageStatusEnum.RECALL.getStatus().equals(message.getStatus())) { 440 || ImMessageStatusEnum.RECALL.getStatus().equals(message.getStatus())) {
441 throw exception(MESSAGE_NOT_IN_GROUP); 441 throw exception(MESSAGE_NOT_IN_GROUP);
442 } 442 }
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/message/ImChannelMessageServiceImpl.java
@@ -13,12 +13,13 @@ import cn.iocoder.yudao.module.im.dal.dataobject.channel.ImChannelMaterialDO; @@ -13,12 +13,13 @@ import cn.iocoder.yudao.module.im.dal.dataobject.channel.ImChannelMaterialDO;
13 import cn.iocoder.yudao.module.im.dal.dataobject.message.ImChannelMessageDO; 13 import cn.iocoder.yudao.module.im.dal.dataobject.message.ImChannelMessageDO;
14 import cn.iocoder.yudao.module.im.dal.mysql.message.ImChannelMessageMapper; 14 import cn.iocoder.yudao.module.im.dal.mysql.message.ImChannelMessageMapper;
15 import cn.iocoder.yudao.module.im.enums.ImConversationTypeEnum; 15 import cn.iocoder.yudao.module.im.enums.ImConversationTypeEnum;
16 -import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum; 16 +import cn.iocoder.yudao.module.im.enums.ImContentTypeEnum;
17 import cn.iocoder.yudao.module.im.service.channel.ImChannelMaterialService; 17 import cn.iocoder.yudao.module.im.service.channel.ImChannelMaterialService;
18 import cn.iocoder.yudao.module.im.service.conversation.ImConversationReadService; 18 import cn.iocoder.yudao.module.im.service.conversation.ImConversationReadService;
19 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService; 19 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService;
20 -import cn.iocoder.yudao.module.im.service.websocket.dto.ImChannelMessageDTO;  
21 -import cn.iocoder.yudao.module.im.service.websocket.dto.message.MaterialMessage; 20 +import cn.iocoder.yudao.module.im.service.websocket.notification.message.ImChannelMessageNotification;
  21 +import cn.iocoder.yudao.module.im.service.websocket.notification.message.ImMessageReadNotification;
  22 +import cn.iocoder.yudao.module.im.dal.dataobject.message.content.MaterialMessage;
22 import jakarta.annotation.Resource; 23 import jakarta.annotation.Resource;
23 import org.springframework.scheduling.annotation.Async; 24 import org.springframework.scheduling.annotation.Async;
24 import org.springframework.stereotype.Service; 25 import org.springframework.stereotype.Service;
@@ -116,7 +117,7 @@ public class ImChannelMessageServiceImpl implements ImChannelMessageService { @@ -116,7 +117,7 @@ public class ImChannelMessageServiceImpl implements ImChannelMessageService {
116 String payloadJson = JsonUtils.toJsonString(payload); 117 String payloadJson = JsonUtils.toJsonString(payload);
117 // 2.2 落库 1 行 message;reqVO 同名字段(materialId / receiverUserIds)自动拷贝,剩余字段补 set 118 // 2.2 落库 1 行 message;reqVO 同名字段(materialId / receiverUserIds)自动拷贝,剩余字段补 set
118 ImChannelMessageDO message = BeanUtils.toBean(reqVO, ImChannelMessageDO.class).setChannelId(material.getChannelId()) 119 ImChannelMessageDO message = BeanUtils.toBean(reqVO, ImChannelMessageDO.class).setChannelId(material.getChannelId())
119 - .setType(ImMessageTypeEnum.MATERIAL.getType()).setContent(payloadJson).setSendTime(LocalDateTime.now()); 120 + .setType(ImContentTypeEnum.MATERIAL.getType()).setContent(payloadJson).setSendTime(LocalDateTime.now());
120 channelMessageMapper.insert(message); 121 channelMessageMapper.insert(message);
121 122
122 // 3. 异步推 WebSocket:指定用户走点对点;全员(receiverUserIds 为空)走广播 123 // 3. 异步推 WebSocket:指定用户走点对点;全员(receiverUserIds 为空)走广播
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/message/ImGroupMessageServiceImpl.java
@@ -20,7 +20,7 @@ import cn.iocoder.yudao.module.im.enums.ImConversationTypeEnum; @@ -20,7 +20,7 @@ import cn.iocoder.yudao.module.im.enums.ImConversationTypeEnum;
20 import cn.iocoder.yudao.module.im.enums.group.ImGroupMemberRoleEnum; 20 import cn.iocoder.yudao.module.im.enums.group.ImGroupMemberRoleEnum;
21 import cn.iocoder.yudao.module.im.enums.message.ImMessageReceiptStatusEnum; 21 import cn.iocoder.yudao.module.im.enums.message.ImMessageReceiptStatusEnum;
22 import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum; 22 import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum;
23 -import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum; 23 +import cn.iocoder.yudao.module.im.enums.ImContentTypeEnum;
24 import cn.iocoder.yudao.module.im.framework.config.ImProperties; 24 import cn.iocoder.yudao.module.im.framework.config.ImProperties;
25 import cn.iocoder.yudao.module.im.service.conversation.ImConversationReadService; 25 import cn.iocoder.yudao.module.im.service.conversation.ImConversationReadService;
26 import cn.iocoder.yudao.module.im.service.group.ImGroupMemberService; 26 import cn.iocoder.yudao.module.im.service.group.ImGroupMemberService;
@@ -28,9 +28,11 @@ import cn.iocoder.yudao.module.im.service.group.ImGroupService; @@ -28,9 +28,11 @@ import cn.iocoder.yudao.module.im.service.group.ImGroupService;
28 import cn.iocoder.yudao.module.im.service.message.dto.ImGroupMessageSendDTO; 28 import cn.iocoder.yudao.module.im.service.message.dto.ImGroupMessageSendDTO;
29 import cn.iocoder.yudao.module.im.service.sensitiveword.ImSensitiveWordService; 29 import cn.iocoder.yudao.module.im.service.sensitiveword.ImSensitiveWordService;
30 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService; 30 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService;
31 -import cn.iocoder.yudao.module.im.service.websocket.dto.ImGroupMessageDTO;  
32 -import cn.iocoder.yudao.module.im.service.websocket.dto.message.QuoteMessage;  
33 -import cn.iocoder.yudao.module.im.service.websocket.dto.message.RecallMessage; 31 +import cn.iocoder.yudao.module.im.service.websocket.notification.message.ImGroupMessageNotification;
  32 +import cn.iocoder.yudao.module.im.service.websocket.notification.message.ImMessageReadNotification;
  33 +import cn.iocoder.yudao.module.im.service.websocket.notification.message.ImMessageReceiptNotification;
  34 +import cn.iocoder.yudao.module.im.dal.dataobject.message.content.QuoteMessage;
  35 +import cn.iocoder.yudao.module.im.dal.dataobject.message.content.RecallMessage;
34 import cn.iocoder.yudao.module.im.util.ImMessageUtils; 36 import cn.iocoder.yudao.module.im.util.ImMessageUtils;
35 import jakarta.annotation.Resource; 37 import jakarta.annotation.Resource;
36 import lombok.extern.slf4j.Slf4j; 38 import lombok.extern.slf4j.Slf4j;
@@ -93,7 +95,7 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { @@ -93,7 +95,7 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService {
93 // 1.4 禁言校验 95 // 1.4 禁言校验
94 validateMuteStatus(group, senderMember); 96 validateMuteStatus(group, senderMember);
95 // 1.5 文本消息敏感词过滤 97 // 1.5 文本消息敏感词过滤
96 - if (ImMessageTypeEnum.TEXT.getType().equals(reqVO.getType())) { 98 + if (ImContentTypeEnum.TEXT.getType().equals(reqVO.getType())) {
97 sensitiveWordService.validateText(reqVO.getContent()); 99 sensitiveWordService.validateText(reqVO.getContent());
98 } 100 }
99 101
@@ -142,7 +144,7 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { @@ -142,7 +144,7 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService {
142 .setAtUserIds(dto.getAtUserIds()).setReceiverUserIds(new ArrayList<>(receiverUserIds)) 144 .setAtUserIds(dto.getAtUserIds()).setReceiverUserIds(new ArrayList<>(receiverUserIds))
143 .setReceiptStatus(resolveReceiptStatus(dto.getReceipt())); 145 .setReceiptStatus(resolveReceiptStatus(dto.getReceipt()));
144 // 1.3 按 type.persistent 决定是否入库 146 // 1.3 按 type.persistent 决定是否入库
145 - if (ImMessageTypeEnum.validate(dto.getType()).isPersistent()) { 147 + if (ImContentTypeEnum.validate(dto.getType()).isPersistent()) {
146 groupMessageMapper.insert(message); 148 groupMessageMapper.insert(message);
147 } 149 }
148 150
@@ -181,7 +183,7 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { @@ -181,7 +183,7 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService {
181 183
182 // 3. 发送撤回事件 184 // 3. 发送撤回事件
183 return sendGroupMessage(userId, new ImGroupMessageSendDTO().setGroupId(message.getGroupId()) 185 return sendGroupMessage(userId, new ImGroupMessageSendDTO().setGroupId(message.getGroupId())
184 - .setType(ImMessageTypeEnum.RECALL.getType()) 186 + .setType(ImContentTypeEnum.RECALL.getType())
185 .setReceiverUserIds(message.getReceiverUserIds()) 187 .setReceiverUserIds(message.getReceiverUserIds())
186 .setContent(new RecallMessage().setMessageId(messageId))); 188 .setContent(new RecallMessage().setMessageId(messageId)));
187 } 189 }
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/message/ImPrivateMessageServiceImpl.java
@@ -15,16 +15,18 @@ import cn.iocoder.yudao.module.im.dal.mysql.message.ImPrivateMessageMapper; @@ -15,16 +15,18 @@ import cn.iocoder.yudao.module.im.dal.mysql.message.ImPrivateMessageMapper;
15 import cn.iocoder.yudao.module.im.enums.ImConversationTypeEnum; 15 import cn.iocoder.yudao.module.im.enums.ImConversationTypeEnum;
16 import cn.iocoder.yudao.module.im.enums.message.ImMessageReceiptStatusEnum; 16 import cn.iocoder.yudao.module.im.enums.message.ImMessageReceiptStatusEnum;
17 import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum; 17 import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum;
18 -import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum; 18 +import cn.iocoder.yudao.module.im.enums.ImContentTypeEnum;
19 import cn.iocoder.yudao.module.im.framework.config.ImProperties; 19 import cn.iocoder.yudao.module.im.framework.config.ImProperties;
20 import cn.iocoder.yudao.module.im.service.conversation.ImConversationReadService; 20 import cn.iocoder.yudao.module.im.service.conversation.ImConversationReadService;
21 import cn.iocoder.yudao.module.im.service.friend.ImFriendService; 21 import cn.iocoder.yudao.module.im.service.friend.ImFriendService;
22 import cn.iocoder.yudao.module.im.service.message.dto.ImPrivateMessageSendDTO; 22 import cn.iocoder.yudao.module.im.service.message.dto.ImPrivateMessageSendDTO;
23 import cn.iocoder.yudao.module.im.service.sensitiveword.ImSensitiveWordService; 23 import cn.iocoder.yudao.module.im.service.sensitiveword.ImSensitiveWordService;
24 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService; 24 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService;
25 -import cn.iocoder.yudao.module.im.service.websocket.dto.ImPrivateMessageDTO;  
26 -import cn.iocoder.yudao.module.im.service.websocket.dto.message.QuoteMessage;  
27 -import cn.iocoder.yudao.module.im.service.websocket.dto.message.RecallMessage; 25 +import cn.iocoder.yudao.module.im.service.websocket.notification.message.ImMessageReadNotification;
  26 +import cn.iocoder.yudao.module.im.service.websocket.notification.message.ImMessageReceiptNotification;
  27 +import cn.iocoder.yudao.module.im.service.websocket.notification.message.ImPrivateMessageNotification;
  28 +import cn.iocoder.yudao.module.im.dal.dataobject.message.content.QuoteMessage;
  29 +import cn.iocoder.yudao.module.im.dal.dataobject.message.content.RecallMessage;
28 import cn.iocoder.yudao.module.im.util.ImMessageUtils; 30 import cn.iocoder.yudao.module.im.util.ImMessageUtils;
29 import jakarta.annotation.Resource; 31 import jakarta.annotation.Resource;
30 import lombok.extern.slf4j.Slf4j; 32 import lombok.extern.slf4j.Slf4j;
@@ -80,7 +82,7 @@ public class ImPrivateMessageServiceImpl implements ImPrivateMessageService { @@ -80,7 +82,7 @@ public class ImPrivateMessageServiceImpl implements ImPrivateMessageService {
80 // 1.3 好友校验 82 // 1.3 好友校验
81 friendService.validateFriend(senderId, reqVO.getReceiverId()); 83 friendService.validateFriend(senderId, reqVO.getReceiverId());
82 // 1.4 文本消息敏感词过滤 84 // 1.4 文本消息敏感词过滤
83 - if (ImMessageTypeEnum.TEXT.getType().equals(reqVO.getType())) { 85 + if (ImContentTypeEnum.TEXT.getType().equals(reqVO.getType())) {
84 sensitiveWordService.validateText(reqVO.getContent()); 86 sensitiveWordService.validateText(reqVO.getContent());
85 } 87 }
86 88
@@ -123,7 +125,7 @@ public class ImPrivateMessageServiceImpl implements ImPrivateMessageService { @@ -123,7 +125,7 @@ public class ImPrivateMessageServiceImpl implements ImPrivateMessageService {
123 // 1.3 决定是否持久化:dto.persistent 优先;为 null 时按 type 默认 125 // 1.3 决定是否持久化:dto.persistent 优先;为 null 时按 type 默认
124 boolean persistent = dto.getPersistent() != null 126 boolean persistent = dto.getPersistent() != null
125 ? dto.getPersistent() 127 ? dto.getPersistent()
126 - : ImMessageTypeEnum.validate(dto.getType()).isPersistent(); 128 + : ImContentTypeEnum.validate(dto.getType()).isPersistent();
127 if (persistent) { 129 if (persistent) {
128 privateMessageMapper.insert(message); 130 privateMessageMapper.insert(message);
129 } 131 }
@@ -177,7 +179,7 @@ public class ImPrivateMessageServiceImpl implements ImPrivateMessageService { @@ -177,7 +179,7 @@ public class ImPrivateMessageServiceImpl implements ImPrivateMessageService {
177 179
178 // 3. 发送撤回事件 180 // 3. 发送撤回事件
179 return sendPrivateMessage(userId, new ImPrivateMessageSendDTO().setReceiverId(message.getReceiverId()) 181 return sendPrivateMessage(userId, new ImPrivateMessageSendDTO().setReceiverId(message.getReceiverId())
180 - .setType(ImMessageTypeEnum.RECALL.getType()).setContent(new RecallMessage().setMessageId(messageId))); 182 + .setType(ImContentTypeEnum.RECALL.getType()).setContent(new RecallMessage().setMessageId(messageId)));
181 } 183 }
182 184
183 /** 185 /**
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/message/dto/ImGroupMessageSendDTO.java
1 package cn.iocoder.yudao.module.im.service.message.dto; 1 package cn.iocoder.yudao.module.im.service.message.dto;
2 2
3 import cn.iocoder.yudao.module.im.dal.dataobject.message.ImGroupMessageDO; 3 import cn.iocoder.yudao.module.im.dal.dataobject.message.ImGroupMessageDO;
4 -import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum;  
5 -import cn.iocoder.yudao.module.im.service.websocket.dto.notification.group.*; 4 +import cn.iocoder.yudao.module.im.enums.ImContentTypeEnum;
  5 +import cn.iocoder.yudao.module.im.service.websocket.notification.group.*;
6 import jakarta.validation.constraints.NotNull; 6 import jakarta.validation.constraints.NotNull;
7 import lombok.Data; 7 import lombok.Data;
8 8
@@ -26,7 +26,7 @@ public class ImGroupMessageSendDTO { @@ -26,7 +26,7 @@ public class ImGroupMessageSendDTO {
26 /** 26 /**
27 * 消息类型 27 * 消息类型
28 * <p> 28 * <p>
29 - * 枚举 {@link ImMessageTypeEnum} 29 + * 枚举 {@link ImContentTypeEnum}
30 */ 30 */
31 @NotNull(message = "消息类型不能为空") 31 @NotNull(message = "消息类型不能为空")
32 private Integer type; 32 private Integer type;
@@ -53,14 +53,14 @@ public class ImGroupMessageSendDTO { @@ -53,14 +53,14 @@ public class ImGroupMessageSendDTO {
53 */ 53 */
54 private Boolean receipt; 54 private Boolean receipt;
55 55
56 - // ========== 群广播事件静态工厂(对应 ImMessageTypeEnum 群事件) ========== 56 + // ========== 群广播事件静态工厂(对应 ImContentTypeEnum 群事件) ==========
57 57
58 public static ImGroupMessageSendDTO ofGroupCreate(Long groupId, Long operatorUserId, Collection<Long> memberUserIds) { 58 public static ImGroupMessageSendDTO ofGroupCreate(Long groupId, Long operatorUserId, Collection<Long> memberUserIds) {
59 GroupCreateNotification notification = new GroupCreateNotification(); 59 GroupCreateNotification notification = new GroupCreateNotification();
60 notification.setOperatorUserId(operatorUserId); 60 notification.setOperatorUserId(operatorUserId);
61 notification.setMemberUserIds(new ArrayList<>(memberUserIds)); 61 notification.setMemberUserIds(new ArrayList<>(memberUserIds));
62 return new ImGroupMessageSendDTO().setGroupId(groupId) 62 return new ImGroupMessageSendDTO().setGroupId(groupId)
63 - .setType(ImMessageTypeEnum.GROUP_CREATE.getType()).setContent(notification); 63 + .setType(ImContentTypeEnum.GROUP_CREATE.getType()).setContent(notification);
64 } 64 }
65 65
66 public static ImGroupMessageSendDTO ofGroupInfoUpdate(Long groupId, Long operatorUserId, String oldAvatar, String newAvatar) { 66 public static ImGroupMessageSendDTO ofGroupInfoUpdate(Long groupId, Long operatorUserId, String oldAvatar, String newAvatar) {
@@ -69,14 +69,14 @@ public class ImGroupMessageSendDTO { @@ -69,14 +69,14 @@ public class ImGroupMessageSendDTO {
69 notification.setOldAvatar(oldAvatar); 69 notification.setOldAvatar(oldAvatar);
70 notification.setNewAvatar(newAvatar); 70 notification.setNewAvatar(newAvatar);
71 return new ImGroupMessageSendDTO().setGroupId(groupId) 71 return new ImGroupMessageSendDTO().setGroupId(groupId)
72 - .setType(ImMessageTypeEnum.GROUP_INFO_UPDATE.getType()).setContent(notification); 72 + .setType(ImContentTypeEnum.GROUP_INFO_UPDATE.getType()).setContent(notification);
73 } 73 }
74 74
75 public static ImGroupMessageSendDTO ofGroupMemberQuit(Long groupId, Long operatorUserId) { 75 public static ImGroupMessageSendDTO ofGroupMemberQuit(Long groupId, Long operatorUserId) {
76 GroupMemberQuitNotification notification = new GroupMemberQuitNotification(); 76 GroupMemberQuitNotification notification = new GroupMemberQuitNotification();
77 notification.setOperatorUserId(operatorUserId); 77 notification.setOperatorUserId(operatorUserId);
78 return new ImGroupMessageSendDTO().setGroupId(groupId) 78 return new ImGroupMessageSendDTO().setGroupId(groupId)
79 - .setType(ImMessageTypeEnum.GROUP_MEMBER_QUIT.getType()).setContent(notification); 79 + .setType(ImContentTypeEnum.GROUP_MEMBER_QUIT.getType()).setContent(notification);
80 } 80 }
81 81
82 public static ImGroupMessageSendDTO ofGroupOwnerTransfer(Long groupId, Long operatorUserId, Long newOwnerUserId) { 82 public static ImGroupMessageSendDTO ofGroupOwnerTransfer(Long groupId, Long operatorUserId, Long newOwnerUserId) {
@@ -84,7 +84,7 @@ public class ImGroupMessageSendDTO { @@ -84,7 +84,7 @@ public class ImGroupMessageSendDTO {
84 notification.setOperatorUserId(operatorUserId); 84 notification.setOperatorUserId(operatorUserId);
85 notification.setNewOwnerUserId(newOwnerUserId); 85 notification.setNewOwnerUserId(newOwnerUserId);
86 return new ImGroupMessageSendDTO().setGroupId(groupId) 86 return new ImGroupMessageSendDTO().setGroupId(groupId)
87 - .setType(ImMessageTypeEnum.GROUP_OWNER_TRANSFER.getType()).setContent(notification); 87 + .setType(ImContentTypeEnum.GROUP_OWNER_TRANSFER.getType()).setContent(notification);
88 } 88 }
89 89
90 public static ImGroupMessageSendDTO ofGroupMemberKick(Long groupId, Long operatorUserId, Collection<Long> memberUserIds) { 90 public static ImGroupMessageSendDTO ofGroupMemberKick(Long groupId, Long operatorUserId, Collection<Long> memberUserIds) {
@@ -92,7 +92,7 @@ public class ImGroupMessageSendDTO { @@ -92,7 +92,7 @@ public class ImGroupMessageSendDTO {
92 notification.setOperatorUserId(operatorUserId); 92 notification.setOperatorUserId(operatorUserId);
93 notification.setMemberUserIds(new ArrayList<>(memberUserIds)); 93 notification.setMemberUserIds(new ArrayList<>(memberUserIds));
94 return new ImGroupMessageSendDTO().setGroupId(groupId) 94 return new ImGroupMessageSendDTO().setGroupId(groupId)
95 - .setType(ImMessageTypeEnum.GROUP_MEMBER_KICK.getType()).setContent(notification); 95 + .setType(ImContentTypeEnum.GROUP_MEMBER_KICK.getType()).setContent(notification);
96 } 96 }
97 97
98 public static ImGroupMessageSendDTO ofGroupMemberInvite(Long groupId, Long operatorUserId, Collection<Long> memberUserIds) { 98 public static ImGroupMessageSendDTO ofGroupMemberInvite(Long groupId, Long operatorUserId, Collection<Long> memberUserIds) {
@@ -100,7 +100,7 @@ public class ImGroupMessageSendDTO { @@ -100,7 +100,7 @@ public class ImGroupMessageSendDTO {
100 notification.setOperatorUserId(operatorUserId); 100 notification.setOperatorUserId(operatorUserId);
101 notification.setMemberUserIds(new ArrayList<>(memberUserIds)); 101 notification.setMemberUserIds(new ArrayList<>(memberUserIds));
102 return new ImGroupMessageSendDTO().setGroupId(groupId) 102 return new ImGroupMessageSendDTO().setGroupId(groupId)
103 - .setType(ImMessageTypeEnum.GROUP_MEMBER_INVITE.getType()).setContent(notification); 103 + .setType(ImContentTypeEnum.GROUP_MEMBER_INVITE.getType()).setContent(notification);
104 } 104 }
105 105
106 public static ImGroupMessageSendDTO ofGroupMemberEnter(Long groupId, Long entrantUserId, Integer addSource) { 106 public static ImGroupMessageSendDTO ofGroupMemberEnter(Long groupId, Long entrantUserId, Integer addSource) {
@@ -109,14 +109,14 @@ public class ImGroupMessageSendDTO { @@ -109,14 +109,14 @@ public class ImGroupMessageSendDTO {
109 notification.setEntrantUserId(entrantUserId); 109 notification.setEntrantUserId(entrantUserId);
110 notification.setAddSource(addSource); 110 notification.setAddSource(addSource);
111 return new ImGroupMessageSendDTO().setGroupId(groupId) 111 return new ImGroupMessageSendDTO().setGroupId(groupId)
112 - .setType(ImMessageTypeEnum.GROUP_MEMBER_ENTER.getType()).setContent(notification); 112 + .setType(ImContentTypeEnum.GROUP_MEMBER_ENTER.getType()).setContent(notification);
113 } 113 }
114 114
115 public static ImGroupMessageSendDTO ofGroupDissolve(Long groupId, Long operatorUserId) { 115 public static ImGroupMessageSendDTO ofGroupDissolve(Long groupId, Long operatorUserId) {
116 GroupDissolveNotification notification = new GroupDissolveNotification(); 116 GroupDissolveNotification notification = new GroupDissolveNotification();
117 notification.setOperatorUserId(operatorUserId); 117 notification.setOperatorUserId(operatorUserId);
118 return new ImGroupMessageSendDTO().setGroupId(groupId) 118 return new ImGroupMessageSendDTO().setGroupId(groupId)
119 - .setType(ImMessageTypeEnum.GROUP_DISSOLVE.getType()).setContent(notification); 119 + .setType(ImContentTypeEnum.GROUP_DISSOLVE.getType()).setContent(notification);
120 } 120 }
121 121
122 public static ImGroupMessageSendDTO ofGroupMemberNicknameUpdate(Long groupId, Long operatorUserId, String displayUserName) { 122 public static ImGroupMessageSendDTO ofGroupMemberNicknameUpdate(Long groupId, Long operatorUserId, String displayUserName) {
@@ -124,7 +124,7 @@ public class ImGroupMessageSendDTO { @@ -124,7 +124,7 @@ public class ImGroupMessageSendDTO {
124 notification.setOperatorUserId(operatorUserId); 124 notification.setOperatorUserId(operatorUserId);
125 notification.setDisplayUserName(displayUserName); 125 notification.setDisplayUserName(displayUserName);
126 return new ImGroupMessageSendDTO().setGroupId(groupId) 126 return new ImGroupMessageSendDTO().setGroupId(groupId)
127 - .setType(ImMessageTypeEnum.GROUP_MEMBER_NICKNAME_UPDATE.getType()).setContent(notification); 127 + .setType(ImContentTypeEnum.GROUP_MEMBER_NICKNAME_UPDATE.getType()).setContent(notification);
128 } 128 }
129 129
130 public static ImGroupMessageSendDTO ofGroupAdminAdd(Long groupId, Long operatorUserId, Collection<Long> memberUserIds) { 130 public static ImGroupMessageSendDTO ofGroupAdminAdd(Long groupId, Long operatorUserId, Collection<Long> memberUserIds) {
@@ -132,7 +132,7 @@ public class ImGroupMessageSendDTO { @@ -132,7 +132,7 @@ public class ImGroupMessageSendDTO {
132 notification.setOperatorUserId(operatorUserId); 132 notification.setOperatorUserId(operatorUserId);
133 notification.setMemberUserIds(new ArrayList<>(memberUserIds)); 133 notification.setMemberUserIds(new ArrayList<>(memberUserIds));
134 return new ImGroupMessageSendDTO().setGroupId(groupId) 134 return new ImGroupMessageSendDTO().setGroupId(groupId)
135 - .setType(ImMessageTypeEnum.GROUP_ADMIN_ADD.getType()).setContent(notification); 135 + .setType(ImContentTypeEnum.GROUP_ADMIN_ADD.getType()).setContent(notification);
136 } 136 }
137 137
138 public static ImGroupMessageSendDTO ofGroupAdminRemove(Long groupId, Long operatorUserId, Collection<Long> memberUserIds) { 138 public static ImGroupMessageSendDTO ofGroupAdminRemove(Long groupId, Long operatorUserId, Collection<Long> memberUserIds) {
@@ -140,7 +140,7 @@ public class ImGroupMessageSendDTO { @@ -140,7 +140,7 @@ public class ImGroupMessageSendDTO {
140 notification.setOperatorUserId(operatorUserId); 140 notification.setOperatorUserId(operatorUserId);
141 notification.setMemberUserIds(new ArrayList<>(memberUserIds)); 141 notification.setMemberUserIds(new ArrayList<>(memberUserIds));
142 return new ImGroupMessageSendDTO().setGroupId(groupId) 142 return new ImGroupMessageSendDTO().setGroupId(groupId)
143 - .setType(ImMessageTypeEnum.GROUP_ADMIN_REMOVE.getType()).setContent(notification); 143 + .setType(ImContentTypeEnum.GROUP_ADMIN_REMOVE.getType()).setContent(notification);
144 } 144 }
145 145
146 public static ImGroupMessageSendDTO ofGroupNoticeUpdate(Long groupId, Long operatorUserId, String oldNotice, String newNotice) { 146 public static ImGroupMessageSendDTO ofGroupNoticeUpdate(Long groupId, Long operatorUserId, String oldNotice, String newNotice) {
@@ -148,7 +148,7 @@ public class ImGroupMessageSendDTO { @@ -148,7 +148,7 @@ public class ImGroupMessageSendDTO {
148 notification.setOperatorUserId(operatorUserId); 148 notification.setOperatorUserId(operatorUserId);
149 notification.setOldNotice(oldNotice).setNewNotice(newNotice); 149 notification.setOldNotice(oldNotice).setNewNotice(newNotice);
150 return new ImGroupMessageSendDTO().setGroupId(groupId) 150 return new ImGroupMessageSendDTO().setGroupId(groupId)
151 - .setType(ImMessageTypeEnum.GROUP_NOTICE_UPDATE.getType()).setContent(notification); 151 + .setType(ImContentTypeEnum.GROUP_NOTICE_UPDATE.getType()).setContent(notification);
152 } 152 }
153 153
154 public static ImGroupMessageSendDTO ofGroupNameUpdate(Long groupId, Long operatorUserId, String oldName, String newName) { 154 public static ImGroupMessageSendDTO ofGroupNameUpdate(Long groupId, Long operatorUserId, String oldName, String newName) {
@@ -156,7 +156,7 @@ public class ImGroupMessageSendDTO { @@ -156,7 +156,7 @@ public class ImGroupMessageSendDTO {
156 notification.setOperatorUserId(operatorUserId); 156 notification.setOperatorUserId(operatorUserId);
157 notification.setOldName(oldName).setNewName(newName); 157 notification.setOldName(oldName).setNewName(newName);
158 return new ImGroupMessageSendDTO().setGroupId(groupId) 158 return new ImGroupMessageSendDTO().setGroupId(groupId)
159 - .setType(ImMessageTypeEnum.GROUP_NAME_UPDATE.getType()).setContent(notification); 159 + .setType(ImContentTypeEnum.GROUP_NAME_UPDATE.getType()).setContent(notification);
160 } 160 }
161 161
162 public static ImGroupMessageSendDTO ofGroupMemberSettingUpdate(Long groupId, Long operatorUserId, Boolean silent, String groupRemark) { 162 public static ImGroupMessageSendDTO ofGroupMemberSettingUpdate(Long groupId, Long operatorUserId, Boolean silent, String groupRemark) {
@@ -164,7 +164,7 @@ public class ImGroupMessageSendDTO { @@ -164,7 +164,7 @@ public class ImGroupMessageSendDTO {
164 notification.setOperatorUserId(operatorUserId); 164 notification.setOperatorUserId(operatorUserId);
165 notification.setSilent(silent).setGroupRemark(groupRemark); 165 notification.setSilent(silent).setGroupRemark(groupRemark);
166 return new ImGroupMessageSendDTO().setGroupId(groupId) 166 return new ImGroupMessageSendDTO().setGroupId(groupId)
167 - .setType(ImMessageTypeEnum.GROUP_MEMBER_SETTING_UPDATE.getType()).setContent(notification); 167 + .setType(ImContentTypeEnum.GROUP_MEMBER_SETTING_UPDATE.getType()).setContent(notification);
168 } 168 }
169 169
170 public static ImGroupMessageSendDTO ofGroupMessagePin(Long groupId, Long operatorUserId, ImGroupMessageDO message) { 170 public static ImGroupMessageSendDTO ofGroupMessagePin(Long groupId, Long operatorUserId, ImGroupMessageDO message) {
@@ -176,7 +176,7 @@ public class ImGroupMessageSendDTO { @@ -176,7 +176,7 @@ public class ImGroupMessageSendDTO {
176 notification.setOperatorUserId(operatorUserId); 176 notification.setOperatorUserId(operatorUserId);
177 notification.setMessageId(message.getId()).setMessage(pinnedMessage); 177 notification.setMessageId(message.getId()).setMessage(pinnedMessage);
178 return new ImGroupMessageSendDTO().setGroupId(groupId) 178 return new ImGroupMessageSendDTO().setGroupId(groupId)
179 - .setType(ImMessageTypeEnum.GROUP_MESSAGE_PIN.getType()).setContent(notification); 179 + .setType(ImContentTypeEnum.GROUP_MESSAGE_PIN.getType()).setContent(notification);
180 } 180 }
181 181
182 public static ImGroupMessageSendDTO ofGroupMessageUnpin(Long groupId, Long operatorUserId, Long messageId) { 182 public static ImGroupMessageSendDTO ofGroupMessageUnpin(Long groupId, Long operatorUserId, Long messageId) {
@@ -184,7 +184,7 @@ public class ImGroupMessageSendDTO { @@ -184,7 +184,7 @@ public class ImGroupMessageSendDTO {
184 notification.setOperatorUserId(operatorUserId); 184 notification.setOperatorUserId(operatorUserId);
185 notification.setMessageId(messageId); 185 notification.setMessageId(messageId);
186 return new ImGroupMessageSendDTO().setGroupId(groupId) 186 return new ImGroupMessageSendDTO().setGroupId(groupId)
187 - .setType(ImMessageTypeEnum.GROUP_MESSAGE_UNPIN.getType()).setContent(notification); 187 + .setType(ImContentTypeEnum.GROUP_MESSAGE_UNPIN.getType()).setContent(notification);
188 } 188 }
189 189
190 public static ImGroupMessageSendDTO ofGroupMemberMuted(Long groupId, Long operatorUserId, 190 public static ImGroupMessageSendDTO ofGroupMemberMuted(Long groupId, Long operatorUserId,
@@ -195,7 +195,7 @@ public class ImGroupMessageSendDTO { @@ -195,7 +195,7 @@ public class ImGroupMessageSendDTO {
195 notification.setMutedUserId(mutedUserId); 195 notification.setMutedUserId(mutedUserId);
196 notification.setMuteEndTime(muteEndTime); 196 notification.setMuteEndTime(muteEndTime);
197 return new ImGroupMessageSendDTO().setGroupId(groupId) 197 return new ImGroupMessageSendDTO().setGroupId(groupId)
198 - .setType(ImMessageTypeEnum.GROUP_MEMBER_MUTED.getType()).setContent(notification); 198 + .setType(ImContentTypeEnum.GROUP_MEMBER_MUTED.getType()).setContent(notification);
199 } 199 }
200 200
201 public static ImGroupMessageSendDTO ofGroupMemberCancelMuted(Long groupId, Long operatorUserId, Long mutedUserId) { 201 public static ImGroupMessageSendDTO ofGroupMemberCancelMuted(Long groupId, Long operatorUserId, Long mutedUserId) {
@@ -203,21 +203,21 @@ public class ImGroupMessageSendDTO { @@ -203,21 +203,21 @@ public class ImGroupMessageSendDTO {
203 notification.setOperatorUserId(operatorUserId); 203 notification.setOperatorUserId(operatorUserId);
204 notification.setMutedUserId(mutedUserId); 204 notification.setMutedUserId(mutedUserId);
205 return new ImGroupMessageSendDTO().setGroupId(groupId) 205 return new ImGroupMessageSendDTO().setGroupId(groupId)
206 - .setType(ImMessageTypeEnum.GROUP_MEMBER_CANCEL_MUTED.getType()).setContent(notification); 206 + .setType(ImContentTypeEnum.GROUP_MEMBER_CANCEL_MUTED.getType()).setContent(notification);
207 } 207 }
208 208
209 public static ImGroupMessageSendDTO ofGroupMuted(Long groupId, Long operatorUserId) { 209 public static ImGroupMessageSendDTO ofGroupMuted(Long groupId, Long operatorUserId) {
210 GroupMutedNotification notification = new GroupMutedNotification(); 210 GroupMutedNotification notification = new GroupMutedNotification();
211 notification.setOperatorUserId(operatorUserId); 211 notification.setOperatorUserId(operatorUserId);
212 return new ImGroupMessageSendDTO().setGroupId(groupId) 212 return new ImGroupMessageSendDTO().setGroupId(groupId)
213 - .setType(ImMessageTypeEnum.GROUP_MUTED.getType()).setContent(notification); 213 + .setType(ImContentTypeEnum.GROUP_MUTED.getType()).setContent(notification);
214 } 214 }
215 215
216 public static ImGroupMessageSendDTO ofGroupCancelMuted(Long groupId, Long operatorUserId) { 216 public static ImGroupMessageSendDTO ofGroupCancelMuted(Long groupId, Long operatorUserId) {
217 GroupCancelMutedNotification notification = new GroupCancelMutedNotification(); 217 GroupCancelMutedNotification notification = new GroupCancelMutedNotification();
218 notification.setOperatorUserId(operatorUserId); 218 notification.setOperatorUserId(operatorUserId);
219 return new ImGroupMessageSendDTO().setGroupId(groupId) 219 return new ImGroupMessageSendDTO().setGroupId(groupId)
220 - .setType(ImMessageTypeEnum.GROUP_CANCEL_MUTED.getType()).setContent(notification); 220 + .setType(ImContentTypeEnum.GROUP_CANCEL_MUTED.getType()).setContent(notification);
221 } 221 }
222 222
223 public static ImGroupMessageSendDTO ofGroupBanned(Long groupId, Long operatorUserId, boolean banned) { 223 public static ImGroupMessageSendDTO ofGroupBanned(Long groupId, Long operatorUserId, boolean banned) {
@@ -225,7 +225,7 @@ public class ImGroupMessageSendDTO { @@ -225,7 +225,7 @@ public class ImGroupMessageSendDTO {
225 notification.setOperatorUserId(operatorUserId); 225 notification.setOperatorUserId(operatorUserId);
226 notification.setBanned(banned); 226 notification.setBanned(banned);
227 return new ImGroupMessageSendDTO().setGroupId(groupId) 227 return new ImGroupMessageSendDTO().setGroupId(groupId)
228 - .setType(ImMessageTypeEnum.GROUP_BANNED.getType()).setContent(notification); 228 + .setType(ImContentTypeEnum.GROUP_BANNED.getType()).setContent(notification);
229 } 229 }
230 230
231 } 231 }
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/message/dto/ImPrivateMessageSendDTO.java
1 package cn.iocoder.yudao.module.im.service.message.dto; 1 package cn.iocoder.yudao.module.im.service.message.dto;
2 2
3 -import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum; 3 +import cn.iocoder.yudao.module.im.enums.ImContentTypeEnum;
4 import lombok.Data; 4 import lombok.Data;
5 5
6 /** 6 /**
@@ -18,7 +18,7 @@ public class ImPrivateMessageSendDTO { @@ -18,7 +18,7 @@ public class ImPrivateMessageSendDTO {
18 /** 18 /**
19 * 消息类型 19 * 消息类型
20 * <p> 20 * <p>
21 - * 枚举 {@link ImMessageTypeEnum} 21 + * 枚举 {@link ImContentTypeEnum}
22 */ 22 */
23 private Integer type; 23 private Integer type;
24 /** 24 /**
@@ -30,7 +30,7 @@ public class ImPrivateMessageSendDTO { @@ -30,7 +30,7 @@ public class ImPrivateMessageSendDTO {
30 /** 30 /**
31 * 是否持久化 + 推送给接收方(单边语义开关) 31 * 是否持久化 + 推送给接收方(单边语义开关)
32 * <p> 32 * <p>
33 - * null:默认按 {@link ImMessageTypeEnum#isPersistent()} 决定是否入库 + 双向 WS 推送(保持原行为)<br> 33 + * null:默认按 {@link ImContentTypeEnum#isPersistent()} 决定是否入库 + 双向 WS 推送(保持原行为)<br>
34 * false:覆盖为单边——不入库、仅推 sender 多端,对方不感知(如「你已删除 XXX」这类仅自己可见的 TIP)<br> 34 * false:覆盖为单边——不入库、仅推 sender 多端,对方不感知(如「你已删除 XXX」这类仅自己可见的 TIP)<br>
35 * true:覆盖为双向 + 入库 35 * true:覆盖为双向 + 入库
36 */ 36 */
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/rtc/ImRtcCallServiceImpl.java
@@ -15,7 +15,7 @@ import cn.iocoder.yudao.module.im.dal.mysql.rtc.ImRtcCallMapper; @@ -15,7 +15,7 @@ import cn.iocoder.yudao.module.im.dal.mysql.rtc.ImRtcCallMapper;
15 import cn.iocoder.yudao.module.im.dal.mysql.rtc.ImRtcParticipantMapper; 15 import cn.iocoder.yudao.module.im.dal.mysql.rtc.ImRtcParticipantMapper;
16 import cn.iocoder.yudao.module.im.dal.redis.rtc.ImRtcCallLockRedisDAO; 16 import cn.iocoder.yudao.module.im.dal.redis.rtc.ImRtcCallLockRedisDAO;
17 import cn.iocoder.yudao.module.im.enums.ImConversationTypeEnum; 17 import cn.iocoder.yudao.module.im.enums.ImConversationTypeEnum;
18 -import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum; 18 +import cn.iocoder.yudao.module.im.enums.ImContentTypeEnum;
19 import cn.iocoder.yudao.module.im.enums.rtc.ImRtcCallEndReasonEnum; 19 import cn.iocoder.yudao.module.im.enums.rtc.ImRtcCallEndReasonEnum;
20 import cn.iocoder.yudao.module.im.enums.rtc.ImRtcCallStatusEnum; 20 import cn.iocoder.yudao.module.im.enums.rtc.ImRtcCallStatusEnum;
21 import cn.iocoder.yudao.module.im.enums.rtc.ImRtcParticipantRoleEnum; 21 import cn.iocoder.yudao.module.im.enums.rtc.ImRtcParticipantRoleEnum;
@@ -30,8 +30,7 @@ import cn.iocoder.yudao.module.im.service.message.ImPrivateMessageService; @@ -30,8 +30,7 @@ import cn.iocoder.yudao.module.im.service.message.ImPrivateMessageService;
30 import cn.iocoder.yudao.module.im.service.message.dto.ImGroupMessageSendDTO; 30 import cn.iocoder.yudao.module.im.service.message.dto.ImGroupMessageSendDTO;
31 import cn.iocoder.yudao.module.im.service.message.dto.ImPrivateMessageSendDTO; 31 import cn.iocoder.yudao.module.im.service.message.dto.ImPrivateMessageSendDTO;
32 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService; 32 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService;
33 -import cn.iocoder.yudao.module.im.service.websocket.dto.ImPrivateMessageDTO;  
34 -import cn.iocoder.yudao.module.im.service.websocket.dto.notification.rtc.*; 33 +import cn.iocoder.yudao.module.im.service.websocket.notification.rtc.*;
35 import cn.iocoder.yudao.module.system.api.user.AdminUserApi; 34 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
36 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; 35 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
37 import jakarta.annotation.Resource; 36 import jakarta.annotation.Resource;
@@ -1047,7 +1046,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -1047,7 +1046,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
1047 * @param userId 加入的参与者用户编号 1046 * @param userId 加入的参与者用户编号
1048 */ 1047 */
1049 private void pushParticipantConnectedNotification(ImRtcCallDO call, Long userId) { 1048 private void pushParticipantConnectedNotification(ImRtcCallDO call, Long userId) {
1050 - pushParticipantNotification(call, ImMessageTypeEnum.RTC_PARTICIPANT_CONNECTED.getType(), userId, 1049 + pushParticipantNotification(call, ImContentTypeEnum.RTC_PARTICIPANT_CONNECTED.getType(), userId,
1051 ImRtcParticipantConnectedNotification.of(call, userId)); 1050 ImRtcParticipantConnectedNotification.of(call, userId));
1052 } 1051 }
1053 1052
@@ -1058,7 +1057,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -1058,7 +1057,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
1058 * @param userId 离开的参与者用户编号 1057 * @param userId 离开的参与者用户编号
1059 */ 1058 */
1060 private void pushParticipantDisconnectedNotification(ImRtcCallDO call, Long userId) { 1059 private void pushParticipantDisconnectedNotification(ImRtcCallDO call, Long userId) {
1061 - pushParticipantNotification(call, ImMessageTypeEnum.RTC_PARTICIPANT_DISCONNECTED.getType(), userId, 1060 + pushParticipantNotification(call, ImContentTypeEnum.RTC_PARTICIPANT_DISCONNECTED.getType(), userId,
1062 ImRtcParticipantDisconnectedNotification.of(call, userId)); 1061 ImRtcParticipantDisconnectedNotification.of(call, userId));
1063 } 1062 }
1064 1063
@@ -1091,7 +1090,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -1091,7 +1090,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
1091 private void pushCallStartNotification(ImRtcCallDO call, AdminUserRespDTO inviter, Set<Long> invitees) { 1090 private void pushCallStartNotification(ImRtcCallDO call, AdminUserRespDTO inviter, Set<Long> invitees) {
1092 ImRtcCallStartNotification payload = ImRtcCallStartNotification.of(call, inviter); 1091 ImRtcCallStartNotification payload = ImRtcCallStartNotification.of(call, inviter);
1093 Long peerUserId = ImConversationTypeEnum.isGroup(call.getConversationType()) ? null : CollUtil.getFirst(invitees); 1092 Long peerUserId = ImConversationTypeEnum.isGroup(call.getConversationType()) ? null : CollUtil.getFirst(invitees);
1094 - pushCallChatMessage(call, ImMessageTypeEnum.RTC_CALL_START, payload, peerUserId); 1093 + pushCallChatMessage(call, ImContentTypeEnum.RTC_CALL_START, payload, peerUserId);
1095 } 1094 }
1096 1095
1097 /** 1096 /**
@@ -1115,7 +1114,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -1115,7 +1114,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
1115 p -> ObjUtil.notEqual(p.getUserId(), call.getInviterUserId())); 1114 p -> ObjUtil.notEqual(p.getUserId(), call.getInviterUserId()));
1116 peerUserId = peer != null ? peer.getUserId() : null; 1115 peerUserId = peer != null ? peer.getUserId() : null;
1117 } 1116 }
1118 - pushCallChatMessage(call, ImMessageTypeEnum.RTC_CALL_END, payload, peerUserId); 1117 + pushCallChatMessage(call, ImContentTypeEnum.RTC_CALL_END, payload, peerUserId);
1119 } 1118 }
1120 1119
1121 /** 1120 /**
@@ -1128,7 +1127,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -1128,7 +1127,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
1128 * @param payload 推送 payload 1127 * @param payload 推送 payload
1129 * @param peerUserId 私聊对端用户编号;群聊忽略,私聊缺失时回退为 senderId 1128 * @param peerUserId 私聊对端用户编号;群聊忽略,私聊缺失时回退为 senderId
1130 */ 1129 */
1131 - private void pushCallChatMessage(ImRtcCallDO call, ImMessageTypeEnum type, Object payload, Long peerUserId) { 1130 + private void pushCallChatMessage(ImRtcCallDO call, ImContentTypeEnum type, Object payload, Long peerUserId) {
1132 Long senderId = call.getInviterUserId(); 1131 Long senderId = call.getInviterUserId();
1133 if (ImConversationTypeEnum.isGroup(call.getConversationType())) { 1132 if (ImConversationTypeEnum.isGroup(call.getConversationType())) {
1134 ImGroupMessageSendDTO dto = new ImGroupMessageSendDTO().setGroupId(call.getGroupId()) 1133 ImGroupMessageSendDTO dto = new ImGroupMessageSendDTO().setGroupId(call.getGroupId())
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/statistics/ImStatisticsManagerService.java
@@ -80,7 +80,7 @@ public interface ImStatisticsManagerService { @@ -80,7 +80,7 @@ public interface ImStatisticsManagerService {
80 Map<LocalDateTime, Long> getGroupMessageDailyCountMap(LocalDateTime beginTime, LocalDateTime endTime); 80 Map<LocalDateTime, Long> getGroupMessageDailyCountMap(LocalDateTime beginTime, LocalDateTime endTime);
81 81
82 /** 82 /**
83 - * 获取区间内消息类型分布 Map(key 为消息类型) 83 + * 获取区间内内容类型分布 Map(key 为消息类型)
84 */ 84 */
85 Map<Integer, Long> getMessageTypeCountMap(LocalDateTime beginTime, LocalDateTime endTime); 85 Map<Integer, Long> getMessageTypeCountMap(LocalDateTime beginTime, LocalDateTime endTime);
86 86
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/ImWebSocketService.java
1 package cn.iocoder.yudao.module.im.service.websocket; 1 package cn.iocoder.yudao.module.im.service.websocket;
2 2
3 -import cn.iocoder.yudao.module.im.service.websocket.dto.ImChannelMessageDTO;  
4 -import cn.iocoder.yudao.module.im.service.websocket.dto.ImGroupMessageDTO;  
5 -import cn.iocoder.yudao.module.im.service.websocket.dto.ImPrivateMessageDTO;  
6 -  
7 import java.util.Collection; 3 import java.util.Collection;
8 import java.util.Collections; 4 import java.util.Collections;
9 5
10 /** 6 /**
11 * IM WebSocket 推送 Service 接口 7 * IM WebSocket 推送 Service 接口
12 * <p> 8 * <p>
13 - * 统一封装 WebSocket 消息推送,事务内调用时提交后异步执行。 9 + * 统一封装 WebSocket 通知推送,事务内调用时提交后异步执行。
14 * 10 *
15 * @author 芋道源码 11 * @author 芋道源码
16 */ 12 */
17 public interface ImWebSocketService { 13 public interface ImWebSocketService {
18 14
19 /** 15 /**
20 - * 异步推送私聊消息给指定用户  
21 - *  
22 - * @param userId 目标用户编号  
23 - * @param dto 私聊消息 DTO  
24 - */  
25 - default void sendPrivateMessageAsync(Long userId, ImPrivateMessageDTO dto) {  
26 - sendPrivateMessageAsync(Collections.singleton(userId), dto);  
27 - }  
28 -  
29 - /**  
30 - * 异步批量推送私聊消息给多个用户;用于同一份 DTO 扇出到多个收件人  
31 - * <p>  
32 - * 相比逐个发送,仅注册一次 afterCommit 回调和异步任务。  
33 - *  
34 - * @param userIds 目标用户编号列表  
35 - * @param dto 私聊消息 DTO  
36 - */  
37 - void sendPrivateMessageAsync(Collection<Long> userIds, ImPrivateMessageDTO dto);  
38 -  
39 - /**  
40 - * 异步推送群聊消息给指定用户  
41 - *  
42 - * @param userId 目标用户编号  
43 - * @param dto 群聊消息 DTO  
44 - */  
45 - default void sendGroupMessageAsync(Long userId, ImGroupMessageDTO dto) {  
46 - sendGroupMessageAsync(Collections.singleton(userId), dto);  
47 - }  
48 -  
49 - /**  
50 - * 异步批量推送群聊消息给多个用户  
51 - *  
52 - * @param userIds 目标用户编号列表  
53 - * @param dto 群聊消息 DTO  
54 - */  
55 - void sendGroupMessageAsync(Collection<Long> userIds, ImGroupMessageDTO dto);  
56 -  
57 - /**  
58 - * 异步推送频道消息给指定用户 16 + * 异步推送 WebSocket 通知给指定用户
59 * 17 *
60 - * @param userId 目标用户编号  
61 - * @param dto 频道消息 DTO 18 + * @param userId 目标用户编号
  19 + * @param conversationType 会话类型,参见 ImConversationTypeEnum 枚举类
  20 + * @param contentType 内容类型,参见 ImContentTypeEnum 枚举类
  21 + * @param payload 通知 payload
62 */ 22 */
63 - default void sendChannelMessageAsync(Long userId, ImChannelMessageDTO dto) {  
64 - sendChannelMessageAsync(Collections.singleton(userId), dto); 23 + default void sendNotificationAsync(Long userId, Integer conversationType, Integer contentType, Object payload) {
  24 + sendNotificationAsync(Collections.singleton(userId), conversationType, contentType, payload);
65 } 25 }
66 26
67 /** 27 /**
68 - * 异步批量推送频道消息给多个用户 28 + * 异步批量推送 WebSocket 通知给多个用户
69 * 29 *
70 - * @param userIds 目标用户编号列表  
71 - * @param dto 频道消息 DTO 30 + * @param userIds 目标用户编号列表
  31 + * @param conversationType 会话类型,参见 ImConversationTypeEnum 枚举类
  32 + * @param contentType 内容类型,参见 ImContentTypeEnum 枚举类
  33 + * @param payload 通知 payload
72 */ 34 */
73 - void sendChannelMessageAsync(Collection<Long> userIds, ImChannelMessageDTO dto); 35 + void sendNotificationAsync(Collection<Long> userIds, Integer conversationType, Integer contentType, Object payload);
74 36
75 /** 37 /**
76 - * 异步广播频道消息给当前所有在线管理端用户;用于全员推送 38 + * 异步广播 WebSocket 通知给当前所有在线管理端用户
77 * 39 *
78 - * @param dto 频道消息 DTO 40 + * @param conversationType 会话类型,参见 ImConversationTypeEnum 枚举类
  41 + * @param contentType 内容类型,参见 ImContentTypeEnum 枚举类
  42 + * @param payload 通知 payload
79 */ 43 */
80 - void broadcastChannelMessageAsync(ImChannelMessageDTO dto); 44 + void broadcastNotificationAsync(Integer conversationType, Integer contentType, Object payload);
81 45
82 } 46 }
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/ImWebSocketServiceImpl.java
@@ -2,9 +2,7 @@ package cn.iocoder.yudao.module.im.service.websocket; @@ -2,9 +2,7 @@ package cn.iocoder.yudao.module.im.service.websocket;
2 2
3 import cn.hutool.extra.spring.SpringUtil; 3 import cn.hutool.extra.spring.SpringUtil;
4 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; 4 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
5 -import cn.iocoder.yudao.module.im.service.websocket.dto.ImChannelMessageDTO;  
6 -import cn.iocoder.yudao.module.im.service.websocket.dto.ImGroupMessageDTO;  
7 -import cn.iocoder.yudao.module.im.service.websocket.dto.ImPrivateMessageDTO; 5 +import cn.iocoder.yudao.module.im.service.websocket.notification.ImNotificationWebSocketDTO;
8 import cn.iocoder.yudao.module.infra.api.websocket.WebSocketSenderApi; 6 import cn.iocoder.yudao.module.infra.api.websocket.WebSocketSenderApi;
9 import jakarta.annotation.Resource; 7 import jakarta.annotation.Resource;
10 import lombok.extern.slf4j.Slf4j; 8 import lombok.extern.slf4j.Slf4j;
@@ -88,31 +86,30 @@ public class ImWebSocketServiceImpl implements ImWebSocketService { @@ -88,31 +86,30 @@ public class ImWebSocketServiceImpl implements ImWebSocketService {
88 } 86 }
89 87
90 /** 88 /**
91 - * 异步发送频道 WebSocket 消息 89 + * 异步发送 WebSocket 通知
92 */ 90 */
93 @Async 91 @Async
94 - public void doSendChannelMessage(Collection<Long> userIds, ImChannelMessageDTO dto) { 92 + public void doSendNotification(Collection<Long> userIds, ImNotificationWebSocketDTO notification) {
95 for (Long userId : getDistinctUserIds(userIds)) { 93 for (Long userId : getDistinctUserIds(userIds)) {
96 try { 94 try {
97 webSocketSenderApi.sendObject(UserTypeEnum.ADMIN.getValue(), userId, 95 webSocketSenderApi.sendObject(UserTypeEnum.ADMIN.getValue(), userId,
98 - ImChannelMessageDTO.TYPE, dto); 96 + ImNotificationWebSocketDTO.TYPE, notification);
99 } catch (Exception e) { 97 } catch (Exception e) {
100 - log.error("[doSendChannelMessage][userId({}) dto({}) 发送失败]", userId, dto, e); 98 + log.error("[doSendNotification][userId({}) notification({}) 发送失败]", userId, notification, e);
101 } 99 }
102 } 100 }
103 } 101 }
104 102
105 /** 103 /**
106 - * 异步广播频道 WebSocket 消息给当前所有在线管理端用户;  
107 - * 依赖 infra WebSocketSenderApi 按 UserType 广播能力,离线用户由客户端上线 pull 兜底 104 + * 异步广播 WebSocket 通知
108 */ 105 */
109 @Async 106 @Async
110 - public void doBroadcastChannelMessage(ImChannelMessageDTO dto) { 107 + public void doBroadcastNotification(ImNotificationWebSocketDTO notification) {
111 try { 108 try {
112 webSocketSenderApi.sendObject(UserTypeEnum.ADMIN.getValue(), 109 webSocketSenderApi.sendObject(UserTypeEnum.ADMIN.getValue(),
113 - ImChannelMessageDTO.TYPE, dto); 110 + ImNotificationWebSocketDTO.TYPE, notification);
114 } catch (Exception e) { 111 } catch (Exception e) {
115 - log.error("[doBroadcastChannelMessage][dto({}) 广播失败]", dto, e); 112 + log.error("[doBroadcastNotification][notification({}) 广播失败]", notification, e);
116 } 113 }
117 } 114 }
118 115
@@ -121,19 +118,15 @@ public class ImWebSocketServiceImpl implements ImWebSocketService { @@ -121,19 +118,15 @@ public class ImWebSocketServiceImpl implements ImWebSocketService {
121 } 118 }
122 119
123 /** 120 /**
124 - * 事务感知的任务调度:  
125 - * - 有事务:注册 afterCommit 回调,事务提交后再执行,防止客户端拿到消息去查库时数据还没落盘  
126 - * - 无事务:直接执行(如非 @Transactional 方法中的调用) 121 + * 事务感知的任务调度
127 * 122 *
128 - * @param task 待执行的推送任务(内部通过 getSelf() 走 @Async 异步执行) 123 + * @param task 待执行的推送任务
129 */ 124 */
130 private void executeAfterTransaction(Runnable task) { 125 private void executeAfterTransaction(Runnable task) {
131 - // 情况一:没有事务,直接执行  
132 if (!TransactionSynchronizationManager.isSynchronizationActive()) { 126 if (!TransactionSynchronizationManager.isSynchronizationActive()) {
133 task.run(); 127 task.run();
134 return; 128 return;
135 } 129 }
136 - // 情况二:有事务,注册 afterCommit 事件,在事务提交后执行  
137 TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() { 130 TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
138 131
139 @Override 132 @Override
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/ImPrivateMessageDTO.java deleted
1 -package cn.iocoder.yudao.module.im.service.websocket.dto;  
2 -  
3 -import cn.hutool.core.lang.Assert;  
4 -import cn.iocoder.yudao.framework.common.util.json.JsonUtils;  
5 -import cn.iocoder.yudao.framework.common.util.object.BeanUtils;  
6 -import cn.iocoder.yudao.module.im.dal.dataobject.message.ImPrivateMessageDO;  
7 -import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum;  
8 -import cn.iocoder.yudao.module.im.service.websocket.dto.notification.friend.BaseFriendNotification;  
9 -import cn.iocoder.yudao.module.im.service.websocket.dto.notification.group.BaseGroupNotification;  
10 -import lombok.Data;  
11 -import lombok.experimental.Accessors;  
12 -  
13 -import java.time.LocalDateTime;  
14 -  
15 -/**  
16 - * IM 私聊消息 WebSocket 统一推送 DTO  
17 - * <p>  
18 - * 发送、已读、回执、撤回都通过 {@link #type} 字段区分,  
19 - * 并统一复用 {@link #id} 字段表达目标消息或已读位置。  
20 - *  
21 - * @author 芋道源码  
22 - */  
23 -@Data  
24 -@Accessors(chain = true)  
25 -public class ImPrivateMessageDTO {  
26 -  
27 - public static final String TYPE = "im-private-message";  
28 -  
29 - /**  
30 - * 消息编号  
31 - * <p>  
32 - * 普通消息:当前消息 id  
33 - * READ:已读位置(我已读到这条消息)  
34 - * RECEIPT:已读位置(对方已读到这条消息)  
35 - * RECALL:被撤回的原消息 id  
36 - */  
37 - private Long id;  
38 - /**  
39 - * 客户端消息编号  
40 - */  
41 - private String clientMessageId;  
42 - /**  
43 - * 发送人编号  
44 - */  
45 - private Long senderId;  
46 - /**  
47 - * 接收人编号  
48 - */  
49 - private Long receiverId;  
50 - /**  
51 - * 消息类型  
52 - */  
53 - private Integer type;  
54 - /**  
55 - * 消息内容  
56 - */  
57 - private String content;  
58 - /**  
59 - * 消息状态  
60 - */  
61 - private Integer status;  
62 - /**  
63 - * 回执状态  
64 - */  
65 - private Integer receiptStatus;  
66 - /**  
67 - * 发送时间  
68 - */  
69 - private LocalDateTime sendTime;  
70 -  
71 - // ========== 静态工厂方法 ==========  
72 -  
73 - /**  
74 - * 构建发送消息 DTO  
75 - *  
76 - * @param message 私聊消息 DO  
77 - * @return 私聊 DTO  
78 - */  
79 - public static ImPrivateMessageDTO ofSend(ImPrivateMessageDO message) {  
80 - return BeanUtils.toBean(message, ImPrivateMessageDTO.class);  
81 - }  
82 -  
83 - /**  
84 - * 构建已读同步 DTO(多端同步:通知自己的其他终端"我已经读了某个会话")  
85 - *  
86 - * @param senderId 当前用户编号  
87 - * @param receiverId 对方用户编号  
88 - * @param readId 已读位置(最大已读消息编号)  
89 - * @return 私聊 DTO  
90 - */  
91 - public static ImPrivateMessageDTO ofRead(Long senderId, Long receiverId, Long readId) {  
92 - return new ImPrivateMessageDTO()  
93 - .setId(readId).setType(ImMessageTypeEnum.READ.getType())  
94 - .setSenderId(senderId).setReceiverId(receiverId);  
95 - }  
96 -  
97 - /**  
98 - * 构建已读回执 DTO(通知对方"我已读了你的消息")  
99 - *  
100 - * @param senderId 已读方的用户编号  
101 - * @param receiverId 对方用户编号  
102 - * @param readId 已读位置(最大已读消息编号)  
103 - * @return 私聊 DTO  
104 - */  
105 - public static ImPrivateMessageDTO ofReceipt(Long senderId, Long receiverId, Long readId) {  
106 - return new ImPrivateMessageDTO()  
107 - .setId(readId).setType(ImMessageTypeEnum.RECEIPT.getType())  
108 - .setSenderId(senderId).setReceiverId(receiverId);  
109 - }  
110 -  
111 - // ==================== 好友变更相关 ====================  
112 -  
113 - /**  
114 - * 构建好友通知推送 DTO(统一入口)  
115 - *  
116 - * @param type 消息类型;取自 {@link ImMessageTypeEnum} 中的 FRIEND_* 段  
117 - * @param operatorUserId 操作人用户编号;同时作为帧的 senderId 用于定位接收端 friendUserId  
118 - * @param receiverUserId 推送目标用户编号  
119 - * @param payload 好友通知 payload(继承 {@link BaseFriendNotification})  
120 - * @return 私聊 DTO  
121 - */  
122 - public static ImPrivateMessageDTO ofFriendNotification(Integer type, Long operatorUserId,  
123 - Long receiverUserId, BaseFriendNotification payload) {  
124 - validateNotification(type, payload, ImMessageTypeEnum.isFriendNotification(type));  
125 - return new ImPrivateMessageDTO().setType(type)  
126 - .setSenderId(operatorUserId).setReceiverId(receiverUserId)  
127 - .setContent(JsonUtils.toJsonString(payload)).setSendTime(LocalDateTime.now());  
128 - }  
129 -  
130 - // ==================== 群定向私聊通知 ====================  
131 -  
132 - // TODO DONE @AI:群申请定向通知继续走私聊通道  
133 - /**  
134 - * 构建群通知推送 DTO(走私聊通道定向推送,不入群消息流)  
135 - * <p>  
136 - * 用于 GROUP_REQUEST_RECEIVED / GROUP_REQUEST_APPROVED / GROUP_REQUEST_REJECTED 段位;  
137 - * 与 {@link cn.iocoder.yudao.module.im.service.message.dto.ImGroupMessageSendDTO} 走 sendGroupMessage 群广播路径不同  
138 - *  
139 - * @param type 消息类型;取自 {@link ImMessageTypeEnum} 中的 GROUP_REQUEST_* 段  
140 - * @param operatorUserId 操作人用户编号;同时作为帧的 senderId  
141 - * @param receiverUserId 推送目标用户编号  
142 - * @param payload 群事件 payload(继承 {@link BaseGroupNotification})  
143 - * @return 私聊 DTO  
144 - */  
145 - public static ImPrivateMessageDTO ofGroupNotification(Integer type, Long operatorUserId,  
146 - Long receiverUserId, BaseGroupNotification payload) {  
147 - validateNotification(type, payload, ImMessageTypeEnum.isGroupRequestNotification(type));  
148 - return new ImPrivateMessageDTO().setType(type)  
149 - .setSenderId(operatorUserId).setReceiverId(receiverUserId)  
150 - .setContent(JsonUtils.toJsonString(payload)).setSendTime(LocalDateTime.now());  
151 - }  
152 -  
153 - // ==================== 实时通话信令 ====================  
154 -  
155 - /**  
156 - * 构建通话信令推送 DTO(走私聊通道仅推参与方,不入消息流)  
157 - * <p>  
158 - * 用于 RTC_CALL(INVITE / REJECT 等)/ RTC_PARTICIPANT_CONNECTED / RTC_PARTICIPANT_DISCONNECTED  
159 - *  
160 - * @param type 消息类型;取自 {@link ImMessageTypeEnum} 中的 RTC_* 段  
161 - * @param senderId 发送人编号;INVITE 时为发起人,REJECT 时为拒绝者,参与者事件时为加入 / 离开者  
162 - * @param receiverUserId 推送目标用户编号  
163 - * @param payload 通话事件 payload(任意 RTC 通知 DTO)  
164 - * @return 私聊 DTO  
165 - */  
166 - public static ImPrivateMessageDTO ofRtcNotification(Integer type, Long senderId,  
167 - Long receiverUserId, Object payload) {  
168 - validateNotification(type, payload, ImMessageTypeEnum.isRtcNotification(type));  
169 - return new ImPrivateMessageDTO().setType(type)  
170 - .setSenderId(senderId).setReceiverId(receiverUserId)  
171 - .setContent(JsonUtils.toJsonString(payload)).setSendTime(LocalDateTime.now());  
172 - }  
173 -  
174 - private static void validateNotification(Integer type, Object payload, boolean supported) {  
175 - Assert.notNull(type, "消息类型不能为空");  
176 - Assert.notNull(payload, "消息内容不能为空");  
177 - Assert.isTrue(supported, "消息类型不匹配 type={}", type);  
178 - }  
179 -  
180 -}  
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/ImNotificationWebSocketDTO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.im.service.websocket.notification;
  2 +
  3 +import lombok.Data;
  4 +import lombok.experimental.Accessors;
  5 +
  6 +/**
  7 + * IM WebSocket 在线通知外壳
  8 + * <p>
  9 + * conversationType 定位会话维度;contentType 定位业务内容;payload 承载对应通知对象。
  10 + * 会进入聊天流的私聊、群聊、频道事件走 message 子包;不进入聊天流的好友、加群申请、通话信令走 NONE 会话。
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Data
  15 +@Accessors(chain = true)
  16 +public class ImNotificationWebSocketDTO {
  17 +
  18 + public static final String TYPE = "im-notification";
  19 +
  20 + /**
  21 + * 会话类型,参见 ImConversationTypeEnum 枚举类
  22 + */
  23 + private Integer conversationType;
  24 + /**
  25 + * 内容类型,参见 ImContentTypeEnum 枚举类
  26 + */
  27 + private Integer contentType;
  28 + /**
  29 + * 负载数据
  30 + */
  31 + private Object payload;
  32 +
  33 +}
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/friend/BaseFriendNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/friend/BaseFriendNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.friend; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.friend;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 4
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/friend/FriendAddNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/friend/FriendAddNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.friend; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.friend;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 4
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/friend/FriendBlockNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/friend/FriendBlockNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.friend; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.friend;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 4
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/friend/FriendDeleteNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/friend/FriendDeleteNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.friend; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.friend;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 4
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/friend/FriendInfoUpdatedNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/friend/FriendInfoUpdatedNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.friend; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.friend;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 4
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/friend/FriendRequestApprovedNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/friend/FriendRequestApprovedNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.friend; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.friend;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 4
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/friend/FriendRequestNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/friend/FriendRequestNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.friend; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.friend;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 4
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/friend/FriendRequestRejectedNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/friend/FriendRequestRejectedNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.friend; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.friend;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 4
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/friend/FriendUnblockNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/friend/FriendUnblockNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.friend; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.friend;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 4
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/friend/FriendUpdateNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/friend/FriendUpdateNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.friend; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.friend;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 4
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/group/BaseGroupNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/group/BaseGroupNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.group; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.group;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 4
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/group/GroupAdminAddNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/group/GroupAdminAddNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.group; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.group;
2 2
3 /** 3 /**
4 * 添加管理员事件通知(memberUserIds 为被设管理员的成员) 4 * 添加管理员事件通知(memberUserIds 为被设管理员的成员)
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/group/GroupAdminRemoveNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/group/GroupAdminRemoveNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.group; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.group;
2 2
3 /** 3 /**
4 * 撤销管理员事件通知(memberUserIds 为被撤销管理员的成员) 4 * 撤销管理员事件通知(memberUserIds 为被撤销管理员的成员)
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/group/GroupBannedNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/group/GroupBannedNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.group; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.group;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 4
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/group/GroupCancelMutedNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/group/GroupCancelMutedNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.group; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.group;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 import lombok.EqualsAndHashCode; 4 import lombok.EqualsAndHashCode;
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/group/GroupCreateNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/group/GroupCreateNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.group; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.group;
2 2
3 /** 3 /**
4 * 群创建事件通知(memberUserIds 含创建者 + 初始邀请成员) 4 * 群创建事件通知(memberUserIds 含创建者 + 初始邀请成员)
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/group/GroupDissolveNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/group/GroupDissolveNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.group; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.group;
2 2
3 /** 3 /**
4 * 群解散事件通知 4 * 群解散事件通知
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/group/GroupInfoUpdateNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/group/GroupInfoUpdateNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.group; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.group;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 4
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/group/GroupMemberCancelMutedNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/group/GroupMemberCancelMutedNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.group; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.group;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 import lombok.EqualsAndHashCode; 4 import lombok.EqualsAndHashCode;
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/group/GroupMemberEnterNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/group/GroupMemberEnterNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.group; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.group;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 import lombok.EqualsAndHashCode; 4 import lombok.EqualsAndHashCode;
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/group/GroupMemberInviteNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/group/GroupMemberInviteNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.group; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.group;
2 2
3 /** 3 /**
4 * 成员加入事件通知(memberUserIds 为被邀请人) 4 * 成员加入事件通知(memberUserIds 为被邀请人)
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/group/GroupMemberKickNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/group/GroupMemberKickNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.group; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.group;
2 2
3 /** 3 /**
4 * 成员被移出事件通知(memberUserIds 为被移出成员) 4 * 成员被移出事件通知(memberUserIds 为被移出成员)
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/group/GroupMemberListNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/group/GroupMemberListNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.group; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.group;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 4
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/group/GroupMemberMutedNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/group/GroupMemberMutedNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.group; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.group;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 import lombok.EqualsAndHashCode; 4 import lombok.EqualsAndHashCode;
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/group/GroupMemberNicknameUpdateNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/group/GroupMemberNicknameUpdateNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.group; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.group;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 4
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/group/GroupMemberQuitNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/group/GroupMemberQuitNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.group; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.group;
2 2
3 /** 3 /**
4 * 成员退群事件通知 4 * 成员退群事件通知
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/group/GroupMemberSettingUpdateNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/group/GroupMemberSettingUpdateNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.group; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.group;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 4
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/group/GroupMessagePinNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/group/GroupMessagePinNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.group; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.group;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 4
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/group/GroupMessageUnpinNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/group/GroupMessageUnpinNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.group; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.group;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 4
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/group/GroupMutedNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/group/GroupMutedNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.group; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.group;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 4
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/group/GroupNameUpdateNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/group/GroupNameUpdateNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.group; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.group;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 4
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/group/GroupNoticeUpdateNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/group/GroupNoticeUpdateNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.group; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.group;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 4
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/group/GroupOwnerTransferNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/group/GroupOwnerTransferNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.group; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.group;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 4
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/group/GroupRequestApprovedNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/group/GroupRequestApprovedNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.group; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.group;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 import lombok.EqualsAndHashCode; 4 import lombok.EqualsAndHashCode;
@@ -6,7 +6,7 @@ import lombok.EqualsAndHashCode; @@ -6,7 +6,7 @@ import lombok.EqualsAndHashCode;
6 /** 6 /**
7 * 入群申请被同意通知 7 * 入群申请被同意通知
8 * <p> 8 * <p>
9 - * 走私聊通道定向推送给申请人 + 群主 + 全部管理员;admin 侧据此把 unhandledCount 减 1 并从未处理列表移除 9 + * 定向推送给申请人 + 群主 + 全部管理员;admin 侧据此把 unhandledCount 减 1 并从未处理列表移除
10 */ 10 */
11 @EqualsAndHashCode(callSuper = true) 11 @EqualsAndHashCode(callSuper = true)
12 @Data 12 @Data
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/group/GroupRequestReceivedNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/group/GroupRequestReceivedNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.group; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.group;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 import lombok.EqualsAndHashCode; 4 import lombok.EqualsAndHashCode;
@@ -6,7 +6,7 @@ import lombok.EqualsAndHashCode; @@ -6,7 +6,7 @@ import lombok.EqualsAndHashCode;
6 /** 6 /**
7 * 收到新的入群申请通知 7 * 收到新的入群申请通知
8 * <p> 8 * <p>
9 - * 走私聊通道定向推送给群主 + 全部管理员(多端同步);payload 已携带申请方昵称 / 头像,前端按 requestId 直接 push 进列表 9 + * 定向推送给群主 + 全部管理员(多端同步);payload 已携带申请方昵称 / 头像,前端按 requestId 直接 push 进列表
10 */ 10 */
11 @EqualsAndHashCode(callSuper = true) 11 @EqualsAndHashCode(callSuper = true)
12 @Data 12 @Data
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/group/GroupRequestRejectedNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/group/GroupRequestRejectedNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.group; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.group;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 import lombok.EqualsAndHashCode; 4 import lombok.EqualsAndHashCode;
@@ -6,7 +6,7 @@ import lombok.EqualsAndHashCode; @@ -6,7 +6,7 @@ import lombok.EqualsAndHashCode;
6 /** 6 /**
7 * 入群申请被拒绝通知 7 * 入群申请被拒绝通知
8 * <p> 8 * <p>
9 - * 走私聊通道定向推送给申请人 + 群主 + 全部管理员;admin 侧据此把 unhandledCount 减 1 并从未处理列表移除 9 + * 定向推送给申请人 + 群主 + 全部管理员;admin 侧据此把 unhandledCount 减 1 并从未处理列表移除
10 */ 10 */
11 @EqualsAndHashCode(callSuper = true) 11 @EqualsAndHashCode(callSuper = true)
12 @Data 12 @Data
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/ImChannelMessageDTO.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/message/ImChannelMessageNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.message;
2 2
3 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 3 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
4 import cn.iocoder.yudao.module.im.dal.dataobject.message.ImChannelMessageDO; 4 import cn.iocoder.yudao.module.im.dal.dataobject.message.ImChannelMessageDO;
5 -import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum;  
6 import lombok.Data; 5 import lombok.Data;
7 import lombok.experimental.Accessors; 6 import lombok.experimental.Accessors;
8 7
9 import java.time.LocalDateTime; 8 import java.time.LocalDateTime;
10 9
11 /** 10 /**
12 - * IM 频道消息 WebSocket 推送 DTO 11 + * IM 频道消息 WebSocket 推送通知
13 * <p> 12 * <p>
14 * 单向:服务端运营推送 → C 端用户;C 端不能向频道发消息。 13 * 单向:服务端运营推送 → C 端用户;C 端不能向频道发消息。
15 * 字段分层:顶层是消息元数据 + 检索维度,content 是 MaterialMessage payload 的 JSON 串。 14 * 字段分层:顶层是消息元数据 + 检索维度,content 是 MaterialMessage payload 的 JSON 串。
@@ -18,9 +17,7 @@ import java.time.LocalDateTime; @@ -18,9 +17,7 @@ import java.time.LocalDateTime;
18 */ 17 */
19 @Data 18 @Data
20 @Accessors(chain = true) 19 @Accessors(chain = true)
21 -public class ImChannelMessageDTO {  
22 -  
23 - public static final String TYPE = "im-channel-message"; 20 +public class ImChannelMessageNotification {
24 21
25 /** 22 /**
26 * 消息编号 23 * 消息编号
@@ -48,23 +45,10 @@ public class ImChannelMessageDTO { @@ -48,23 +45,10 @@ public class ImChannelMessageDTO {
48 private LocalDateTime sendTime; 45 private LocalDateTime sendTime;
49 46
50 /** 47 /**
51 - * 由频道消息 DO 构建推送 DTO  
52 - */  
53 - public static ImChannelMessageDTO ofSend(ImChannelMessageDO message) {  
54 - return BeanUtils.toBean(message, ImChannelMessageDTO.class);  
55 - }  
56 -  
57 - /**  
58 - * 构建已读同步 DTO;多端同步:通知自己的其他终端「我已经读了某频道」  
59 - *  
60 - * @param channelId 频道编号  
61 - * @param readId 已读位置(最大已读消息编号)  
62 - * @return 频道 DTO 48 + * 由频道消息 DO 构建推送通知
63 */ 49 */
64 - public static ImChannelMessageDTO ofRead(Long channelId, Long readId) {  
65 - return new ImChannelMessageDTO()  
66 - .setId(readId).setType(ImMessageTypeEnum.READ.getType())  
67 - .setChannelId(channelId); 50 + public static ImChannelMessageNotification ofSend(ImChannelMessageDO message) {
  51 + return BeanUtils.toBean(message, ImChannelMessageNotification.class);
68 } 52 }
69 53
70 } 54 }
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/ImGroupMessageDTO.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/message/ImGroupMessageNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.message;
2 2
3 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 3 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
4 import cn.iocoder.yudao.module.im.dal.dataobject.message.ImGroupMessageDO; 4 import cn.iocoder.yudao.module.im.dal.dataobject.message.ImGroupMessageDO;
5 -import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum;  
6 import lombok.Data; 5 import lombok.Data;
7 6
8 import java.time.LocalDateTime; 7 import java.time.LocalDateTime;
9 import java.util.List; 8 import java.util.List;
10 9
11 /** 10 /**
12 - * IM 群聊消息 WebSocket 统一推送 DTO  
13 - * <p>  
14 - * 发送、已读、回执都通过 {@link #type} 字段区分,  
15 - * 并统一复用 {@link #id} 字段表达目标消息或已读位置。 11 + * IM 群聊消息 WebSocket 统一推送通知
16 * 12 *
17 * @author 芋道源码 13 * @author 芋道源码
18 */ 14 */
19 @Data 15 @Data
20 -public class ImGroupMessageDTO {  
21 -  
22 - public static final String TYPE = "im-group-message"; 16 +public class ImGroupMessageNotification {
23 17
24 /** 18 /**
25 * 消息编号 19 * 消息编号
26 - * <p>  
27 - * 普通消息:当前消息 id  
28 - * READ:无(群已读不需要)  
29 - * RECEIPT:需要回执的目标消息 id  
30 */ 20 */
31 private Long id; 21 private Long id;
32 /** 22 /**
@@ -54,6 +44,14 @@ public class ImGroupMessageDTO { @@ -54,6 +44,14 @@ public class ImGroupMessageDTO {
54 */ 44 */
55 private Integer status; 45 private Integer status;
56 /** 46 /**
  47 + * 回执状态
  48 + */
  49 + private Integer receiptStatus;
  50 + /**
  51 + * 已读人数
  52 + */
  53 + private Integer readCount;
  54 + /**
57 * 发送时间 55 * 发送时间
58 */ 56 */
59 private LocalDateTime sendTime; 57 private LocalDateTime sendTime;
@@ -66,58 +64,14 @@ public class ImGroupMessageDTO { @@ -66,58 +64,14 @@ public class ImGroupMessageDTO {
66 */ 64 */
67 private List<Long> receiverUserIds; 65 private List<Long> receiverUserIds;
68 /** 66 /**
69 - * 群回执状态  
70 - */  
71 - private Integer receiptStatus;  
72 - /**  
73 - * 群回执已读人数  
74 - */  
75 - private Integer readCount;  
76 - /**  
77 - * 已读位置  
78 - */  
79 - private Long readId;  
80 -  
81 - // ========== 静态工厂方法 ==========  
82 -  
83 - /**  
84 - * 构建发送消息 DTO 67 + * 构建发送消息通知
85 * 68 *
86 * @param message 群聊消息 DO 69 * @param message 群聊消息 DO
87 - * @return 群聊 DTO  
88 - */  
89 - public static ImGroupMessageDTO ofSend(ImGroupMessageDO message) {  
90 - return BeanUtils.toBean(message, ImGroupMessageDTO.class).setReceiverUserIds(null);  
91 - }  
92 -  
93 - /**  
94 - * 构建已读同步 DTO(多端同步:通知自己的其他终端"我已经读了某个群")  
95 - *  
96 - * @param senderId 当前用户编号  
97 - * @param groupId 群编号  
98 - * @param readId 已读位置(最大已读消息编号)  
99 - * @return 群聊 DTO  
100 - */  
101 - public static ImGroupMessageDTO ofRead(Long senderId, Long groupId, Long readId) {  
102 - return new ImGroupMessageDTO()  
103 - .setId(readId).setReadId(readId).setType(ImMessageTypeEnum.READ.getType())  
104 - .setSenderId(senderId).setGroupId(groupId);  
105 - }  
106 -  
107 - /**  
108 - * 构建群回执 DTO(广播回执状态和已读人数)  
109 - *  
110 - * @param messageId 消息编号  
111 - * @param groupId 群编号  
112 - * @param readCount 已读人数  
113 - * @param receiptStatus 回执状态  
114 - * @return 群聊 DTO 70 + * @return 群聊通知
115 */ 71 */
116 - public static ImGroupMessageDTO ofReceipt(Long messageId, Long groupId,  
117 - Integer readCount, Integer receiptStatus) {  
118 - return new ImGroupMessageDTO()  
119 - .setId(messageId).setType(ImMessageTypeEnum.RECEIPT.getType())  
120 - .setGroupId(groupId).setReadCount(readCount).setReceiptStatus(receiptStatus); 72 + public static ImGroupMessageNotification ofSend(ImGroupMessageDO message) {
  73 + return BeanUtils.toBean(message, ImGroupMessageNotification.class)
  74 + .setReadCount(message.getReadCount() != null ? message.getReadCount() : 0);
121 } 75 }
122 76
123 } 77 }
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/message/ImMessageReadNotification.java 0 → 100644
  1 +package cn.iocoder.yudao.module.im.service.websocket.notification.message;
  2 +
  3 +import lombok.Data;
  4 +import lombok.experimental.Accessors;
  5 +
  6 +/**
  7 + * IM 消息已读同步通知
  8 + *
  9 + * @author 芋道源码
  10 + */
  11 +@Data
  12 +@Accessors(chain = true)
  13 +public class ImMessageReadNotification {
  14 +
  15 + /**
  16 + * 已读位置(最大已读消息编号)
  17 + */
  18 + private Long id;
  19 + /**
  20 + * 发送人编号
  21 + */
  22 + private Long senderId;
  23 + /**
  24 + * 私聊接收人编号
  25 + */
  26 + private Long receiverId;
  27 + /**
  28 + * 群编号
  29 + */
  30 + private Long groupId;
  31 + /**
  32 + * 频道编号
  33 + */
  34 + private Long channelId;
  35 + /**
  36 + * 已读位置(最大已读消息编号)
  37 + */
  38 + private Long readId;
  39 +
  40 + public static ImMessageReadNotification ofPrivate(Long senderId, Long receiverId, Long readId) {
  41 + return new ImMessageReadNotification()
  42 + .setId(readId).setReadId(readId)
  43 + .setSenderId(senderId).setReceiverId(receiverId);
  44 + }
  45 +
  46 + public static ImMessageReadNotification ofGroup(Long senderId, Long groupId, Long readId) {
  47 + return new ImMessageReadNotification()
  48 + .setId(readId).setReadId(readId)
  49 + .setSenderId(senderId).setGroupId(groupId);
  50 + }
  51 +
  52 + public static ImMessageReadNotification ofChannel(Long channelId, Long readId) {
  53 + return new ImMessageReadNotification()
  54 + .setId(readId).setReadId(readId)
  55 + .setChannelId(channelId);
  56 + }
  57 +
  58 +}
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/message/ImMessageReceiptNotification.java 0 → 100644
  1 +package cn.iocoder.yudao.module.im.service.websocket.notification.message;
  2 +
  3 +import lombok.Data;
  4 +import lombok.experimental.Accessors;
  5 +
  6 +/**
  7 + * IM 消息回执通知
  8 + *
  9 + * @author 芋道源码
  10 + */
  11 +@Data
  12 +@Accessors(chain = true)
  13 +public class ImMessageReceiptNotification {
  14 +
  15 + /**
  16 + * 消息编号
  17 + */
  18 + private Long id;
  19 + /**
  20 + * 已读方的用户编号
  21 + */
  22 + private Long senderId;
  23 + /**
  24 + * 私聊接收人编号
  25 + */
  26 + private Long receiverId;
  27 + /**
  28 + * 群编号
  29 + */
  30 + private Long groupId;
  31 + /**
  32 + * 已读人数
  33 + */
  34 + private Integer readCount;
  35 + /**
  36 + * 回执状态
  37 + */
  38 + private Integer receiptStatus;
  39 +
  40 + public static ImMessageReceiptNotification ofPrivate(Long senderId, Long receiverId, Long readId) {
  41 + return new ImMessageReceiptNotification()
  42 + .setId(readId).setSenderId(senderId).setReceiverId(receiverId);
  43 + }
  44 +
  45 + public static ImMessageReceiptNotification ofGroup(Long messageId, Long groupId,
  46 + Integer readCount, Integer receiptStatus) {
  47 + return new ImMessageReceiptNotification()
  48 + .setId(messageId).setGroupId(groupId)
  49 + .setReadCount(readCount).setReceiptStatus(receiptStatus);
  50 + }
  51 +
  52 +}
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/message/ImPrivateMessageNotification.java 0 → 100644
  1 +package cn.iocoder.yudao.module.im.service.websocket.notification.message;
  2 +
  3 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  4 +import cn.iocoder.yudao.module.im.dal.dataobject.message.ImPrivateMessageDO;
  5 +import lombok.Data;
  6 +import lombok.experimental.Accessors;
  7 +
  8 +import java.time.LocalDateTime;
  9 +
  10 +/**
  11 + * IM 私聊消息 WebSocket 统一推送通知
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@Data
  16 +@Accessors(chain = true)
  17 +public class ImPrivateMessageNotification {
  18 +
  19 + /**
  20 + * 消息编号
  21 + */
  22 + private Long id;
  23 + /**
  24 + * 客户端消息编号
  25 + */
  26 + private String clientMessageId;
  27 + /**
  28 + * 发送人编号
  29 + */
  30 + private Long senderId;
  31 + /**
  32 + * 接收人编号
  33 + */
  34 + private Long receiverId;
  35 + /**
  36 + * 消息类型
  37 + */
  38 + private Integer type;
  39 + /**
  40 + * 消息内容
  41 + */
  42 + private String content;
  43 + /**
  44 + * 消息状态
  45 + */
  46 + private Integer status;
  47 + /**
  48 + * 回执状态
  49 + */
  50 + private Integer receiptStatus;
  51 + /**
  52 + * 发送时间
  53 + */
  54 + private LocalDateTime sendTime;
  55 +
  56 + // ========== 静态工厂方法 ==========
  57 +
  58 + /**
  59 + * 构建发送消息通知
  60 + *
  61 + * @param message 私聊消息 DO
  62 + * @return 私聊通知
  63 + */
  64 + public static ImPrivateMessageNotification ofSend(ImPrivateMessageDO message) {
  65 + return BeanUtils.toBean(message, ImPrivateMessageNotification.class);
  66 + }
  67 +
  68 +}
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/package-info.java 0 → 100644
  1 +/**
  2 + * IM WebSocket 在线通知对象。
  3 + *
  4 + * <p>
  5 + * 本包只放 WebSocket 外层通知对象,固定使用 im-notification 作为推送 type。
  6 + * 具体业务 payload 放在子包中:
  7 + * <ul>
  8 + * <li>{@code message}:私聊、群聊、频道消息通知,以及消息内容结构;</li>
  9 + * <li>{@code friend}:好友关系和好友申请通知;</li>
  10 + * <li>{@code group}:群资料、群成员、加群申请通知;</li>
  11 + * <li>{@code rtc}:实时通话通知。</li>
  12 + * </ul>
  13 + */
  14 +package cn.iocoder.yudao.module.im.service.websocket.notification;
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/rtc/ImRtcCallEndNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/rtc/ImRtcCallEndNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.rtc; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.rtc;
2 2
3 import cn.iocoder.yudao.module.im.dal.dataobject.rtc.ImRtcCallDO; 3 import cn.iocoder.yudao.module.im.dal.dataobject.rtc.ImRtcCallDO;
4 import cn.iocoder.yudao.module.im.enums.rtc.ImRtcCallEndReasonEnum; 4 import cn.iocoder.yudao.module.im.enums.rtc.ImRtcCallEndReasonEnum;
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/rtc/ImRtcCallNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/rtc/ImRtcCallNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.rtc; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.rtc;
2 2
3 import cn.iocoder.yudao.module.im.dal.dataobject.rtc.ImRtcCallDO; 3 import cn.iocoder.yudao.module.im.dal.dataobject.rtc.ImRtcCallDO;
4 import cn.iocoder.yudao.module.im.enums.rtc.ImRtcParticipantStatusEnum; 4 import cn.iocoder.yudao.module.im.enums.rtc.ImRtcParticipantStatusEnum;
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/rtc/ImRtcCallStartNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/rtc/ImRtcCallStartNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.rtc; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.rtc;
2 2
3 import cn.iocoder.yudao.module.im.dal.dataobject.rtc.ImRtcCallDO; 3 import cn.iocoder.yudao.module.im.dal.dataobject.rtc.ImRtcCallDO;
4 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; 4 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/rtc/ImRtcParticipantConnectedNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/rtc/ImRtcParticipantConnectedNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.rtc; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.rtc;
2 2
3 import cn.iocoder.yudao.module.im.dal.dataobject.rtc.ImRtcCallDO; 3 import cn.iocoder.yudao.module.im.dal.dataobject.rtc.ImRtcCallDO;
4 import lombok.Data; 4 import lombok.Data;
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/rtc/ImRtcParticipantDisconnectedNotification.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/notification/rtc/ImRtcParticipantDisconnectedNotification.java
1 -package cn.iocoder.yudao.module.im.service.websocket.dto.notification.rtc; 1 +package cn.iocoder.yudao.module.im.service.websocket.notification.rtc;
2 2
3 import cn.iocoder.yudao.module.im.dal.dataobject.rtc.ImRtcCallDO; 3 import cn.iocoder.yudao.module.im.dal.dataobject.rtc.ImRtcCallDO;
4 import lombok.Data; 4 import lombok.Data;
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/util/ImMessageUtils.java
@@ -4,8 +4,8 @@ import cn.hutool.core.collection.CollUtil; @@ -4,8 +4,8 @@ import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.convert.Convert; 4 import cn.hutool.core.convert.Convert;
5 import cn.hutool.core.util.StrUtil; 5 import cn.hutool.core.util.StrUtil;
6 import cn.iocoder.yudao.framework.common.util.json.JsonUtils; 6 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
7 -import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum;  
8 -import cn.iocoder.yudao.module.im.service.websocket.dto.message.QuoteMessage; 7 +import cn.iocoder.yudao.module.im.enums.ImContentTypeEnum;
  8 +import cn.iocoder.yudao.module.im.dal.dataobject.message.content.QuoteMessage;
9 9
10 import java.util.Collection; 10 import java.util.Collection;
11 import java.util.LinkedHashMap; 11 import java.util.LinkedHashMap;
@@ -39,9 +39,9 @@ public class ImMessageUtils { @@ -39,9 +39,9 @@ public class ImMessageUtils {
39 * @param content 消息内容 39 * @param content 消息内容
40 */ 40 */
41 public static void validateUserMessageContent(Integer type, String content) { 41 public static void validateUserMessageContent(Integer type, String content) {
42 - ImMessageTypeEnum messageType; 42 + ImContentTypeEnum messageType;
43 try { 43 try {
44 - messageType = ImMessageTypeEnum.validate(type); 44 + messageType = ImContentTypeEnum.validate(type);
45 } catch (IllegalArgumentException e) { 45 } catch (IllegalArgumentException e) {
46 throw exception(MESSAGE_CONTENT_INVALID); 46 throw exception(MESSAGE_CONTENT_INVALID);
47 } 47 }
@@ -52,23 +52,23 @@ public class ImMessageUtils { @@ -52,23 +52,23 @@ public class ImMessageUtils {
52 if (map == null) { 52 if (map == null) {
53 throw exception(MESSAGE_CONTENT_INVALID); 53 throw exception(MESSAGE_CONTENT_INVALID);
54 } 54 }
55 - if (ImMessageTypeEnum.TEXT == messageType) { 55 + if (ImContentTypeEnum.TEXT == messageType) {
56 validateTextContent(map); 56 validateTextContent(map);
57 - } else if (ImMessageTypeEnum.IMAGE == messageType || ImMessageTypeEnum.FACE == messageType) { 57 + } else if (ImContentTypeEnum.IMAGE == messageType || ImContentTypeEnum.FACE == messageType) {
58 validateUrl(getString(map, "url")); 58 validateUrl(getString(map, "url"));
59 - } else if (ImMessageTypeEnum.VOICE == messageType) { 59 + } else if (ImContentTypeEnum.VOICE == messageType) {
60 validateUrl(getString(map, "url")); 60 validateUrl(getString(map, "url"));
61 validatePositiveNumber(map.get("duration")); 61 validatePositiveNumber(map.get("duration"));
62 - } else if (ImMessageTypeEnum.VIDEO == messageType) { 62 + } else if (ImContentTypeEnum.VIDEO == messageType) {
63 validateUrl(getString(map, "url")); 63 validateUrl(getString(map, "url"));
64 - } else if (ImMessageTypeEnum.FILE == messageType) { 64 + } else if (ImContentTypeEnum.FILE == messageType) {
65 validateUrl(getString(map, "url")); 65 validateUrl(getString(map, "url"));
66 validateNotBlank(getString(map, "name")); 66 validateNotBlank(getString(map, "name"));
67 - } else if (ImMessageTypeEnum.CARD == messageType) { 67 + } else if (ImContentTypeEnum.CARD == messageType) {
68 validateCardContent(map); 68 validateCardContent(map);
69 - } else if (ImMessageTypeEnum.MERGE == messageType) { 69 + } else if (ImContentTypeEnum.MERGE == messageType) {
70 validateMergeContent(map); 70 validateMergeContent(map);
71 - } else if (ImMessageTypeEnum.MATERIAL == messageType) { 71 + } else if (ImContentTypeEnum.MATERIAL == messageType) {
72 validateMaterialContent(map); 72 validateMaterialContent(map);
73 } 73 }
74 } 74 }
yudao-module-im/src/test/java/cn/iocoder/yudao/module/im/dal/mysql/statistics/ImStatisticsManagerMapperTest.java
@@ -11,7 +11,7 @@ import cn.iocoder.yudao.module.im.dal.mysql.group.ImGroupMemberMapper; @@ -11,7 +11,7 @@ import cn.iocoder.yudao.module.im.dal.mysql.group.ImGroupMemberMapper;
11 import cn.iocoder.yudao.module.im.dal.mysql.message.ImGroupMessageMapper; 11 import cn.iocoder.yudao.module.im.dal.mysql.message.ImGroupMessageMapper;
12 import cn.iocoder.yudao.module.im.dal.mysql.message.ImPrivateMessageMapper; 12 import cn.iocoder.yudao.module.im.dal.mysql.message.ImPrivateMessageMapper;
13 import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum; 13 import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum;
14 -import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum; 14 +import cn.iocoder.yudao.module.im.enums.ImContentTypeEnum;
15 import jakarta.annotation.Resource; 15 import jakarta.annotation.Resource;
16 import org.junit.jupiter.api.BeforeEach; 16 import org.junit.jupiter.api.BeforeEach;
17 import org.junit.jupiter.api.Test; 17 import org.junit.jupiter.api.Test;
@@ -194,10 +194,10 @@ public class ImStatisticsManagerMapperTest extends BaseDbUnitTest { @@ -194,10 +194,10 @@ public class ImStatisticsManagerMapperTest extends BaseDbUnitTest {
194 @Test 194 @Test
195 public void testSelectMessageTypeDistribution_mergePrivateAndGroup() { 195 public void testSelectMessageTypeDistribution_mergePrivateAndGroup() {
196 // 准备:私聊 type=0 ×1,群聊 type=0 ×2、type=1 ×1 196 // 准备:私聊 type=0 ×1,群聊 type=0 ×2、type=1 ×1
197 - privateMessageMapper.insert(buildPrivate(1L, 2L, WINDOW_BEGIN.plusDays(1)).setType(ImMessageTypeEnum.TEXT.getType()));  
198 - groupMessageMapper.insert(buildGroupMessage(1L, 100L, WINDOW_BEGIN.plusDays(1)).setType(ImMessageTypeEnum.TEXT.getType()));  
199 - groupMessageMapper.insert(buildGroupMessage(1L, 100L, WINDOW_BEGIN.plusDays(1)).setType(ImMessageTypeEnum.TEXT.getType()));  
200 - groupMessageMapper.insert(buildGroupMessage(1L, 100L, WINDOW_BEGIN.plusDays(1)).setType(ImMessageTypeEnum.IMAGE.getType())); 197 + privateMessageMapper.insert(buildPrivate(1L, 2L, WINDOW_BEGIN.plusDays(1)).setType(ImContentTypeEnum.TEXT.getType()));
  198 + groupMessageMapper.insert(buildGroupMessage(1L, 100L, WINDOW_BEGIN.plusDays(1)).setType(ImContentTypeEnum.TEXT.getType()));
  199 + groupMessageMapper.insert(buildGroupMessage(1L, 100L, WINDOW_BEGIN.plusDays(1)).setType(ImContentTypeEnum.TEXT.getType()));
  200 + groupMessageMapper.insert(buildGroupMessage(1L, 100L, WINDOW_BEGIN.plusDays(1)).setType(ImContentTypeEnum.IMAGE.getType()));
201 201
202 // 调用 202 // 调用
203 List<Map<String, Object>> dist = mapper.selectMessageTypeDistribution(WINDOW_BEGIN, WINDOW_END); 203 List<Map<String, Object>> dist = mapper.selectMessageTypeDistribution(WINDOW_BEGIN, WINDOW_END);
@@ -205,8 +205,8 @@ public class ImStatisticsManagerMapperTest extends BaseDbUnitTest { @@ -205,8 +205,8 @@ public class ImStatisticsManagerMapperTest extends BaseDbUnitTest {
205 // 断言:type=TEXT(0) → 3;type=IMAGE(1) → 1 205 // 断言:type=TEXT(0) → 3;type=IMAGE(1) → 1
206 Map<Object, Long> byType = dist.stream().collect(java.util.stream.Collectors.toMap( 206 Map<Object, Long> byType = dist.stream().collect(java.util.stream.Collectors.toMap(
207 m -> ((Number) m.get("type")).intValue(), m -> ((Number) m.get("count")).longValue())); 207 m -> ((Number) m.get("type")).intValue(), m -> ((Number) m.get("count")).longValue()));
208 - assertEquals(3L, byType.get(ImMessageTypeEnum.TEXT.getType()));  
209 - assertEquals(1L, byType.get(ImMessageTypeEnum.IMAGE.getType())); 208 + assertEquals(3L, byType.get(ImContentTypeEnum.TEXT.getType()));
  209 + assertEquals(1L, byType.get(ImContentTypeEnum.IMAGE.getType()));
210 } 210 }
211 211
212 @Test 212 @Test
@@ -243,7 +243,7 @@ public class ImStatisticsManagerMapperTest extends BaseDbUnitTest { @@ -243,7 +243,7 @@ public class ImStatisticsManagerMapperTest extends BaseDbUnitTest {
243 return ImPrivateMessageDO.builder() 243 return ImPrivateMessageDO.builder()
244 .clientMessageId("uuid-" + System.nanoTime()) 244 .clientMessageId("uuid-" + System.nanoTime())
245 .senderId(senderId).receiverId(receiverId) 245 .senderId(senderId).receiverId(receiverId)
246 - .type(ImMessageTypeEnum.TEXT.getType()) 246 + .type(ImContentTypeEnum.TEXT.getType())
247 .content("{}") 247 .content("{}")
248 .status(ImMessageStatusEnum.NORMAL.getStatus()) 248 .status(ImMessageStatusEnum.NORMAL.getStatus())
249 .sendTime(sendTime).build(); 249 .sendTime(sendTime).build();
@@ -253,7 +253,7 @@ public class ImStatisticsManagerMapperTest extends BaseDbUnitTest { @@ -253,7 +253,7 @@ public class ImStatisticsManagerMapperTest extends BaseDbUnitTest {
253 return new ImGroupMessageDO() 253 return new ImGroupMessageDO()
254 .setClientMessageId("uuid-" + System.nanoTime()) 254 .setClientMessageId("uuid-" + System.nanoTime())
255 .setSenderId(senderId).setGroupId(groupId) 255 .setSenderId(senderId).setGroupId(groupId)
256 - .setType(ImMessageTypeEnum.TEXT.getType()) 256 + .setType(ImContentTypeEnum.TEXT.getType())
257 .setContent("{}") 257 .setContent("{}")
258 .setStatus(ImMessageStatusEnum.NORMAL.getStatus()) 258 .setStatus(ImMessageStatusEnum.NORMAL.getStatus())
259 .setSendTime(sendTime); 259 .setSendTime(sendTime);
yudao-module-im/src/test/java/cn/iocoder/yudao/module/im/service/friend/ImFriendRequestServiceImplTest.java
@@ -12,7 +12,6 @@ import cn.iocoder.yudao.module.im.enums.friend.ImFriendRequestHandleResultEnum; @@ -12,7 +12,6 @@ import cn.iocoder.yudao.module.im.enums.friend.ImFriendRequestHandleResultEnum;
12 import cn.iocoder.yudao.module.im.enums.friend.ImFriendStateEnum; 12 import cn.iocoder.yudao.module.im.enums.friend.ImFriendStateEnum;
13 import cn.iocoder.yudao.module.im.framework.config.ImProperties; 13 import cn.iocoder.yudao.module.im.framework.config.ImProperties;
14 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService; 14 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService;
15 -import cn.iocoder.yudao.module.im.service.websocket.dto.ImPrivateMessageDTO;  
16 import cn.iocoder.yudao.module.system.api.user.AdminUserApi; 15 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
17 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; 16 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
18 import org.junit.jupiter.api.Test; 17 import org.junit.jupiter.api.Test;
yudao-module-im/src/test/java/cn/iocoder/yudao/module/im/service/friend/ImFriendServiceImplTest.java
@@ -10,7 +10,6 @@ import cn.iocoder.yudao.module.im.dal.mysql.friend.ImFriendMapper; @@ -10,7 +10,6 @@ import cn.iocoder.yudao.module.im.dal.mysql.friend.ImFriendMapper;
10 import cn.iocoder.yudao.module.im.service.message.ImPrivateMessageService; 10 import cn.iocoder.yudao.module.im.service.message.ImPrivateMessageService;
11 import cn.iocoder.yudao.module.im.service.message.dto.ImPrivateMessageSendDTO; 11 import cn.iocoder.yudao.module.im.service.message.dto.ImPrivateMessageSendDTO;
12 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService; 12 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService;
13 -import cn.iocoder.yudao.module.im.service.websocket.dto.ImPrivateMessageDTO;  
14 import cn.iocoder.yudao.module.system.api.user.AdminUserApi; 13 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
15 import org.junit.jupiter.api.Test; 14 import org.junit.jupiter.api.Test;
16 import org.mockito.ArgumentCaptor; 15 import org.mockito.ArgumentCaptor;
@@ -158,7 +157,7 @@ public class ImFriendServiceImplTest extends BaseMockitoUnitTest { @@ -158,7 +157,7 @@ public class ImFriendServiceImplTest extends BaseMockitoUnitTest {
158 verify(imFriendMapper, never()).insert(any(ImFriendDO.class)); 157 verify(imFriendMapper, never()).insert(any(ImFriendDO.class));
159 verify(imFriendMapper, never()).updateById(any(ImFriendDO.class)); 158 verify(imFriendMapper, never()).updateById(any(ImFriendDO.class));
160 verify(imFriendMapper, never()).updateReAddFields(anyLong(), anyInt(), any(LocalDateTime.class), 159 verify(imFriendMapper, never()).updateReAddFields(anyLong(), anyInt(), any(LocalDateTime.class),
161 - anyBoolean(), anyBoolean(), anyBoolean(), any(), any()); 160 + any(LocalDateTime.class), anyBoolean(), anyBoolean(), anyBoolean(), any(), any());
162 } 161 }
163 162
164 @Test 163 @Test
@@ -173,7 +172,7 @@ public class ImFriendServiceImplTest extends BaseMockitoUnitTest { @@ -173,7 +172,7 @@ public class ImFriendServiceImplTest extends BaseMockitoUnitTest {
173 172
174 // 断言:恢复 ENABLE,并清空 deleteTime 173 // 断言:恢复 ENABLE,并清空 deleteTime
175 verify(imFriendMapper).updateReAddFields(eq(10L), eq(CommonStatusEnum.ENABLE.getStatus()), 174 verify(imFriendMapper).updateReAddFields(eq(10L), eq(CommonStatusEnum.ENABLE.getStatus()),
176 - any(LocalDateTime.class), eq(false), eq(false), eq(false), isNull(), isNull()); 175 + any(LocalDateTime.class), any(LocalDateTime.class), eq(false), eq(false), eq(false), isNull(), isNull());
177 verify(imFriendMapper, never()).insert(any(ImFriendDO.class)); 176 verify(imFriendMapper, never()).insert(any(ImFriendDO.class));
178 } 177 }
179 178
yudao-module-im/src/test/java/cn/iocoder/yudao/module/im/service/group/ImGroupMemberServiceImplTest.java
@@ -9,7 +9,7 @@ import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO; @@ -9,7 +9,7 @@ import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO;
9 import cn.iocoder.yudao.module.im.dal.mysql.group.ImGroupMemberMapper; 9 import cn.iocoder.yudao.module.im.dal.mysql.group.ImGroupMemberMapper;
10 import cn.iocoder.yudao.module.im.enums.group.ImGroupMemberRoleEnum; 10 import cn.iocoder.yudao.module.im.enums.group.ImGroupMemberRoleEnum;
11 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService; 11 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService;
12 -import cn.iocoder.yudao.module.im.service.websocket.dto.ImGroupMessageDTO; 12 +import cn.iocoder.yudao.module.im.service.websocket.notification.message.ImGroupMessageNotification;
13 import org.junit.jupiter.api.Test; 13 import org.junit.jupiter.api.Test;
14 import org.mockito.ArgumentCaptor; 14 import org.mockito.ArgumentCaptor;
15 import org.mockito.InjectMocks; 15 import org.mockito.InjectMocks;
yudao-module-im/src/test/java/cn/iocoder/yudao/module/im/service/group/ImGroupRequestServiceImplTest.java
@@ -13,11 +13,10 @@ import cn.iocoder.yudao.module.im.dal.mysql.group.ImGroupRequestMapper; @@ -13,11 +13,10 @@ import cn.iocoder.yudao.module.im.dal.mysql.group.ImGroupRequestMapper;
13 import cn.iocoder.yudao.module.im.enums.group.ImGroupAddSourceEnum; 13 import cn.iocoder.yudao.module.im.enums.group.ImGroupAddSourceEnum;
14 import cn.iocoder.yudao.module.im.enums.group.ImGroupMemberRoleEnum; 14 import cn.iocoder.yudao.module.im.enums.group.ImGroupMemberRoleEnum;
15 import cn.iocoder.yudao.module.im.enums.group.ImGroupRequestHandleResultEnum; 15 import cn.iocoder.yudao.module.im.enums.group.ImGroupRequestHandleResultEnum;
16 -import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum; 16 +import cn.iocoder.yudao.module.im.enums.ImContentTypeEnum;
17 import cn.iocoder.yudao.module.im.service.message.ImGroupMessageService; 17 import cn.iocoder.yudao.module.im.service.message.ImGroupMessageService;
18 import cn.iocoder.yudao.module.im.service.message.dto.ImGroupMessageSendDTO; 18 import cn.iocoder.yudao.module.im.service.message.dto.ImGroupMessageSendDTO;
19 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService; 19 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService;
20 -import cn.iocoder.yudao.module.im.service.websocket.dto.ImPrivateMessageDTO;  
21 import cn.iocoder.yudao.module.system.api.user.AdminUserApi; 20 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
22 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; 21 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
23 import org.junit.jupiter.api.Test; 22 import org.junit.jupiter.api.Test;
@@ -84,7 +83,7 @@ public class ImGroupRequestServiceImplTest extends BaseMockitoUnitTest { @@ -84,7 +83,7 @@ public class ImGroupRequestServiceImplTest extends BaseMockitoUnitTest {
84 // 推 1510 自由进群 83 // 推 1510 自由进群
85 ArgumentCaptor<ImGroupMessageSendDTO> dtoCaptor = ArgumentCaptor.forClass(ImGroupMessageSendDTO.class); 84 ArgumentCaptor<ImGroupMessageSendDTO> dtoCaptor = ArgumentCaptor.forClass(ImGroupMessageSendDTO.class);
86 verify(groupMessageService).sendGroupMessage(eq(1L), dtoCaptor.capture()); 85 verify(groupMessageService).sendGroupMessage(eq(1L), dtoCaptor.capture());
87 - assertEquals(ImMessageTypeEnum.GROUP_MEMBER_ENTER.getType(), dtoCaptor.getValue().getType()); 86 + assertEquals(ImContentTypeEnum.GROUP_MEMBER_ENTER.getType(), dtoCaptor.getValue().getType());
88 } 87 }
89 88
90 @Test 89 @Test
@@ -207,7 +206,7 @@ public class ImGroupRequestServiceImplTest extends BaseMockitoUnitTest { @@ -207,7 +206,7 @@ public class ImGroupRequestServiceImplTest extends BaseMockitoUnitTest {
207 eq(ImGroupAddSourceEnum.SEARCH.getSource()), isNull()); 206 eq(ImGroupAddSourceEnum.SEARCH.getSource()), isNull());
208 ArgumentCaptor<ImGroupMessageSendDTO> dtoCaptor = ArgumentCaptor.forClass(ImGroupMessageSendDTO.class); 207 ArgumentCaptor<ImGroupMessageSendDTO> dtoCaptor = ArgumentCaptor.forClass(ImGroupMessageSendDTO.class);
209 verify(groupMessageService).sendGroupMessage(eq(1L), dtoCaptor.capture()); 208 verify(groupMessageService).sendGroupMessage(eq(1L), dtoCaptor.capture());
210 - assertEquals(ImMessageTypeEnum.GROUP_MEMBER_ENTER.getType(), dtoCaptor.getValue().getType()); 209 + assertEquals(ImContentTypeEnum.GROUP_MEMBER_ENTER.getType(), dtoCaptor.getValue().getType());
211 // 1505 推送给申请人 + owner,去重后两条 210 // 1505 推送给申请人 + owner,去重后两条
212 verify(websocketService, times(2)).sendPrivateMessageAsync(anyLong(), any(ImPrivateMessageDTO.class)); 211 verify(websocketService, times(2)).sendPrivateMessageAsync(anyLong(), any(ImPrivateMessageDTO.class));
213 } 212 }
yudao-module-im/src/test/java/cn/iocoder/yudao/module/im/service/group/ImGroupServiceImplTest.java
@@ -19,13 +19,13 @@ import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO; @@ -19,13 +19,13 @@ import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO;
19 import cn.iocoder.yudao.module.im.dal.mysql.group.ImGroupMapper; 19 import cn.iocoder.yudao.module.im.dal.mysql.group.ImGroupMapper;
20 import cn.iocoder.yudao.module.im.enums.group.ImGroupAddSourceEnum; 20 import cn.iocoder.yudao.module.im.enums.group.ImGroupAddSourceEnum;
21 import cn.iocoder.yudao.module.im.enums.group.ImGroupMemberRoleEnum; 21 import cn.iocoder.yudao.module.im.enums.group.ImGroupMemberRoleEnum;
22 -import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum; 22 +import cn.iocoder.yudao.module.im.enums.ImContentTypeEnum;
23 import cn.iocoder.yudao.module.im.framework.config.ImProperties; 23 import cn.iocoder.yudao.module.im.framework.config.ImProperties;
24 import cn.iocoder.yudao.module.im.service.friend.ImFriendService; 24 import cn.iocoder.yudao.module.im.service.friend.ImFriendService;
25 import cn.iocoder.yudao.module.im.service.message.ImGroupMessageService; 25 import cn.iocoder.yudao.module.im.service.message.ImGroupMessageService;
26 import cn.iocoder.yudao.module.im.service.message.dto.ImGroupMessageSendDTO; 26 import cn.iocoder.yudao.module.im.service.message.dto.ImGroupMessageSendDTO;
27 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService; 27 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService;
28 -import cn.iocoder.yudao.module.im.service.websocket.dto.ImGroupMessageDTO; 28 +import cn.iocoder.yudao.module.im.service.websocket.notification.message.ImGroupMessageNotification;
29 import cn.iocoder.yudao.module.system.api.user.AdminUserApi; 29 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
30 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; 30 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
31 import org.junit.jupiter.api.Test; 31 import org.junit.jupiter.api.Test;
@@ -100,7 +100,7 @@ public class ImGroupServiceImplTest extends BaseMockitoUnitTest { @@ -100,7 +100,7 @@ public class ImGroupServiceImplTest extends BaseMockitoUnitTest {
100 // 验证:推送 GROUP_CREATE 通知(payload memberUserIds 含创建者自己) 100 // 验证:推送 GROUP_CREATE 通知(payload memberUserIds 含创建者自己)
101 ArgumentCaptor<ImGroupMessageSendDTO> dtoCaptor = ArgumentCaptor.forClass(ImGroupMessageSendDTO.class); 101 ArgumentCaptor<ImGroupMessageSendDTO> dtoCaptor = ArgumentCaptor.forClass(ImGroupMessageSendDTO.class);
102 verify(groupMessageService).sendGroupMessage(eq(1L), anyCollection(), dtoCaptor.capture()); 102 verify(groupMessageService).sendGroupMessage(eq(1L), anyCollection(), dtoCaptor.capture());
103 - assertEquals(ImMessageTypeEnum.GROUP_CREATE.getType(), dtoCaptor.getValue().getType()); 103 + assertEquals(ImContentTypeEnum.GROUP_CREATE.getType(), dtoCaptor.getValue().getType());
104 } 104 }
105 105
106 @Test 106 @Test
@@ -132,7 +132,7 @@ public class ImGroupServiceImplTest extends BaseMockitoUnitTest { @@ -132,7 +132,7 @@ public class ImGroupServiceImplTest extends BaseMockitoUnitTest {
132 // 验证:推送 GROUP_CREATE 通知,payload memberUserIds 含全员(创建者 + 邀请) 132 // 验证:推送 GROUP_CREATE 通知,payload memberUserIds 含全员(创建者 + 邀请)
133 ArgumentCaptor<ImGroupMessageSendDTO> dtoCaptor = ArgumentCaptor.forClass(ImGroupMessageSendDTO.class); 133 ArgumentCaptor<ImGroupMessageSendDTO> dtoCaptor = ArgumentCaptor.forClass(ImGroupMessageSendDTO.class);
134 verify(groupMessageService).sendGroupMessage(eq(1L), anyCollection(), dtoCaptor.capture()); 134 verify(groupMessageService).sendGroupMessage(eq(1L), anyCollection(), dtoCaptor.capture());
135 - assertEquals(ImMessageTypeEnum.GROUP_CREATE.getType(), dtoCaptor.getValue().getType()); 135 + assertEquals(ImContentTypeEnum.GROUP_CREATE.getType(), dtoCaptor.getValue().getType());
136 } 136 }
137 137
138 @Test 138 @Test
@@ -205,7 +205,7 @@ public class ImGroupServiceImplTest extends BaseMockitoUnitTest { @@ -205,7 +205,7 @@ public class ImGroupServiceImplTest extends BaseMockitoUnitTest {
205 // 推送 GROUP_NAME_UPDATE 通知给全员 205 // 推送 GROUP_NAME_UPDATE 通知给全员
206 ArgumentCaptor<ImGroupMessageSendDTO> dtoCaptor = ArgumentCaptor.forClass(ImGroupMessageSendDTO.class); 206 ArgumentCaptor<ImGroupMessageSendDTO> dtoCaptor = ArgumentCaptor.forClass(ImGroupMessageSendDTO.class);
207 verify(groupMessageService).sendGroupMessage(eq(1L), anyCollection(), dtoCaptor.capture()); 207 verify(groupMessageService).sendGroupMessage(eq(1L), anyCollection(), dtoCaptor.capture());
208 - assertEquals(ImMessageTypeEnum.GROUP_NAME_UPDATE.getType(), dtoCaptor.getValue().getType()); 208 + assertEquals(ImContentTypeEnum.GROUP_NAME_UPDATE.getType(), dtoCaptor.getValue().getType());
209 } 209 }
210 } 210 }
211 211
@@ -234,7 +234,7 @@ public class ImGroupServiceImplTest extends BaseMockitoUnitTest { @@ -234,7 +234,7 @@ public class ImGroupServiceImplTest extends BaseMockitoUnitTest {
234 // 推送 GROUP_DISSOLVE 通知(send-before-remove,sendGroupMessage 内部查 active 自动覆盖全员,含群主多端同步) 234 // 推送 GROUP_DISSOLVE 通知(send-before-remove,sendGroupMessage 内部查 active 自动覆盖全员,含群主多端同步)
235 ArgumentCaptor<ImGroupMessageSendDTO> dtoCaptor = ArgumentCaptor.forClass(ImGroupMessageSendDTO.class); 235 ArgumentCaptor<ImGroupMessageSendDTO> dtoCaptor = ArgumentCaptor.forClass(ImGroupMessageSendDTO.class);
236 verify(groupMessageService).sendGroupMessage(eq(1L), dtoCaptor.capture()); 236 verify(groupMessageService).sendGroupMessage(eq(1L), dtoCaptor.capture());
237 - assertEquals(ImMessageTypeEnum.GROUP_DISSOLVE.getType(), dtoCaptor.getValue().getType()); 237 + assertEquals(ImContentTypeEnum.GROUP_DISSOLVE.getType(), dtoCaptor.getValue().getType());
238 } 238 }
239 } 239 }
240 240
@@ -276,7 +276,7 @@ public class ImGroupServiceImplTest extends BaseMockitoUnitTest { @@ -276,7 +276,7 @@ public class ImGroupServiceImplTest extends BaseMockitoUnitTest {
276 // 断言:使用管理员编号发通知并完成清理 276 // 断言:使用管理员编号发通知并完成清理
277 ArgumentCaptor<ImGroupMessageSendDTO> dtoCaptor = ArgumentCaptor.forClass(ImGroupMessageSendDTO.class); 277 ArgumentCaptor<ImGroupMessageSendDTO> dtoCaptor = ArgumentCaptor.forClass(ImGroupMessageSendDTO.class);
278 verify(groupMessageService).sendGroupMessage(eq(99L), dtoCaptor.capture()); 278 verify(groupMessageService).sendGroupMessage(eq(99L), dtoCaptor.capture());
279 - assertEquals(ImMessageTypeEnum.GROUP_DISSOLVE.getType(), dtoCaptor.getValue().getType()); 279 + assertEquals(ImContentTypeEnum.GROUP_DISSOLVE.getType(), dtoCaptor.getValue().getType());
280 verify(groupMemberService).removeGroupMembersByGroupId(10L); 280 verify(groupMemberService).removeGroupMembersByGroupId(10L);
281 } 281 }
282 } 282 }
@@ -345,7 +345,7 @@ public class ImGroupServiceImplTest extends BaseMockitoUnitTest { @@ -345,7 +345,7 @@ public class ImGroupServiceImplTest extends BaseMockitoUnitTest {
345 verify(webSocketService, never()).sendGroupMessageAsync(anyCollection(), any(ImGroupMessageDTO.class)); 345 verify(webSocketService, never()).sendGroupMessageAsync(anyCollection(), any(ImGroupMessageDTO.class));
346 ArgumentCaptor<ImGroupMessageSendDTO> dtoCaptor = ArgumentCaptor.forClass(ImGroupMessageSendDTO.class); 346 ArgumentCaptor<ImGroupMessageSendDTO> dtoCaptor = ArgumentCaptor.forClass(ImGroupMessageSendDTO.class);
347 verify(groupMessageService).sendGroupMessage(eq(1L), anyCollection(), dtoCaptor.capture()); 347 verify(groupMessageService).sendGroupMessage(eq(1L), anyCollection(), dtoCaptor.capture());
348 - assertEquals(ImMessageTypeEnum.GROUP_MEMBER_INVITE.getType(), dtoCaptor.getValue().getType()); 348 + assertEquals(ImContentTypeEnum.GROUP_MEMBER_INVITE.getType(), dtoCaptor.getValue().getType());
349 } 349 }
350 } 350 }
351 351
@@ -429,7 +429,7 @@ public class ImGroupServiceImplTest extends BaseMockitoUnitTest { @@ -429,7 +429,7 @@ public class ImGroupServiceImplTest extends BaseMockitoUnitTest {
429 eq(ImGroupAddSourceEnum.INVITE.getSource()), eq(1L)); 429 eq(ImGroupAddSourceEnum.INVITE.getSource()), eq(1L));
430 ArgumentCaptor<ImGroupMessageSendDTO> dtoCaptor = ArgumentCaptor.forClass(ImGroupMessageSendDTO.class); 430 ArgumentCaptor<ImGroupMessageSendDTO> dtoCaptor = ArgumentCaptor.forClass(ImGroupMessageSendDTO.class);
431 verify(groupMessageService).sendGroupMessage(eq(1L), anyCollection(), dtoCaptor.capture()); 431 verify(groupMessageService).sendGroupMessage(eq(1L), anyCollection(), dtoCaptor.capture());
432 - assertEquals(ImMessageTypeEnum.GROUP_MEMBER_INVITE.getType(), dtoCaptor.getValue().getType()); 432 + assertEquals(ImContentTypeEnum.GROUP_MEMBER_INVITE.getType(), dtoCaptor.getValue().getType());
433 } 433 }
434 } 434 }
435 435
@@ -564,7 +564,7 @@ public class ImGroupServiceImplTest extends BaseMockitoUnitTest { @@ -564,7 +564,7 @@ public class ImGroupServiceImplTest extends BaseMockitoUnitTest {
564 // 推送 GROUP_MEMBER_QUIT 通知给全员(含 quitter,前端自判清群) 564 // 推送 GROUP_MEMBER_QUIT 通知给全员(含 quitter,前端自判清群)
565 ArgumentCaptor<ImGroupMessageSendDTO> dtoCaptor = ArgumentCaptor.forClass(ImGroupMessageSendDTO.class); 565 ArgumentCaptor<ImGroupMessageSendDTO> dtoCaptor = ArgumentCaptor.forClass(ImGroupMessageSendDTO.class);
566 verify(groupMessageService).sendGroupMessage(eq(1L), dtoCaptor.capture()); 566 verify(groupMessageService).sendGroupMessage(eq(1L), dtoCaptor.capture());
567 - assertEquals(ImMessageTypeEnum.GROUP_MEMBER_QUIT.getType(), dtoCaptor.getValue().getType()); 567 + assertEquals(ImContentTypeEnum.GROUP_MEMBER_QUIT.getType(), dtoCaptor.getValue().getType());
568 } 568 }
569 } 569 }
570 570
@@ -642,7 +642,7 @@ public class ImGroupServiceImplTest extends BaseMockitoUnitTest { @@ -642,7 +642,7 @@ public class ImGroupServiceImplTest extends BaseMockitoUnitTest {
642 // 推送 GROUP_MEMBER_KICK 通知给全员(含被踢者,前端自判清群) 642 // 推送 GROUP_MEMBER_KICK 通知给全员(含被踢者,前端自判清群)
643 ArgumentCaptor<ImGroupMessageSendDTO> dtoCaptor = ArgumentCaptor.forClass(ImGroupMessageSendDTO.class); 643 ArgumentCaptor<ImGroupMessageSendDTO> dtoCaptor = ArgumentCaptor.forClass(ImGroupMessageSendDTO.class);
644 verify(groupMessageService).sendGroupMessage(eq(1L), dtoCaptor.capture()); 644 verify(groupMessageService).sendGroupMessage(eq(1L), dtoCaptor.capture());
645 - assertEquals(ImMessageTypeEnum.GROUP_MEMBER_KICK.getType(), dtoCaptor.getValue().getType()); 645 + assertEquals(ImContentTypeEnum.GROUP_MEMBER_KICK.getType(), dtoCaptor.getValue().getType());
646 } 646 }
647 } 647 }
648 648
yudao-module-im/src/test/java/cn/iocoder/yudao/module/im/service/message/ImGroupMessageServiceImplTest.java
@@ -14,7 +14,7 @@ import cn.iocoder.yudao.module.im.enums.ImConversationTypeEnum; @@ -14,7 +14,7 @@ import cn.iocoder.yudao.module.im.enums.ImConversationTypeEnum;
14 import cn.iocoder.yudao.module.im.enums.group.ImGroupMemberRoleEnum; 14 import cn.iocoder.yudao.module.im.enums.group.ImGroupMemberRoleEnum;
15 import cn.iocoder.yudao.module.im.enums.message.ImMessageReceiptStatusEnum; 15 import cn.iocoder.yudao.module.im.enums.message.ImMessageReceiptStatusEnum;
16 import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum; 16 import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum;
17 -import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum; 17 +import cn.iocoder.yudao.module.im.enums.ImContentTypeEnum;
18 import cn.iocoder.yudao.module.im.framework.config.ImProperties; 18 import cn.iocoder.yudao.module.im.framework.config.ImProperties;
19 import cn.iocoder.yudao.module.im.service.conversation.ImConversationReadService; 19 import cn.iocoder.yudao.module.im.service.conversation.ImConversationReadService;
20 import cn.iocoder.yudao.module.im.service.group.ImGroupMemberService; 20 import cn.iocoder.yudao.module.im.service.group.ImGroupMemberService;
@@ -22,8 +22,8 @@ import cn.iocoder.yudao.module.im.service.group.ImGroupService; @@ -22,8 +22,8 @@ import cn.iocoder.yudao.module.im.service.group.ImGroupService;
22 import cn.iocoder.yudao.module.im.service.message.dto.ImGroupMessageSendDTO; 22 import cn.iocoder.yudao.module.im.service.message.dto.ImGroupMessageSendDTO;
23 import cn.iocoder.yudao.module.im.service.sensitiveword.ImSensitiveWordService; 23 import cn.iocoder.yudao.module.im.service.sensitiveword.ImSensitiveWordService;
24 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService; 24 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService;
25 -import cn.iocoder.yudao.module.im.service.websocket.dto.ImGroupMessageDTO;  
26 -import cn.iocoder.yudao.module.im.service.websocket.dto.message.RecallMessage; 25 +import cn.iocoder.yudao.module.im.service.websocket.notification.message.ImGroupMessageNotification;
  26 +import cn.iocoder.yudao.module.im.dal.dataobject.message.content.RecallMessage;
27 import org.junit.jupiter.api.Test; 27 import org.junit.jupiter.api.Test;
28 import org.mockito.ArgumentCaptor; 28 import org.mockito.ArgumentCaptor;
29 import org.mockito.InjectMocks; 29 import org.mockito.InjectMocks;
@@ -70,7 +70,7 @@ public class ImGroupMessageServiceImplTest extends BaseMockitoUnitTest { @@ -70,7 +70,7 @@ public class ImGroupMessageServiceImplTest extends BaseMockitoUnitTest {
70 ImGroupMessageSendReqVO reqVO = new ImGroupMessageSendReqVO(); 70 ImGroupMessageSendReqVO reqVO = new ImGroupMessageSendReqVO();
71 reqVO.setClientMessageId("test-uuid-group-001"); 71 reqVO.setClientMessageId("test-uuid-group-001");
72 reqVO.setGroupId(10L); 72 reqVO.setGroupId(10L);
73 - reqVO.setType(ImMessageTypeEnum.TEXT.getType()); 73 + reqVO.setType(ImContentTypeEnum.TEXT.getType());
74 reqVO.setContent("{\"content\":\"群聊你好\"}"); 74 reqVO.setContent("{\"content\":\"群聊你好\"}");
75 return reqVO; 75 return reqVO;
76 } 76 }
@@ -85,6 +85,7 @@ public class ImGroupMessageServiceImplTest extends BaseMockitoUnitTest { @@ -85,6 +85,7 @@ public class ImGroupMessageServiceImplTest extends BaseMockitoUnitTest {
85 85
86 // 准备 86 // 准备
87 ImGroupMessageSendReqVO reqVO = buildSendReqVO(); 87 ImGroupMessageSendReqVO reqVO = buildSendReqVO();
  88 + reqVO.setReceipt(true);
88 when(groupMessageMapper.selectBySenderIdAndClientMessageId(1L, "test-uuid-group-001")) 89 when(groupMessageMapper.selectBySenderIdAndClientMessageId(1L, "test-uuid-group-001"))
89 .thenReturn(null); 90 .thenReturn(null);
90 ImGroupDO group = new ImGroupDO(); 91 ImGroupDO group = new ImGroupDO();
@@ -112,7 +113,7 @@ public class ImGroupMessageServiceImplTest extends BaseMockitoUnitTest { @@ -112,7 +113,7 @@ public class ImGroupMessageServiceImplTest extends BaseMockitoUnitTest {
112 assertEquals(1L, result.getSenderId()); 113 assertEquals(1L, result.getSenderId());
113 assertEquals(10L, result.getGroupId()); 114 assertEquals(10L, result.getGroupId());
114 assertEquals(ImMessageStatusEnum.NORMAL.getStatus(), result.getStatus()); 115 assertEquals(ImMessageStatusEnum.NORMAL.getStatus(), result.getStatus());
115 - assertEquals(ImMessageReceiptStatusEnum.NO_RECEIPT.getStatus(), result.getReceiptStatus()); 116 + assertEquals(ImMessageReceiptStatusEnum.PENDING.getStatus(), result.getReceiptStatus());
116 117
117 // 验证推送给 3 个群成员(含发送者自己,用于多端同步) 118 // 验证推送给 3 个群成员(含发送者自己,用于多端同步)
118 verify(imWebSocketService).sendGroupMessageAsync(argThat((Collection<Long> ids) -> 119 verify(imWebSocketService).sendGroupMessageAsync(argThat((Collection<Long> ids) ->
@@ -889,7 +890,7 @@ public class ImGroupMessageServiceImplTest extends BaseMockitoUnitTest { @@ -889,7 +890,7 @@ public class ImGroupMessageServiceImplTest extends BaseMockitoUnitTest {
889 public void testSendGroupMessage_dto_persistsAndSerializesPojoContent() { 890 public void testSendGroupMessage_dto_persistsAndSerializesPojoContent() {
890 // 准备:persistent=true 类型 + POJO content 891 // 准备:persistent=true 类型 + POJO content
891 ImGroupMessageSendDTO dto = new ImGroupMessageSendDTO() 892 ImGroupMessageSendDTO dto = new ImGroupMessageSendDTO()
892 - .setGroupId(10L).setType(ImMessageTypeEnum.RECALL.getType()) 893 + .setGroupId(10L).setType(ImContentTypeEnum.RECALL.getType())
893 .setContent(new RecallMessage().setMessageId(50L)); 894 .setContent(new RecallMessage().setMessageId(50L));
894 when(groupMemberService.getActiveGroupMemberUserIdsByGroupId(10L)).thenReturn(List.of(1L)); 895 when(groupMemberService.getActiveGroupMemberUserIdsByGroupId(10L)).thenReturn(List.of(1L));
895 896
@@ -901,7 +902,7 @@ public class ImGroupMessageServiceImplTest extends BaseMockitoUnitTest { @@ -901,7 +902,7 @@ public class ImGroupMessageServiceImplTest extends BaseMockitoUnitTest {
901 ImGroupMessageDO message = captor.getValue(); 902 ImGroupMessageDO message = captor.getValue();
902 assertEquals(1L, message.getSenderId()); 903 assertEquals(1L, message.getSenderId());
903 assertEquals(10L, message.getGroupId()); 904 assertEquals(10L, message.getGroupId());
904 - assertEquals(ImMessageTypeEnum.RECALL.getType(), message.getType()); 905 + assertEquals(ImContentTypeEnum.RECALL.getType(), message.getType());
905 assertEquals("{\"messageId\":50}", message.getContent()); 906 assertEquals("{\"messageId\":50}", message.getContent());
906 assertEquals(ImMessageStatusEnum.NORMAL.getStatus(), message.getStatus()); 907 assertEquals(ImMessageStatusEnum.NORMAL.getStatus(), message.getStatus());
907 assertEquals(ImMessageReceiptStatusEnum.NO_RECEIPT.getStatus(), message.getReceiptStatus()); 908 assertEquals(ImMessageReceiptStatusEnum.NO_RECEIPT.getStatus(), message.getReceiptStatus());
@@ -913,7 +914,7 @@ public class ImGroupMessageServiceImplTest extends BaseMockitoUnitTest { @@ -913,7 +914,7 @@ public class ImGroupMessageServiceImplTest extends BaseMockitoUnitTest {
913 public void testSendGroupMessage_dto_receiptPending() { 914 public void testSendGroupMessage_dto_receiptPending() {
914 // 准备:dto.receipt=true → receiptStatus=PENDING 915 // 准备:dto.receipt=true → receiptStatus=PENDING
915 ImGroupMessageSendDTO dto = new ImGroupMessageSendDTO() 916 ImGroupMessageSendDTO dto = new ImGroupMessageSendDTO()
916 - .setGroupId(10L).setType(ImMessageTypeEnum.RECALL.getType()) 917 + .setGroupId(10L).setType(ImContentTypeEnum.RECALL.getType())
917 .setContent("{\"messageId\":50}").setReceipt(true); 918 .setContent("{\"messageId\":50}").setReceipt(true);
918 when(groupMemberService.getActiveGroupMemberUserIdsByGroupId(10L)).thenReturn(List.of(1L)); 919 when(groupMemberService.getActiveGroupMemberUserIdsByGroupId(10L)).thenReturn(List.of(1L));
919 920
@@ -928,7 +929,7 @@ public class ImGroupMessageServiceImplTest extends BaseMockitoUnitTest { @@ -928,7 +929,7 @@ public class ImGroupMessageServiceImplTest extends BaseMockitoUnitTest {
928 public void testSendGroupMessage_dto_nonPersistentTypeNotInserted() { 929 public void testSendGroupMessage_dto_nonPersistentTypeNotInserted() {
929 // 准备:persistent=false 类型(RECEIPT 回执)→ 不入库,仅推送 930 // 准备:persistent=false 类型(RECEIPT 回执)→ 不入库,仅推送
930 ImGroupMessageSendDTO dto = new ImGroupMessageSendDTO() 931 ImGroupMessageSendDTO dto = new ImGroupMessageSendDTO()
931 - .setGroupId(10L).setType(ImMessageTypeEnum.RECEIPT.getType()); 932 + .setGroupId(10L).setType(ImContentTypeEnum.RECEIPT.getType());
932 when(groupMemberService.getActiveGroupMemberUserIdsByGroupId(10L)).thenReturn(List.of(1L, 2L)); 933 when(groupMemberService.getActiveGroupMemberUserIdsByGroupId(10L)).thenReturn(List.of(1L, 2L));
933 934
934 groupMessageService.sendGroupMessage(1L, dto); 935 groupMessageService.sendGroupMessage(1L, dto);
@@ -942,7 +943,7 @@ public class ImGroupMessageServiceImplTest extends BaseMockitoUnitTest { @@ -942,7 +943,7 @@ public class ImGroupMessageServiceImplTest extends BaseMockitoUnitTest {
942 // 准备:调用方传入显式 targets(解散场景成员已被批量 DISABLE,必须按移除前快照推送) 943 // 准备:调用方传入显式 targets(解散场景成员已被批量 DISABLE,必须按移除前快照推送)
943 Set<Long> targets = Set.of(1L, 2L, 3L); 944 Set<Long> targets = Set.of(1L, 2L, 3L);
944 ImGroupMessageSendDTO dto = new ImGroupMessageSendDTO() 945 ImGroupMessageSendDTO dto = new ImGroupMessageSendDTO()
945 - .setGroupId(10L).setType(ImMessageTypeEnum.GROUP_DISSOLVE.getType()).setContent("{}"); 946 + .setGroupId(10L).setType(ImContentTypeEnum.GROUP_DISSOLVE.getType()).setContent("{}");
946 947
947 groupMessageService.sendGroupMessage(1L, targets, dto); 948 groupMessageService.sendGroupMessage(1L, targets, dto);
948 949
yudao-module-im/src/test/java/cn/iocoder/yudao/module/im/service/message/ImPrivateMessageServiceImplTest.java
@@ -9,7 +9,7 @@ import cn.iocoder.yudao.module.im.dal.dataobject.message.ImPrivateMessageDO; @@ -9,7 +9,7 @@ import cn.iocoder.yudao.module.im.dal.dataobject.message.ImPrivateMessageDO;
9 import cn.iocoder.yudao.module.im.dal.mysql.message.ImPrivateMessageMapper; 9 import cn.iocoder.yudao.module.im.dal.mysql.message.ImPrivateMessageMapper;
10 import cn.iocoder.yudao.module.im.enums.message.ImMessageReceiptStatusEnum; 10 import cn.iocoder.yudao.module.im.enums.message.ImMessageReceiptStatusEnum;
11 import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum; 11 import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum;
12 -import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum; 12 +import cn.iocoder.yudao.module.im.enums.ImContentTypeEnum;
13 import cn.iocoder.yudao.module.im.framework.config.ImProperties; 13 import cn.iocoder.yudao.module.im.framework.config.ImProperties;
14 import cn.iocoder.yudao.module.im.service.conversation.ImConversationReadService; 14 import cn.iocoder.yudao.module.im.service.conversation.ImConversationReadService;
15 import cn.iocoder.yudao.module.im.service.friend.ImFriendService; 15 import cn.iocoder.yudao.module.im.service.friend.ImFriendService;
@@ -380,7 +380,7 @@ public class ImPrivateMessageServiceImplTest extends BaseMockitoUnitTest { @@ -380,7 +380,7 @@ public class ImPrivateMessageServiceImplTest extends BaseMockitoUnitTest {
380 public void testSendPrivateMessage_dto_persistsAndSerializesPojoContent() { 380 public void testSendPrivateMessage_dto_persistsAndSerializesPojoContent() {
381 // 准备:persistent=true 类型 + POJO content 381 // 准备:persistent=true 类型 + POJO content
382 ImPrivateMessageSendDTO dto = new ImPrivateMessageSendDTO() 382 ImPrivateMessageSendDTO dto = new ImPrivateMessageSendDTO()
383 - .setReceiverId(2L).setType(ImMessageTypeEnum.RECALL.getType()) 383 + .setReceiverId(2L).setType(ImContentTypeEnum.RECALL.getType())
384 .setContent(new RecallMessage().setMessageId(50L)); 384 .setContent(new RecallMessage().setMessageId(50L));
385 385
386 privateMessageService.sendPrivateMessage(1L, dto); 386 privateMessageService.sendPrivateMessage(1L, dto);
@@ -391,7 +391,7 @@ public class ImPrivateMessageServiceImplTest extends BaseMockitoUnitTest { @@ -391,7 +391,7 @@ public class ImPrivateMessageServiceImplTest extends BaseMockitoUnitTest {
391 ImPrivateMessageDO message = captor.getValue(); 391 ImPrivateMessageDO message = captor.getValue();
392 assertEquals(1L, message.getSenderId()); 392 assertEquals(1L, message.getSenderId());
393 assertEquals(2L, message.getReceiverId()); 393 assertEquals(2L, message.getReceiverId());
394 - assertEquals(ImMessageTypeEnum.RECALL.getType(), message.getType()); 394 + assertEquals(ImContentTypeEnum.RECALL.getType(), message.getType());
395 assertEquals("{\"messageId\":50}", message.getContent()); 395 assertEquals("{\"messageId\":50}", message.getContent());
396 assertEquals(ImMessageStatusEnum.NORMAL.getStatus(), message.getStatus()); 396 assertEquals(ImMessageStatusEnum.NORMAL.getStatus(), message.getStatus());
397 assertNotNull(message.getClientMessageId()); 397 assertNotNull(message.getClientMessageId());
@@ -405,7 +405,7 @@ public class ImPrivateMessageServiceImplTest extends BaseMockitoUnitTest { @@ -405,7 +405,7 @@ public class ImPrivateMessageServiceImplTest extends BaseMockitoUnitTest {
405 public void testSendPrivateMessage_dto_nonPersistentTypeNotInserted() { 405 public void testSendPrivateMessage_dto_nonPersistentTypeNotInserted() {
406 // 准备:persistent=false 类型(FRIEND_DELETE 通知)→ 不入库;仅推 sender 多端,receiver 不感知 406 // 准备:persistent=false 类型(FRIEND_DELETE 通知)→ 不入库;仅推 sender 多端,receiver 不感知
407 ImPrivateMessageSendDTO dto = new ImPrivateMessageSendDTO() 407 ImPrivateMessageSendDTO dto = new ImPrivateMessageSendDTO()
408 - .setReceiverId(2L).setType(ImMessageTypeEnum.FRIEND_DELETE.getType()); 408 + .setReceiverId(2L).setType(ImContentTypeEnum.FRIEND_DELETE.getType());
409 409
410 privateMessageService.sendPrivateMessage(1L, dto); 410 privateMessageService.sendPrivateMessage(1L, dto);
411 411
yudao-module-im/src/test/java/cn/iocoder/yudao/module/im/service/rtc/ImRtcCallServiceImplTest.java
@@ -20,7 +20,6 @@ import cn.iocoder.yudao.module.im.enums.rtc.ImRtcParticipantStatusEnum; @@ -20,7 +20,6 @@ import cn.iocoder.yudao.module.im.enums.rtc.ImRtcParticipantStatusEnum;
20 import cn.iocoder.yudao.module.im.framework.config.ImProperties; 20 import cn.iocoder.yudao.module.im.framework.config.ImProperties;
21 import cn.iocoder.yudao.module.im.service.group.ImGroupMemberService; 21 import cn.iocoder.yudao.module.im.service.group.ImGroupMemberService;
22 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService; 22 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService;
23 -import cn.iocoder.yudao.module.im.service.websocket.dto.ImPrivateMessageDTO;  
24 import cn.iocoder.yudao.module.system.api.user.AdminUserApi; 23 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
25 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; 24 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
26 import org.junit.jupiter.api.Test; 25 import org.junit.jupiter.api.Test;
yudao-module-im/src/test/java/cn/iocoder/yudao/module/im/service/websocket/ImWebSocketServiceImplTest.java
@@ -4,8 +4,11 @@ import cn.hutool.core.collection.ListUtil; @@ -4,8 +4,11 @@ import cn.hutool.core.collection.ListUtil;
4 import cn.hutool.extra.spring.SpringUtil; 4 import cn.hutool.extra.spring.SpringUtil;
5 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; 5 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
6 import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; 6 import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
7 -import cn.iocoder.yudao.module.im.service.websocket.dto.ImGroupMessageDTO;  
8 -import cn.iocoder.yudao.module.im.service.websocket.dto.ImPrivateMessageDTO; 7 +import cn.iocoder.yudao.module.im.enums.ImContentTypeEnum;
  8 +import cn.iocoder.yudao.module.im.enums.ImConversationTypeEnum;
  9 +import cn.iocoder.yudao.module.im.service.websocket.notification.ImNotificationWebSocketDTO;
  10 +import cn.iocoder.yudao.module.im.service.websocket.notification.message.ImGroupMessageNotification;
  11 +import cn.iocoder.yudao.module.im.service.websocket.notification.message.ImPrivateMessageNotification;
9 import cn.iocoder.yudao.module.infra.api.websocket.WebSocketSenderApi; 12 import cn.iocoder.yudao.module.infra.api.websocket.WebSocketSenderApi;
10 import org.junit.jupiter.api.AfterEach; 13 import org.junit.jupiter.api.AfterEach;
11 import org.junit.jupiter.api.Test; 14 import org.junit.jupiter.api.Test;
@@ -21,6 +24,7 @@ import java.util.List; @@ -21,6 +24,7 @@ import java.util.List;
21 24
22 import static org.junit.jupiter.api.Assertions.assertEquals; 25 import static org.junit.jupiter.api.Assertions.assertEquals;
23 import static org.mockito.ArgumentMatchers.eq; 26 import static org.mockito.ArgumentMatchers.eq;
  27 +import static org.mockito.ArgumentMatchers.argThat;
24 import static org.mockito.Mockito.*; 28 import static org.mockito.Mockito.*;
25 29
26 /** 30 /**
@@ -44,10 +48,10 @@ public class ImWebSocketServiceImplTest extends BaseMockitoUnitTest { @@ -44,10 +48,10 @@ public class ImWebSocketServiceImplTest extends BaseMockitoUnitTest {
44 } 48 }
45 } 49 }
46 50
47 - // ========== sendPrivateMessageAsync ========== 51 + // ========== sendNotificationAsync ==========
48 52
49 @Test 53 @Test
50 - public void testSendPrivateMessageAsync_noTransactionSendsImmediately() { 54 + public void testSendNotificationAsync_private_noTransactionSendsImmediately() {
51 try (MockedStatic<SpringUtil> springUtilMockedStatic = mockStatic(SpringUtil.class)) { 55 try (MockedStatic<SpringUtil> springUtilMockedStatic = mockStatic(SpringUtil.class)) {
52 springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(ImWebSocketServiceImpl.class))) 56 springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(ImWebSocketServiceImpl.class)))
53 .thenReturn(imWebSocketService); 57 .thenReturn(imWebSocketService);
@@ -60,12 +64,14 @@ public class ImWebSocketServiceImplTest extends BaseMockitoUnitTest { @@ -60,12 +64,14 @@ public class ImWebSocketServiceImplTest extends BaseMockitoUnitTest {
60 64
61 // 断言 65 // 断言
62 verify(webSocketSenderApi).sendObject( 66 verify(webSocketSenderApi).sendObject(
63 - eq(UserTypeEnum.ADMIN.getValue()), eq(2L), eq(ImPrivateMessageDTO.TYPE), eq(dto)); 67 + eq(UserTypeEnum.ADMIN.getValue()), eq(2L), eq(ImNotificationWebSocketDTO.TYPE),
  68 + argThat(actual -> isNotification(actual, ImConversationTypeEnum.PRIVATE,
  69 + ImContentTypeEnum.TEXT, dto)));
64 } 70 }
65 } 71 }
66 72
67 @Test 73 @Test
68 - public void testSendPrivateMessageAsync_inTransactionDeferredUntilCommit() { 74 + public void testSendNotificationAsync_private_inTransactionDeferredUntilCommit() {
69 try (MockedStatic<SpringUtil> springUtilMockedStatic = mockStatic(SpringUtil.class)) { 75 try (MockedStatic<SpringUtil> springUtilMockedStatic = mockStatic(SpringUtil.class)) {
70 springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(ImWebSocketServiceImpl.class))) 76 springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(ImWebSocketServiceImpl.class)))
71 .thenReturn(imWebSocketService); 77 .thenReturn(imWebSocketService);
@@ -89,43 +95,51 @@ public class ImWebSocketServiceImplTest extends BaseMockitoUnitTest { @@ -89,43 +95,51 @@ public class ImWebSocketServiceImplTest extends BaseMockitoUnitTest {
89 95
90 // 断言:提交后推送 96 // 断言:提交后推送
91 verify(webSocketSenderApi).sendObject( 97 verify(webSocketSenderApi).sendObject(
92 - eq(UserTypeEnum.ADMIN.getValue()), eq(2L), eq(ImPrivateMessageDTO.TYPE), eq(dto)); 98 + eq(UserTypeEnum.ADMIN.getValue()), eq(2L), eq(ImNotificationWebSocketDTO.TYPE),
  99 + argThat(actual -> isNotification(actual, ImConversationTypeEnum.PRIVATE,
  100 + ImContentTypeEnum.TEXT, dto)));
93 } finally { 101 } finally {
94 TransactionSynchronizationManager.clear(); 102 TransactionSynchronizationManager.clear();
95 } 103 }
96 } 104 }
97 } 105 }
98 106
99 - // ========== sendGroupMessageAsync ========== 107 + // ========== sendNotificationAsync ==========
100 108
101 @Test 109 @Test
102 - public void testSendGroupMessageAsync_fanOutToAllUsers() { 110 + public void testSendNotificationAsync_group_fanOutToAllUsers() {
103 try (MockedStatic<SpringUtil> springUtilMockedStatic = mockStatic(SpringUtil.class)) { 111 try (MockedStatic<SpringUtil> springUtilMockedStatic = mockStatic(SpringUtil.class)) {
104 springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(ImWebSocketServiceImpl.class))) 112 springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(ImWebSocketServiceImpl.class)))
105 .thenReturn(imWebSocketService); 113 .thenReturn(imWebSocketService);
106 114
107 - ImGroupMessageDTO dto = new ImGroupMessageDTO(); 115 + ImGroupMessageNotification dto = new ImGroupMessageNotification();
108 dto.setGroupId(10L); 116 dto.setGroupId(10L);
109 dto.setSenderId(1L); 117 dto.setSenderId(1L);
110 118
111 imWebSocketService.sendGroupMessageAsync(ListUtil.of(1L, 2L, 3L), dto); 119 imWebSocketService.sendGroupMessageAsync(ListUtil.of(1L, 2L, 3L), dto);
112 120
113 verify(webSocketSenderApi).sendObject( 121 verify(webSocketSenderApi).sendObject(
114 - eq(UserTypeEnum.ADMIN.getValue()), eq(1L), eq(ImGroupMessageDTO.TYPE), eq(dto)); 122 + eq(UserTypeEnum.ADMIN.getValue()), eq(1L), eq(ImNotificationWebSocketDTO.TYPE),
  123 + argThat(actual -> isNotification(actual, ImConversationTypeEnum.GROUP,
  124 + ImContentTypeEnum.TEXT, dto)));
115 verify(webSocketSenderApi).sendObject( 125 verify(webSocketSenderApi).sendObject(
116 - eq(UserTypeEnum.ADMIN.getValue()), eq(2L), eq(ImGroupMessageDTO.TYPE), eq(dto)); 126 + eq(UserTypeEnum.ADMIN.getValue()), eq(2L), eq(ImNotificationWebSocketDTO.TYPE),
  127 + argThat(actual -> isNotification(actual, ImConversationTypeEnum.GROUP,
  128 + ImContentTypeEnum.TEXT, dto)));
117 verify(webSocketSenderApi).sendObject( 129 verify(webSocketSenderApi).sendObject(
118 - eq(UserTypeEnum.ADMIN.getValue()), eq(3L), eq(ImGroupMessageDTO.TYPE), eq(dto)); 130 + eq(UserTypeEnum.ADMIN.getValue()), eq(3L), eq(ImNotificationWebSocketDTO.TYPE),
  131 + argThat(actual -> isNotification(actual, ImConversationTypeEnum.GROUP,
  132 + ImContentTypeEnum.TEXT, dto)));
119 } 133 }
120 } 134 }
121 135
122 @Test 136 @Test
123 - public void testSendGroupMessageAsync_senderExceptionDoesNotBreakOthers() { 137 + public void testSendNotificationAsync_group_senderExceptionDoesNotBreakOthers() {
124 try (MockedStatic<SpringUtil> springUtilMockedStatic = mockStatic(SpringUtil.class)) { 138 try (MockedStatic<SpringUtil> springUtilMockedStatic = mockStatic(SpringUtil.class)) {
125 springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(ImWebSocketServiceImpl.class))) 139 springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(ImWebSocketServiceImpl.class)))
126 .thenReturn(imWebSocketService); 140 .thenReturn(imWebSocketService);
127 141
128 - ImGroupMessageDTO dto = new ImGroupMessageDTO(); 142 + ImGroupMessageNotification dto = new ImGroupMessageNotification();
129 dto.setGroupId(10L); 143 dto.setGroupId(10L);
130 // 给 1 号用户推送时抛异常,不能影响 2/3 号 144 // 给 1 号用户推送时抛异常,不能影响 2/3 号
131 doThrow(new RuntimeException("user offline")) 145 doThrow(new RuntimeException("user offline"))
@@ -143,8 +157,8 @@ public class ImWebSocketServiceImplTest extends BaseMockitoUnitTest { @@ -143,8 +157,8 @@ public class ImWebSocketServiceImplTest extends BaseMockitoUnitTest {
143 public void testDoSendGroupMessage_emptyUserIds_noSend() { 157 public void testDoSendGroupMessage_emptyUserIds_noSend() {
144 ImGroupMessageDTO dto = new ImGroupMessageDTO().setGroupId(10L); 158 ImGroupMessageDTO dto = new ImGroupMessageDTO().setGroupId(10L);
145 159
146 - imWebSocketService.doSendGroupMessage(Collections.emptyList(), dto);  
147 - imWebSocketService.doSendGroupMessage(null, dto); 160 + imWebSocketService.doSendNotification(Collections.emptyList(), notification);
  161 + imWebSocketService.doSendNotification(null, notification);
148 162
149 verifyNoInteractions(webSocketSenderApi); 163 verifyNoInteractions(webSocketSenderApi);
150 } 164 }
@@ -153,17 +167,21 @@ public class ImWebSocketServiceImplTest extends BaseMockitoUnitTest { @@ -153,17 +167,21 @@ public class ImWebSocketServiceImplTest extends BaseMockitoUnitTest {
153 public void testDoSendGroupMessage_distinctUserIds() { 167 public void testDoSendGroupMessage_distinctUserIds() {
154 ImGroupMessageDTO dto = new ImGroupMessageDTO().setGroupId(10L); 168 ImGroupMessageDTO dto = new ImGroupMessageDTO().setGroupId(10L);
155 169
156 - imWebSocketService.doSendGroupMessage(Arrays.asList(1L, 2L, 1L, null), dto); 170 + imWebSocketService.doSendNotification(Arrays.asList(1L, 2L, 1L, null), notification);
157 171
158 verify(webSocketSenderApi).sendObject( 172 verify(webSocketSenderApi).sendObject(
159 - eq(UserTypeEnum.ADMIN.getValue()), eq(1L), eq(ImGroupMessageDTO.TYPE), eq(dto)); 173 + eq(UserTypeEnum.ADMIN.getValue()), eq(1L), eq(ImNotificationWebSocketDTO.TYPE),
  174 + argThat(actual -> isNotification(actual, ImConversationTypeEnum.GROUP,
  175 + ImContentTypeEnum.TEXT, dto)));
160 verify(webSocketSenderApi).sendObject( 176 verify(webSocketSenderApi).sendObject(
161 - eq(UserTypeEnum.ADMIN.getValue()), eq(2L), eq(ImGroupMessageDTO.TYPE), eq(dto)); 177 + eq(UserTypeEnum.ADMIN.getValue()), eq(2L), eq(ImNotificationWebSocketDTO.TYPE),
  178 + argThat(actual -> isNotification(actual, ImConversationTypeEnum.GROUP,
  179 + ImContentTypeEnum.TEXT, dto)));
162 verifyNoMoreInteractions(webSocketSenderApi); 180 verifyNoMoreInteractions(webSocketSenderApi);
163 } 181 }
164 182
165 @Test 183 @Test
166 - public void testSendPrivateMessageAsync_exceptionSwallowed() { 184 + public void testSendNotificationAsync_private_exceptionSwallowed() {
167 try (MockedStatic<SpringUtil> springUtilMockedStatic = mockStatic(SpringUtil.class)) { 185 try (MockedStatic<SpringUtil> springUtilMockedStatic = mockStatic(SpringUtil.class)) {
168 springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(ImWebSocketServiceImpl.class))) 186 springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(ImWebSocketServiceImpl.class)))
169 .thenReturn(imWebSocketService); 187 .thenReturn(imWebSocketService);
@@ -181,12 +199,12 @@ public class ImWebSocketServiceImplTest extends BaseMockitoUnitTest { @@ -181,12 +199,12 @@ public class ImWebSocketServiceImplTest extends BaseMockitoUnitTest {
181 } 199 }
182 200
183 @Test 201 @Test
184 - public void testSendGroupMessageAsync_singleUserDefaultOverload() { 202 + public void testSendNotificationAsync_group_singleUserDefaultOverload() {
185 try (MockedStatic<SpringUtil> springUtilMockedStatic = mockStatic(SpringUtil.class)) { 203 try (MockedStatic<SpringUtil> springUtilMockedStatic = mockStatic(SpringUtil.class)) {
186 springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(ImWebSocketServiceImpl.class))) 204 springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(ImWebSocketServiceImpl.class)))
187 .thenReturn(imWebSocketService); 205 .thenReturn(imWebSocketService);
188 206
189 - ImGroupMessageDTO dto = new ImGroupMessageDTO(); 207 + ImGroupMessageNotification dto = new ImGroupMessageNotification();
190 dto.setGroupId(10L); 208 dto.setGroupId(10L);
191 209
192 imWebSocketService.sendGroupMessageAsync(42L, dto); 210 imWebSocketService.sendGroupMessageAsync(42L, dto);