Commit c24a3a02c28161e91672668037031c44bbf4f597

Authored by YunaiV
2 parents c48f52ec 97096216

Merge branch 'feature/im-dev' of https://gitee.com/zhijiantianya/ruoyi-vue-pro into master-jdk17

# Conflicts:
#	sql/mysql/ruoyi-vue-pro.sql
Showing 155 changed files with 2800 additions and 2541 deletions

Too many changes.

To preserve performance only 100 of 155 files are displayed.

sql/mysql/ruoyi-vue-pro.sql
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 Target Server Version : 80200 (8.2.0) 11 Target Server Version : 80200 (8.2.0)
12 File Encoding : 65001 12 File Encoding : 65001
13 13
14 - Date: 19/06/2026 18:41:15 14 + Date: 31/05/2026 22:29:18
15 */ 15 */
16 16
17 SET NAMES utf8mb4; 17 SET NAMES utf8mb4;
@@ -49,7 +49,7 @@ CREATE TABLE `infra_api_access_log` ( @@ -49,7 +49,7 @@ CREATE TABLE `infra_api_access_log` (
49 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', 49 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
50 PRIMARY KEY (`id`) USING BTREE, 50 PRIMARY KEY (`id`) USING BTREE,
51 INDEX `idx_create_time`(`create_time` ASC) USING BTREE 51 INDEX `idx_create_time`(`create_time` ASC) USING BTREE
52 -) ENGINE = InnoDB AUTO_INCREMENT = 36333 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'API 访问日志表'; 52 +) ENGINE = InnoDB AUTO_INCREMENT = 36301 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'API 访问日志表';
53 53
54 -- ---------------------------- 54 -- ----------------------------
55 -- Records of infra_api_access_log 55 -- Records of infra_api_access_log
@@ -92,7 +92,7 @@ CREATE TABLE `infra_api_error_log` ( @@ -92,7 +92,7 @@ CREATE TABLE `infra_api_error_log` (
92 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', 92 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
93 PRIMARY KEY (`id`) USING BTREE, 93 PRIMARY KEY (`id`) USING BTREE,
94 INDEX `idx_create_time`(`create_time` ASC) USING BTREE 94 INDEX `idx_create_time`(`create_time` ASC) USING BTREE
95 -) ENGINE = InnoDB AUTO_INCREMENT = 24233 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统异常日志'; 95 +) ENGINE = InnoDB AUTO_INCREMENT = 23958 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统异常日志';
96 96
97 -- ---------------------------- 97 -- ----------------------------
98 -- Records of infra_api_error_log 98 -- Records of infra_api_error_log
@@ -253,7 +253,7 @@ CREATE TABLE `infra_file` ( @@ -253,7 +253,7 @@ CREATE TABLE `infra_file` (
253 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', 253 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
254 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', 254 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
255 PRIMARY KEY (`id`) USING BTREE 255 PRIMARY KEY (`id`) USING BTREE
256 -) ENGINE = InnoDB AUTO_INCREMENT = 2260 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件表'; 256 +) ENGINE = InnoDB AUTO_INCREMENT = 2233 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件表';
257 257
258 -- ---------------------------- 258 -- ----------------------------
259 -- Records of infra_file 259 -- Records of infra_file
@@ -462,7 +462,7 @@ CREATE TABLE `system_dict_data` ( @@ -462,7 +462,7 @@ CREATE TABLE `system_dict_data` (
462 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', 462 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
463 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', 463 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
464 PRIMARY KEY (`id`) USING BTREE 464 PRIMARY KEY (`id`) USING BTREE
465 -) ENGINE = InnoDB AUTO_INCREMENT = 1061137 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '字典数据表'; 465 +) ENGINE = InnoDB AUTO_INCREMENT = 1061122 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '字典数据表';
466 466
467 -- ---------------------------- 467 -- ----------------------------
468 -- Records of system_dict_data 468 -- Records of system_dict_data
@@ -1374,14 +1374,14 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st @@ -1374,14 +1374,14 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st
1374 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 (3443, 1, '草稿', '0', 'mes_wm_product_produce_status', 0, 'info', '', '草稿状态', '1', '2026-04-05 15:53:46', '1', '2026-04-05 15:53:46', b'0'); 1374 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 (3443, 1, '草稿', '0', 'mes_wm_product_produce_status', 0, 'info', '', '草稿状态', '1', '2026-04-05 15:53:46', '1', '2026-04-05 15:53:46', b'0');
1375 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 (3444, 2, '已完成', '4', 'mes_wm_product_produce_status', 0, 'success', '', '已完成状态', '1', '2026-04-05 15:53:46', '1', '2026-04-05 15:53:46', b'0'); 1375 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 (3444, 2, '已完成', '4', 'mes_wm_product_produce_status', 0, 'success', '', '已完成状态', '1', '2026-04-05 15:53:46', '1', '2026-04-05 15:53:46', b'0');
1376 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 (3445, 3, '已取消', '5', 'mes_wm_product_produce_status', 0, 'danger', '', '已取消状态', '1', '2026-04-05 15:53:46', '1', '2026-04-05 15:53:46', b'0'); 1376 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 (3445, 3, '已取消', '5', 'mes_wm_product_produce_status', 0, 'danger', '', '已取消状态', '1', '2026-04-05 15:53:46', '1', '2026-04-05 15:53:46', b'0');
1377 -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 (3446, 0, '草稿', '0', 'mes_pro_task_status', 0, 'default', '', 'PREPARE', '1', '2026-04-16 09:47:00', '1', '2026-06-13 10:32:58', b'0');  
1378 -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 (3447, 1, '已完成', '4', 'mes_pro_task_status', 0, 'success', '', 'FINISHED', '1', '2026-04-16 09:47:00', '1', '2026-06-13 10:32:58', b'0');  
1379 -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 (3448, 2, '已取消', '5', 'mes_pro_task_status', 0, 'danger', '', 'CANCELED', '1', '2026-04-16 09:47:00', '1', '2026-06-13 10:32:58', b'0');  
1380 -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 (3525, 1, '正常', '0', 'im_message_status', 0, 'success', '', '正常(初始状态)', 'admin', '2026-04-30 15:14:36', 'admin', '2026-06-16 03:41:55', b'0');  
1381 -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 (3526, 2, '已撤回', '2', 'im_message_status', 0, 'danger', '', '已撤回', 'admin', '2026-04-30 15:14:36', 'admin', '2026-06-16 03:41:55', b'0');  
1382 -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 (3530, 1, '不需要回执', '0', 'im_message_receipt_status', 0, 'info', '', 'NO_RECEIPT', 'admin', '2026-04-30 11:35:07', 'admin', '2026-06-14 00:32:47', b'0');  
1383 -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 (3531, 2, '待完成', '1', 'im_message_receipt_status', 0, 'warning', '', 'PENDING', 'admin', '2026-04-30 11:35:07', 'admin', '2026-06-14 00:32:47', b'0');  
1384 -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 (3532, 3, '已完成', '2', 'im_message_receipt_status', 0, 'success', '', 'DONE', 'admin', '2026-04-30 11:35:07', 'admin', '2026-06-14 00:32:47', b'0'); 1377 +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 (3446, 0, '草稿', '0', 'mes_pro_task_status', 0, '', '', NULL, '1', '2026-04-16 09:47:00', '1', '2026-04-16 09:47:00', b'0');
  1378 +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 (3447, 1, '已完成', '4', 'mes_pro_task_status', 0, '', '', NULL, '1', '2026-04-16 09:47:00', '1', '2026-04-16 09:47:00', b'0');
  1379 +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 (3448, 2, '已取消', '5', 'mes_pro_task_status', 0, '', '', NULL, '1', '2026-04-16 09:47:00', '1', '2026-04-16 09:47:00', b'0');
  1380 +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 (3525, 1, '正常', '0', 'im_message_status', 0, 'success', '', '正常(初始状态)', 'admin', '2026-04-30 15:14:36', 'admin', '2026-04-30 15:14:36', b'0');
  1381 +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 (3526, 2, '已撤回', '2', 'im_message_status', 0, 'danger', '', '已撤回', 'admin', '2026-04-30 15:14:36', 'admin', '2026-04-30 15:14:36', b'0');
  1382 +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 (3530, 1, '不需要回执', '0', 'im_message_receipt_status', 0, 'info', '', 'NO_RECEIPT', 'admin', '2026-04-30 11:35:07', 'admin', '2026-04-30 11:35:07', b'0');
  1383 +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 (3531, 2, '待完成', '1', 'im_message_receipt_status', 0, 'warning', '', 'PENDING', 'admin', '2026-04-30 11:35:07', 'admin', '2026-04-30 11:35:07', b'0');
  1384 +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 (3532, 3, '已完成', '2', 'im_message_receipt_status', 0, 'success', '', 'DONE', 'admin', '2026-04-30 11:35:07', 'admin', '2026-04-30 11:35:07', b'0');
1385 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 (3540, 1, '正常', '0', 'im_friend_status', 0, 'success', '', '正常好友关系', 'admin', '2026-04-30 11:35:07', 'admin', '2026-04-30 11:35:07', b'0'); 1385 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 (3540, 1, '正常', '0', 'im_friend_status', 0, 'success', '', '正常好友关系', 'admin', '2026-04-30 11:35:07', 'admin', '2026-04-30 11:35:07', b'0');
1386 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 (3541, 2, '已删除', '1', 'im_friend_status', 0, 'danger', '', '已删除好友关系', 'admin', '2026-04-30 11:35:07', 'admin', '2026-04-30 11:35:07', b'0'); 1386 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 (3541, 2, '已删除', '1', 'im_friend_status', 0, 'danger', '', '已删除好友关系', 'admin', '2026-04-30 11:35:07', 'admin', '2026-04-30 11:35:07', b'0');
1387 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 (3550, 1, '正常', '0', 'im_group_status', 0, 'success', '', '群正常', 'admin', '2026-04-30 11:35:07', 'admin', '2026-04-30 11:35:07', b'0'); 1387 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 (3550, 1, '正常', '0', 'im_group_status', 0, 'success', '', '群正常', 'admin', '2026-04-30 11:35:07', 'admin', '2026-04-30 11:35:07', b'0');
@@ -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_content_type', 0, '', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-06-16 03:41:55', 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-06-16 03:41:55', 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-06-16 03:41:55', 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-06-16 03:41:55', 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-06-16 03:41:55', 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-06-16 03:41:55', 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-06-16 03:41:55', 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-06-16 03:41:55', 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-06-16 03:41:55', 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-06-16 03:41:55', 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-06-16 03:47:00', 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-06-16 03:41:55', 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-06-16 03:47:00', 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-06-16 03:47:00', 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-06-16 03:41:55', 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-06-16 03:41:55', 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-06-16 03:41:55', 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-06-16 03:41:55', 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-06-16 03:41:55', 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-06-16 03:41:55', 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-06-16 03:41:55', 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-06-16 03:41:55', 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-06-16 03:41:55', 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-06-16 03:41:55', 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-06-16 03:41:55', 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-06-16 03:41:55', 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-06-16 03:41:55', 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-06-16 03:41:55', 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-06-16 03:41:55', 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-06-16 03:41:55', 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-06-16 03:41:55', 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-06-16 03:41:55', 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-06-16 03:41:55', 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,26 +1474,11 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st @@ -1474,26 +1474,11 @@ 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_content_type', 0, 'info', '', '入消息流;私聊定向通知,群聊全员广播', 'admin', '2026-05-18 03:36:12', 'admin', '2026-06-16 03:41:55', 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-06-16 03:41:55', 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', 'admin', '2026-06-16 03:41:55', 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 -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 (1061122, 7, 'SN 码', '109', 'mes_wm_barcode_biz_type', 0, 'default', '', 'SN', '1', '2026-06-13 10:30:30', '1', '2026-06-13 10:30:30', b'0');  
1483 -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 (1061123, 107, '合并转发', '107', 'im_content_type', 0, '', '', NULL, 'admin', '2026-06-16 03:47:00', 'admin', '2026-06-16 03:47:00', b'0');  
1484 -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 (1061124, 108, '名片', '108', 'im_content_type', 0, '', '', NULL, 'admin', '2026-06-16 03:47:00', 'admin', '2026-06-16 03:47:00', b'0');  
1485 -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 (1061125, 115, '表情', '115', 'im_content_type', 0, '', '', NULL, 'admin', '2026-06-16 03:47:00', 'admin', '2026-06-16 03:47:00', b'0');  
1486 -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 (1061126, 1201, '好友申请被同意', '1201', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-06-16 03:47:00', 'admin', '2026-06-16 03:47:00', b'0');  
1487 -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 (1061127, 1202, '好友申请被拒绝', '1202', 'im_content_type', 0, 'warning', '', NULL, 'admin', '2026-06-16 03:47:00', 'admin', '2026-06-16 03:47:00', b'0');  
1488 -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 (1061128, 1203, '收到新的好友申请', '1203', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-06-16 03:47:00', 'admin', '2026-06-16 03:47:00', b'0');  
1489 -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 (1061129, 1207, '加入黑名单', '1207', 'im_content_type', 0, 'danger', '', NULL, 'admin', '2026-06-16 03:47:00', 'admin', '2026-06-16 03:47:00', b'0');  
1490 -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 (1061130, 1208, '移出黑名单', '1208', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-06-16 03:47:00', 'admin', '2026-06-16 03:47:00', b'0');  
1491 -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 (1061131, 1209, '好友资料变更', '1209', 'im_content_type', 0, 'info', '', NULL, 'admin', '2026-06-16 03:47:00', 'admin', '2026-06-16 03:47:00', b'0');  
1492 -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 (1061132, 1210, '好友信息批量更新', '1210', 'im_content_type', 0, 'info', '', NULL, 'admin', '2026-06-16 03:47:00', 'admin', '2026-06-16 03:47:00', b'0');  
1493 -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 (1061133, 1530, '群成员个人设置变更', '1530', 'im_content_type', 0, 'info', '', NULL, 'admin', '2026-06-16 03:47:00', 'admin', '2026-06-16 03:47:00', b'0');  
1494 -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 (1061134, 1601, '通话信令', '1601', 'im_content_type', 0, 'info', '', NULL, 'admin', '2026-06-16 03:47:00', 'admin', '2026-06-16 03:47:00', b'0');  
1495 -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 (1061135, 1602, '通话参与者加入', '1602', 'im_content_type', 0, 'info', '', NULL, 'admin', '2026-06-16 03:47:00', 'admin', '2026-06-16 03:47:00', b'0');  
1496 -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 (1061136, 1603, '通话参与者离开', '1603', 'im_content_type', 0, 'info', '', NULL, 'admin', '2026-06-16 03:47:00', 'admin', '2026-06-16 03:47:00', b'0');  
1497 COMMIT; 1482 COMMIT;
1498 1483
1499 -- ---------------------------- 1484 -- ----------------------------
@@ -1651,7 +1636,7 @@ INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creat @@ -1651,7 +1636,7 @@ INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creat
1651 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2029, 'MES 工单类型', 'mes_pro_work_order_type', 0, 'MES 生产管理 - 工单类型(1=自行生产,2=代工,3=采购)', '1', '2026-02-17 11:43:47', '1', '2026-02-17 11:43:47', b'0', NULL); 1636 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2029, 'MES 工单类型', 'mes_pro_work_order_type', 0, 'MES 生产管理 - 工单类型(1=自行生产,2=代工,3=采购)', '1', '2026-02-17 11:43:47', '1', '2026-02-17 11:43:47', b'0', NULL);
1652 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2036, 'MES 工序关系类型', 'mes_pro_link_type', 0, '工艺路线中工序之间的关系类型', '1', '2026-02-19 04:24:53', '1', '2026-04-05 15:05:07', b'0', NULL); 1637 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2036, 'MES 工序关系类型', 'mes_pro_link_type', 0, '工艺路线中工序之间的关系类型', '1', '2026-02-19 04:24:53', '1', '2026-04-05 15:05:07', b'0', NULL);
1653 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2037, 'MES 时间单位', 'mes_time_unit_type', 0, '生产时间的计量单位', '1', '2026-02-19 04:24:53', '1', '2026-04-05 15:04:57', b'0', NULL); 1638 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2037, 'MES 时间单位', 'mes_time_unit_type', 0, '生产时间的计量单位', '1', '2026-02-19 04:24:53', '1', '2026-04-05 15:04:57', b'0', NULL);
1654 -INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2038, 'MES 生产任务状态', 'mes_pro_task_status', 0, 'MES 生产管理 - 任务状态(0=草稿,4=已完成,5=已取消)', '1', '2026-02-19 15:25:27', '1', '2026-06-13 10:32:58', b'0', NULL); 1639 +INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2038, 'MES 生产任务状态', 'mes_pro_task_status', 0, 'MES 生产管理 - 任务状态(0=草稿,1=进行中,2=暂停,3=已完成,4=已取消)', '1', '2026-02-19 15:25:27', '1', '2026-02-19 15:25:27', b'0', NULL);
1655 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2039, 'MES 点检保养项目类型', 'mes_dv_subject_type', 0, 'MES 设备管理 - 点检保养项目类型(1=设备点检,2=设备保养)', '1', '2026-02-20 01:42:58', '1', '2026-02-20 01:42:58', b'0', NULL); 1640 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2039, 'MES 点检保养项目类型', 'mes_dv_subject_type', 0, 'MES 设备管理 - 点检保养项目类型(1=设备点检,2=设备保养)', '1', '2026-02-20 01:42:58', '1', '2026-02-20 01:42:58', b'0', NULL);
1656 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2040, 'MES 保养记录状态', 'mes_mainten_record_status', 0, NULL, 'admin', '2026-02-20 02:59:55', 'admin', '2026-02-20 02:59:55', b'0', NULL); 1641 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2040, 'MES 保养记录状态', 'mes_mainten_record_status', 0, NULL, 'admin', '2026-02-20 02:59:55', 'admin', '2026-02-20 02:59:55', b'0', NULL);
1657 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2041, 'MES 保养结果', 'mes_mainten_status', 0, NULL, 'admin', '2026-02-20 02:59:55', 'admin', '2026-02-20 02:59:55', b'0', NULL); 1642 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2041, 'MES 保养结果', 'mes_mainten_status', 0, NULL, 'admin', '2026-02-20 02:59:55', 'admin', '2026-02-20 02:59:55', b'0', NULL);
@@ -1704,11 +1689,11 @@ INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creat @@ -1704,11 +1689,11 @@ INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creat
1704 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);
1705 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);
1706 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');
1707 -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-06-16 03:41:55', b'0', NULL);  
1708 -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-06-16 03:41:55', 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);
1709 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);
1710 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);
1711 -INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2205, 'IM 消息状态', 'im_message_status', 0, '对应 ImMessageStatusEnum;0=正常 / 2=已撤回(私聊 / 群聊共用)', 'admin', '2026-04-30 15:14:36', 'admin', '2026-06-16 03:41:55', b'0', NULL); 1696 +INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2205, 'IM 消息状态', 'im_message_status', 0, '对应 ImMessageStatusEnum;0=正常 / 2=已撤回(私聊 / 群聊共用)', 'admin', '2026-04-30 15:14:36', 'admin', '2026-04-30 15:14:36', b'0', NULL);
1712 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2206, 'IM 群成员角色', 'im_group_member_role', 0, NULL, '1', '2026-05-02 02:14:12', '1', '2026-05-02 02:14:12', b'0', NULL); 1697 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2206, 'IM 群成员角色', 'im_group_member_role', 0, NULL, '1', '2026-05-02 02:14:12', '1', '2026-05-02 02:14:12', b'0', NULL);
1713 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2207, 'IM 好友添加来源', 'im_friend_add_source', 0, NULL, '1', '2026-05-04 02:43:41', '1', '2026-05-04 02:43:41', b'0', NULL); 1698 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2207, 'IM 好友添加来源', 'im_friend_add_source', 0, NULL, '1', '2026-05-04 02:43:41', '1', '2026-05-04 02:43:41', b'0', NULL);
1714 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2208, 'IM 好友申请处理结果', 'im_friend_request_handle_result', 0, NULL, '1', '2026-05-04 02:43:41', '1', '2026-05-04 02:43:41', b'0', NULL); 1699 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2208, 'IM 好友申请处理结果', 'im_friend_request_handle_result', 0, NULL, '1', '2026-05-04 02:43:41', '1', '2026-05-04 02:43:41', b'0', NULL);
@@ -1751,7 +1736,7 @@ CREATE TABLE `system_login_log` ( @@ -1751,7 +1736,7 @@ CREATE TABLE `system_login_log` (
1751 PRIMARY KEY (`id`) USING BTREE, 1736 PRIMARY KEY (`id`) USING BTREE,
1752 INDEX `idx_username`(`username` ASC) USING BTREE, 1737 INDEX `idx_username`(`username` ASC) USING BTREE,
1753 INDEX `idx_create_time`(`create_time` ASC) USING BTREE 1738 INDEX `idx_create_time`(`create_time` ASC) USING BTREE
1754 -) ENGINE = InnoDB AUTO_INCREMENT = 5226 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统访问记录'; 1739 +) ENGINE = InnoDB AUTO_INCREMENT = 4697 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统访问记录';
1755 1740
1756 -- ---------------------------- 1741 -- ----------------------------
1757 -- Records of system_login_log 1742 -- Records of system_login_log
@@ -2229,7 +2214,7 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i @@ -2229,7 +2214,7 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
2229 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2156, '查询项目', 'report:go-view-project:query', 3, 0, 2153, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2023-02-07 19:25:53', '1', '2023-02-07 19:25:53', b'0'); 2214 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2156, '查询项目', 'report:go-view-project:query', 3, 0, 2153, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2023-02-07 19:25:53', '1', '2023-02-07 19:25:53', b'0');
2230 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2157, '使用 SQL 查询数据', 'report:go-view-data:get-by-sql', 3, 3, 2153, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2023-02-07 19:26:15', '1', '2023-02-07 19:26:15', b'0'); 2215 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2157, '使用 SQL 查询数据', 'report:go-view-data:get-by-sql', 3, 3, 2153, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2023-02-07 19:26:15', '1', '2023-02-07 19:26:15', b'0');
2231 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2158, '使用 HTTP 查询数据', 'report:go-view-data:get-by-http', 3, 4, 2153, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2023-02-07 19:26:35', '1', '2023-02-07 19:26:35', b'0'); 2216 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2158, '使用 HTTP 查询数据', 'report:go-view-data:get-by-http', 3, 4, 2153, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2023-02-07 19:26:35', '1', '2023-02-07 19:26:35', b'0');
2232 -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2159, 'Boot 开发文档', '', 1, 1, 0, 'https://doc.iocoder.cn/', 'ep:document', NULL, NULL, 0, b'1', b'1', b'1', '1', '2023-02-10 22:46:28', '1', '2026-06-12 00:05:19', b'0'); 2217 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2159, 'Boot 开发文档', '', 1, 1, 0, 'https://doc.iocoder.cn/', 'ep:document', NULL, NULL, 0, b'1', b'1', b'1', '1', '2023-02-10 22:46:28', '1', '2026-01-05 19:31:07', b'0');
2233 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2160, 'Cloud 开发文档', '', 1, 2, 0, 'https://cloud.iocoder.cn', 'ep:document-copy', NULL, NULL, 0, b'1', b'1', b'1', '1', '2023-02-10 22:47:07', '1', '2023-12-02 21:32:29', b'0'); 2218 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2160, 'Cloud 开发文档', '', 1, 2, 0, 'https://cloud.iocoder.cn', 'ep:document-copy', NULL, NULL, 0, b'1', b'1', b'1', '1', '2023-02-10 22:47:07', '1', '2023-12-02 21:32:29', b'0');
2234 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2161, '接入示例', '', 1, 99, 1117, 'demo', 'fa-solid:dragon', 'pay/demo/index', NULL, 0, b'1', b'1', b'1', '', '2023-02-11 14:21:42', '1', '2024-01-18 23:50:00', b'0'); 2219 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2161, '接入示例', '', 1, 99, 1117, 'demo', 'fa-solid:dragon', 'pay/demo/index', NULL, 0, b'1', b'1', b'1', '', '2023-02-11 14:21:42', '1', '2024-01-18 23:50:00', b'0');
2235 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2162, '商品导出', 'product:spu:export', 3, 5, 2014, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-07-30 14:22:58', '', '2022-07-30 14:22:58', b'0'); 2220 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2162, '商品导出', 'product:spu:export', 3, 5, 2014, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-07-30 14:22:58', '', '2022-07-30 14:22:58', b'0');
@@ -3453,7 +3438,7 @@ CREATE TABLE `system_oauth2_access_token` ( @@ -3453,7 +3438,7 @@ CREATE TABLE `system_oauth2_access_token` (
3453 PRIMARY KEY (`id`) USING BTREE, 3438 PRIMARY KEY (`id`) USING BTREE,
3454 INDEX `idx_access_token`(`access_token` ASC) USING BTREE, 3439 INDEX `idx_access_token`(`access_token` ASC) USING BTREE,
3455 INDEX `idx_refresh_token`(`refresh_token` ASC) USING BTREE 3440 INDEX `idx_refresh_token`(`refresh_token` ASC) USING BTREE
3456 -) ENGINE = InnoDB AUTO_INCREMENT = 107056 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 访问令牌'; 3441 +) ENGINE = InnoDB AUTO_INCREMENT = 57395 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 访问令牌';
3457 3442
3458 -- ---------------------------- 3443 -- ----------------------------
3459 -- Records of system_oauth2_access_token 3444 -- Records of system_oauth2_access_token
@@ -3526,7 +3511,7 @@ BEGIN; @@ -3526,7 +3511,7 @@ BEGIN;
3526 INSERT INTO `system_oauth2_client` (`id`, `client_id`, `secret`, `name`, `logo`, `description`, `status`, `access_token_validity_seconds`, `refresh_token_validity_seconds`, `redirect_uris`, `authorized_grant_types`, `scopes`, `auto_approve_scopes`, `authorities`, `resource_ids`, `additional_information`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, 'default', 'admin123', '芋道源码', 'http://test.yudao.iocoder.cn/20250502/sort2_1746189740718.png', '我是描述', 0, 1800, 2592000, '[\"https://www.iocoder.cn\",\"https://doc.iocoder.cn\"]', '[\"password\",\"authorization_code\",\"implicit\",\"refresh_token\",\"client_credentials\"]', '[\"user.read\",\"user.write\"]', '[]', '[\"user.read\",\"user.write\"]', '[]', '{}', '1', '2022-05-11 21:47:12', '1', '2025-12-07 20:07:09', b'0'); 3511 INSERT INTO `system_oauth2_client` (`id`, `client_id`, `secret`, `name`, `logo`, `description`, `status`, `access_token_validity_seconds`, `refresh_token_validity_seconds`, `redirect_uris`, `authorized_grant_types`, `scopes`, `auto_approve_scopes`, `authorities`, `resource_ids`, `additional_information`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, 'default', 'admin123', '芋道源码', 'http://test.yudao.iocoder.cn/20250502/sort2_1746189740718.png', '我是描述', 0, 1800, 2592000, '[\"https://www.iocoder.cn\",\"https://doc.iocoder.cn\"]', '[\"password\",\"authorization_code\",\"implicit\",\"refresh_token\",\"client_credentials\"]', '[\"user.read\",\"user.write\"]', '[]', '[\"user.read\",\"user.write\"]', '[]', '{}', '1', '2022-05-11 21:47:12', '1', '2025-12-07 20:07:09', b'0');
3527 INSERT INTO `system_oauth2_client` (`id`, `client_id`, `secret`, `name`, `logo`, `description`, `status`, `access_token_validity_seconds`, `refresh_token_validity_seconds`, `redirect_uris`, `authorized_grant_types`, `scopes`, `auto_approve_scopes`, `authorities`, `resource_ids`, `additional_information`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (40, 'test', 'test2', 'biubiu', 'http://test.yudao.iocoder.cn/20251227/javayuanma_1766829882970.jpg', '啦啦啦啦', 0, 1800, 43200, '[\"https://www.iocoder.cn\"]', '[\"password\",\"authorization_code\",\"implicit\"]', '[\"user_info\",\"projects\"]', '[\"user_info\"]', '[]', '[]', '{}', '1', '2022-05-12 00:28:20', '1', '2025-12-27 18:04:44', b'0'); 3512 INSERT INTO `system_oauth2_client` (`id`, `client_id`, `secret`, `name`, `logo`, `description`, `status`, `access_token_validity_seconds`, `refresh_token_validity_seconds`, `redirect_uris`, `authorized_grant_types`, `scopes`, `auto_approve_scopes`, `authorities`, `resource_ids`, `additional_information`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (40, 'test', 'test2', 'biubiu', 'http://test.yudao.iocoder.cn/20251227/javayuanma_1766829882970.jpg', '啦啦啦啦', 0, 1800, 43200, '[\"https://www.iocoder.cn\"]', '[\"password\",\"authorization_code\",\"implicit\"]', '[\"user_info\",\"projects\"]', '[\"user_info\"]', '[]', '[]', '{}', '1', '2022-05-12 00:28:20', '1', '2025-12-27 18:04:44', b'0');
3528 INSERT INTO `system_oauth2_client` (`id`, `client_id`, `secret`, `name`, `logo`, `description`, `status`, `access_token_validity_seconds`, `refresh_token_validity_seconds`, `redirect_uris`, `authorized_grant_types`, `scopes`, `auto_approve_scopes`, `authorities`, `resource_ids`, `additional_information`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (41, 'yudao-sso-demo-by-code', 'test', '基于授权码模式,如何实现 SSO 单点登录?', 'http://test.yudao.iocoder.cn/it/20250502/sign_1746181948685.png', NULL, 0, 1800, 43200, '[\"http://127.0.0.1:18080\"]', '[\"authorization_code\",\"refresh_token\"]', '[\"user.read\",\"user.write\"]', '[]', '[]', '[]', NULL, '1', '2022-09-29 13:28:31', '1', '2025-05-02 18:32:30', b'0'); 3513 INSERT INTO `system_oauth2_client` (`id`, `client_id`, `secret`, `name`, `logo`, `description`, `status`, `access_token_validity_seconds`, `refresh_token_validity_seconds`, `redirect_uris`, `authorized_grant_types`, `scopes`, `auto_approve_scopes`, `authorities`, `resource_ids`, `additional_information`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (41, 'yudao-sso-demo-by-code', 'test', '基于授权码模式,如何实现 SSO 单点登录?', 'http://test.yudao.iocoder.cn/it/20250502/sign_1746181948685.png', NULL, 0, 1800, 43200, '[\"http://127.0.0.1:18080\"]', '[\"authorization_code\",\"refresh_token\"]', '[\"user.read\",\"user.write\"]', '[]', '[]', '[]', NULL, '1', '2022-09-29 13:28:31', '1', '2025-05-02 18:32:30', b'0');
3529 -INSERT INTO `system_oauth2_client` (`id`, `client_id`, `secret`, `name`, `logo`, `description`, `status`, `access_token_validity_seconds`, `refresh_token_validity_seconds`, `redirect_uris`, `authorized_grant_types`, `scopes`, `auto_approve_scopes`, `authorities`, `resource_ids`, `additional_information`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (42, 'yudao-sso-demo-by-password', 'test', '基于密码模式,如何实现 SSO 单点登录?', 'http://test.yudao.iocoder.cn/oauth2/20260615/iShot_2026-05-31_23.18.10.png', NULL, 0, 1800, 43200, '[\"http://127.0.0.1:18080\"]', '[\"password\",\"refresh_token\"]', '[\"user.read\",\"user.write\"]', '[]', '[]', '[]', NULL, '1', '2022-10-04 17:40:16', '1', '2026-06-15 18:58:30', b'0'); 3514 +INSERT INTO `system_oauth2_client` (`id`, `client_id`, `secret`, `name`, `logo`, `description`, `status`, `access_token_validity_seconds`, `refresh_token_validity_seconds`, `redirect_uris`, `authorized_grant_types`, `scopes`, `auto_approve_scopes`, `authorities`, `resource_ids`, `additional_information`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (42, 'yudao-sso-demo-by-password', 'test', '基于密码模式,如何实现 SSO 单点登录?', 'http://test.yudao.iocoder.cn/20251025/images (3)_1761360515810.jpeg', NULL, 0, 1800, 43200, '[\"http://127.0.0.1:18080\"]', '[\"password\",\"refresh_token\"]', '[\"user.read\",\"user.write\"]', '[]', '[]', '[]', NULL, '1', '2022-10-04 17:40:16', '1', '2025-10-25 10:49:40', b'0');
3530 COMMIT; 3515 COMMIT;
3531 3516
3532 -- ---------------------------- 3517 -- ----------------------------
@@ -3579,7 +3564,7 @@ CREATE TABLE `system_oauth2_refresh_token` ( @@ -3579,7 +3564,7 @@ CREATE TABLE `system_oauth2_refresh_token` (
3579 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', 3564 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
3580 PRIMARY KEY (`id`) USING BTREE, 3565 PRIMARY KEY (`id`) USING BTREE,
3581 INDEX `idx_refresh_token`(`refresh_token` ASC) USING BTREE 3566 INDEX `idx_refresh_token`(`refresh_token` ASC) USING BTREE
3582 -) ENGINE = InnoDB AUTO_INCREMENT = 3244 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 刷新令牌'; 3567 +) ENGINE = InnoDB AUTO_INCREMENT = 2728 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 刷新令牌';
3583 3568
3584 -- ---------------------------- 3569 -- ----------------------------
3585 -- Records of system_oauth2_refresh_token 3570 -- Records of system_oauth2_refresh_token
@@ -3615,7 +3600,7 @@ CREATE TABLE `system_operate_log` ( @@ -3615,7 +3600,7 @@ CREATE TABLE `system_operate_log` (
3615 PRIMARY KEY (`id`) USING BTREE, 3600 PRIMARY KEY (`id`) USING BTREE,
3616 INDEX `idx_user_id`(`user_id` ASC) USING BTREE, 3601 INDEX `idx_user_id`(`user_id` ASC) USING BTREE,
3617 INDEX `idx_create_time`(`create_time` ASC) USING BTREE 3602 INDEX `idx_create_time`(`create_time` ASC) USING BTREE
3618 -) ENGINE = InnoDB AUTO_INCREMENT = 9207 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '操作日志记录 V2 版本'; 3603 +) ENGINE = InnoDB AUTO_INCREMENT = 9195 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '操作日志记录 V2 版本';
3619 3604
3620 -- ---------------------------- 3605 -- ----------------------------
3621 -- Records of system_operate_log 3606 -- Records of system_operate_log
@@ -3641,7 +3626,7 @@ CREATE TABLE `system_post` ( @@ -3641,7 +3626,7 @@ CREATE TABLE `system_post` (
3641 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', 3626 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
3642 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', 3627 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
3643 PRIMARY KEY (`id`) USING BTREE 3628 PRIMARY KEY (`id`) USING BTREE
3644 -) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '岗位信息表'; 3629 +) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '岗位信息表';
3645 3630
3646 -- ---------------------------- 3631 -- ----------------------------
3647 -- Records of system_post 3632 -- Records of system_post
@@ -3685,7 +3670,7 @@ INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_sco @@ -3685,7 +3670,7 @@ INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_sco
3685 INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3, 'CRM 管理员', 'crm_admin', 2, 1, '', 0, 1, 'CRM 专属角色', '1', '2024-02-24 10:51:13', '1', '2024-02-24 02:51:32', b'0', 1); 3670 INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3, 'CRM 管理员', 'crm_admin', 2, 1, '', 0, 1, 'CRM 专属角色', '1', '2024-02-24 10:51:13', '1', '2024-02-24 02:51:32', b'0', 1);
3686 INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (109, '租户管理员', 'tenant_admin', 0, 1, '', 0, 1, '系统自动生成', '1', '2022-02-22 00:56:14', '1', '2022-02-22 00:56:14', b'0', 121); 3671 INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (109, '租户管理员', 'tenant_admin', 0, 1, '', 0, 1, '系统自动生成', '1', '2022-02-22 00:56:14', '1', '2022-02-22 00:56:14', b'0', 121);
3687 INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (111, '租户管理员', 'tenant_admin', 0, 1, '', 0, 1, '系统自动生成', '1', '2022-03-07 21:37:58', '1', '2022-03-07 21:37:58', b'0', 122); 3672 INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (111, '租户管理员', 'tenant_admin', 0, 1, '', 0, 1, '系统自动生成', '1', '2022-03-07 21:37:58', '1', '2022-03-07 21:37:58', b'0', 122);
3688 -INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (155, '测试数据权限12', 'test-dp', 4, 2, '[112,100,102,103,104,105,107,108]', 0, 2, '1111', '1', '2025-03-31 14:58:06', '1', '2026-06-07 01:37:53', b'0', 1); 3673 +INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (155, '测试数据权限1', 'test-dp', 4, 2, '[112,100,102,103,104,105,107,108]', 0, 2, '1111', '1', '2025-03-31 14:58:06', '1', '2025-12-04 23:29:40', b'0', 1);
3689 COMMIT; 3674 COMMIT;
3690 3675
3691 -- ---------------------------- 3676 -- ----------------------------
@@ -3704,7 +3689,7 @@ CREATE TABLE `system_role_menu` ( @@ -3704,7 +3689,7 @@ CREATE TABLE `system_role_menu` (
3704 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', 3689 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
3705 PRIMARY KEY (`id`) USING BTREE, 3690 PRIMARY KEY (`id`) USING BTREE,
3706 INDEX `idx_role_id`(`role_id` ASC) USING BTREE 3691 INDEX `idx_role_id`(`role_id` ASC) USING BTREE
3707 -) ENGINE = InnoDB AUTO_INCREMENT = 6692 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '角色和菜单关联表'; 3692 +) ENGINE = InnoDB AUTO_INCREMENT = 6381 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '角色和菜单关联表';
3708 3693
3709 -- ---------------------------- 3694 -- ----------------------------
3710 -- Records of system_role_menu 3695 -- Records of system_role_menu
@@ -3744,6 +3729,7 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t @@ -3744,6 +3729,7 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t
3744 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (706, 2, 112, '1', '2022-02-22 13:16:57', '1', '2022-02-22 13:16:57', b'0', 1); 3729 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (706, 2, 112, '1', '2022-02-22 13:16:57', '1', '2022-02-22 13:16:57', b'0', 1);
3745 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (707, 2, 113, '1', '2022-02-22 13:16:57', '1', '2022-02-22 13:16:57', b'0', 1); 3730 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (707, 2, 113, '1', '2022-02-22 13:16:57', '1', '2022-02-22 13:16:57', b'0', 1);
3746 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1296, 110, 1, '110', '2022-02-23 00:23:55', '110', '2022-02-23 00:23:55', b'0', 121); 3731 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1296, 110, 1, '110', '2022-02-23 00:23:55', '110', '2022-02-23 00:23:55', b'0', 121);
  3732 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1578, 111, 1, '1', '2022-03-07 21:37:58', '1', '2022-03-07 21:37:58', b'0', 122);
3747 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1729, 109, 100, '1', '2022-09-21 22:08:51', '1', '2022-09-21 22:08:51', b'0', 121); 3733 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1729, 109, 100, '1', '2022-09-21 22:08:51', '1', '2022-09-21 22:08:51', b'0', 121);
3748 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1730, 109, 101, '1', '2022-09-21 22:08:51', '1', '2022-09-21 22:08:51', b'0', 121); 3734 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1730, 109, 101, '1', '2022-09-21 22:08:51', '1', '2022-09-21 22:08:51', b'0', 121);
3749 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1731, 109, 1063, '1', '2022-09-21 22:08:51', '1', '2022-09-21 22:08:51', b'0', 121); 3735 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1731, 109, 1063, '1', '2022-09-21 22:08:51', '1', '2022-09-21 22:08:51', b'0', 121);
@@ -3761,6 +3747,23 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t @@ -3761,6 +3747,23 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t
3761 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1743, 109, 1010, '1', '2022-09-21 22:08:51', '1', '2022-09-21 22:08:51', b'0', 121); 3747 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1743, 109, 1010, '1', '2022-09-21 22:08:51', '1', '2022-09-21 22:08:51', b'0', 121);
3762 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1744, 109, 1011, '1', '2022-09-21 22:08:51', '1', '2022-09-21 22:08:51', b'0', 121); 3748 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1744, 109, 1011, '1', '2022-09-21 22:08:51', '1', '2022-09-21 22:08:51', b'0', 121);
3763 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1745, 109, 1012, '1', '2022-09-21 22:08:51', '1', '2022-09-21 22:08:51', b'0', 121); 3749 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1745, 109, 1012, '1', '2022-09-21 22:08:51', '1', '2022-09-21 22:08:51', b'0', 121);
  3750 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1746, 111, 100, '1', '2022-09-21 22:08:52', '1', '2022-09-21 22:08:52', b'0', 122);
  3751 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1747, 111, 101, '1', '2022-09-21 22:08:52', '1', '2022-09-21 22:08:52', b'0', 122);
  3752 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1748, 111, 1063, '1', '2022-09-21 22:08:52', '1', '2022-09-21 22:08:52', b'0', 122);
  3753 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1749, 111, 1064, '1', '2022-09-21 22:08:52', '1', '2022-09-21 22:08:52', b'0', 122);
  3754 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1750, 111, 1001, '1', '2022-09-21 22:08:52', '1', '2022-09-21 22:08:52', b'0', 122);
  3755 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1751, 111, 1065, '1', '2022-09-21 22:08:52', '1', '2022-09-21 22:08:52', b'0', 122);
  3756 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1752, 111, 1002, '1', '2022-09-21 22:08:52', '1', '2022-09-21 22:08:52', b'0', 122);
  3757 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1753, 111, 1003, '1', '2022-09-21 22:08:52', '1', '2022-09-21 22:08:52', b'0', 122);
  3758 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1754, 111, 1004, '1', '2022-09-21 22:08:52', '1', '2022-09-21 22:08:52', b'0', 122);
  3759 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1755, 111, 1005, '1', '2022-09-21 22:08:52', '1', '2022-09-21 22:08:52', b'0', 122);
  3760 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1756, 111, 1006, '1', '2022-09-21 22:08:52', '1', '2022-09-21 22:08:52', b'0', 122);
  3761 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1757, 111, 1007, '1', '2022-09-21 22:08:52', '1', '2022-09-21 22:08:52', b'0', 122);
  3762 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1758, 111, 1008, '1', '2022-09-21 22:08:52', '1', '2022-09-21 22:08:52', b'0', 122);
  3763 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1759, 111, 1009, '1', '2022-09-21 22:08:52', '1', '2022-09-21 22:08:52', b'0', 122);
  3764 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1760, 111, 1010, '1', '2022-09-21 22:08:52', '1', '2022-09-21 22:08:52', b'0', 122);
  3765 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1761, 111, 1011, '1', '2022-09-21 22:08:52', '1', '2022-09-21 22:08:52', b'0', 122);
  3766 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1762, 111, 1012, '1', '2022-09-21 22:08:52', '1', '2022-09-21 22:08:52', b'0', 122);
3764 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1763, 109, 100, '1', '2022-09-21 22:08:53', '1', '2022-09-21 22:08:53', b'0', 121); 3767 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1763, 109, 100, '1', '2022-09-21 22:08:53', '1', '2022-09-21 22:08:53', b'0', 121);
3765 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1764, 109, 101, '1', '2022-09-21 22:08:53', '1', '2022-09-21 22:08:53', b'0', 121); 3768 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1764, 109, 101, '1', '2022-09-21 22:08:53', '1', '2022-09-21 22:08:53', b'0', 121);
3766 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1765, 109, 1063, '1', '2022-09-21 22:08:53', '1', '2022-09-21 22:08:53', b'0', 121); 3769 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1765, 109, 1063, '1', '2022-09-21 22:08:53', '1', '2022-09-21 22:08:53', b'0', 121);
@@ -3778,6 +3781,23 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t @@ -3778,6 +3781,23 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t
3778 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1777, 109, 1010, '1', '2022-09-21 22:08:53', '1', '2022-09-21 22:08:53', b'0', 121); 3781 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1777, 109, 1010, '1', '2022-09-21 22:08:53', '1', '2022-09-21 22:08:53', b'0', 121);
3779 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1778, 109, 1011, '1', '2022-09-21 22:08:53', '1', '2022-09-21 22:08:53', b'0', 121); 3782 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1778, 109, 1011, '1', '2022-09-21 22:08:53', '1', '2022-09-21 22:08:53', b'0', 121);
3780 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1779, 109, 1012, '1', '2022-09-21 22:08:53', '1', '2022-09-21 22:08:53', b'0', 121); 3783 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1779, 109, 1012, '1', '2022-09-21 22:08:53', '1', '2022-09-21 22:08:53', b'0', 121);
  3784 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1780, 111, 100, '1', '2022-09-21 22:08:54', '1', '2022-09-21 22:08:54', b'0', 122);
  3785 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1781, 111, 101, '1', '2022-09-21 22:08:54', '1', '2022-09-21 22:08:54', b'0', 122);
  3786 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1782, 111, 1063, '1', '2022-09-21 22:08:54', '1', '2022-09-21 22:08:54', b'0', 122);
  3787 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1783, 111, 1064, '1', '2022-09-21 22:08:54', '1', '2022-09-21 22:08:54', b'0', 122);
  3788 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1784, 111, 1001, '1', '2022-09-21 22:08:54', '1', '2022-09-21 22:08:54', b'0', 122);
  3789 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1785, 111, 1065, '1', '2022-09-21 22:08:54', '1', '2022-09-21 22:08:54', b'0', 122);
  3790 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1786, 111, 1002, '1', '2022-09-21 22:08:54', '1', '2022-09-21 22:08:54', b'0', 122);
  3791 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1787, 111, 1003, '1', '2022-09-21 22:08:54', '1', '2022-09-21 22:08:54', b'0', 122);
  3792 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1788, 111, 1004, '1', '2022-09-21 22:08:54', '1', '2022-09-21 22:08:54', b'0', 122);
  3793 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1789, 111, 1005, '1', '2022-09-21 22:08:54', '1', '2022-09-21 22:08:54', b'0', 122);
  3794 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1790, 111, 1006, '1', '2022-09-21 22:08:54', '1', '2022-09-21 22:08:54', b'0', 122);
  3795 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1791, 111, 1007, '1', '2022-09-21 22:08:54', '1', '2022-09-21 22:08:54', b'0', 122);
  3796 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1792, 111, 1008, '1', '2022-09-21 22:08:54', '1', '2022-09-21 22:08:54', b'0', 122);
  3797 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1793, 111, 1009, '1', '2022-09-21 22:08:54', '1', '2022-09-21 22:08:54', b'0', 122);
  3798 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1794, 111, 1010, '1', '2022-09-21 22:08:54', '1', '2022-09-21 22:08:54', b'0', 122);
  3799 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1795, 111, 1011, '1', '2022-09-21 22:08:54', '1', '2022-09-21 22:08:54', b'0', 122);
  3800 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1796, 111, 1012, '1', '2022-09-21 22:08:54', '1', '2022-09-21 22:08:54', b'0', 122);
3781 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1797, 109, 100, '1', '2022-09-21 22:08:55', '1', '2022-09-21 22:08:55', b'0', 121); 3801 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1797, 109, 100, '1', '2022-09-21 22:08:55', '1', '2022-09-21 22:08:55', b'0', 121);
3782 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1798, 109, 101, '1', '2022-09-21 22:08:55', '1', '2022-09-21 22:08:55', b'0', 121); 3802 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1798, 109, 101, '1', '2022-09-21 22:08:55', '1', '2022-09-21 22:08:55', b'0', 121);
3783 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1799, 109, 1063, '1', '2022-09-21 22:08:55', '1', '2022-09-21 22:08:55', b'0', 121); 3803 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1799, 109, 1063, '1', '2022-09-21 22:08:55', '1', '2022-09-21 22:08:55', b'0', 121);
@@ -3795,16 +3815,43 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t @@ -3795,16 +3815,43 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t
3795 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1811, 109, 1010, '1', '2022-09-21 22:08:55', '1', '2022-09-21 22:08:55', b'0', 121); 3815 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1811, 109, 1010, '1', '2022-09-21 22:08:55', '1', '2022-09-21 22:08:55', b'0', 121);
3796 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1812, 109, 1011, '1', '2022-09-21 22:08:55', '1', '2022-09-21 22:08:55', b'0', 121); 3816 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1812, 109, 1011, '1', '2022-09-21 22:08:55', '1', '2022-09-21 22:08:55', b'0', 121);
3797 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1813, 109, 1012, '1', '2022-09-21 22:08:55', '1', '2022-09-21 22:08:55', b'0', 121); 3817 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1813, 109, 1012, '1', '2022-09-21 22:08:55', '1', '2022-09-21 22:08:55', b'0', 121);
  3818 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1814, 111, 100, '1', '2022-09-21 22:08:56', '1', '2022-09-21 22:08:56', b'0', 122);
  3819 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1815, 111, 101, '1', '2022-09-21 22:08:56', '1', '2022-09-21 22:08:56', b'0', 122);
  3820 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1816, 111, 1063, '1', '2022-09-21 22:08:56', '1', '2022-09-21 22:08:56', b'0', 122);
  3821 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1817, 111, 1064, '1', '2022-09-21 22:08:56', '1', '2022-09-21 22:08:56', b'0', 122);
  3822 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1818, 111, 1001, '1', '2022-09-21 22:08:56', '1', '2022-09-21 22:08:56', b'0', 122);
  3823 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1819, 111, 1065, '1', '2022-09-21 22:08:56', '1', '2022-09-21 22:08:56', b'0', 122);
  3824 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1820, 111, 1002, '1', '2022-09-21 22:08:56', '1', '2022-09-21 22:08:56', b'0', 122);
  3825 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1821, 111, 1003, '1', '2022-09-21 22:08:56', '1', '2022-09-21 22:08:56', b'0', 122);
  3826 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1822, 111, 1004, '1', '2022-09-21 22:08:56', '1', '2022-09-21 22:08:56', b'0', 122);
  3827 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1823, 111, 1005, '1', '2022-09-21 22:08:56', '1', '2022-09-21 22:08:56', b'0', 122);
  3828 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1824, 111, 1006, '1', '2022-09-21 22:08:56', '1', '2022-09-21 22:08:56', b'0', 122);
  3829 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1825, 111, 1007, '1', '2022-09-21 22:08:56', '1', '2022-09-21 22:08:56', b'0', 122);
  3830 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1826, 111, 1008, '1', '2022-09-21 22:08:56', '1', '2022-09-21 22:08:56', b'0', 122);
  3831 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1827, 111, 1009, '1', '2022-09-21 22:08:56', '1', '2022-09-21 22:08:56', b'0', 122);
  3832 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1828, 111, 1010, '1', '2022-09-21 22:08:56', '1', '2022-09-21 22:08:56', b'0', 122);
  3833 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1829, 111, 1011, '1', '2022-09-21 22:08:56', '1', '2022-09-21 22:08:56', b'0', 122);
  3834 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1830, 111, 1012, '1', '2022-09-21 22:08:56', '1', '2022-09-21 22:08:56', b'0', 122);
3798 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1831, 109, 103, '1', '2022-09-21 22:43:23', '1', '2022-09-21 22:43:23', b'0', 121); 3835 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1831, 109, 103, '1', '2022-09-21 22:43:23', '1', '2022-09-21 22:43:23', b'0', 121);
3799 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1832, 109, 1017, '1', '2022-09-21 22:43:23', '1', '2022-09-21 22:43:23', b'0', 121); 3836 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1832, 109, 1017, '1', '2022-09-21 22:43:23', '1', '2022-09-21 22:43:23', b'0', 121);
3800 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1833, 109, 1018, '1', '2022-09-21 22:43:23', '1', '2022-09-21 22:43:23', b'0', 121); 3837 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1833, 109, 1018, '1', '2022-09-21 22:43:23', '1', '2022-09-21 22:43:23', b'0', 121);
3801 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1834, 109, 1019, '1', '2022-09-21 22:43:23', '1', '2022-09-21 22:43:23', b'0', 121); 3838 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1834, 109, 1019, '1', '2022-09-21 22:43:23', '1', '2022-09-21 22:43:23', b'0', 121);
3802 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1835, 109, 1020, '1', '2022-09-21 22:43:23', '1', '2022-09-21 22:43:23', b'0', 121); 3839 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1835, 109, 1020, '1', '2022-09-21 22:43:23', '1', '2022-09-21 22:43:23', b'0', 121);
  3840 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1836, 111, 103, '1', '2022-09-21 22:43:24', '1', '2022-09-21 22:43:24', b'0', 122);
  3841 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1837, 111, 1017, '1', '2022-09-21 22:43:24', '1', '2022-09-21 22:43:24', b'0', 122);
  3842 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1838, 111, 1018, '1', '2022-09-21 22:43:24', '1', '2022-09-21 22:43:24', b'0', 122);
  3843 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1839, 111, 1019, '1', '2022-09-21 22:43:24', '1', '2022-09-21 22:43:24', b'0', 122);
  3844 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1840, 111, 1020, '1', '2022-09-21 22:43:24', '1', '2022-09-21 22:43:24', b'0', 122);
3803 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1841, 109, 1036, '1', '2022-09-21 22:48:13', '1', '2022-09-21 22:48:13', b'0', 121); 3845 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1841, 109, 1036, '1', '2022-09-21 22:48:13', '1', '2022-09-21 22:48:13', b'0', 121);
3804 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1842, 109, 1037, '1', '2022-09-21 22:48:13', '1', '2022-09-21 22:48:13', b'0', 121); 3846 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1842, 109, 1037, '1', '2022-09-21 22:48:13', '1', '2022-09-21 22:48:13', b'0', 121);
3805 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1843, 109, 1038, '1', '2022-09-21 22:48:13', '1', '2022-09-21 22:48:13', b'0', 121); 3847 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1843, 109, 1038, '1', '2022-09-21 22:48:13', '1', '2022-09-21 22:48:13', b'0', 121);
3806 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1844, 109, 1039, '1', '2022-09-21 22:48:13', '1', '2022-09-21 22:48:13', b'0', 121); 3848 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1844, 109, 1039, '1', '2022-09-21 22:48:13', '1', '2022-09-21 22:48:13', b'0', 121);
3807 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1845, 109, 107, '1', '2022-09-21 22:48:13', '1', '2022-09-21 22:48:13', b'0', 121); 3849 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1845, 109, 107, '1', '2022-09-21 22:48:13', '1', '2022-09-21 22:48:13', b'0', 121);
  3850 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1846, 111, 1036, '1', '2022-09-21 22:48:13', '1', '2022-09-21 22:48:13', b'0', 122);
  3851 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1847, 111, 1037, '1', '2022-09-21 22:48:13', '1', '2022-09-21 22:48:13', b'0', 122);
  3852 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1848, 111, 1038, '1', '2022-09-21 22:48:13', '1', '2022-09-21 22:48:13', b'0', 122);
  3853 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1849, 111, 1039, '1', '2022-09-21 22:48:13', '1', '2022-09-21 22:48:13', b'0', 122);
  3854 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1850, 111, 107, '1', '2022-09-21 22:48:13', '1', '2022-09-21 22:48:13', b'0', 122);
3808 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1991, 2, 1024, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1); 3855 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1991, 2, 1024, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
3809 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1992, 2, 1025, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1); 3856 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1992, 2, 1025, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
3810 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1993, 2, 1026, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1); 3857 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1993, 2, 1026, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
@@ -3974,6 +4021,18 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t @@ -3974,6 +4021,18 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t
3974 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2938, 109, 1141, '1', '2023-12-02 23:19:40', '1', '2023-12-02 23:19:40', b'0', 121); 4021 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2938, 109, 1141, '1', '2023-12-02 23:19:40', '1', '2023-12-02 23:19:40', b'0', 121);
3975 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2939, 109, 1142, '1', '2023-12-02 23:19:40', '1', '2023-12-02 23:19:40', b'0', 121); 4022 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2939, 109, 1142, '1', '2023-12-02 23:19:40', '1', '2023-12-02 23:19:40', b'0', 121);
3976 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2940, 109, 1143, '1', '2023-12-02 23:19:40', '1', '2023-12-02 23:19:40', b'0', 121); 4023 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2940, 109, 1143, '1', '2023-12-02 23:19:40', '1', '2023-12-02 23:19:40', b'0', 121);
  4024 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2941, 111, 1224, '1', '2023-12-02 23:19:40', '1', '2023-12-02 23:19:40', b'0', 122);
  4025 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2942, 111, 1225, '1', '2023-12-02 23:19:40', '1', '2023-12-02 23:19:40', b'0', 122);
  4026 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2943, 111, 1226, '1', '2023-12-02 23:19:40', '1', '2023-12-02 23:19:40', b'0', 122);
  4027 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2944, 111, 1227, '1', '2023-12-02 23:19:40', '1', '2023-12-02 23:19:40', b'0', 122);
  4028 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2945, 111, 1228, '1', '2023-12-02 23:19:40', '1', '2023-12-02 23:19:40', b'0', 122);
  4029 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2946, 111, 1229, '1', '2023-12-02 23:19:40', '1', '2023-12-02 23:19:40', b'0', 122);
  4030 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2947, 111, 1138, '1', '2023-12-02 23:19:40', '1', '2023-12-02 23:19:40', b'0', 122);
  4031 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2948, 111, 1139, '1', '2023-12-02 23:19:40', '1', '2023-12-02 23:19:40', b'0', 122);
  4032 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2949, 111, 1140, '1', '2023-12-02 23:19:40', '1', '2023-12-02 23:19:40', b'0', 122);
  4033 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2950, 111, 1141, '1', '2023-12-02 23:19:40', '1', '2023-12-02 23:19:40', b'0', 122);
  4034 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2951, 111, 1142, '1', '2023-12-02 23:19:40', '1', '2023-12-02 23:19:40', b'0', 122);
  4035 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2952, 111, 1143, '1', '2023-12-02 23:19:40', '1', '2023-12-02 23:19:40', b'0', 122);
3977 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2993, 109, 2, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 121); 4036 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2993, 109, 2, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 121);
3978 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2994, 109, 1031, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 121); 4037 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2994, 109, 1031, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 121);
3979 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2995, 109, 1032, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 121); 4038 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2995, 109, 1032, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 121);
@@ -4049,11 +4108,91 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t @@ -4049,11 +4108,91 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t
4049 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3066, 109, 1258, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 121); 4108 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3066, 109, 1258, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 121);
4050 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3067, 109, 1259, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 121); 4109 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3067, 109, 1259, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 121);
4051 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3068, 109, 1260, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 121); 4110 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3068, 109, 1260, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 121);
  4111 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3069, 111, 2, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4112 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3070, 111, 1031, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4113 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3071, 111, 1032, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4114 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3072, 111, 1033, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4115 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3073, 111, 1034, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4116 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3074, 111, 1035, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4117 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3075, 111, 1050, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4118 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3076, 111, 1051, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4119 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3077, 111, 1052, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4120 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3078, 111, 1053, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4121 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3079, 111, 1054, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4122 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3080, 111, 1056, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4123 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3081, 111, 1057, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4124 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3082, 111, 1058, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4125 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3083, 111, 1059, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4126 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3084, 111, 1060, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4127 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3085, 111, 1066, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4128 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3086, 111, 1067, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4129 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3087, 111, 1070, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4130 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3088, 111, 1075, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4131 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3090, 111, 1077, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4132 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3091, 111, 1078, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4133 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3092, 111, 1082, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4134 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3093, 111, 1083, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4135 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3094, 111, 1084, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4136 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3095, 111, 1085, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4137 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3096, 111, 1086, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4138 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3097, 111, 1087, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4139 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3098, 111, 1088, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4140 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3099, 111, 1089, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4141 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3100, 111, 1090, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4142 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3101, 111, 1091, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4143 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3102, 111, 1092, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4144 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3103, 111, 106, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4145 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3104, 111, 110, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4146 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3105, 111, 111, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4147 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3106, 111, 112, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4148 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3107, 111, 113, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4149 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3108, 111, 114, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4150 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3109, 111, 115, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4151 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3110, 111, 116, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4152 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3111, 111, 2472, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4153 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3112, 111, 2478, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4154 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3113, 111, 2479, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4155 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3114, 111, 2480, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4156 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3115, 111, 2481, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4157 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3116, 111, 2482, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4158 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3117, 111, 2483, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4159 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3118, 111, 2484, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4160 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3119, 111, 2485, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4161 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3120, 111, 2486, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4162 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3121, 111, 2487, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4163 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3122, 111, 2488, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4164 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3123, 111, 2489, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4165 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3124, 111, 2490, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4166 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3125, 111, 2491, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4167 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3126, 111, 2492, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4168 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3127, 111, 2493, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4169 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3128, 111, 2494, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4170 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3129, 111, 2495, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4171 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3130, 111, 2497, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4172 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3131, 111, 1237, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4173 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3132, 111, 1238, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4174 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3133, 111, 1239, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4175 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3134, 111, 1240, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4176 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3135, 111, 1241, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4177 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3136, 111, 1242, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4178 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3137, 111, 1243, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4179 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3138, 111, 2525, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4180 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3139, 111, 1255, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4181 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3140, 111, 1256, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4182 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3141, 111, 1257, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4183 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3142, 111, 1258, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4184 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3143, 111, 1259, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
  4185 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3144, 111, 1260, '1', '2023-12-02 23:41:02', '1', '2023-12-02 23:41:02', b'0', 122);
4052 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3221, 109, 102, '1', '2023-12-30 11:42:36', '1', '2023-12-30 11:42:36', b'0', 121); 4186 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3221, 109, 102, '1', '2023-12-30 11:42:36', '1', '2023-12-30 11:42:36', b'0', 121);
4053 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3222, 109, 1013, '1', '2023-12-30 11:42:36', '1', '2023-12-30 11:42:36', b'0', 121); 4187 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3222, 109, 1013, '1', '2023-12-30 11:42:36', '1', '2023-12-30 11:42:36', b'0', 121);
4054 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3223, 109, 1014, '1', '2023-12-30 11:42:36', '1', '2023-12-30 11:42:36', b'0', 121); 4188 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3223, 109, 1014, '1', '2023-12-30 11:42:36', '1', '2023-12-30 11:42:36', b'0', 121);
4055 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3224, 109, 1015, '1', '2023-12-30 11:42:36', '1', '2023-12-30 11:42:36', b'0', 121); 4189 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3224, 109, 1015, '1', '2023-12-30 11:42:36', '1', '2023-12-30 11:42:36', b'0', 121);
4056 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3225, 109, 1016, '1', '2023-12-30 11:42:36', '1', '2023-12-30 11:42:36', b'0', 121); 4190 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3225, 109, 1016, '1', '2023-12-30 11:42:36', '1', '2023-12-30 11:42:36', b'0', 121);
  4191 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3226, 111, 102, '1', '2023-12-30 11:42:36', '1', '2023-12-30 11:42:36', b'0', 122);
  4192 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3227, 111, 1013, '1', '2023-12-30 11:42:36', '1', '2023-12-30 11:42:36', b'0', 122);
  4193 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3228, 111, 1014, '1', '2023-12-30 11:42:36', '1', '2023-12-30 11:42:36', b'0', 122);
  4194 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3229, 111, 1015, '1', '2023-12-30 11:42:36', '1', '2023-12-30 11:42:36', b'0', 122);
  4195 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3230, 111, 1016, '1', '2023-12-30 11:42:36', '1', '2023-12-30 11:42:36', b'0', 122);
4057 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4163, 109, 5, '1', '2024-03-30 17:53:17', '1', '2024-03-30 17:53:17', b'0', 121); 4196 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4163, 109, 5, '1', '2024-03-30 17:53:17', '1', '2024-03-30 17:53:17', b'0', 121);
4058 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4164, 109, 1118, '1', '2024-03-30 17:53:17', '1', '2024-03-30 17:53:17', b'0', 121); 4197 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4164, 109, 1118, '1', '2024-03-30 17:53:17', '1', '2024-03-30 17:53:17', b'0', 121);
4059 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4165, 109, 1119, '1', '2024-03-30 17:53:17', '1', '2024-03-30 17:53:17', b'0', 121); 4198 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4165, 109, 1119, '1', '2024-03-30 17:53:17', '1', '2024-03-30 17:53:17', b'0', 121);
@@ -4112,6 +4251,64 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t @@ -4112,6 +4251,64 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t
4112 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4219, 109, 1220, '1', '2024-03-30 17:53:17', '1', '2024-03-30 17:53:17', b'0', 121); 4251 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4219, 109, 1220, '1', '2024-03-30 17:53:17', '1', '2024-03-30 17:53:17', b'0', 121);
4113 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4220, 109, 1221, '1', '2024-03-30 17:53:17', '1', '2024-03-30 17:53:17', b'0', 121); 4252 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4220, 109, 1221, '1', '2024-03-30 17:53:17', '1', '2024-03-30 17:53:17', b'0', 121);
4114 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4221, 109, 1222, '1', '2024-03-30 17:53:17', '1', '2024-03-30 17:53:17', b'0', 121); 4253 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4221, 109, 1222, '1', '2024-03-30 17:53:17', '1', '2024-03-30 17:53:17', b'0', 121);
  4254 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4222, 111, 5, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4255 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4223, 111, 1118, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4256 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4224, 111, 1119, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4257 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4225, 111, 1120, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4258 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4226, 111, 2713, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4259 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4227, 111, 2714, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4260 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4228, 111, 2715, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4261 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4229, 111, 2716, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4262 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4230, 111, 2717, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4263 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4231, 111, 2718, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4264 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4232, 111, 2720, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4265 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4233, 111, 1185, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4266 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4234, 111, 2721, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4267 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4235, 111, 1186, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4268 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4236, 111, 2722, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4269 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4237, 111, 1187, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4270 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4238, 111, 2723, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4271 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4239, 111, 1188, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4272 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4240, 111, 2724, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4273 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4241, 111, 1189, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4274 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4242, 111, 2725, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4275 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4243, 111, 1190, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4276 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4244, 111, 2726, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4277 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4245, 111, 1191, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4278 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4246, 111, 2727, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4279 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4247, 111, 1192, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4280 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4248, 111, 2728, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4281 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4249, 111, 1193, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4282 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4250, 111, 2729, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4283 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4251, 111, 1194, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4284 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4252, 111, 2730, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4285 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4253, 111, 1195, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4286 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4254, 111, 2731, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4287 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4256, 111, 2732, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4288 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4257, 111, 1197, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4289 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4258, 111, 2733, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4290 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4259, 111, 1198, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4291 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4260, 111, 2734, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4292 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4261, 111, 1199, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4293 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4262, 111, 2735, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4294 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4263, 111, 1200, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4295 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4264, 111, 1201, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4296 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4265, 111, 1202, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4297 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4266, 111, 1207, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4298 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4267, 111, 1208, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4299 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4268, 111, 1209, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4300 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4269, 111, 1210, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4301 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4270, 111, 1211, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4302 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4271, 111, 1212, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4303 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4272, 111, 1213, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4304 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4273, 111, 1215, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4305 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4274, 111, 1216, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4306 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4275, 111, 1217, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4307 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4276, 111, 1218, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4308 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4277, 111, 1219, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4309 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4278, 111, 1220, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4310 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4279, 111, 1221, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
  4311 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4280, 111, 1222, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 122);
4115 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5779, 2, 2739, '1', '2024-07-07 20:39:38', '1', '2024-07-07 20:39:38', b'0', 1); 4312 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5779, 2, 2739, '1', '2024-07-07 20:39:38', '1', '2024-07-07 20:39:38', b'0', 1);
4116 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5780, 2, 2740, '1', '2024-07-07 20:39:38', '1', '2024-07-07 20:39:38', b'0', 1); 4313 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5780, 2, 2740, '1', '2024-07-07 20:39:38', '1', '2024-07-07 20:39:38', b'0', 1);
4117 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5781, 2, 2758, '1', '2024-07-07 20:39:38', '1', '2024-07-07 20:39:38', b'0', 1); 4314 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5781, 2, 2758, '1', '2024-07-07 20:39:38', '1', '2024-07-07 20:39:38', b'0', 1);
@@ -4121,6 +4318,8 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t @@ -4121,6 +4318,8 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t
4121 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5785, 2, 2030, '1', '2024-07-07 20:39:38', '1', '2024-07-07 20:39:38', b'0', 1); 4318 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5785, 2, 2030, '1', '2024-07-07 20:39:38', '1', '2024-07-07 20:39:38', b'0', 1);
4122 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5789, 109, 2739, '1', '2024-07-13 22:37:24', '1', '2024-07-13 22:37:24', b'0', 121); 4319 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5789, 109, 2739, '1', '2024-07-13 22:37:24', '1', '2024-07-13 22:37:24', b'0', 121);
4123 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5790, 109, 2740, '1', '2024-07-13 22:37:24', '1', '2024-07-13 22:37:24', b'0', 121); 4320 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5790, 109, 2740, '1', '2024-07-13 22:37:24', '1', '2024-07-13 22:37:24', b'0', 121);
  4321 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5791, 111, 2739, '1', '2024-07-13 22:37:24', '1', '2024-07-13 22:37:24', b'0', 122);
  4322 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5792, 111, 2740, '1', '2024-07-13 22:37:24', '1', '2024-07-13 22:37:24', b'0', 122);
4124 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6053, 155, 4000, '1', '2025-04-01 13:48:26', '1', '2025-04-01 13:48:26', b'0', 1); 4323 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6053, 155, 4000, '1', '2025-04-01 13:48:26', '1', '2025-04-01 13:48:26', b'0', 1);
4125 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6097, 155, 4050, '1', '2025-04-01 13:48:26', '1', '2025-04-01 13:48:26', b'0', 1); 4324 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6097, 155, 4050, '1', '2025-04-01 13:48:26', '1', '2025-04-01 13:48:26', b'0', 1);
4126 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6104, 155, 4032, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1); 4325 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6104, 155, 4032, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1);
@@ -4195,6 +4394,45 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t @@ -4195,6 +4394,45 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t
4195 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6175, 109, 2557, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 121); 4394 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6175, 109, 2557, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 121);
4196 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6176, 109, 2558, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 121); 4395 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6176, 109, 2558, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 121);
4197 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6177, 109, 2559, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 121); 4396 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6177, 109, 2559, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 121);
  4397 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6178, 111, 1117, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4398 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6179, 111, 1126, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4399 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6180, 111, 1127, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4400 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6181, 111, 1128, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4401 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6182, 111, 1129, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4402 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6183, 111, 1130, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4403 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6184, 111, 1132, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4404 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6185, 111, 1133, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4405 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6186, 111, 1134, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4406 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6187, 111, 1135, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4407 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6188, 111, 1136, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4408 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6189, 111, 1137, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4409 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6190, 111, 2161, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4410 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6191, 111, 1150, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4411 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6192, 111, 1161, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4412 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6193, 111, 1162, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4413 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6194, 111, 1166, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4414 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6195, 111, 1173, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4415 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6196, 111, 1174, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4416 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6197, 111, 1178, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4417 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6198, 111, 2745, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4418 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6199, 111, 2746, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4419 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6200, 111, 2747, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4420 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6201, 111, 2748, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4421 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6202, 111, 2301, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4422 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6203, 111, 2302, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4423 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6204, 111, 5011, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4424 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6205, 111, 5012, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4425 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6206, 111, 2549, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4426 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6207, 111, 2550, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4427 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6208, 111, 2551, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4428 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6209, 111, 2552, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4429 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6210, 111, 2553, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4430 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6211, 111, 2554, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4431 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6212, 111, 2555, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4432 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6213, 111, 2556, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4433 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6214, 111, 2557, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4434 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6215, 111, 2558, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
  4435 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6216, 111, 2559, '1', '2025-09-06 20:52:12', '1', '2025-09-06 20:52:12', b'0', 122);
4198 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6217, 109, 2756, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 121); 4436 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6217, 109, 2756, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 121);
4199 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6218, 109, 2757, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 121); 4437 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6218, 109, 2757, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 121);
4200 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6219, 109, 2262, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 121); 4438 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6219, 109, 2262, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 121);
@@ -4233,6 +4471,44 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t @@ -4233,6 +4471,44 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t
4233 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6252, 109, 2335, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 121); 4471 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6252, 109, 2335, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 121);
4234 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6253, 109, 2363, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 121); 4472 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6253, 109, 2363, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 121);
4235 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6254, 109, 2364, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 121); 4473 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6254, 109, 2364, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 121);
  4474 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6255, 111, 2756, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
  4475 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6256, 111, 2757, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
  4476 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6257, 111, 2262, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
  4477 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6258, 111, 2275, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
  4478 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6259, 111, 2276, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
  4479 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6260, 111, 2277, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
  4480 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6261, 111, 2281, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
  4481 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6262, 111, 2282, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
  4482 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6263, 111, 2283, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
  4483 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6264, 111, 2284, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
  4484 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6265, 111, 2285, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
  4485 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6266, 111, 2287, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
  4486 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6267, 111, 2288, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
  4487 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6268, 111, 2293, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
  4488 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6269, 111, 2294, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
  4489 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6270, 111, 2297, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
  4490 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6271, 111, 2300, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
  4491 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6272, 111, 2317, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
  4492 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6273, 111, 2318, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
  4493 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6274, 111, 2319, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
  4494 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6275, 111, 2320, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
  4495 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6276, 111, 2321, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
  4496 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6277, 111, 2322, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
  4497 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6278, 111, 2323, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
  4498 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6279, 111, 2324, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
  4499 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6280, 111, 2325, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
  4500 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6281, 111, 2326, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
  4501 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6282, 111, 2327, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
  4502 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6283, 111, 2328, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
  4503 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6284, 111, 2329, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
  4504 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6285, 111, 2330, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
  4505 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6286, 111, 2331, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
  4506 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6287, 111, 2332, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
  4507 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6288, 111, 2333, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
  4508 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6289, 111, 2334, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
  4509 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6290, 111, 2335, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
  4510 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6291, 111, 2363, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
  4511 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6292, 111, 2364, '1', '2025-09-06 20:52:25', '1', '2025-09-06 20:52:25', b'0', 122);
4236 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6293, 2, 5, '1', '2026-01-04 18:09:41', '1', '2026-01-04 18:09:41', b'0', 1); 4512 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6293, 2, 5, '1', '2026-01-04 18:09:41', '1', '2026-01-04 18:09:41', b'0', 1);
4237 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6294, 2, 1118, '1', '2026-01-04 18:09:41', '1', '2026-01-04 18:09:41', b'0', 1); 4513 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6294, 2, 1118, '1', '2026-01-04 18:09:41', '1', '2026-01-04 18:09:41', b'0', 1);
4238 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6295, 2, 1119, '1', '2026-01-04 18:09:41', '1', '2026-01-04 18:09:41', b'0', 1); 4514 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6295, 2, 1119, '1', '2026-01-04 18:09:41', '1', '2026-01-04 18:09:41', b'0', 1);
@@ -4303,6 +4579,7 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t @@ -4303,6 +4579,7 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t
4303 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6360, 2, 5811, '', '2026-03-30 03:13:05', '', '2026-03-30 03:13:05', b'0', 1); 4579 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6360, 2, 5811, '', '2026-03-30 03:13:05', '', '2026-03-30 03:13:05', b'0', 1);
4304 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6361, 3, 5811, '', '2026-03-30 03:13:05', '', '2026-03-30 03:13:05', b'0', 1); 4580 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6361, 3, 5811, '', '2026-03-30 03:13:05', '', '2026-03-30 03:13:05', b'0', 1);
4305 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6362, 109, 5811, '', '2026-03-30 03:13:05', '', '2026-03-30 03:13:05', b'0', 121); 4581 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6362, 109, 5811, '', '2026-03-30 03:13:05', '', '2026-03-30 03:13:05', b'0', 121);
  4582 +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6363, 111, 5811, '', '2026-03-30 03:13:05', '', '2026-03-30 03:13:05', b'0', 122);
4306 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6364, 155, 5811, '', '2026-03-30 03:13:05', '', '2026-03-30 03:13:05', b'0', 1); 4583 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6364, 155, 5811, '', '2026-03-30 03:13:05', '', '2026-03-30 03:13:05', b'0', 1);
4307 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6365, 2, 6400, '1', '2026-05-09 16:11:01', '1', '2026-05-09 16:11:01', b'0', 1); 4584 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6365, 2, 6400, '1', '2026-05-09 16:11:01', '1', '2026-05-09 16:11:01', b'0', 1);
4308 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6366, 2, 6401, '1', '2026-05-09 16:11:01', '1', '2026-05-09 16:11:01', b'0', 1); 4585 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6366, 2, 6401, '1', '2026-05-09 16:11:01', '1', '2026-05-09 16:11:01', b'0', 1);
@@ -4312,317 +4589,6 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t @@ -4312,317 +4589,6 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t
4312 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6370, 2, 6405, '1', '2026-05-09 16:11:01', '1', '2026-05-09 16:11:01', b'0', 1); 4589 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6370, 2, 6405, '1', '2026-05-09 16:11:01', '1', '2026-05-09 16:11:01', b'0', 1);
4313 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6371, 2, 6406, '1', '2026-05-09 16:11:01', '1', '2026-05-09 16:11:01', b'0', 1); 4590 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6371, 2, 6406, '1', '2026-05-09 16:11:01', '1', '2026-05-09 16:11:01', b'0', 1);
4314 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6380, 2, 6490, '1', '2026-05-14 09:36:12', '1', '2026-05-14 09:36:12', b'0', 1); 4591 INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6380, 2, 6490, '1', '2026-05-14 09:36:12', '1', '2026-05-14 09:36:12', b'0', 1);
4315 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6381, 111, 1, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4316 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6382, 111, 2, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4317 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6383, 111, 5, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4318 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6384, 111, 1031, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4319 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6385, 111, 1032, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4320 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6386, 111, 1033, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4321 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6387, 111, 1034, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4322 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6388, 111, 1035, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4323 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6389, 111, 1036, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4324 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6390, 111, 1037, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4325 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6391, 111, 1038, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4326 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6392, 111, 1039, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4327 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6393, 111, 1050, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4328 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6394, 111, 1051, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4329 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6395, 111, 1052, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4330 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6396, 111, 1053, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4331 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6397, 111, 1054, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4332 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6398, 111, 1056, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4333 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6399, 111, 1057, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4334 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6400, 111, 1058, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4335 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6401, 111, 1059, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4336 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6402, 111, 1060, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4337 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6403, 111, 1063, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4338 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6404, 111, 1064, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4339 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6405, 111, 1065, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4340 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6406, 111, 1066, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4341 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6407, 111, 1067, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4342 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6408, 111, 1070, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4343 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6409, 111, 1075, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4344 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6410, 111, 1077, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4345 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6411, 111, 1078, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4346 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6412, 111, 1082, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4347 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6413, 111, 1083, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4348 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6414, 111, 1084, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4349 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6415, 111, 1085, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4350 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6416, 111, 1086, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4351 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6417, 111, 1087, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4352 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6418, 111, 1088, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4353 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6419, 111, 1089, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4354 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6420, 111, 1090, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4355 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6421, 111, 1091, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4356 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6422, 111, 1092, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4357 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6423, 111, 1117, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4358 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6424, 111, 1118, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4359 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6425, 111, 1119, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4360 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6426, 111, 1120, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4361 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6427, 111, 100, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4362 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6428, 111, 101, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4363 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6429, 111, 102, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4364 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6430, 111, 1126, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4365 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6431, 111, 103, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4366 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6432, 111, 1127, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4367 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6433, 111, 1128, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4368 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6434, 111, 1129, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4369 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6435, 111, 106, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4370 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6436, 111, 1130, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4371 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6437, 111, 107, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4372 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6438, 111, 1132, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4373 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6439, 111, 1133, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4374 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6440, 111, 110, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4375 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6441, 111, 1134, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4376 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6442, 111, 111, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4377 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6443, 111, 1135, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4378 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6444, 111, 112, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4379 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6445, 111, 1136, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4380 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6446, 111, 113, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4381 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6447, 111, 1137, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4382 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6448, 111, 2161, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4383 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6449, 111, 114, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4384 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6450, 111, 1138, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4385 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6451, 111, 1139, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4386 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6452, 111, 115, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4387 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6453, 111, 1140, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4388 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6454, 111, 116, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4389 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6455, 111, 1141, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4390 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6456, 111, 1142, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4391 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6457, 111, 1143, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4392 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6458, 111, 1150, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4393 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6459, 111, 1161, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4394 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6460, 111, 1162, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4395 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6461, 111, 1166, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4396 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6462, 111, 1173, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4397 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6463, 111, 1174, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4398 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6464, 111, 2713, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4399 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6465, 111, 2714, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4400 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6466, 111, 1178, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4401 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6467, 111, 2715, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4402 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6468, 111, 2716, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4403 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6469, 111, 2717, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4404 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6470, 111, 2718, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4405 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6471, 111, 2720, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4406 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6472, 111, 2721, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4407 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6473, 111, 1185, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4408 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6474, 111, 2722, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4409 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6475, 111, 1186, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4410 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6476, 111, 1187, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4411 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6477, 111, 2723, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4412 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6478, 111, 1188, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4413 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6479, 111, 2724, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4414 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6480, 111, 1189, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4415 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6481, 111, 2725, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4416 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6482, 111, 1190, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4417 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6483, 111, 2726, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4418 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6484, 111, 1191, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4419 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6485, 111, 2727, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4420 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6486, 111, 1192, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4421 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6487, 111, 2728, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4422 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6488, 111, 2729, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4423 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6489, 111, 1193, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4424 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6490, 111, 1194, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4425 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6491, 111, 2730, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4426 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6492, 111, 1195, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4427 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6493, 111, 2731, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4428 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6494, 111, 2732, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4429 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6495, 111, 1197, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4430 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6496, 111, 2733, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4431 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6497, 111, 1198, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4432 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6498, 111, 2734, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4433 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6499, 111, 1199, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4434 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6500, 111, 2735, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4435 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6501, 111, 1200, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4436 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6502, 111, 1201, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4437 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6503, 111, 1202, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4438 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6504, 111, 2739, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4439 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6505, 111, 2740, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4440 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6506, 111, 1207, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4441 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6507, 111, 1208, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4442 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6508, 111, 1209, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4443 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6509, 111, 2745, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4444 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6510, 111, 1210, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4445 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6511, 111, 2746, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4446 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6512, 111, 1211, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4447 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6513, 111, 2747, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4448 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6514, 111, 1212, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4449 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6515, 111, 2748, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4450 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6516, 111, 1213, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4451 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6517, 111, 1215, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4452 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6518, 111, 1216, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4453 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6519, 111, 1217, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4454 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6520, 111, 1218, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4455 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6521, 111, 1219, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4456 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6522, 111, 1220, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4457 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6523, 111, 2756, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4458 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6524, 111, 1221, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4459 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6525, 111, 2757, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4460 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6526, 111, 1222, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4461 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6527, 111, 1224, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4462 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6528, 111, 1225, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4463 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6529, 111, 1226, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4464 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6530, 111, 1227, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4465 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6531, 111, 1228, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4466 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6532, 111, 1229, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4467 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6533, 111, 1237, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4468 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6534, 111, 1238, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4469 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6535, 111, 2262, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4470 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6536, 111, 1239, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4471 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6537, 111, 1240, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4472 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6538, 111, 1241, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4473 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6539, 111, 1242, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4474 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6540, 111, 1243, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4475 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6541, 111, 2275, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4476 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6542, 111, 2276, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4477 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6543, 111, 2277, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4478 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6544, 111, 1255, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4479 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6545, 111, 1256, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4480 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6546, 111, 1257, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4481 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6547, 111, 2281, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4482 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6548, 111, 1258, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4483 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6549, 111, 2282, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4484 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6550, 111, 1259, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4485 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6551, 111, 2283, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4486 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6552, 111, 1260, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4487 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6553, 111, 2284, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4488 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6554, 111, 2285, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4489 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6555, 111, 2287, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4490 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6556, 111, 2288, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4491 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6557, 111, 2293, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4492 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6558, 111, 2294, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4493 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6559, 111, 2297, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4494 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6560, 111, 2300, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4495 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6561, 111, 2301, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4496 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6562, 111, 2302, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4497 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6563, 111, 2317, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4498 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6564, 111, 2318, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4499 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6565, 111, 2319, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4500 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6566, 111, 2320, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4501 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6567, 111, 2321, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4502 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6568, 111, 2322, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4503 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6569, 111, 2323, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4504 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6570, 111, 2324, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4505 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6571, 111, 2325, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4506 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6572, 111, 2326, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4507 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6573, 111, 2327, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4508 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6574, 111, 2328, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4509 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6575, 111, 2329, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4510 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6576, 111, 2330, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4511 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6577, 111, 2331, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4512 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6578, 111, 2332, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4513 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6579, 111, 2333, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4514 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6580, 111, 2334, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4515 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6581, 111, 2335, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4516 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6582, 111, 2363, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4517 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6583, 111, 2364, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4518 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6584, 111, 5011, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4519 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6585, 111, 5012, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4520 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6586, 111, 2472, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4521 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6587, 111, 2478, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4522 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6588, 111, 2479, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4523 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6589, 111, 2480, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4524 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6590, 111, 2481, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4525 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6591, 111, 2482, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4526 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6592, 111, 2483, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4527 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6593, 111, 2484, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4528 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6594, 111, 2485, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4529 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6595, 111, 2486, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4530 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6596, 111, 2487, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4531 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6597, 111, 2488, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4532 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6598, 111, 2489, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4533 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6599, 111, 2490, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4534 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6600, 111, 2491, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4535 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6601, 111, 2492, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4536 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6602, 111, 2493, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4537 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6603, 111, 2494, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4538 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6604, 111, 2495, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4539 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6605, 111, 2497, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4540 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6606, 111, 2525, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4541 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6607, 111, 1001, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4542 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6608, 111, 1002, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4543 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6609, 111, 1003, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4544 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6610, 111, 1004, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4545 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6611, 111, 1005, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4546 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6612, 111, 1006, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4547 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6613, 111, 1007, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4548 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6614, 111, 1008, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4549 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6615, 111, 1009, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4550 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6616, 111, 1010, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4551 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6617, 111, 1011, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4552 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6618, 111, 1012, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4553 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6619, 111, 1013, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4554 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6620, 111, 2549, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4555 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6621, 111, 1014, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4556 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6622, 111, 2550, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4557 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6623, 111, 1015, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4558 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6624, 111, 2551, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4559 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6625, 111, 1016, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4560 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6626, 111, 2552, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4561 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6627, 111, 1017, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4562 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6628, 111, 2553, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4563 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6629, 111, 1018, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4564 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6630, 111, 2554, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4565 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6631, 111, 1019, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4566 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6632, 111, 2555, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4567 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6633, 111, 1020, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4568 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6634, 111, 2556, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4569 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6635, 111, 2557, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4570 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6636, 111, 2558, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4571 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6637, 111, 2559, '1', '2026-06-01 23:29:35', '1', '2026-06-01 23:29:35', b'0', 122);  
4572 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6638, 155, 5780, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4573 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6639, 155, 2084, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4574 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6640, 155, 2085, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4575 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6641, 155, 2086, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4576 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6642, 155, 2087, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4577 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6643, 155, 2088, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4578 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6644, 155, 2089, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4579 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6645, 155, 2090, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4580 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6646, 155, 2091, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4581 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6647, 155, 2092, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4582 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6648, 155, 2093, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4583 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6649, 155, 5805, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4584 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6650, 155, 2094, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4585 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6651, 155, 2095, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4586 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6652, 155, 2096, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4587 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6653, 155, 2097, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4588 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6654, 155, 2098, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4589 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6655, 155, 5042, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4590 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6656, 155, 2099, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4591 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6657, 155, 5043, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4592 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6658, 155, 2100, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4593 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6659, 155, 5044, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4594 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6660, 155, 2101, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4595 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6661, 155, 5045, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4596 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6662, 155, 2102, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4597 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6663, 155, 5046, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4598 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6664, 155, 2103, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4599 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6665, 155, 2104, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4600 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6666, 155, 2105, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4601 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6667, 155, 2106, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4602 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6668, 155, 2107, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4603 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6669, 155, 2108, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4604 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6670, 155, 2109, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4605 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6671, 155, 2110, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4606 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6672, 155, 2111, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4607 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6673, 155, 2112, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4608 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6674, 155, 2113, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4609 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6675, 155, 2114, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4610 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6676, 155, 2115, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4611 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6677, 155, 2116, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4612 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6678, 155, 2117, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4613 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6679, 155, 2118, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4614 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6680, 155, 2119, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4615 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6681, 155, 2120, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4616 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6682, 155, 2121, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4617 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6683, 155, 2122, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4618 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6684, 155, 2123, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4619 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6685, 155, 2124, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4620 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6686, 155, 2125, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4621 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6687, 155, 2126, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4622 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6688, 155, 2127, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4623 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6689, 155, 2128, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4624 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6690, 155, 2129, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4625 -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6691, 155, 5100, '1', '2026-06-10 09:04:18', '1', '2026-06-10 09:04:18', b'0', 1);  
4626 COMMIT; 4592 COMMIT;
4627 4593
4628 -- ---------------------------- 4594 -- ----------------------------
@@ -4677,7 +4643,7 @@ CREATE TABLE `system_sms_code` ( @@ -4677,7 +4643,7 @@ CREATE TABLE `system_sms_code` (
4677 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', 4643 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
4678 PRIMARY KEY (`id`) USING BTREE, 4644 PRIMARY KEY (`id`) USING BTREE,
4679 INDEX `idx_mobile`(`mobile` ASC) USING BTREE COMMENT '手机号' 4645 INDEX `idx_mobile`(`mobile` ASC) USING BTREE COMMENT '手机号'
4680 -) ENGINE = InnoDB AUTO_INCREMENT = 694 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '手机验证码'; 4646 +) ENGINE = InnoDB AUTO_INCREMENT = 690 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '手机验证码';
4681 4647
4682 -- ---------------------------- 4648 -- ----------------------------
4683 -- Records of system_sms_code 4649 -- Records of system_sms_code
@@ -4718,7 +4684,7 @@ CREATE TABLE `system_sms_log` ( @@ -4718,7 +4684,7 @@ CREATE TABLE `system_sms_log` (
4718 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', 4684 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
4719 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', 4685 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
4720 PRIMARY KEY (`id`) USING BTREE 4686 PRIMARY KEY (`id`) USING BTREE
4721 -) ENGINE = InnoDB AUTO_INCREMENT = 1568 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '短信日志'; 4687 +) ENGINE = InnoDB AUTO_INCREMENT = 1553 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '短信日志';
4722 4688
4723 -- ---------------------------- 4689 -- ----------------------------
4724 -- Records of system_sms_log 4690 -- Records of system_sms_log
@@ -4895,7 +4861,7 @@ CREATE TABLE `system_tenant` ( @@ -4895,7 +4861,7 @@ CREATE TABLE `system_tenant` (
4895 BEGIN; 4861 BEGIN;
4896 INSERT INTO `system_tenant` (`id`, `name`, `contact_user_id`, `contact_name`, `contact_mobile`, `status`, `websites`, `package_id`, `expire_time`, `account_count`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '芋道源码', NULL, '芋艿', '17321315478', 0, 'www.iocoder.cn,127.0.0.1:3000,wxc4598c446f8a9cb3', 0, '2099-02-19 17:14:16', 9999, '1', '2021-01-05 17:03:47', '1', '2025-08-19 05:18:41', b'0'); 4862 INSERT INTO `system_tenant` (`id`, `name`, `contact_user_id`, `contact_name`, `contact_mobile`, `status`, `websites`, `package_id`, `expire_time`, `account_count`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '芋道源码', NULL, '芋艿', '17321315478', 0, 'www.iocoder.cn,127.0.0.1:3000,wxc4598c446f8a9cb3', 0, '2099-02-19 17:14:16', 9999, '1', '2021-01-05 17:03:47', '1', '2025-08-19 05:18:41', b'0');
4897 INSERT INTO `system_tenant` (`id`, `name`, `contact_user_id`, `contact_name`, `contact_mobile`, `status`, `websites`, `package_id`, `expire_time`, `account_count`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (121, '小租户', 110, '小王2', '15601691300', 0, 'zsxq.iocoder.cn,123321', 111, '2026-07-10 00:00:00', 30, '1', '2022-02-22 00:56:14', '1', '2025-08-19 21:19:29', b'0'); 4863 INSERT INTO `system_tenant` (`id`, `name`, `contact_user_id`, `contact_name`, `contact_mobile`, `status`, `websites`, `package_id`, `expire_time`, `account_count`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (121, '小租户', 110, '小王2', '15601691300', 0, 'zsxq.iocoder.cn,123321', 111, '2026-07-10 00:00:00', 30, '1', '2022-02-22 00:56:14', '1', '2025-08-19 21:19:29', b'0');
4898 -INSERT INTO `system_tenant` (`id`, `name`, `contact_user_id`, `contact_name`, `contact_mobile`, `status`, `websites`, `package_id`, `expire_time`, `account_count`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (122, '测试租户', 113, '芋道', '15601691300', 0, 'test.iocoder.cn,222,333', 111, '2023-04-29 00:00:00', 50, '1', '2022-03-07 21:37:58', '1', '2026-06-01 23:29:35', b'0'); 4864 +INSERT INTO `system_tenant` (`id`, `name`, `contact_user_id`, `contact_name`, `contact_mobile`, `status`, `websites`, `package_id`, `expire_time`, `account_count`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (122, '测试租户', 113, '芋道', '15601691300', 0, 'test.iocoder.cn,222,333', 111, '2023-04-29 00:00:00', 50, '1', '2022-03-07 21:37:58', '1', '2025-12-21 09:50:00', b'0');
4899 COMMIT; 4865 COMMIT;
4900 4866
4901 -- ---------------------------- 4867 -- ----------------------------
@@ -4914,14 +4880,13 @@ CREATE TABLE `system_tenant_package` ( @@ -4914,14 +4880,13 @@ CREATE TABLE `system_tenant_package` (
4914 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', 4880 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
4915 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', 4881 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
4916 PRIMARY KEY (`id`) USING BTREE 4882 PRIMARY KEY (`id`) USING BTREE
4917 -) ENGINE = InnoDB AUTO_INCREMENT = 114 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '租户套餐表'; 4883 +) ENGINE = InnoDB AUTO_INCREMENT = 113 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '租户套餐表';
4918 4884
4919 -- ---------------------------- 4885 -- ----------------------------
4920 -- Records of system_tenant_package 4886 -- Records of system_tenant_package
4921 -- ---------------------------- 4887 -- ----------------------------
4922 BEGIN; 4888 BEGIN;
4923 INSERT INTO `system_tenant_package` (`id`, `name`, `status`, `remark`, `menu_ids`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (111, '普通套餐', 0, '小功能', '[1,2,5,1031,1032,1033,1034,1035,1036,1037,1038,1039,1050,1051,1052,1053,1054,1056,1057,1058,1059,1060,1063,1064,1065,1066,1067,1070,1075,1077,1078,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1117,1118,1119,1120,100,101,102,1126,103,1127,1128,1129,106,1130,107,1132,1133,110,1134,111,1135,112,1136,113,1137,2161,114,1138,1139,115,1140,116,1141,1142,1143,1150,1161,1162,1166,1173,1174,2713,2714,1178,2715,2716,2717,2718,2720,2721,1185,2722,1186,1187,2723,1188,2724,1189,2725,1190,2726,1191,2727,1192,2728,2729,1193,1194,2730,1195,2731,2732,1197,2733,1198,2734,1199,2735,1200,1201,1202,2739,2740,1207,1208,1209,2745,1210,2746,1211,2747,1212,2748,1213,1215,1216,1217,1218,1219,1220,2756,1221,2757,1222,1224,1225,1226,1227,1228,1229,1237,1238,2262,1239,1240,1241,1242,1243,2275,2276,2277,1255,1256,1257,2281,1258,2282,1259,2283,1260,2284,2285,2287,2288,2293,2294,2297,2300,2301,2302,2317,2318,2319,2320,2321,2322,2323,2324,2325,2326,2327,2328,2329,2330,2331,2332,2333,2334,2335,2363,2364,5011,5012,2472,2478,2479,2480,2481,2482,2483,2484,2485,2486,2487,2488,2489,2490,2491,2492,2493,2494,2495,2497,2525,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1013,2549,1014,2550,1015,2551,1016,2552,1017,2553,1018,2554,1019,2555,1020,2556,2557,2558,2559]', '1', '2022-02-22 00:54:00', '1', '2025-09-06 20:52:25', b'0'); 4889 INSERT INTO `system_tenant_package` (`id`, `name`, `status`, `remark`, `menu_ids`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (111, '普通套餐', 0, '小功能', '[1,2,5,1031,1032,1033,1034,1035,1036,1037,1038,1039,1050,1051,1052,1053,1054,1056,1057,1058,1059,1060,1063,1064,1065,1066,1067,1070,1075,1077,1078,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1117,1118,1119,1120,100,101,102,1126,103,1127,1128,1129,106,1130,107,1132,1133,110,1134,111,1135,112,1136,113,1137,2161,114,1138,1139,115,1140,116,1141,1142,1143,1150,1161,1162,1166,1173,1174,2713,2714,1178,2715,2716,2717,2718,2720,2721,1185,2722,1186,1187,2723,1188,2724,1189,2725,1190,2726,1191,2727,1192,2728,2729,1193,1194,2730,1195,2731,2732,1197,2733,1198,2734,1199,2735,1200,1201,1202,2739,2740,1207,1208,1209,2745,1210,2746,1211,2747,1212,2748,1213,1215,1216,1217,1218,1219,1220,2756,1221,2757,1222,1224,1225,1226,1227,1228,1229,1237,1238,2262,1239,1240,1241,1242,1243,2275,2276,2277,1255,1256,1257,2281,1258,2282,1259,2283,1260,2284,2285,2287,2288,2293,2294,2297,2300,2301,2302,2317,2318,2319,2320,2321,2322,2323,2324,2325,2326,2327,2328,2329,2330,2331,2332,2333,2334,2335,2363,2364,5011,5012,2472,2478,2479,2480,2481,2482,2483,2484,2485,2486,2487,2488,2489,2490,2491,2492,2493,2494,2495,2497,2525,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1013,2549,1014,2550,1015,2551,1016,2552,1017,2553,1018,2554,1019,2555,1020,2556,2557,2558,2559]', '1', '2022-02-22 00:54:00', '1', '2025-09-06 20:52:25', b'0');
4924 -INSERT INTO `system_tenant_package` (`id`, `name`, `status`, `remark`, `menu_ids`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (113, '测试套餐(啥都没有)', 0, '', '[2160,1254,2159]', '1', '2026-06-01 23:22:39', '1', '2026-06-09 14:44:00', b'0');  
4925 COMMIT; 4890 COMMIT;
4926 4891
4927 -- ---------------------------- 4892 -- ----------------------------
@@ -5039,26 +5004,26 @@ CREATE TABLE `system_users` ( @@ -5039,26 +5004,26 @@ CREATE TABLE `system_users` (
5039 -- Records of system_users 5004 -- Records of system_users
5040 -- ---------------------------- 5005 -- ----------------------------
5041 BEGIN; 5006 BEGIN;
5042 -INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, 'admin', '$2a$04$.vd8nPeLwxt6hnSzmAoAyul8BOLX7Cib6QhcxRe30rfvrIPQHH1OG', '芋道源码', '管理员', 103, '[1,2]', '13aoteman@126.com', '18818260272', 1, 'http://test.yudao.iocoder.cn/20260517/blob_1778998103688.png', 0, '0:0:0:0:0:0:0:1', '2026-06-19 18:38:00', 'admin', '2021-01-05 17:03:47', NULL, '2026-06-19 18:38:00', b'0', 1);  
5043 -INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (100, 'yudao', '$2a$04$.vd8nPeLwxt6hnSzmAoAyul8BOLX7Cib6QhcxRe30rfvrIPQHH1OG', '芋道', '不要吓我', 104, '[1]', 'yudao@iocoder.cn', '15601691300', 1, NULL, 0, '127.0.0.1', '2026-06-17 09:37:17', '', '2021-01-07 09:07:17', NULL, '2026-06-17 09:37:17', b'0', 1); 5007 +INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, 'admin', '$2a$04$.vd8nPeLwxt6hnSzmAoAyul8BOLX7Cib6QhcxRe30rfvrIPQHH1OG', '芋道源码', '管理员', 103, '[1,2]', '13aoteman@126.com', '18818260272', 1, 'http://test.yudao.iocoder.cn/20260517/blob_1778998103688.png', 0, '0:0:0:0:0:0:0:1', '2026-05-31 21:54:49', 'admin', '2021-01-05 17:03:47', NULL, '2026-05-31 21:54:49', b'0', 1);
  5008 +INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (100, 'yudao', '$2a$04$.vd8nPeLwxt6hnSzmAoAyul8BOLX7Cib6QhcxRe30rfvrIPQHH1OG', '芋道', '不要吓我', 104, '[1]', 'yudao@iocoder.cn', '15601691300', 1, NULL, 0, '0:0:0:0:0:0:0:1', '2026-04-19 17:40:55', '', '2021-01-07 09:07:17', NULL, '2026-04-19 17:40:55', b'0', 1);
5044 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (103, 'yuanma', '$2a$04$k/d6mc0nySN0i2udwcI8Ee8V5aM5OHixBRbQfXmPuFTUl3Zf/DBs.', '源码', NULL, 106, NULL, 'yuanma@iocoder.cn', '15601701300', 0, NULL, 0, '0:0:0:0:0:0:0:1', '2026-04-27 13:19:27', '', '2021-01-13 23:50:35', NULL, '2026-04-27 13:19:27', b'0', 1); 5009 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (103, 'yuanma', '$2a$04$k/d6mc0nySN0i2udwcI8Ee8V5aM5OHixBRbQfXmPuFTUl3Zf/DBs.', '源码', NULL, 106, NULL, 'yuanma@iocoder.cn', '15601701300', 0, NULL, 0, '0:0:0:0:0:0:0:1', '2026-04-27 13:19:27', '', '2021-01-13 23:50:35', NULL, '2026-04-27 13:19:27', b'0', 1);
5045 -INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (104, 'test', '$2a$04$BrwaYn303hjA/6TnXqdGoOLhyHOAA0bVrAFu6.1dJKycqKUnIoRz2', '测试号', NULL, 107, '[1,2]', '111@qq.com', '15601691200', 1, NULL, 0, '0:0:0:0:0:0:0:1', '2026-06-16 11:37:56', '', '2021-01-21 02:13:53', NULL, '2026-06-16 11:37:56', b'0', 1); 5010 +INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (104, 'test', '$2a$04$BrwaYn303hjA/6TnXqdGoOLhyHOAA0bVrAFu6.1dJKycqKUnIoRz2', '测试号', NULL, 107, '[1,2]', '111@qq.com', '15601691200', 1, NULL, 0, '0:0:0:0:0:0:0:1', '2026-05-20 23:37:11', '', '2021-01-21 02:13:53', NULL, '2026-05-20 23:37:11', b'0', 1);
5046 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (107, 'admin107', '$2a$10$dYOOBKMO93v/.ReCqzyFg.o67Tqk.bbc2bhrpyBGkIw9aypCtr2pm', '芋艿', NULL, NULL, NULL, '', '15601691300', 0, NULL, 0, '', NULL, '1', '2022-02-20 22:59:33', '1', '2025-04-21 14:23:08', b'0', 118); 5011 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (107, 'admin107', '$2a$10$dYOOBKMO93v/.ReCqzyFg.o67Tqk.bbc2bhrpyBGkIw9aypCtr2pm', '芋艿', NULL, NULL, NULL, '', '15601691300', 0, NULL, 0, '', NULL, '1', '2022-02-20 22:59:33', '1', '2025-04-21 14:23:08', b'0', 118);
5047 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (108, 'admin108', '$2a$10$y6mfvKoNYL1GXWak8nYwVOH.kCWqjactkzdoIDgiKl93WN3Ejg.Lu', '芋艿', NULL, NULL, NULL, '', '15601691300', 0, NULL, 0, '', NULL, '1', '2022-02-20 23:00:50', '1', '2025-04-21 14:23:08', b'0', 119); 5012 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (108, 'admin108', '$2a$10$y6mfvKoNYL1GXWak8nYwVOH.kCWqjactkzdoIDgiKl93WN3Ejg.Lu', '芋艿', NULL, NULL, NULL, '', '15601691300', 0, NULL, 0, '', NULL, '1', '2022-02-20 23:00:50', '1', '2025-04-21 14:23:08', b'0', 119);
5048 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (109, 'admin109', '$2a$10$JAqvH0tEc0I7dfDVBI7zyuB4E3j.uH6daIjV53.vUS6PknFkDJkuK', '芋艿', NULL, NULL, NULL, '', '15601691300', 0, NULL, 0, '', NULL, '1', '2022-02-20 23:11:50', '1', '2025-04-21 14:23:08', b'0', 120); 5013 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (109, 'admin109', '$2a$10$JAqvH0tEc0I7dfDVBI7zyuB4E3j.uH6daIjV53.vUS6PknFkDJkuK', '芋艿', NULL, NULL, NULL, '', '15601691300', 0, NULL, 0, '', NULL, '1', '2022-02-20 23:11:50', '1', '2025-04-21 14:23:08', b'0', 120);
5049 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (110, 'admin110', '$2a$10$mRMIYLDtRHlf6.9ipiqH1.Z.bh/R9dO9d5iHiGYPigi6r5KOoR2Wm', '小王', NULL, NULL, NULL, '', '15601691300', 0, NULL, 0, '0:0:0:0:0:0:0:1', '2024-07-20 22:23:17', '1', '2022-02-22 00:56:14', NULL, '2025-04-21 14:23:08', b'0', 121); 5014 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (110, 'admin110', '$2a$10$mRMIYLDtRHlf6.9ipiqH1.Z.bh/R9dO9d5iHiGYPigi6r5KOoR2Wm', '小王', NULL, NULL, NULL, '', '15601691300', 0, NULL, 0, '0:0:0:0:0:0:0:1', '2024-07-20 22:23:17', '1', '2022-02-22 00:56:14', NULL, '2025-04-21 14:23:08', b'0', 121);
5050 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (111, 'test', '$2a$10$mRMIYLDtRHlf6.9ipiqH1.Z.bh/R9dO9d5iHiGYPigi6r5KOoR2Wm', '测试用户', NULL, NULL, '[]', '', '', 0, NULL, 0, '0:0:0:0:0:0:0:1', '2023-12-30 11:42:17', '110', '2022-02-23 13:14:33', NULL, '2025-04-21 14:23:08', b'0', 121); 5015 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (111, 'test', '$2a$10$mRMIYLDtRHlf6.9ipiqH1.Z.bh/R9dO9d5iHiGYPigi6r5KOoR2Wm', '测试用户', NULL, NULL, '[]', '', '', 0, NULL, 0, '0:0:0:0:0:0:0:1', '2023-12-30 11:42:17', '110', '2022-02-23 13:14:33', NULL, '2025-04-21 14:23:08', b'0', 121);
5051 -INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (112, 'newobject', '$2a$04$dB0z8Q819fJWz0hbaLe6B.VfHCjYgWx6LFfET5lyz3JwcqlyCkQ4C', '新对象', NULL, 100, '[]', '', '15601691235', 1, NULL, 0, '127.0.0.1', '2026-06-17 09:07:20', '1', '2022-02-23 19:08:03', NULL, '2026-06-17 09:07:20', b'0', 1); 5016 +INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (112, 'newobject', '$2a$04$dB0z8Q819fJWz0hbaLe6B.VfHCjYgWx6LFfET5lyz3JwcqlyCkQ4C', '新对象', NULL, 100, '[]', '', '15601691235', 1, NULL, 0, '0:0:0:0:0:0:0:1', '2024-03-16 23:11:38', '1', '2022-02-23 19:08:03', NULL, '2025-04-21 14:23:08', b'0', 1);
5052 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (113, 'aoteman', '$2a$10$0acJOIk2D25/oC87nyclE..0lzeu9DtQ/n3geP4fkun/zIVRhHJIO', '芋道1', NULL, NULL, NULL, '', '15601691300', 0, NULL, 0, '127.0.0.1', '2022-03-19 18:38:51', '1', '2022-03-07 21:37:58', '1', '2025-05-05 15:30:53', b'0', 122); 5017 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (113, 'aoteman', '$2a$10$0acJOIk2D25/oC87nyclE..0lzeu9DtQ/n3geP4fkun/zIVRhHJIO', '芋道1', NULL, NULL, NULL, '', '15601691300', 0, NULL, 0, '127.0.0.1', '2022-03-19 18:38:51', '1', '2022-03-07 21:37:58', '1', '2025-05-05 15:30:53', b'0', 122);
5053 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (114, 'hrmgr', '$2a$10$TR4eybBioGRhBmDBWkqWLO6NIh3mzYa8KBKDDB5woiGYFVlRAi.fu', 'hr 小姐姐', NULL, NULL, '[5]', '', '15601691236', 1, NULL, 0, '0:0:0:0:0:0:0:1', '2026-01-04 18:16:01', '1', '2022-03-19 21:50:58', NULL, '2026-01-04 18:16:01', b'0', 1); 5018 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (114, 'hrmgr', '$2a$10$TR4eybBioGRhBmDBWkqWLO6NIh3mzYa8KBKDDB5woiGYFVlRAi.fu', 'hr 小姐姐', NULL, NULL, '[5]', '', '15601691236', 1, NULL, 0, '0:0:0:0:0:0:0:1', '2026-01-04 18:16:01', '1', '2022-03-19 21:50:58', NULL, '2026-01-04 18:16:01', b'0', 1);
5054 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (115, 'aotemane', '$2a$04$GcyP0Vyzb2F2Yni5PuIK9ueGxM0tkZGMtDwVRwrNbtMvorzbpNsV2', '阿呆', '11222', 102, '[1,2]', '7648@qq.com', '15601691229', 2, NULL, 0, '', NULL, '1', '2022-04-30 02:55:43', '1', '2025-04-21 14:23:08', b'0', 1); 5019 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (115, 'aotemane', '$2a$04$GcyP0Vyzb2F2Yni5PuIK9ueGxM0tkZGMtDwVRwrNbtMvorzbpNsV2', '阿呆', '11222', 102, '[1,2]', '7648@qq.com', '15601691229', 2, NULL, 0, '', NULL, '1', '2022-04-30 02:55:43', '1', '2025-04-21 14:23:08', b'0', 1);
5055 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (117, 'admin123', '$2a$04$sEtimsHu9YCkYY4/oqElHem2Ijc9ld20eYO6lN.g/21NfLUTDLB9W', '测试号02', '1111', 100, '[2]', '', '15601691234', 1, NULL, 0, '0:0:0:0:0:0:0:1', '2024-10-02 10:16:20', '1', '2022-07-09 17:40:26', '1', '2025-05-14 09:56:04', b'0', 1); 5020 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (117, 'admin123', '$2a$04$sEtimsHu9YCkYY4/oqElHem2Ijc9ld20eYO6lN.g/21NfLUTDLB9W', '测试号02', '1111', 100, '[2]', '', '15601691234', 1, NULL, 0, '0:0:0:0:0:0:0:1', '2024-10-02 10:16:20', '1', '2022-07-09 17:40:26', '1', '2025-05-14 09:56:04', b'0', 1);
5056 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (118, 'goudan', '$2a$04$3suGZjnA6rM5bErf38u1felbgqbsPHGdRG3l9NkxPCEt2ah9Y6aJi', '狗蛋', NULL, 103, '[1]', '', '15601691239', 1, NULL, 0, '0:0:0:0:0:0:0:1', '2025-11-23 15:28:25', '1', '2022-07-09 17:44:43', NULL, '2025-11-23 15:28:25', b'0', 1); 5021 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (118, 'goudan', '$2a$04$3suGZjnA6rM5bErf38u1felbgqbsPHGdRG3l9NkxPCEt2ah9Y6aJi', '狗蛋', NULL, 103, '[1]', '', '15601691239', 1, NULL, 0, '0:0:0:0:0:0:0:1', '2025-11-23 15:28:25', '1', '2022-07-09 17:44:43', NULL, '2025-11-23 15:28:25', b'0', 1);
5057 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (139, 'wwbwwb', '$2a$04$FJLIyg8lbPytP29pbZaiU.LesJvCsYfEaHqQfB0pGQhK3e9BeZmLy', '小秃头', '123', 108, '[2,4]', '', '', 1, NULL, 0, '0:0:0:0:0:0:0:1', '2024-09-10 21:03:58', NULL, '2024-09-10 21:03:58', '1', '2025-12-15 22:38:15', b'0', 1); 5022 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (139, 'wwbwwb', '$2a$04$FJLIyg8lbPytP29pbZaiU.LesJvCsYfEaHqQfB0pGQhK3e9BeZmLy', '小秃头', '123', 108, '[2,4]', '', '', 1, NULL, 0, '0:0:0:0:0:0:0:1', '2024-09-10 21:03:58', NULL, '2024-09-10 21:03:58', '1', '2025-12-15 22:38:15', b'0', 1);
5058 -INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (141, 'admin1', '$2a$04$oj6F6d7HrZ70kYVD3TNzEu.m3TPUzajOVuC66zdKna8KRerK1FmVa', '新用户', NULL, NULL, NULL, '', '', 0, '', 0, '127.0.0.1', '2026-06-17 09:37:18', '1', '2025-04-08 13:09:07', NULL, '2026-06-17 09:37:18', b'0', 1);  
5059 -INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (142, 'test01', '$2a$04$4bCYWZkjxxOC4QE0LY2M9uEEKWeJbLfs489NFtQoyidL5I0FndRaO', 'test01', '', NULL, '[]', '', '19021719925', 1, '', 0, '0:0:0:0:0:0:0:1', '2026-06-17 10:44:58', '1', '2025-07-09 21:07:10', NULL, '2026-06-17 10:44:58', b'0', 1); 5023 +INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (141, 'admin1', '$2a$04$oj6F6d7HrZ70kYVD3TNzEu.m3TPUzajOVuC66zdKna8KRerK1FmVa', '新用户', NULL, NULL, NULL, '', '', 0, '', 0, '0:0:0:0:0:0:0:1', '2025-04-08 13:09:07', '1', '2025-04-08 13:09:07', '1', '2025-05-14 19:11:48', b'0', 1);
  5024 +INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (142, 'test01', '$2a$04$4bCYWZkjxxOC4QE0LY2M9uEEKWeJbLfs489NFtQoyidL5I0FndRaO', 'test01', '', NULL, '[]', '', '19021719925', 1, '', 0, '0:0:0:0:0:0:0:1', '2025-07-29 19:47:17', '1', '2025-07-09 21:07:10', NULL, '2025-12-02 13:23:11', b'0', 1);
5060 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (143, 'a00001', '$2a$04$GhVHFviOw/SsTmiQtifHJesDYFlHMeGK7OWh7aGCCjGGVCmbHVAwa', 'a00001', NULL, 104, NULL, '', '', 0, '', 0, '0:0:0:0:0:0:0:1', '2025-12-01 16:10:13', NULL, '2025-12-01 16:10:13', '1', '2025-12-05 21:34:05', b'0', 1); 5025 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (143, 'a00001', '$2a$04$GhVHFviOw/SsTmiQtifHJesDYFlHMeGK7OWh7aGCCjGGVCmbHVAwa', 'a00001', NULL, 104, NULL, '', '', 0, '', 0, '0:0:0:0:0:0:0:1', '2025-12-01 16:10:13', NULL, '2025-12-01 16:10:13', '1', '2025-12-05 21:34:05', b'0', 1);
5061 -INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (144, 'aoteman001', '$2a$04$omQOmhz8OyUFBKw77nr8KOtMp6xdvoQ1gWStjk9r8.OYT3Bv6oEYe', 'aoteman00112', NULL, 104, NULL, '', '', 0, '', 1, '0:0:0:0:0:0:0:1', '2025-12-01 17:05:27', '1', '2025-12-01 17:05:27', '1', '2026-06-15 18:58:56', b'0', 1); 5026 +INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (144, 'aoteman001', '$2a$04$omQOmhz8OyUFBKw77nr8KOtMp6xdvoQ1gWStjk9r8.OYT3Bv6oEYe', 'aoteman001', NULL, 104, NULL, '', '', 0, '', 1, '0:0:0:0:0:0:0:1', '2025-12-01 17:05:27', '1', '2025-12-01 17:05:27', '1', '2026-05-31 21:52:48', b'0', 1);
5062 COMMIT; 5027 COMMIT;
5063 5028
5064 -- ---------------------------- 5029 -- ----------------------------
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/ImConversationReadController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.im.controller.admin.conversation;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  5 +import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationReadRespVO;
  6 +import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ImConversationReadDO;
  7 +import cn.iocoder.yudao.module.im.service.conversation.ImConversationReadService;
  8 +import io.swagger.v3.oas.annotations.Operation;
  9 +import io.swagger.v3.oas.annotations.Parameter;
  10 +import io.swagger.v3.oas.annotations.Parameters;
  11 +import io.swagger.v3.oas.annotations.tags.Tag;
  12 +import jakarta.annotation.Resource;
  13 +import jakarta.validation.constraints.Max;
  14 +import jakarta.validation.constraints.Min;
  15 +import org.springframework.validation.annotation.Validated;
  16 +import org.springframework.web.bind.annotation.GetMapping;
  17 +import org.springframework.web.bind.annotation.RequestMapping;
  18 +import org.springframework.web.bind.annotation.RequestParam;
  19 +import org.springframework.web.bind.annotation.RestController;
  20 +
  21 +import java.util.List;
  22 +
  23 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  24 +import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId;
  25 +
  26 +@Tag(name = "管理后台 - IM 会话读位置")
  27 +@RestController
  28 +@RequestMapping("/im/conversation-read")
  29 +@Validated
  30 +public class ImConversationReadController {
  31 +
  32 + @Resource
  33 + private ImConversationReadService conversationReadService;
  34 +
  35 + @GetMapping("/pull")
  36 + @Operation(summary = "增量拉取当前用户的会话读位置(重连 / 离线补偿)")
  37 + @Parameters({
  38 + @Parameter(name = "lastUpdateTime", description = "上次拉取到的最新更新时间(毫秒时间戳);首次拉取不传"),
  39 + @Parameter(name = "lastId", description = "上次拉取到的最后一条记录 id;首次拉取不传"),
  40 + @Parameter(name = "limit", description = "单次拉取条数", required = true)
  41 + })
  42 + public CommonResult<List<ImConversationReadRespVO>> pullMyConversationRead(
  43 + @RequestParam(value = "lastUpdateTime", required = false) Long lastUpdateTime,
  44 + @RequestParam(value = "lastId", required = false) Long lastId,
  45 + @RequestParam("limit") @Min(1) @Max(200) Integer limit) {
  46 + List<ImConversationReadDO> list = conversationReadService.pullConversationReadList(
  47 + getLoginUserId(), lastUpdateTime, lastId, limit);
  48 + return success(BeanUtils.toBean(list, ImConversationReadRespVO.class));
  49 + }
  50 +
  51 +}
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ImConversationReadRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.im.controller.admin.conversation.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.time.LocalDateTime;
  7 +
  8 +/**
  9 + * IM 会话读位置 Response VO
  10 + *
  11 + * @author 芋道源码
  12 + */
  13 +@Schema(description = "管理后台 - IM 会话读位置 Response VO")
  14 +@Data
  15 +public class ImConversationReadRespVO {
  16 +
  17 + @Schema(description = "读位置编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  18 + private Long id;
  19 +
  20 + @Schema(description = "会话类型", example = "1")
  21 + private Integer conversationType; // 参见 ImConversationTypeEnum 枚举
  22 +
  23 + @Schema(description = "目标编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048")
  24 + private Long targetId;
  25 +
  26 + @Schema(description = "最大已读消息编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "4096")
  27 + private Long messageId;
  28 +
  29 + @Schema(description = "最近更新时间(增量拉取游标用)")
  30 + private LocalDateTime updateTime;
  31 +
  32 +}
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/friend/ImFriendController.java
@@ -17,6 +17,8 @@ import io.swagger.v3.oas.annotations.Parameters; @@ -17,6 +17,8 @@ import io.swagger.v3.oas.annotations.Parameters;
17 import io.swagger.v3.oas.annotations.tags.Tag; 17 import io.swagger.v3.oas.annotations.tags.Tag;
18 import jakarta.annotation.Resource; 18 import jakarta.annotation.Resource;
19 import jakarta.validation.Valid; 19 import jakarta.validation.Valid;
  20 +import jakarta.validation.constraints.Max;
  21 +import jakarta.validation.constraints.Min;
20 import jakarta.validation.constraints.NotNull; 22 import jakarta.validation.constraints.NotNull;
21 import org.springframework.validation.annotation.Validated; 23 import org.springframework.validation.annotation.Validated;
22 import org.springframework.web.bind.annotation.*; 24 import org.springframework.web.bind.annotation.*;
@@ -46,11 +48,25 @@ public class ImFriendController { @@ -46,11 +48,25 @@ public class ImFriendController {
46 @GetMapping("/list") 48 @GetMapping("/list")
47 @Operation(summary = "获得当前登录用户的好友列表") 49 @Operation(summary = "获得当前登录用户的好友列表")
48 public CommonResult<List<ImFriendRespVO>> getMyFriendList() { 50 public CommonResult<List<ImFriendRespVO>> getMyFriendList() {
49 - // 含 DISABLE 历史好友:保留给前端展示「已删除好友」的历史对话信息;前端按 status 决定会话级联清理  
50 List<ImFriendDO> friends = friendService.getFriendList(getLoginUserId()); 51 List<ImFriendDO> friends = friendService.getFriendList(getLoginUserId());
51 return success(buildFriendRespVOList(friends)); 52 return success(buildFriendRespVOList(friends));
52 } 53 }
53 54
  55 + @GetMapping("/pull")
  56 + @Operation(summary = "增量拉取当前用户的好友关系(重连 / 离线补偿)")
  57 + @Parameters({
  58 + @Parameter(name = "lastUpdateTime", description = "上次拉取到的最新更新时间(毫秒时间戳);首次拉取不传"),
  59 + @Parameter(name = "lastId", description = "上次拉取到的最后一条记录 id;首次拉取不传"),
  60 + @Parameter(name = "limit", description = "单次拉取条数", required = true)
  61 + })
  62 + public CommonResult<List<ImFriendRespVO>> pullMyFriendList(
  63 + @RequestParam(value = "lastUpdateTime", required = false) Long lastUpdateTime,
  64 + @RequestParam(value = "lastId", required = false) Long lastId,
  65 + @RequestParam("limit") @Min(1) @Max(200) Integer limit) {
  66 + List<ImFriendDO> list = friendService.pullFriendList(getLoginUserId(), lastUpdateTime, lastId, limit);
  67 + return success(buildFriendRespVOList(list));
  68 + }
  69 +
54 @GetMapping("/get") 70 @GetMapping("/get")
55 @Operation(summary = "获得好友详情") 71 @Operation(summary = "获得好友详情")
56 @Parameter(name = "friendUserId", description = "好友的用户编号", required = true, example = "2048") 72 @Parameter(name = "friendUserId", description = "好友的用户编号", required = true, example = "2048")
@@ -62,8 +78,8 @@ public class ImFriendController { @@ -62,8 +78,8 @@ public class ImFriendController {
62 @DeleteMapping("/delete") 78 @DeleteMapping("/delete")
63 @Operation(summary = "删除好友(单向软删除)") 79 @Operation(summary = "删除好友(单向软删除)")
64 @Parameters({ 80 @Parameters({
65 - @Parameter(description = "好友的用户编号", required = true, example = "2048"),  
66 - @Parameter(description = "是否级联清理本端相关数据(如私聊会话)") 81 + @Parameter(name = "friendUserId", description = "好友的用户编号", required = true, example = "2048"),
  82 + @Parameter(name = "clear", description = "是否级联清理本端相关数据(如私聊会话)")
67 }) 83 })
68 public CommonResult<Boolean> deleteFriend( 84 public CommonResult<Boolean> deleteFriend(
69 @RequestParam("friendUserId") @NotNull(message = "好友用户编号不能为空") Long friendUserId, 85 @RequestParam("friendUserId") @NotNull(message = "好友用户编号不能为空") Long friendUserId,
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/friend/ImFriendRequestController.java
@@ -13,6 +13,7 @@ import cn.iocoder.yudao.module.system.api.user.AdminUserApi; @@ -13,6 +13,7 @@ import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
13 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; 13 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
14 import io.swagger.v3.oas.annotations.Operation; 14 import io.swagger.v3.oas.annotations.Operation;
15 import io.swagger.v3.oas.annotations.Parameter; 15 import io.swagger.v3.oas.annotations.Parameter;
  16 +import io.swagger.v3.oas.annotations.Parameters;
16 import io.swagger.v3.oas.annotations.tags.Tag; 17 import io.swagger.v3.oas.annotations.tags.Tag;
17 import jakarta.annotation.Resource; 18 import jakarta.annotation.Resource;
18 import jakarta.validation.Valid; 19 import jakarta.validation.Valid;
@@ -79,15 +80,32 @@ public class ImFriendRequestController { @@ -79,15 +80,32 @@ public class ImFriendRequestController {
79 80
80 @GetMapping("/list") 81 @GetMapping("/list")
81 @Operation(summary = "查询「我相关」的好友申请列表(游标分页:传 maxId 加载更多)") 82 @Operation(summary = "查询「我相关」的好友申请列表(游标分页:传 maxId 加载更多)")
  83 + @Parameters({
  84 + @Parameter(name = "maxId", description = "当前列表最旧记录的 id;首页不传"),
  85 + @Parameter(name = "limit", description = "单次拉取条数", required = true)
  86 + })
82 public CommonResult<List<ImFriendRequestRespVO>> getMyFriendRequestList( 87 public CommonResult<List<ImFriendRequestRespVO>> getMyFriendRequestList(
83 - @Parameter(description = "当前列表最旧记录的 id;首页不传")  
84 @RequestParam(value = "maxId", required = false) Long maxId, 88 @RequestParam(value = "maxId", required = false) Long maxId,
85 - @Parameter(description = "单次拉取条数", required = true)  
86 @RequestParam("limit") @Min(1) @Max(200) Integer limit) { 89 @RequestParam("limit") @Min(1) @Max(200) Integer limit) {
87 List<ImFriendRequestDO> list = friendRequestService.getMyFriendRequestList(getLoginUserId(), maxId, limit); 90 List<ImFriendRequestDO> list = friendRequestService.getMyFriendRequestList(getLoginUserId(), maxId, limit);
88 return success(buildList(list)); 91 return success(buildList(list));
89 } 92 }
90 93
  94 + @GetMapping("/pull")
  95 + @Operation(summary = "增量拉取「我相关」的好友申请(重连 / 离线补偿)")
  96 + @Parameters({
  97 + @Parameter(name = "lastUpdateTime", description = "上次拉取到的最新更新时间(毫秒时间戳);首次拉取不传"),
  98 + @Parameter(name = "lastId", description = "上次拉取到的最后一条记录 id;首次拉取不传"),
  99 + @Parameter(name = "limit", description = "单次拉取条数", required = true)
  100 + })
  101 + public CommonResult<List<ImFriendRequestRespVO>> pullMyFriendRequestList(
  102 + @RequestParam(value = "lastUpdateTime", required = false) Long lastUpdateTime,
  103 + @RequestParam(value = "lastId", required = false) Long lastId,
  104 + @RequestParam("limit") @Min(1) @Max(200) Integer limit) {
  105 + List<ImFriendRequestDO> list = friendRequestService.pullFriendRequestList(getLoginUserId(), lastUpdateTime, lastId, limit);
  106 + return success(buildList(list));
  107 + }
  108 +
91 @GetMapping("/get") 109 @GetMapping("/get")
92 @Operation(summary = "按 id 单查「我相关」的申请记录(带越权过滤;WebSocket 通知到达后用)") 110 @Operation(summary = "按 id 单查「我相关」的申请记录(带越权过滤;WebSocket 通知到达后用)")
93 @Parameter(name = "id", description = "申请记录编号", required = true) 111 @Parameter(name = "id", description = "申请记录编号", required = true)
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/friend/vo/ImFriendRespVO.java
@@ -47,6 +47,9 @@ public class ImFriendRespVO { @@ -47,6 +47,9 @@ public class ImFriendRespVO {
47 @Schema(description = "删除好友时间") 47 @Schema(description = "删除好友时间")
48 private LocalDateTime deleteTime; 48 private LocalDateTime deleteTime;
49 49
  50 + @Schema(description = "最近更新时间(增量拉取游标用)")
  51 + private LocalDateTime updateTime;
  52 +
50 // ========== 下面是聚合字段,方便前端显示 ========== 53 // ========== 下面是聚合字段,方便前端显示 ==========
51 54
52 @Schema(description = "好友昵称(实时聚合自 AdminUser)", example = "芋道") 55 @Schema(description = "好友昵称(实时聚合自 AdminUser)", example = "芋道")
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/friend/vo/request/ImFriendRequestRespVO.java
@@ -41,6 +41,9 @@ public class ImFriendRequestRespVO { @@ -41,6 +41,9 @@ public class ImFriendRequestRespVO {
41 @Schema(description = "申请创建时间") 41 @Schema(description = "申请创建时间")
42 private LocalDateTime createTime; 42 private LocalDateTime createTime;
43 43
  44 + @Schema(description = "最近更新时间(增量拉取游标用)")
  45 + private LocalDateTime updateTime;
  46 +
44 // ========== 下面是聚合字段,方便前端显示 ========== 47 // ========== 下面是聚合字段,方便前端显示 ==========
45 48
46 @Schema(description = "发起方昵称(实时聚合自 AdminUser)", example = "芋道") 49 @Schema(description = "发起方昵称(实时聚合自 AdminUser)", example = "芋道")
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/group/ImGroupController.java
@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.im.controller.admin.group; @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.im.controller.admin.group;
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 4 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
5 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 5 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  6 +import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
6 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 7 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
7 import cn.iocoder.yudao.module.im.controller.admin.group.vo.*; 8 import cn.iocoder.yudao.module.im.controller.admin.group.vo.*;
8 import cn.iocoder.yudao.module.im.controller.admin.group.vo.member.ImGroupMemberInviteReqVO; 9 import cn.iocoder.yudao.module.im.controller.admin.group.vo.member.ImGroupMemberInviteReqVO;
@@ -187,8 +188,10 @@ public class ImGroupController { @@ -187,8 +188,10 @@ public class ImGroupController {
187 return Collections.emptyList(); 188 return Collections.emptyList();
188 } 189 }
189 // 仅当前用户是有效成员的群才允许回填置顶消息 190 // 仅当前用户是有效成员的群才允许回填置顶消息
190 - Set<Long> activeGroupIds = convertSet(  
191 - groupMemberService.getActiveGroupMemberListByUserId(loginUserId), ImGroupMemberDO::getGroupId); 191 + Map<Long, ImGroupMemberDO> memberMap = convertMap(
  192 + groupMemberService.getGroupMemberListByUserId(loginUserId), ImGroupMemberDO::getGroupId);
  193 + Set<Long> activeGroupIds = convertSet(memberMap.values(), ImGroupMemberDO::getGroupId,
  194 + member -> CommonStatusEnum.ENABLE.getStatus().equals(member.getStatus()));
192 Set<Long> allMessageIds = convertSetByFlatMap(groups, group -> activeGroupIds.contains(group.getId()) 195 Set<Long> allMessageIds = convertSetByFlatMap(groups, group -> activeGroupIds.contains(group.getId())
193 ? CollUtil.emptyIfNull(group.getPinnedMessageIds()).stream() : Stream.empty()); 196 ? CollUtil.emptyIfNull(group.getPinnedMessageIds()).stream() : Stream.empty());
194 Map<Long, ImGroupMessageDO> messageMap = groupMessageService.getGroupMessageMap(allMessageIds); 197 Map<Long, ImGroupMessageDO> messageMap = groupMessageService.getGroupMessageMap(allMessageIds);
@@ -198,6 +201,8 @@ public class ImGroupController { @@ -198,6 +201,8 @@ public class ImGroupController {
198 // 标记登录用户在该群的成员状态,供前端区分当前群与历史退群 201 // 标记登录用户在该群的成员状态,供前端区分当前群与历史退群
199 boolean joined = activeGroupIds.contains(group.getId()); 202 boolean joined = activeGroupIds.contains(group.getId());
200 groupVO.setJoinStatus(joined ? CommonStatusEnum.ENABLE.getStatus() : CommonStatusEnum.DISABLE.getStatus()); 203 groupVO.setJoinStatus(joined ? CommonStatusEnum.ENABLE.getStatus() : CommonStatusEnum.DISABLE.getStatus());
  204 + MapUtils.findAndThen(memberMap, group.getId(), member ->
  205 + groupVO.setGroupRemark(member.getGroupRemark()).setSilent(Boolean.TRUE.equals(member.getSilent())));
201 if (!joined || CollUtil.isEmpty(group.getPinnedMessageIds())) { 206 if (!joined || CollUtil.isEmpty(group.getPinnedMessageIds())) {
202 return groupVO; 207 return groupVO;
203 } 208 }
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/group/ImGroupMemberController.java
@@ -21,6 +21,7 @@ import jakarta.validation.Valid; @@ -21,6 +21,7 @@ import jakarta.validation.Valid;
21 import org.springframework.validation.annotation.Validated; 21 import org.springframework.validation.annotation.Validated;
22 import org.springframework.web.bind.annotation.*; 22 import org.springframework.web.bind.annotation.*;
23 23
  24 +import java.util.Collections;
24 import java.util.List; 25 import java.util.List;
25 import java.util.Map; 26 import java.util.Map;
26 27
@@ -88,7 +89,7 @@ public class ImGroupMemberController { @@ -88,7 +89,7 @@ public class ImGroupMemberController {
88 } 89 }
89 90
90 @GetMapping("/list") 91 @GetMapping("/list")
91 - @Operation(summary = "获得指定群的成员列表") 92 + @Operation(summary = "获得指定群的成员列表(按群全量拉取,作为前端本地成员 cache 的完整基线)")
92 @Parameter(name = "groupId", description = "群编号", required = true, example = "1024") 93 @Parameter(name = "groupId", description = "群编号", required = true, example = "1024")
93 public CommonResult<List<ImGroupMemberRespVO>> getGroupMemberList(@RequestParam("groupId") Long groupId) { 94 public CommonResult<List<ImGroupMemberRespVO>> getGroupMemberList(@RequestParam("groupId") Long groupId) {
94 // 1.1 查询群成员列表(包含 DISABLE 已退群的成员,不按时间过滤) 95 // 1.1 查询群成员列表(包含 DISABLE 已退群的成员,不按时间过滤)
@@ -101,16 +102,30 @@ public class ImGroupMemberController { @@ -101,16 +102,30 @@ public class ImGroupMemberController {
101 throw exception(GROUP_MEMBER_NOT_IN_GROUP); 102 throw exception(GROUP_MEMBER_NOT_IN_GROUP);
102 } 103 }
103 104
104 - // 2.批量聚合 AdminUser 信息(昵称 / 头像) 105 + // 2. 批量聚合昵称 / 头像,并对非本人置空私人字段
  106 + return success(buildGroupMemberRespVOList(members));
  107 + }
  108 +
  109 + // ========== 私有方法:VO 组装 ==========
  110 +
  111 + /**
  112 + * 群成员列表批量转 VO + 关联回填昵称 / 头像,并对非本人置空私人字段
  113 + */
  114 + private List<ImGroupMemberRespVO> buildGroupMemberRespVOList(List<ImGroupMemberDO> members) {
  115 + if (CollUtil.isEmpty(members)) {
  116 + return Collections.emptyList();
  117 + }
  118 + Long loginUserId = getLoginUserId();
  119 + // 批量聚合 AdminUser 信息(昵称 / 头像),避免 N+1
105 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap( 120 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
106 convertList(members, ImGroupMemberDO::getUserId)); 121 convertList(members, ImGroupMemberDO::getUserId));
107 - return success(convertList(members, m -> {  
108 - ImGroupMemberRespVO vo = BeanUtils.toBean(m, ImGroupMemberRespVO.class);  
109 - MapUtils.findAndThen(userMap, m.getUserId(), user -> 122 + return convertList(members, member -> {
  123 + ImGroupMemberRespVO vo = BeanUtils.toBean(member, ImGroupMemberRespVO.class);
  124 + MapUtils.findAndThen(userMap, member.getUserId(), user ->
110 vo.setNickname(user.getNickname()).setAvatar(user.getAvatar())); 125 vo.setNickname(user.getNickname()).setAvatar(user.getAvatar()));
111 - hidePrivateFieldsIfNotSelf(vo, m.getUserId(), loginUserId); 126 + hidePrivateFieldsIfNotSelf(vo, member.getUserId(), loginUserId);
112 return vo; 127 return vo;
113 - })); 128 + });
114 } 129 }
115 130
116 /** 131 /**
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/group/ImGroupRequestController.java
@@ -19,9 +19,12 @@ import cn.iocoder.yudao.module.system.api.user.AdminUserApi; @@ -19,9 +19,12 @@ import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
19 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; 19 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
20 import io.swagger.v3.oas.annotations.Operation; 20 import io.swagger.v3.oas.annotations.Operation;
21 import io.swagger.v3.oas.annotations.Parameter; 21 import io.swagger.v3.oas.annotations.Parameter;
  22 +import io.swagger.v3.oas.annotations.Parameters;
22 import io.swagger.v3.oas.annotations.tags.Tag; 23 import io.swagger.v3.oas.annotations.tags.Tag;
23 import jakarta.annotation.Resource; 24 import jakarta.annotation.Resource;
24 import jakarta.validation.Valid; 25 import jakarta.validation.Valid;
  26 +import jakarta.validation.constraints.Max;
  27 +import jakarta.validation.constraints.Min;
25 import jakarta.validation.constraints.NotNull; 28 import jakarta.validation.constraints.NotNull;
26 import jakarta.validation.constraints.Size; 29 import jakarta.validation.constraints.Size;
27 import org.springframework.validation.annotation.Validated; 30 import org.springframework.validation.annotation.Validated;
@@ -88,6 +91,22 @@ public class ImGroupRequestController { @@ -88,6 +91,22 @@ public class ImGroupRequestController {
88 return success(buildVOList(list)); 91 return success(buildVOList(list));
89 } 92 }
90 93
  94 + @GetMapping("/pull")
  95 + @Operation(summary = "增量拉取「我管理的群」下的加群申请(重连 / 离线补偿)")
  96 + @Parameters({
  97 + @Parameter(name = "lastUpdateTime", description = "上次拉取到的最新更新时间(毫秒时间戳);首次拉取不传"),
  98 + @Parameter(name = "lastId", description = "上次拉取到的最后一条记录 id;首次拉取不传"),
  99 + @Parameter(name = "limit", description = "单次拉取条数", required = true)
  100 + })
  101 + public CommonResult<List<ImGroupRequestRespVO>> pullMyGroupRequestList(
  102 + @RequestParam(value = "lastUpdateTime", required = false) Long lastUpdateTime,
  103 + @RequestParam(value = "lastId", required = false) Long lastId,
  104 + @RequestParam("limit") @Min(1) @Max(200) Integer limit) {
  105 + List<ImGroupRequestDO> list = groupRequestService.pullGroupRequestList(
  106 + getLoginUserId(), lastUpdateTime, lastId, limit);
  107 + return success(buildVOList(list));
  108 + }
  109 +
91 @GetMapping("/list-by-group") 110 @GetMapping("/list-by-group")
92 @Operation(summary = "查询指定群下的全部加群申请(含已处理);仅群主 / 管理员可查") 111 @Operation(summary = "查询指定群下的全部加群申请(含已处理);仅群主 / 管理员可查")
93 @Parameter(name = "groupId", description = "群编号", required = true, example = "1024") 112 @Parameter(name = "groupId", description = "群编号", required = true, example = "1024")
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/group/vo/ImGroupRespVO.java
@@ -50,6 +50,12 @@ public class ImGroupRespVO { @@ -50,6 +50,12 @@ public class ImGroupRespVO {
50 @Schema(description = "当前登录用户在该群的成员状态:在群 / 已退群(历史退群群仍返回,供前端展示离线消息的群名 / 头像)") 50 @Schema(description = "当前登录用户在该群的成员状态:在群 / 已退群(历史退群群仍返回,供前端展示离线消息的群名 / 头像)")
51 private Integer joinStatus; // 参见 CommonStatusEnum 枚举 51 private Integer joinStatus; // 参见 CommonStatusEnum 枚举
52 52
  53 + @Schema(description = "当前登录用户对该群的备注")
  54 + private String groupRemark;
  55 +
  56 + @Schema(description = "当前登录用户是否免打扰")
  57 + private Boolean silent;
  58 +
53 @Schema(description = "群置顶消息列表,按 pin 顺序(最先置顶的在前);非该群有效成员时为空") 59 @Schema(description = "群置顶消息列表,按 pin 顺序(最先置顶的在前);非该群有效成员时为空")
54 private List<ImGroupMessageRespVO> pinnedMessages; 60 private List<ImGroupMessageRespVO> pinnedMessages;
55 61
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/group/vo/request/ImGroupRequestRespVO.java
@@ -42,6 +42,9 @@ public class ImGroupRequestRespVO { @@ -42,6 +42,9 @@ public class ImGroupRequestRespVO {
42 @Schema(description = "申请创建时间") 42 @Schema(description = "申请创建时间")
43 private LocalDateTime createTime; 43 private LocalDateTime createTime;
44 44
  45 + @Schema(description = "申请更新时间;增量拉取游标")
  46 + private LocalDateTime updateTime;
  47 +
45 // ========== 下面是聚合字段,方便前端显示 ========== 48 // ========== 下面是聚合字段,方便前端显示 ==========
46 49
47 @Schema(description = "申请人 / 被邀请人昵称(实时聚合自 AdminUser)", example = "芋道") 50 @Schema(description = "申请人 / 被邀请人昵称(实时聚合自 AdminUser)", example = "芋道")
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/channel/ImChannelManagerController.java
@@ -75,7 +75,6 @@ public class ImChannelManagerController { @@ -75,7 +75,6 @@ public class ImChannelManagerController {
75 @GetMapping("/simple-list") 75 @GetMapping("/simple-list")
76 @Operation(summary = "获得启用的频道精简列表;前端表单选择频道时调用") 76 @Operation(summary = "获得启用的频道精简列表;前端表单选择频道时调用")
77 public CommonResult<List<ImChannelRespVO>> getSimpleChannelList() { 77 public CommonResult<List<ImChannelRespVO>> getSimpleChannelList() {
78 - // TODO DONE @AI:getChannelListByStatus 统一命名  
79 List<ImChannelDO> list = channelService.getChannelListByStatus(CommonStatusEnum.ENABLE.getStatus()); 78 List<ImChannelDO> list = channelService.getChannelListByStatus(CommonStatusEnum.ENABLE.getStatus());
80 return success(BeanUtils.toBean(list, ImChannelRespVO.class)); 79 return success(BeanUtils.toBean(list, ImChannelRespVO.class));
81 } 80 }
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;
@@ -43,7 +43,7 @@ public class ImGroupMessageManagerRespVO { @@ -43,7 +43,7 @@ public class ImGroupMessageManagerRespVO {
43 private List<String> atUserNicknames; 43 private List<String> atUserNicknames;
44 44
45 @Schema(description = "回执状态", example = "0") 45 @Schema(description = "回执状态", example = "0")
46 - private Integer receiptStatus; // 参见 ImGroupMessageReceiptStatusEnum 枚举类 46 + private Integer receiptStatus; // 参见 ImMessageReceiptStatusEnum 枚举类
47 47
48 @Schema(description = "发送时间", requiredMode = Schema.RequiredMode.REQUIRED) 48 @Schema(description = "发送时间", requiredMode = Schema.RequiredMode.REQUIRED)
49 private LocalDateTime sendTime; 49 private LocalDateTime sendTime;
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;
@@ -36,6 +36,9 @@ public class ImPrivateMessageManagerRespVO { @@ -36,6 +36,9 @@ public class ImPrivateMessageManagerRespVO {
36 @Schema(description = "消息状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") 36 @Schema(description = "消息状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
37 private Integer status; // 参见 ImMessageStatusEnum 枚举类 37 private Integer status; // 参见 ImMessageStatusEnum 枚举类
38 38
  39 + @Schema(description = "回执状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
  40 + private Integer receiptStatus; // 参见 ImMessageReceiptStatusEnum 枚举类
  41 +
39 @Schema(description = "发送时间", requiredMode = Schema.RequiredMode.REQUIRED) 42 @Schema(description = "发送时间", requiredMode = Schema.RequiredMode.REQUIRED)
40 private LocalDateTime sendTime; 43 private LocalDateTime sendTime;
41 44
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/ImChannelMessageController.java
@@ -5,7 +5,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; @@ -5,7 +5,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
6 import cn.iocoder.yudao.module.im.controller.admin.message.vo.channel.ImChannelMessagePullRespVO; 6 import cn.iocoder.yudao.module.im.controller.admin.message.vo.channel.ImChannelMessagePullRespVO;
7 import cn.iocoder.yudao.module.im.dal.dataobject.message.ImChannelMessageDO; 7 import cn.iocoder.yudao.module.im.dal.dataobject.message.ImChannelMessageDO;
8 -import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum; 8 +import cn.iocoder.yudao.module.im.enums.message.ImMessageReceiptStatusEnum;
9 import cn.iocoder.yudao.module.im.service.message.ImChannelMessageService; 9 import cn.iocoder.yudao.module.im.service.message.ImChannelMessageService;
10 import io.swagger.v3.oas.annotations.Operation; 10 import io.swagger.v3.oas.annotations.Operation;
11 import io.swagger.v3.oas.annotations.Parameter; 11 import io.swagger.v3.oas.annotations.Parameter;
@@ -40,25 +40,25 @@ public class ImChannelMessageController { @@ -40,25 +40,25 @@ public class ImChannelMessageController {
40 40
41 @GetMapping("/pull") 41 @GetMapping("/pull")
42 @Operation(summary = "拉取频道消息(离线增量);按 minId 游标分页") 42 @Operation(summary = "拉取频道消息(离线增量);按 minId 游标分页")
43 - public CommonResult<List<ImChannelMessagePullRespVO>> pull( 43 + public CommonResult<List<ImChannelMessagePullRespVO>> pullChannelMessageList(
44 @RequestParam(value = "minId", defaultValue = "0") @PositiveOrZero(message = "minId 不能小于 0") Long minId, 44 @RequestParam(value = "minId", defaultValue = "0") @PositiveOrZero(message = "minId 不能小于 0") Long minId,
45 @RequestParam(value = "size", defaultValue = "100") 45 @RequestParam(value = "size", defaultValue = "100")
46 @Min(value = 1, message = "size 必须大于 0") 46 @Min(value = 1, message = "size 必须大于 0")
47 @Max(value = 200, message = "size 一次最多 200 条") Integer size) { 47 @Max(value = 200, message = "size 一次最多 200 条") Integer size) {
48 // 1. 拉取消息列表 48 // 1. 拉取消息列表
49 Long userId = getLoginUserId(); 49 Long userId = getLoginUserId();
50 - List<ImChannelMessageDO> list = channelMessageService.getMessageListForPull(userId, minId, size); 50 + List<ImChannelMessageDO> list = channelMessageService.pullChannelMessageList(userId, minId, size);
51 if (CollUtil.isEmpty(list)) { 51 if (CollUtil.isEmpty(list)) {
52 return success(Collections.emptyList()); 52 return success(Collections.emptyList());
53 } 53 }
54 - // 2. 按 Redis 已读游标补 status;device A 已读后 device B 拉到这条不再算入未读 54 + // 2. 按已读游标补 receiptStatus(已读 DONE / 未读 PENDING)
55 Map<Long, Long> readMaxByChannel = channelMessageService.getChannelReadMaxMessageIdMap( 55 Map<Long, Long> readMaxByChannel = channelMessageService.getChannelReadMaxMessageIdMap(
56 userId, convertSet(list, ImChannelMessageDO::getChannelId)); 56 userId, convertSet(list, ImChannelMessageDO::getChannelId));
57 return success(BeanUtils.toBean(list, ImChannelMessagePullRespVO.class, vo -> { 57 return success(BeanUtils.toBean(list, ImChannelMessagePullRespVO.class, vo -> {
58 Long readMax = readMaxByChannel.get(vo.getChannelId()); 58 Long readMax = readMaxByChannel.get(vo.getChannelId());
59 - vo.setStatus(readMax != null && readMax >= vo.getId()  
60 - ? ImMessageStatusEnum.READ.getStatus()  
61 - : ImMessageStatusEnum.UNREAD.getStatus()); 59 + vo.setReceiptStatus(readMax != null && readMax >= vo.getId()
  60 + ? ImMessageReceiptStatusEnum.DONE.getStatus()
  61 + : ImMessageReceiptStatusEnum.PENDING.getStatus());
62 })); 62 }));
63 } 63 }
64 64
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/ImPrivateMessageController.java
@@ -61,7 +61,7 @@ public class ImPrivateMessageController { @@ -61,7 +61,7 @@ public class ImPrivateMessageController {
61 61
62 @GetMapping("/max-read-message-id") 62 @GetMapping("/max-read-message-id")
63 @Operation(summary = "查询对方已读到我发的最大消息 id", 63 @Operation(summary = "查询对方已读到我发的最大消息 id",
64 - description = "用于多端 / 离线场景下的已读位置补齐:进入会话或断线重连后调用,结果用于翻转本地自发消息状态") 64 + description = "用于多端 / 离线场景下的已读位置补齐:进入会话或断线重连后调用,据此把本地自发消息更新为已读")
65 @Parameter(name = "peerId", description = "对方用户编号", required = true, example = "2") 65 @Parameter(name = "peerId", description = "对方用户编号", required = true, example = "2")
66 public CommonResult<Long> getMaxReadMessageId(@RequestParam("peerId") Long peerId) { 66 public CommonResult<Long> getMaxReadMessageId(@RequestParam("peerId") Long peerId) {
67 return success(privateMessageService.getMaxReadMessageId(getLoginUserId(), peerId)); 67 return success(privateMessageService.getMaxReadMessageId(getLoginUserId(), peerId));
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/channel/ImChannelMessagePullRespVO.java
@@ -24,8 +24,8 @@ public class ImChannelMessagePullRespVO { @@ -24,8 +24,8 @@ public class ImChannelMessagePullRespVO {
24 @Schema(description = "消息内容;payload JSON 快照", requiredMode = Schema.RequiredMode.REQUIRED) 24 @Schema(description = "消息内容;payload JSON 快照", requiredMode = Schema.RequiredMode.REQUIRED)
25 private String content; 25 private String content;
26 26
27 - @Schema(description = "当前用户的已读态;按 Redis 游标计算填充", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")  
28 - private Integer status; // 参见 ImMessageStatusEnum 枚举类 27 + @Schema(description = "当前用户回执 / 已读态;按 Redis 读位置计算(已读 DONE,未读 PENDING)", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
  28 + private Integer receiptStatus; // 参见 ImMessageReceiptStatusEnum 枚举类
29 29
30 @Schema(description = "发送时间", requiredMode = Schema.RequiredMode.REQUIRED) 30 @Schema(description = "发送时间", requiredMode = Schema.RequiredMode.REQUIRED)
31 private LocalDateTime sendTime; 31 private LocalDateTime sendTime;
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/ImPrivateMessageRespVO.java
@@ -31,7 +31,10 @@ public class ImPrivateMessageRespVO { @@ -31,7 +31,10 @@ public class ImPrivateMessageRespVO {
31 private String content; 31 private String content;
32 32
33 @Schema(description = "消息状态", example = "0") 33 @Schema(description = "消息状态", example = "0")
34 - private Integer status; 34 + private Integer status; // 参见 ImMessageStatusEnum 枚举类
  35 +
  36 + @Schema(description = "回执状态", example = "0")
  37 + private Integer receiptStatus; // 参见 ImMessageReceiptStatusEnum 枚举类
35 38
36 @Schema(description = "发送时间") 39 @Schema(description = "发送时间")
37 private LocalDateTime sendTime; 40 private LocalDateTime sendTime;
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,20 +26,23 @@ public class ImPrivateMessageSendReqVO { @@ -26,20 +26,23 @@ 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\":\"你好\"}")
33 @NotEmpty(message = "消息内容不能为空") 33 @NotEmpty(message = "消息内容不能为空")
34 private String content; 34 private String content;
35 35
  36 + @Schema(description = "是否需要回执", example = "false")
  37 + private Boolean receipt;
  38 +
36 /** 39 /**
37 * 仅允许用户消息(normal)类型 40 * 仅允许用户消息(normal)类型
38 */ 41 */
39 @AssertTrue(message = "消息类型不允许") 42 @AssertTrue(message = "消息类型不允许")
40 @JsonIgnore 43 @JsonIgnore
41 public boolean isTypeNormal() { 44 public boolean isTypeNormal() {
42 - return type == null || ImMessageTypeEnum.validate(type).isNormal(); 45 + return type == null || ImContentTypeEnum.validate(type).isNormal();
43 } 46 }
44 47
45 } 48 }
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/conversation/ImConversationReadDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.im.dal.dataobject.conversation;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import cn.iocoder.yudao.module.im.dal.dataobject.channel.ImChannelDO;
  5 +import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupDO;
  6 +import cn.iocoder.yudao.module.im.dal.dataobject.message.ImChannelMessageDO;
  7 +import cn.iocoder.yudao.module.im.dal.dataobject.message.ImGroupMessageDO;
  8 +import cn.iocoder.yudao.module.im.dal.dataobject.message.ImPrivateMessageDO;
  9 +import cn.iocoder.yudao.module.im.enums.ImConversationTypeEnum;
  10 +import com.baomidou.mybatisplus.annotation.KeySequence;
  11 +import com.baomidou.mybatisplus.annotation.TableId;
  12 +import com.baomidou.mybatisplus.annotation.TableName;
  13 +import lombok.*;
  14 +
  15 +import java.time.LocalDateTime;
  16 +
  17 +/**
  18 + * IM 会话读位置 DO
  19 + * <p>
  20 + * 只表达「用户在某个会话的最大已读位置」,私聊 / 群聊 / 频道统一落这张表,是读位置的唯一权威。
  21 + *
  22 + * @author 芋道源码
  23 + */
  24 +@TableName("im_conversation_read")
  25 +@KeySequence("im_conversation_read_seq")
  26 +@Data
  27 +@EqualsAndHashCode(callSuper = true)
  28 +@ToString(callSuper = true)
  29 +@Builder
  30 +@NoArgsConstructor
  31 +@AllArgsConstructor
  32 +public class ImConversationReadDO extends BaseDO {
  33 +
  34 + /**
  35 + * 编号
  36 + */
  37 + @TableId
  38 + private Long id;
  39 + /**
  40 + * 用户编号
  41 + *
  42 + * 关联 AdminUserDO 的 id 字段
  43 + */
  44 + private Long userId;
  45 + /**
  46 + * 会话类型
  47 + * <p>
  48 + * 枚举 {@link ImConversationTypeEnum}
  49 + */
  50 + private Integer conversationType;
  51 + /**
  52 + * 目标编号
  53 + * <p>
  54 + * 私聊关联 AdminUserDO 的 id;群聊关联 {@link ImGroupDO#getId()};频道关联 {@link ImChannelDO#getId()}
  55 + */
  56 + private Long targetId;
  57 + /**
  58 + * 最大已读消息编号
  59 + * <p>
  60 + * 关联 {@link ImPrivateMessageDO#getId()}、{@link ImGroupMessageDO#getId()}、{@link ImChannelMessageDO#getId()}
  61 + */
  62 + private Long messageId;
  63 + /**
  64 + * 最近已读时间
  65 + */
  66 + private LocalDateTime readTime;
  67 +
  68 +}
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
@@ -3,9 +3,9 @@ package cn.iocoder.yudao.module.im.dal.dataobject.message; @@ -3,9 +3,9 @@ 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.framework.mybatis.core.type.LongListTypeHandler; 4 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.ImGroupMessageReceiptStatusEnum; 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 /**
@@ -67,8 +67,6 @@ public class ImGroupMessageDO extends BaseDO { @@ -67,8 +67,6 @@ public class ImGroupMessageDO extends BaseDO {
67 * 消息状态 67 * 消息状态
68 * <p> 68 * <p>
69 * 枚举 {@link ImMessageStatusEnum} 69 * 枚举 {@link ImMessageStatusEnum}
70 - *  
71 - * 为什么没有 READ 状态?与单聊的差异:单聊用 UNREAD/READ 跟踪每条消息状态,群聊用 Redis 存储每个成员的已读位置(游标模型)  
72 */ 70 */
73 private Integer status; 71 private Integer status;
74 /** 72 /**
@@ -94,7 +92,7 @@ public class ImGroupMessageDO extends BaseDO { @@ -94,7 +92,7 @@ public class ImGroupMessageDO extends BaseDO {
94 /** 92 /**
95 * 回执状态 93 * 回执状态
96 * <p> 94 * <p>
97 - * 枚举 {@link ImGroupMessageReceiptStatusEnum} 95 + * 枚举 {@link ImMessageReceiptStatusEnum}
98 */ 96 */
99 private Integer receiptStatus; 97 private Integer receiptStatus;
100 98
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/ImPrivateMessageDO.java
1 package cn.iocoder.yudao.module.im.dal.dataobject.message; 1 package cn.iocoder.yudao.module.im.dal.dataobject.message;
2 2
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.ImMessageStatusEnum; 5 import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum;
5 -import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum; 6 +import cn.iocoder.yudao.module.im.enums.ImContentTypeEnum;
6 import com.baomidou.mybatisplus.annotation.KeySequence; 7 import com.baomidou.mybatisplus.annotation.KeySequence;
7 import com.baomidou.mybatisplus.annotation.TableId; 8 import com.baomidou.mybatisplus.annotation.TableId;
8 import com.baomidou.mybatisplus.annotation.TableName; 9 import com.baomidou.mybatisplus.annotation.TableName;
@@ -49,7 +50,7 @@ public class ImPrivateMessageDO extends BaseDO { @@ -49,7 +50,7 @@ public class ImPrivateMessageDO extends BaseDO {
49 /** 50 /**
50 * 消息类型 51 * 消息类型
51 * <p> 52 * <p>
52 - * 枚举 {@link ImMessageTypeEnum} 53 + * 枚举 {@link ImContentTypeEnum}
53 */ 54 */
54 private Integer type; 55 private Integer type;
55 /** 56 /**
@@ -65,6 +66,12 @@ public class ImPrivateMessageDO extends BaseDO { @@ -65,6 +66,12 @@ public class ImPrivateMessageDO extends BaseDO {
65 */ 66 */
66 private Integer status; 67 private Integer status;
67 /** 68 /**
  69 + * 回执状态
  70 + * <p>
  71 + * 枚举 {@link ImMessageReceiptStatusEnum}
  72 + */
  73 + private Integer receiptStatus;
  74 + /**
68 * 发送时间 75 * 发送时间
69 */ 76 */
70 private LocalDateTime sendTime; 77 private LocalDateTime sendTime;
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/conversation/ImConversationReadMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.im.dal.mysql.conversation;
  2 +
  3 +import cn.hutool.core.date.LocalDateTimeUtil;
  4 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  6 +import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ImConversationReadDO;
  7 +import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  8 +import org.apache.ibatis.annotations.Mapper;
  9 +
  10 +import java.time.LocalDateTime;
  11 +import java.util.Collection;
  12 +import java.util.List;
  13 +
  14 +/**
  15 + * IM 会话读位置 Mapper
  16 + *
  17 + * @author 芋道源码
  18 + */
  19 +@Mapper
  20 +public interface ImConversationReadMapper extends BaseMapperX<ImConversationReadDO> {
  21 +
  22 + default ImConversationReadDO selectByUserIdAndConversation(Long userId, Integer conversationType, Long conversationId) {
  23 + return selectOne(new LambdaQueryWrapperX<ImConversationReadDO>()
  24 + .eq(ImConversationReadDO::getUserId, userId)
  25 + .eq(ImConversationReadDO::getConversationType, conversationType)
  26 + .eq(ImConversationReadDO::getTargetId, conversationId));
  27 + }
  28 +
  29 + default List<ImConversationReadDO> selectListByConversation(Integer conversationType, Long conversationId) {
  30 + return selectList(new LambdaQueryWrapperX<ImConversationReadDO>()
  31 + .eq(ImConversationReadDO::getConversationType, conversationType)
  32 + .eq(ImConversationReadDO::getTargetId, conversationId));
  33 + }
  34 +
  35 + default List<ImConversationReadDO> selectListByUserIdAndConversations(Long userId, Integer conversationType,
  36 + Collection<Long> conversationIds) {
  37 + return selectList(new LambdaQueryWrapperX<ImConversationReadDO>()
  38 + .eq(ImConversationReadDO::getUserId, userId)
  39 + .eq(ImConversationReadDO::getConversationType, conversationType)
  40 + .in(ImConversationReadDO::getTargetId, conversationIds));
  41 + }
  42 +
  43 + /**
  44 + * 增量拉取当前用户的会话读位置(按 update_time + id 正向游标)
  45 + *
  46 + * @param userId 当前用户编号
  47 + * @param lastUpdateTime 上次拉取到的更新时间;首次拉取传 null
  48 + * @param lastId 上次拉取到的记录编号;首次拉取传 null
  49 + * @param limit 拉取数量
  50 + * @return 会话读位置列表
  51 + */
  52 + default List<ImConversationReadDO> selectPullListByUserId(Long userId, Long lastUpdateTime, Long lastId, Integer limit) {
  53 + LambdaQueryWrapperX<ImConversationReadDO> query = new LambdaQueryWrapperX<ImConversationReadDO>()
  54 + .eq(ImConversationReadDO::getUserId, userId);
  55 + if (lastUpdateTime != null && lastId != null) {
  56 + LocalDateTime lastTime = LocalDateTimeUtil.of(lastUpdateTime);
  57 + query.and(w -> w.gt(ImConversationReadDO::getUpdateTime, lastTime)
  58 + .or(n -> n.eq(ImConversationReadDO::getUpdateTime, lastTime).gt(ImConversationReadDO::getId, lastId)));
  59 + }
  60 + return selectList(query.orderByAsc(ImConversationReadDO::getUpdateTime).orderByAsc(ImConversationReadDO::getId)
  61 + .last("LIMIT " + limit));
  62 + }
  63 +
  64 + /**
  65 + * 单调递增更新读位置:仅当新位置更大时才更新
  66 + * <p>
  67 + * 通过 {@code read_message_id < messageId} 的 CAS 条件,保证乱序 / 并发上报时读位置不会回退。
  68 + *
  69 + * @param id 记录编号
  70 + * @param messageId 新的最大已读消息编号
  71 + * @param readTime 已读时间
  72 + * @return 影响行数;0 表示新位置不大于已有位置,未更新
  73 + */
  74 + default int updateReadMessageIdToLarger(Long id, Long messageId, LocalDateTime readTime) {
  75 + return update(null, Wrappers.<ImConversationReadDO>lambdaUpdate()
  76 + .set(ImConversationReadDO::getMessageId, messageId)
  77 + .set(ImConversationReadDO::getReadTime, readTime)
  78 + .set(ImConversationReadDO::getUpdateTime, readTime)
  79 + .eq(ImConversationReadDO::getId, id)
  80 + .lt(ImConversationReadDO::getMessageId, messageId));
  81 + }
  82 +
  83 +}
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/friend/ImFriendMapper.java
1 package cn.iocoder.yudao.module.im.dal.mysql.friend; 1 package cn.iocoder.yudao.module.im.dal.mysql.friend;
2 2
  3 +import cn.hutool.core.date.LocalDateTimeUtil;
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 5 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; 6 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
@@ -31,6 +32,28 @@ public interface ImFriendMapper extends BaseMapperX&lt;ImFriendDO&gt; { @@ -31,6 +32,28 @@ public interface ImFriendMapper extends BaseMapperX&lt;ImFriendDO&gt; {
31 .eq(ImFriendDO::getUserId, userId) 32 .eq(ImFriendDO::getUserId, userId)
32 .orderByDesc(ImFriendDO::getId)); 33 .orderByDesc(ImFriendDO::getId));
33 } 34 }
  35 +
  36 + /**
  37 + * 增量拉取当前用户的好友关系(含已删除,按 update_time + id 正向游标)
  38 + *
  39 + * @param userId 当前用户编号
  40 + * @param lastUpdateTime 上次拉取到的更新时间;首次拉取传 null
  41 + * @param lastId 上次拉取到的记录编号;首次拉取传 null
  42 + * @param limit 拉取数量
  43 + * @return 好友关系列表
  44 + */
  45 + default List<ImFriendDO> selectPullListByUserId(Long userId, Long lastUpdateTime, Long lastId, Integer limit) {
  46 + LambdaQueryWrapperX<ImFriendDO> query = new LambdaQueryWrapperX<ImFriendDO>()
  47 + .eq(ImFriendDO::getUserId, userId);
  48 + if (lastUpdateTime != null && lastId != null) {
  49 + LocalDateTime lastTime = LocalDateTimeUtil.of(lastUpdateTime);
  50 + query.and(w -> w.gt(ImFriendDO::getUpdateTime, lastTime)
  51 + .or(n -> n.eq(ImFriendDO::getUpdateTime, lastTime).gt(ImFriendDO::getId, lastId)));
  52 + }
  53 + return selectList(query.orderByAsc(ImFriendDO::getUpdateTime).orderByAsc(ImFriendDO::getId)
  54 + .last("LIMIT " + limit));
  55 + }
  56 +
34 default List<ImFriendDO> selectListByUserIdAndStatus(Long userId, Integer status) { 57 default List<ImFriendDO> selectListByUserIdAndStatus(Long userId, Integer status) {
35 return selectList(new LambdaQueryWrapperX<ImFriendDO>() 58 return selectList(new LambdaQueryWrapperX<ImFriendDO>()
36 .eq(ImFriendDO::getUserId, userId) 59 .eq(ImFriendDO::getUserId, userId)
@@ -68,12 +91,14 @@ public interface ImFriendMapper extends BaseMapperX&lt;ImFriendDO&gt; { @@ -68,12 +91,14 @@ public interface ImFriendMapper extends BaseMapperX&lt;ImFriendDO&gt; {
68 91
69 @SuppressWarnings("UnusedReturnValue") 92 @SuppressWarnings("UnusedReturnValue")
70 default int updateReAddFields(Long id, Integer status, LocalDateTime addTime, 93 default int updateReAddFields(Long id, Integer status, LocalDateTime addTime,
  94 + LocalDateTime updateTime,
71 Boolean silent, Boolean pinned, Boolean blocked, 95 Boolean silent, Boolean pinned, Boolean blocked,
72 String displayName, Integer addSource) { 96 String displayName, Integer addSource) {
73 return update(null, Wrappers.<ImFriendDO>lambdaUpdate() 97 return update(null, Wrappers.<ImFriendDO>lambdaUpdate()
74 .eq(ImFriendDO::getId, id) 98 .eq(ImFriendDO::getId, id)
75 .set(ImFriendDO::getStatus, status) 99 .set(ImFriendDO::getStatus, status)
76 .set(ImFriendDO::getAddTime, addTime) 100 .set(ImFriendDO::getAddTime, addTime)
  101 + .set(ImFriendDO::getUpdateTime, updateTime)
77 .set(ImFriendDO::getSilent, silent) 102 .set(ImFriendDO::getSilent, silent)
78 .set(ImFriendDO::getPinned, pinned) 103 .set(ImFriendDO::getPinned, pinned)
79 .set(ImFriendDO::getBlocked, blocked) 104 .set(ImFriendDO::getBlocked, blocked)
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/friend/ImFriendRequestMapper.java
1 package cn.iocoder.yudao.module.im.dal.mysql.friend; 1 package cn.iocoder.yudao.module.im.dal.mysql.friend;
2 2
  3 +import cn.hutool.core.date.LocalDateTimeUtil;
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 5 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; 6 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
@@ -28,6 +29,12 @@ public interface ImFriendRequestMapper extends BaseMapperX&lt;ImFriendRequestDO&gt; { @@ -28,6 +29,12 @@ public interface ImFriendRequestMapper extends BaseMapperX&lt;ImFriendRequestDO&gt; {
28 29
29 /** 30 /**
30 * 拉取「我相关」的好友申请列表 31 * 拉取「我相关」的好友申请列表
  32 + *
  33 + * @param userId 当前用户编号
  34 + * @param maxRequestUpdateTime 起始更新时间;首次拉取传 null
  35 + * @param maxId 起始记录编号;首次拉取传 null
  36 + * @param limit 拉取数量
  37 + * @return 好友申请列表
31 */ 38 */
32 default List<ImFriendRequestDO> selectMyList(Long userId, LocalDateTime maxRequestUpdateTime, 39 default List<ImFriendRequestDO> selectMyList(Long userId, LocalDateTime maxRequestUpdateTime,
33 Long maxId, int limit) { 40 Long maxId, int limit) {
@@ -45,6 +52,28 @@ public interface ImFriendRequestMapper extends BaseMapperX&lt;ImFriendRequestDO&gt; { @@ -45,6 +52,28 @@ public interface ImFriendRequestMapper extends BaseMapperX&lt;ImFriendRequestDO&gt; {
45 return selectList(wrapper); 52 return selectList(wrapper);
46 } 53 }
47 54
  55 + /**
  56 + * 增量拉取「我相关」的好友申请(双向 OR,按 update_time + id 正向游标)
  57 + *
  58 + * @param userId 当前用户编号
  59 + * @param lastUpdateTime 上次拉取到的更新时间;首次拉取传 null
  60 + * @param lastId 上次拉取到的记录编号;首次拉取传 null
  61 + * @param limit 拉取数量
  62 + * @return 好友申请列表
  63 + */
  64 + default List<ImFriendRequestDO> selectPullListByUserId(Long userId, Long lastUpdateTime, Long lastId, Integer limit) {
  65 + LambdaQueryWrapperX<ImFriendRequestDO> query = new LambdaQueryWrapperX<>();
  66 + query.and(w -> w.eq(ImFriendRequestDO::getFromUserId, userId)
  67 + .or().eq(ImFriendRequestDO::getToUserId, userId));
  68 + if (lastUpdateTime != null && lastId != null) {
  69 + LocalDateTime lastTime = LocalDateTimeUtil.of(lastUpdateTime);
  70 + query.and(w -> w.gt(ImFriendRequestDO::getUpdateTime, lastTime)
  71 + .or(n -> n.eq(ImFriendRequestDO::getUpdateTime, lastTime).gt(ImFriendRequestDO::getId, lastId)));
  72 + }
  73 + return selectList(query.orderByAsc(ImFriendRequestDO::getUpdateTime).orderByAsc(ImFriendRequestDO::getId)
  74 + .last("LIMIT " + limit));
  75 + }
  76 +
48 default int updateByIdAndHandleResult(Long id, Integer handleResult, ImFriendRequestDO updateObj) { 77 default int updateByIdAndHandleResult(Long id, Integer handleResult, ImFriendRequestDO updateObj) {
49 return update(updateObj, new LambdaUpdateWrapper<ImFriendRequestDO>() 78 return update(updateObj, new LambdaUpdateWrapper<ImFriendRequestDO>()
50 .eq(ImFriendRequestDO::getId, id).eq(ImFriendRequestDO::getHandleResult, handleResult)); 79 .eq(ImFriendRequestDO::getId, id).eq(ImFriendRequestDO::getHandleResult, handleResult));
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/group/ImGroupMemberMapper.java
1 package cn.iocoder.yudao.module.im.dal.mysql.group; 1 package cn.iocoder.yudao.module.im.dal.mysql.group;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;  
5 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
6 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; 5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
7 import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO; 6 import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO;
@@ -59,20 +58,8 @@ public interface ImGroupMemberMapper extends BaseMapperX&lt;ImGroupMemberDO&gt; { @@ -59,20 +58,8 @@ public interface ImGroupMemberMapper extends BaseMapperX&lt;ImGroupMemberDO&gt; {
59 .eq(ImGroupMemberDO::getStatus, status)); 58 .eq(ImGroupMemberDO::getStatus, status));
60 } 59 }
61 60
62 - /**  
63 - * 查询用户已退群的成员记录  
64 - * <p>  
65 - * 当 {@code minQuitTime} 非空时额外按 {@code quitTime ≥ minQuitTime} 过滤。  
66 - *  
67 - * @param userId 用户编号  
68 - * @param minQuitTime 最早退群时间(含),可空  
69 - * @return 已退群成员记录列表  
70 - */  
71 - default List<ImGroupMemberDO> selectQuitListByUserId(Long userId, LocalDateTime minQuitTime) {  
72 - return selectList(new LambdaQueryWrapperX<ImGroupMemberDO>()  
73 - .eq(ImGroupMemberDO::getUserId, userId)  
74 - .eq(ImGroupMemberDO::getStatus, CommonStatusEnum.DISABLE.getStatus())  
75 - .geIfPresent(ImGroupMemberDO::getQuitTime, minQuitTime)); 61 + default List<ImGroupMemberDO> selectListByUserId(Long userId) {
  62 + return selectList(ImGroupMemberDO::getUserId, userId);
76 } 63 }
77 64
78 @SuppressWarnings("UnusedReturnValue") 65 @SuppressWarnings("UnusedReturnValue")
@@ -143,7 +130,8 @@ public interface ImGroupMemberMapper extends BaseMapperX&lt;ImGroupMemberDO&gt; { @@ -143,7 +130,8 @@ public interface ImGroupMemberMapper extends BaseMapperX&lt;ImGroupMemberDO&gt; {
143 .set(ImGroupMemberDO::getAddSource, addSource) 130 .set(ImGroupMemberDO::getAddSource, addSource)
144 .set(ImGroupMemberDO::getInviterUserId, inviterUserId) 131 .set(ImGroupMemberDO::getInviterUserId, inviterUserId)
145 .set(ImGroupMemberDO::getQuitTime, null) 132 .set(ImGroupMemberDO::getQuitTime, null)
146 - .set(ImGroupMemberDO::getMuteEndTime, null)); 133 + .set(ImGroupMemberDO::getMuteEndTime, null)
  134 + .set(ImGroupMemberDO::getUpdateTime, joinTime));
147 } 135 }
148 136
149 } 137 }
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/group/ImGroupRequestMapper.java
1 package cn.iocoder.yudao.module.im.dal.mysql.group; 1 package cn.iocoder.yudao.module.im.dal.mysql.group;
2 2
  3 +import cn.hutool.core.date.LocalDateTimeUtil;
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 5 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; 6 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
@@ -43,6 +44,28 @@ public interface ImGroupRequestMapper extends BaseMapperX&lt;ImGroupRequestDO&gt; { @@ -43,6 +44,28 @@ public interface ImGroupRequestMapper extends BaseMapperX&lt;ImGroupRequestDO&gt; {
43 .orderByDesc(ImGroupRequestDO::getId)); 44 .orderByDesc(ImGroupRequestDO::getId));
44 } 45 }
45 46
  47 + /**
  48 + * 增量拉取「我管理的群」下的加群申请(含已处理,按 update_time + id 正向游标)
  49 + *
  50 + * @param groupIds 群编号集合
  51 + * @param lastUpdateTime 上次拉取到的更新时间;首次拉取传 null
  52 + * @param lastId 上次拉取到的记录编号;首次拉取传 null
  53 + * @param limit 拉取数量
  54 + * @return 加群申请列表
  55 + */
  56 + default List<ImGroupRequestDO> selectPullListByGroupIds(Collection<Long> groupIds, Long lastUpdateTime,
  57 + Long lastId, Integer limit) {
  58 + LambdaQueryWrapperX<ImGroupRequestDO> query = new LambdaQueryWrapperX<ImGroupRequestDO>()
  59 + .in(ImGroupRequestDO::getGroupId, groupIds);
  60 + if (lastUpdateTime != null && lastId != null) {
  61 + LocalDateTime lastTime = LocalDateTimeUtil.of(lastUpdateTime);
  62 + query.and(w -> w.gt(ImGroupRequestDO::getUpdateTime, lastTime)
  63 + .or(n -> n.eq(ImGroupRequestDO::getUpdateTime, lastTime).gt(ImGroupRequestDO::getId, lastId)));
  64 + }
  65 + return selectList(query.orderByAsc(ImGroupRequestDO::getUpdateTime).orderByAsc(ImGroupRequestDO::getId)
  66 + .last("LIMIT " + limit));
  67 + }
  68 +
46 default int updateByIdAndHandleResult(Long id, Integer expectedHandleResult, ImGroupRequestDO updateObj) { 69 default int updateByIdAndHandleResult(Long id, Integer expectedHandleResult, ImGroupRequestDO updateObj) {
47 return update(updateObj, new LambdaUpdateWrapper<ImGroupRequestDO>() 70 return update(updateObj, new LambdaUpdateWrapper<ImGroupRequestDO>()
48 .eq(ImGroupRequestDO::getId, id).eq(ImGroupRequestDO::getHandleResult, expectedHandleResult)); 71 .eq(ImGroupRequestDO::getId, id).eq(ImGroupRequestDO::getHandleResult, expectedHandleResult));
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/message/ImGroupMessageMapper.java
@@ -4,13 +4,15 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; @@ -4,13 +4,15 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; 5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
6 import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX; 6 import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
  7 +import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
7 import cn.iocoder.yudao.module.im.controller.admin.manager.message.vo.group.ImGroupMessageManagerPageReqVO; 8 import cn.iocoder.yudao.module.im.controller.admin.manager.message.vo.group.ImGroupMessageManagerPageReqVO;
8 import cn.iocoder.yudao.module.im.dal.dataobject.message.ImGroupMessageDO; 9 import cn.iocoder.yudao.module.im.dal.dataobject.message.ImGroupMessageDO;
9 -import cn.iocoder.yudao.module.im.enums.message.ImGroupMessageReceiptStatusEnum; 10 +import cn.iocoder.yudao.module.im.enums.message.ImMessageReceiptStatusEnum;
10 import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum; 11 import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum;
11 import org.apache.ibatis.annotations.Mapper; 12 import org.apache.ibatis.annotations.Mapper;
12 13
13 import java.time.LocalDateTime; 14 import java.time.LocalDateTime;
  15 +import java.util.Collection;
14 import java.util.List; 16 import java.util.List;
15 17
16 /** 18 /**
@@ -22,48 +24,22 @@ import java.util.List; @@ -22,48 +24,22 @@ import java.util.List;
22 public interface ImGroupMessageMapper extends BaseMapperX<ImGroupMessageDO> { 24 public interface ImGroupMessageMapper extends BaseMapperX<ImGroupMessageDO> {
23 25
24 /** 26 /**
25 - * 根据 minId + 时间窗口增量拉取群聊消息(在群成员使用) 27 + * 根据 minId + 时间窗口增量拉取群聊消息
26 * 28 *
27 - * @param groupIds 用户当前仍在群内的群编号列表 29 + * @param userId 当前用户编号
  30 + * @param groupIds 候选群编号集合(当前在群 ∪ 窗口内退群),不能为空
28 * @param minId 最小消息 id(不含) 31 * @param minId 最小消息 id(不含)
29 * @param minSendTime 最早发送时间(不含),限制离线消息时间窗口 32 * @param minSendTime 最早发送时间(不含),限制离线消息时间窗口
30 * @param size 拉取数量 33 * @param size 拉取数量
31 * @return 消息列表(按 id 升序) 34 * @return 消息列表(按 id 升序)
32 */ 35 */
33 - default List<ImGroupMessageDO> selectListByMinId(List<Long> groupIds, Long minId, 36 + default List<ImGroupMessageDO> selectListByMinId(Long userId, Collection<Long> groupIds, Long minId,
34 LocalDateTime minSendTime, Integer size) { 37 LocalDateTime minSendTime, Integer size) {
35 QueryWrapperX<ImGroupMessageDO> wrapper = new QueryWrapperX<>(); 38 QueryWrapperX<ImGroupMessageDO> wrapper = new QueryWrapperX<>();
36 wrapper.in("group_id", groupIds) 39 wrapper.in("group_id", groupIds)
37 .gt("id", minId) 40 .gt("id", minId)
38 .gt("send_time", minSendTime) 41 .gt("send_time", minSendTime)
39 - .orderByAsc("id");  
40 - wrapper.limitN(size);  
41 - return selectList(wrapper);  
42 - }  
43 -  
44 - /**  
45 - * 查询"退群前"的离线消息(退群成员使用)  
46 - * <p>  
47 - * 语义:用户已退出某群,但仍需把 {@code minId} 之后、{@code minSendTime} 之后、不晚于退群时间的消息补齐到本地,便于前端看到完整上下文。  
48 - * <p>  
49 - * 撤回消息(status=RECALL)保留返回,与在群成员的 {@link #selectListByMinId} 行为一致,由前端按撤回信号渲染「消息已撤回」气泡。  
50 - *  
51 - * @param groupId 群编号  
52 - * @param minId 最小消息 id(不含)  
53 - * @param minSendTime 最早发送时间(不含)  
54 - * @param quitTime 退群时间(含),仅返回退群当时已存在的消息  
55 - * @param size 拉取数量  
56 - * @return 消息列表(按 id 升序)  
57 - */  
58 - default List<ImGroupMessageDO> selectListByGroupIdAndMinIdAndQuitTimeBefore(Long groupId, Long minId,  
59 - LocalDateTime minSendTime,  
60 - LocalDateTime quitTime,  
61 - Integer size) {  
62 - QueryWrapperX<ImGroupMessageDO> wrapper = new QueryWrapperX<>();  
63 - wrapper.eq("group_id", groupId)  
64 - .gt("id", minId)  
65 - .gt("send_time", minSendTime)  
66 - .le("send_time", quitTime) 42 + .apply(MyBatisUtils.findInSet("receiver_user_ids"), userId)
67 .orderByAsc("id"); 43 .orderByAsc("id");
68 wrapper.limitN(size); 44 wrapper.limitN(size);
69 return selectList(wrapper); 45 return selectList(wrapper);
@@ -72,17 +48,17 @@ public interface ImGroupMessageMapper extends BaseMapperX&lt;ImGroupMessageDO&gt; { @@ -72,17 +48,17 @@ public interface ImGroupMessageMapper extends BaseMapperX&lt;ImGroupMessageDO&gt; {
72 /** 48 /**
73 * 查询群聊历史消息(游标拉取) 49 * 查询群聊历史消息(游标拉取)
74 * 50 *
75 - * @param groupId 群编号  
76 - * @param maxId 起始消息 id(不含),为空则从最新开始  
77 - * @param limit 拉取数量  
78 - * @param joinTime 入群时间,仅返回入群之后的消息 51 + * @param userId 当前用户编号
  52 + * @param groupId 群编号
  53 + * @param maxId 起始消息 id(不含),为空则从最新开始
  54 + * @param limit 拉取数量
79 * @return 消息列表(按 id 倒序) 55 * @return 消息列表(按 id 倒序)
80 */ 56 */
81 - default List<ImGroupMessageDO> selectHistoryList(Long groupId, Long maxId, Integer limit, LocalDateTime joinTime) { 57 + default List<ImGroupMessageDO> selectHistoryListByUser(Long userId, Long groupId, Long maxId, Integer limit) {
82 QueryWrapperX<ImGroupMessageDO> wrapper = new QueryWrapperX<>(); 58 QueryWrapperX<ImGroupMessageDO> wrapper = new QueryWrapperX<>();
83 wrapper.eq("group_id", groupId) 59 wrapper.eq("group_id", groupId)
84 .lt(maxId != null, "id", maxId) 60 .lt(maxId != null, "id", maxId)
85 - .ge(joinTime != null, "send_time", joinTime) 61 + .apply(MyBatisUtils.findInSet("receiver_user_ids"), userId)
86 .orderByDesc("id"); 62 .orderByDesc("id");
87 wrapper.limitN(limit); 63 wrapper.limitN(limit);
88 return selectList(wrapper); 64 return selectList(wrapper);
@@ -108,7 +84,7 @@ public interface ImGroupMessageMapper extends BaseMapperX&lt;ImGroupMessageDO&gt; { @@ -108,7 +84,7 @@ public interface ImGroupMessageMapper extends BaseMapperX&lt;ImGroupMessageDO&gt; {
108 default List<ImGroupMessageDO> selectListByGroupIdAndPendingReceipt(Long groupId, Long minId, Long maxId) { 84 default List<ImGroupMessageDO> selectListByGroupIdAndPendingReceipt(Long groupId, Long minId, Long maxId) {
109 return selectList(new LambdaQueryWrapperX<ImGroupMessageDO>() 85 return selectList(new LambdaQueryWrapperX<ImGroupMessageDO>()
110 .eq(ImGroupMessageDO::getGroupId, groupId) 86 .eq(ImGroupMessageDO::getGroupId, groupId)
111 - .eq(ImGroupMessageDO::getReceiptStatus, ImGroupMessageReceiptStatusEnum.PENDING.getStatus()) 87 + .eq(ImGroupMessageDO::getReceiptStatus, ImMessageReceiptStatusEnum.PENDING.getStatus())
112 .gt(minId != null, ImGroupMessageDO::getId, minId) 88 .gt(minId != null, ImGroupMessageDO::getId, minId)
113 .le(ImGroupMessageDO::getId, maxId) 89 .le(ImGroupMessageDO::getId, maxId)
114 .ne(ImGroupMessageDO::getStatus, ImMessageStatusEnum.RECALL.getStatus())); 90 .ne(ImGroupMessageDO::getStatus, ImMessageStatusEnum.RECALL.getStatus()));
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/message/ImPrivateMessageMapper.java
@@ -67,23 +67,13 @@ public interface ImPrivateMessageMapper extends BaseMapperX&lt;ImPrivateMessageDO&gt; @@ -67,23 +67,13 @@ public interface ImPrivateMessageMapper extends BaseMapperX&lt;ImPrivateMessageDO&gt;
67 .eq(ImPrivateMessageDO::getClientMessageId, clientMessageId)); 67 .eq(ImPrivateMessageDO::getClientMessageId, clientMessageId));
68 } 68 }
69 69
70 - default Long selectMaxIdBySenderIdAndReceiverIdAndStatus(Long senderId, Long receiverId, Integer status) {  
71 - ImPrivateMessageDO message = selectOne(new LambdaQueryWrapperX<ImPrivateMessageDO>()  
72 - .eq(ImPrivateMessageDO::getSenderId, senderId)  
73 - .eq(ImPrivateMessageDO::getReceiverId, receiverId)  
74 - .eq(ImPrivateMessageDO::getStatus, status)  
75 - .orderByDesc(ImPrivateMessageDO::getId)  
76 - .last("LIMIT 1"));  
77 - return message != null ? message.getId() : null;  
78 - }  
79 -  
80 - default int updateBySenderIdAndReceiverIdAndIdLeAndStatus(Long senderId, Long receiverId, Long maxMessageId,  
81 - Integer whereStatus, ImPrivateMessageDO updateObj) { 70 + default int updateBySenderIdAndReceiverIdAndIdLeAndReceiptStatus(Long senderId, Long receiverId, Long maxMessageId,
  71 + Integer whereReceiptStatus, ImPrivateMessageDO updateObj) {
82 return update(updateObj, new LambdaQueryWrapperX<ImPrivateMessageDO>() 72 return update(updateObj, new LambdaQueryWrapperX<ImPrivateMessageDO>()
83 .eq(ImPrivateMessageDO::getSenderId, senderId) 73 .eq(ImPrivateMessageDO::getSenderId, senderId)
84 .eq(ImPrivateMessageDO::getReceiverId, receiverId) 74 .eq(ImPrivateMessageDO::getReceiverId, receiverId)
85 .le(ImPrivateMessageDO::getId, maxMessageId) 75 .le(ImPrivateMessageDO::getId, maxMessageId)
86 - .eq(ImPrivateMessageDO::getStatus, whereStatus)); 76 + .eq(ImPrivateMessageDO::getReceiptStatus, whereReceiptStatus));
87 } 77 }
88 78
89 default PageResult<ImPrivateMessageDO> selectPage(ImPrivateMessageManagerPageReqVO reqVO) { 79 default PageResult<ImPrivateMessageDO> selectPage(ImPrivateMessageManagerPageReqVO reqVO) {
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/dal/redis/RedisKeyConstants.java
@@ -9,20 +9,6 @@ package cn.iocoder.yudao.module.im.dal.redis; @@ -9,20 +9,6 @@ package cn.iocoder.yudao.module.im.dal.redis;
9 public interface RedisKeyConstants { 9 public interface RedisKeyConstants {
10 10
11 /** 11 /**
12 - * 群消息已读位置  
13 - * KEY 格式: im:group:message:read:{groupId}  
14 - * VALUE 数据类型: Hash (field: userId, value: maxReadMessageId)  
15 - */  
16 - String GROUP_MESSAGE_READ = "im:group:message:read:%s";  
17 -  
18 - /**  
19 - * 频道消息已读位置  
20 - * KEY 格式: im:channel:message:read:{channelId}  
21 - * VALUE 数据类型: Hash (field: userId, value: maxReadMessageId)  
22 - */  
23 - String CHANNEL_MESSAGE_READ = "im:channel:message:read:%s";  
24 -  
25 - /**  
26 * 好友关系状态缓存(合并「是否好友」+「是否拉黑」两态) 12 * 好友关系状态缓存(合并「是否好友」+「是否拉黑」两态)
27 * <p> 13 * <p>
28 * KEY 格式:friend_state:{userId}_{friendUserId} 14 * KEY 格式:friend_state:{userId}_{friendUserId}
@@ -44,7 +30,7 @@ public interface RedisKeyConstants { @@ -44,7 +30,7 @@ public interface RedisKeyConstants {
44 * KEY 格式:group_member_ids:{groupId} 30 * KEY 格式:group_member_ids:{groupId}
45 * VALUE 数据类型:List<Long> 31 * VALUE 数据类型:List<Long>
46 * <p> 32 * <p>
47 - * 说明:只缓存轻量的 userId 列表,适合"群消息推送目标"这类只关心 userId 的场景。 33 + * 说明:只缓存轻量的 userId 列表,适合「群消息推送目标」这类只关心 userId 的场景
48 */ 34 */
49 String GROUP_MEMBER_IDS = "group_member_ids"; 35 String GROUP_MEMBER_IDS = "group_member_ids";
50 36
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/redis/message/ImChannelMessageReadRedisDAO.java deleted
1 -package cn.iocoder.yudao.module.im.dal.redis.message;  
2 -  
3 -import cn.hutool.core.convert.Convert;  
4 -import jakarta.annotation.Resource;  
5 -import org.springframework.data.redis.core.StringRedisTemplate;  
6 -import org.springframework.stereotype.Repository;  
7 -  
8 -import static cn.iocoder.yudao.module.im.dal.redis.RedisKeyConstants.CHANNEL_MESSAGE_READ;  
9 -  
10 -/**  
11 - * IM 频道消息已读位置 Redis DAO  
12 - *  
13 - * @author 芋道源码  
14 - */  
15 -@Repository  
16 -public class ImChannelMessageReadRedisDAO {  
17 -  
18 - @Resource  
19 - private StringRedisTemplate stringRedisTemplate;  
20 -  
21 - /**  
22 - * 更新用户在某频道的最大已读消息编号  
23 - *  
24 - * @param channelId 频道编号  
25 - * @param userId 用户编号  
26 - * @param maxMessageId 最大已读消息编号  
27 - */  
28 - public void updateReadMaxMessageId(Long channelId, Long userId, Long maxMessageId) {  
29 - String key = formatKey(channelId);  
30 - stringRedisTemplate.opsForHash().put(key, userId.toString(), maxMessageId.toString());  
31 - }  
32 -  
33 - /**  
34 - * 获取用户在某频道的最大已读消息编号  
35 - *  
36 - * @param channelId 频道编号  
37 - * @param userId 用户编号  
38 - * @return 最大已读消息编号;不存在则返回 null  
39 - */  
40 - public Long getReadMaxMessageId(Long channelId, Long userId) {  
41 - String key = formatKey(channelId);  
42 - Object val = stringRedisTemplate.opsForHash().get(key, userId.toString());  
43 - return Convert.toLong(val);  
44 - }  
45 -  
46 - private static String formatKey(Long channelId) {  
47 - return String.format(CHANNEL_MESSAGE_READ, channelId);  
48 - }  
49 -  
50 -}  
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/redis/message/ImGroupMessageReadRedisDAO.java deleted
1 -package cn.iocoder.yudao.module.im.dal.redis.message;  
2 -  
3 -import cn.hutool.core.convert.Convert;  
4 -import jakarta.annotation.Resource;  
5 -import org.springframework.data.redis.core.StringRedisTemplate;  
6 -import org.springframework.stereotype.Repository;  
7 -  
8 -import java.util.Collection;  
9 -import java.util.HashMap;  
10 -import java.util.Map;  
11 -  
12 -import static cn.iocoder.yudao.module.im.dal.redis.RedisKeyConstants.GROUP_MESSAGE_READ;  
13 -  
14 -/**  
15 - * IM 群消息已读位置 Redis DAO  
16 - *  
17 - * @author 芋道源码  
18 - */  
19 -@Repository  
20 -public class ImGroupMessageReadRedisDAO {  
21 -  
22 - @Resource  
23 - private StringRedisTemplate stringRedisTemplate;  
24 -  
25 - /**  
26 - * 更新用户在某群的最大已读消息编号  
27 - *  
28 - * @param groupId 群编号  
29 - * @param userId 用户编号  
30 - * @param maxMessageId 最大已读消息编号  
31 - */  
32 - public void updateReadMaxMessageId(Long groupId, Long userId, Long maxMessageId) {  
33 - String key = formatKey(groupId);  
34 - stringRedisTemplate.opsForHash().put(key, userId.toString(), maxMessageId.toString());  
35 - }  
36 -  
37 - /**  
38 - * 获取用户在某群的最大已读消息编号  
39 - *  
40 - * @param groupId 群编号  
41 - * @param userId 用户编号  
42 - * @return 最大已读消息编号,不存在则返回 null  
43 - */  
44 - public Long getReadMaxMessageId(Long groupId, Long userId) {  
45 - String key = formatKey(groupId);  
46 - Object val = stringRedisTemplate.opsForHash().get(key, userId.toString());  
47 - return Convert.toLong(val);  
48 - }  
49 -  
50 - /**  
51 - * 获取某群所有用户的已读位置  
52 - *  
53 - * @param groupId 群编号  
54 - * @return userId → maxReadMessageId 映射  
55 - */  
56 - public Map<Long, Long> getReadMaxMessageIdMap(Long groupId) {  
57 - String key = formatKey(groupId);  
58 - Map<Object, Object> entries = stringRedisTemplate.opsForHash().entries(key);  
59 - // 转换为 Long → Long 的 Map  
60 - Map<Long, Long> result = new HashMap<>(entries.size());  
61 - entries.forEach((k, v) -> result.put(Long.parseLong(k.toString()), Long.parseLong(v.toString())));  
62 - return result;  
63 - }  
64 -  
65 - /**  
66 - * 删除用户在某群的已读位置  
67 - *  
68 - * @param groupId 群编号  
69 - * @param userId 用户编号  
70 - */  
71 - public void deleteReadMaxMessageId(Long groupId, Long userId) {  
72 - String key = formatKey(groupId);  
73 - stringRedisTemplate.opsForHash().delete(key, userId.toString());  
74 - }  
75 -  
76 - /**  
77 - * 批量删除用户在某群的已读位置  
78 - *  
79 - * @param groupId 群编号  
80 - * @param userIds 用户编号集合  
81 - */  
82 - public void deleteReadMaxMessageIds(Long groupId, Collection<Long> userIds) {  
83 - String key = formatKey(groupId);  
84 - Object[] hashKeys = userIds.stream().map(String::valueOf).toArray();  
85 - stringRedisTemplate.opsForHash().delete(key, hashKeys);  
86 - }  
87 -  
88 - /**  
89 - * 删除某群所有用户的已读位置(整个 Hash Key)  
90 - *  
91 - * @param groupId 群编号  
92 - */  
93 - public void deleteReadMaxMessageIdMap(Long groupId) {  
94 - String key = formatKey(groupId);  
95 - stringRedisTemplate.delete(key);  
96 - }  
97 -  
98 - private static String formatKey(Long groupId) {  
99 - return String.format(GROUP_MESSAGE_READ, groupId);  
100 - }  
101 -  
102 -}  
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 /**
@@ -128,10 +128,6 @@ public enum ImMessageTypeEnum implements ArrayValuable&lt;Integer&gt; { @@ -128,10 +128,6 @@ public enum ImMessageTypeEnum implements ArrayValuable&lt;Integer&gt; {
128 RTC_CALL_END(1611, "通话结束", true, false), 128 RTC_CALL_END(1611, "通话结束", true, false),
129 129
130 // ========== 好友通知(1201-1210 直接复用 OpenIM 段位编号) ========== 130 // ========== 好友通知(1201-1210 直接复用 OpenIM 段位编号) ==========
131 - // TODO @芋艿:FRIEND_REQUEST_* 与 GROUP_REQUEST_* 都是 persistent=false 的 SysMsg,离线 pull 拉不到,  
132 - // 目前可能丢失「实时 toast 提醒」体验(业务状态不丢,前端上线 fetch{Friend,Group}RequestList 能补回来);  
133 - // 未来思考下怎么优化:候选方案 1)改 persistent=true 入私聊消息流 + 让客户端按 type 自渲染;  
134 - // 2)服务端补一个「未读通知拉取」接口给前端冷启动调用。  
135 /** 131 /**
136 * 对应 OpenIM:FriendApplicationApprovedNotification 1201 132 * 对应 OpenIM:FriendApplicationApprovedNotification 1201
137 * 对应自己的类:FriendRequestApprovedNotification 133 * 对应自己的类:FriendRequestApprovedNotification
@@ -285,9 +281,9 @@ public enum ImMessageTypeEnum implements ArrayValuable&lt;Integer&gt; { @@ -285,9 +281,9 @@ public enum ImMessageTypeEnum implements ArrayValuable&lt;Integer&gt; {
285 /** 281 /**
286 * 对应 OpenIM:sdkws.GroupMemberInfoSetTips(GroupMemberInfoSetNotification 1516,窄化到 displayUserName) 282 * 对应 OpenIM:sdkws.GroupMemberInfoSetTips(GroupMemberInfoSetNotification 1516,窄化到 displayUserName)
287 * 对应自己的类:GroupMemberNicknameUpdateNotification 283 * 对应自己的类:GroupMemberNicknameUpdateNotification
288 - * 场景:成员修改自己在群里的昵称,全员广播;前端按 displayUserName 局部更新对应 member 284 + * 场景:成员修改自己在群里的昵称,在线成员同步对应 member
289 */ 285 */
290 - GROUP_MEMBER_NICKNAME_UPDATE(1516, "成员昵称变更", true, false), 286 + GROUP_MEMBER_NICKNAME_UPDATE(1516, "成员昵称变更", false, false),
291 /** 287 /**
292 * 对应 OpenIM:GroupMemberSetToAdminNotification 1517 288 * 对应 OpenIM:GroupMemberSetToAdminNotification 1517
293 * 对应自己的类:GroupAdminAddNotification 289 * 对应自己的类:GroupAdminAddNotification
@@ -339,7 +335,7 @@ public enum ImMessageTypeEnum implements ArrayValuable&lt;Integer&gt; { @@ -339,7 +335,7 @@ public enum ImMessageTypeEnum implements ArrayValuable&lt;Integer&gt; {
339 */ 335 */
340 GROUP_BANNED(1533, "群封禁变更", true, false); 336 GROUP_BANNED(1533, "群封禁变更", true, false);
341 337
342 - 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);
343 339
344 private static final Set<Integer> FRIEND_NOTIFICATION_TYPES = CollUtil.newHashSet( 340 private static final Set<Integer> FRIEND_NOTIFICATION_TYPES = CollUtil.newHashSet(
345 FRIEND_REQUEST_APPROVED.type, 341 FRIEND_REQUEST_APPROVED.type,
@@ -396,8 +392,8 @@ public enum ImMessageTypeEnum implements ArrayValuable&lt;Integer&gt; { @@ -396,8 +392,8 @@ public enum ImMessageTypeEnum implements ArrayValuable&lt;Integer&gt; {
396 * @param type 消息类型 392 * @param type 消息类型
397 * @return 枚举实例 393 * @return 枚举实例
398 */ 394 */
399 - public static ImMessageTypeEnum validate(Integer type) {  
400 - 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());
401 Assert.notNull(result, "未注册的消息类型 type={}", type); 397 Assert.notNull(result, "未注册的消息类型 type={}", type);
402 return result; 398 return result;
403 } 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/enums/message/ImGroupMessageReceiptStatusEnum.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/enums/message/ImMessageReceiptStatusEnum.java
@@ -7,19 +7,19 @@ import lombok.Getter; @@ -7,19 +7,19 @@ import lombok.Getter;
7 import java.util.Arrays; 7 import java.util.Arrays;
8 8
9 /** 9 /**
10 - * IM 群消息回执状态枚举 10 + * IM 消息回执状态枚举
11 * 11 *
12 * @author 芋道源码 12 * @author 芋道源码
13 */ 13 */
14 @Getter 14 @Getter
15 @AllArgsConstructor 15 @AllArgsConstructor
16 -public enum ImGroupMessageReceiptStatusEnum implements ArrayValuable<Integer> { 16 +public enum ImMessageReceiptStatusEnum implements ArrayValuable<Integer> {
17 17
18 NO_RECEIPT(0, "不需要回执"), 18 NO_RECEIPT(0, "不需要回执"),
19 PENDING(1, "待完成"), 19 PENDING(1, "待完成"),
20 DONE(2, "已完成"); 20 DONE(2, "已完成");
21 21
22 - public static final Integer[] ARRAYS = Arrays.stream(values()).map(ImGroupMessageReceiptStatusEnum::getStatus).toArray(Integer[]::new); 22 + public static final Integer[] ARRAYS = Arrays.stream(values()).map(ImMessageReceiptStatusEnum::getStatus).toArray(Integer[]::new);
23 23
24 /** 24 /**
25 * 状态 25 * 状态
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/enums/message/ImMessageStatusEnum.java
@@ -8,9 +8,6 @@ import java.util.Arrays; @@ -8,9 +8,6 @@ import java.util.Arrays;
8 8
9 /** 9 /**
10 * IM 消息状态枚举 10 * IM 消息状态枚举
11 - * <p>  
12 - * 私聊:SENDING(-1, 仅客户端) / UNREAD(0) / RECALL(2) / READ(3)  
13 - * 群聊:SENDING(-1, 仅客户端) / UNREAD(0, 作为正常状态) / RECALL(2)  
14 * 11 *
15 * @author 芋道源码 12 * @author 芋道源码
16 */ 13 */
@@ -19,9 +16,8 @@ import java.util.Arrays; @@ -19,9 +16,8 @@ import java.util.Arrays;
19 public enum ImMessageStatusEnum implements ArrayValuable<Integer> { 16 public enum ImMessageStatusEnum implements ArrayValuable<Integer> {
20 17
21 SENDING(-1, "发送中"), // 仅客户端使用 18 SENDING(-1, "发送中"), // 仅客户端使用
22 - UNREAD(0, "未读"), // 私聊=未读,群聊=正常(初始状态)  
23 - RECALL(2, "已撤回"),  
24 - READ(3, "已读"); // 仅私聊使用;群聊已读通过 Redis 已读位置实现 19 + NORMAL(0, "正常"), // 私聊 / 群聊的正常(初始)状态
  20 + RECALL(2, "已撤回");
25 21
26 public static final Integer[] ARRAYS = Arrays.stream(values()).map(ImMessageStatusEnum::getStatus).toArray(Integer[]::new); 22 public static final Integer[] ARRAYS = Arrays.stream(values()).map(ImMessageStatusEnum::getStatus).toArray(Integer[]::new);
27 23
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/enums/rtc/ImRtcParticipantStatusEnum.java
@@ -24,7 +24,6 @@ import java.util.Objects; @@ -24,7 +24,6 @@ import java.util.Objects;
24 @Getter 24 @Getter
25 public enum ImRtcParticipantStatusEnum implements ArrayValuable<Integer> { 25 public enum ImRtcParticipantStatusEnum implements ArrayValuable<Integer> {
26 26
27 - // TODO @芋艿:hand up 要不要也搞下。  
28 INVITING(10, "邀请中"), // 已发出 invite,等被叫响应 27 INVITING(10, "邀请中"), // 已发出 invite,等被叫响应
29 JOINED(20, "已加入"), // 已 connect 进 LiveKit 房间 28 JOINED(20, "已加入"), // 已 connect 进 LiveKit 房间
30 REJECTED(30, "已拒绝"), // 接通前点拒接 29 REJECTED(30, "已拒绝"), // 接通前点拒接
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/mq/consumer/friend/AdminUserProfileUpdateConsumer.java
@@ -2,11 +2,11 @@ package cn.iocoder.yudao.module.im.mq.consumer.friend; @@ -2,11 +2,11 @@ package cn.iocoder.yudao.module.im.mq.consumer.friend;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.iocoder.yudao.module.im.dal.dataobject.friend.ImFriendDO; 4 import cn.iocoder.yudao.module.im.dal.dataobject.friend.ImFriendDO;
5 -import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum; 5 +import cn.iocoder.yudao.module.im.enums.ImContentTypeEnum;
  6 +import cn.iocoder.yudao.module.im.enums.ImConversationTypeEnum;
6 import cn.iocoder.yudao.module.im.service.friend.ImFriendService; 7 import cn.iocoder.yudao.module.im.service.friend.ImFriendService;
7 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService; 8 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService;
8 -import cn.iocoder.yudao.module.im.service.websocket.dto.ImPrivateMessageDTO;  
9 -import cn.iocoder.yudao.module.im.service.websocket.dto.notification.friend.FriendInfoUpdatedNotification; 9 +import cn.iocoder.yudao.module.im.service.websocket.notification.friend.FriendInfoUpdatedNotification;
10 import cn.iocoder.yudao.module.system.api.message.user.AdminUserProfileUpdateMessage; 10 import cn.iocoder.yudao.module.system.api.message.user.AdminUserProfileUpdateMessage;
11 import jakarta.annotation.Resource; 11 import jakarta.annotation.Resource;
12 import lombok.extern.slf4j.Slf4j; 12 import lombok.extern.slf4j.Slf4j;
@@ -52,8 +52,9 @@ public class AdminUserProfileUpdateConsumer { @@ -52,8 +52,9 @@ public class AdminUserProfileUpdateConsumer {
52 try { 52 try {
53 FriendInfoUpdatedNotification payload = (FriendInfoUpdatedNotification) new FriendInfoUpdatedNotification() 53 FriendInfoUpdatedNotification payload = (FriendInfoUpdatedNotification) new FriendInfoUpdatedNotification()
54 .setOperatorUserId(userId).setFriendUserId(userId); 54 .setOperatorUserId(userId).setFriendUserId(userId);
55 - websocketService.sendPrivateMessageAsync(friend.getFriendUserId(), ImPrivateMessageDTO.ofFriendNotification(  
56 - ImMessageTypeEnum.FRIEND_INFO_UPDATED.getType(), userId, friend.getFriendUserId(), payload)); 55 + websocketService.sendNotificationAsync(friend.getFriendUserId(),
  56 + ImConversationTypeEnum.NONE.getType(),
  57 + ImContentTypeEnum.FRIEND_INFO_UPDATED.getType(), payload);
57 successCount++; 58 successCount++;
58 } catch (Exception e) { 59 } catch (Exception e) {
59 log.warn("[onMessage][userId({}) friendUserId({}) 推送失败]", 60 log.warn("[onMessage][userId({}) friendUserId({}) 推送失败]",
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ImConversationReadService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.im.service.conversation;
  2 +
  3 +import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ImConversationReadDO;
  4 +
  5 +import java.util.Collection;
  6 +import java.util.List;
  7 +import java.util.Map;
  8 +
  9 +/**
  10 + * IM 会话读位置 Service 接口
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +public interface ImConversationReadService {
  15 +
  16 + /**
  17 + * 更新用户在某会话的最大已读位置(单调递增,乱序 / 并发上报不会回退)
  18 + *
  19 + * @param userId 用户编号
  20 + * @param conversationType 会话类型
  21 + * @param conversationId 会话编号
  22 + * @param readMessageId 已读到的最大消息编号
  23 + * @return 读位置是否前进;true 时调用方才需要下发已读 / 回执事件
  24 + */
  25 + boolean updateConversationReadPosition(Long userId, Integer conversationType, Long conversationId, Long readMessageId);
  26 +
  27 + /**
  28 + * 获取用户在某会话的最大已读位置
  29 + *
  30 + * @param userId 用户编号
  31 + * @param conversationType 会话类型
  32 + * @param conversationId 会话编号
  33 + * @return 最大已读消息编号;不存在则返回 null
  34 + */
  35 + Long getConversationReadMessageId(Long userId, Integer conversationType, Long conversationId);
  36 +
  37 + /**
  38 + * 获取某会话内所有用户的读位置(用于群回执人数聚合)
  39 + *
  40 + * @param conversationType 会话类型
  41 + * @param conversationId 会话编号
  42 + * @return userId → 最大已读消息编号
  43 + */
  44 + Map<Long, Long> getUserReadMessageIdMap(Integer conversationType, Long conversationId);
  45 +
  46 + /**
  47 + * 批量获取某用户在多个会话的读位置(用于频道批量读位置、重连后按活跃会话补偿)
  48 + *
  49 + * @param userId 用户编号
  50 + * @param conversationType 会话类型
  51 + * @param conversationIds 会话编号集合
  52 + * @return conversationId → 最大已读消息编号
  53 + */
  54 + Map<Long, Long> getConversationReadMessageIdMap(Long userId, Integer conversationType, Collection<Long> conversationIds);
  55 +
  56 + /**
  57 + * 增量拉取当前用户的会话读位置(重连 / 离线补偿:按 update_time + id 游标)
  58 + *
  59 + * @param userId 用户编号
  60 + * @param lastUpdateTime 上次拉取到的最新更新时间(毫秒时间戳);首次拉取传 null
  61 + * @param lastId 上次拉取到的最后一条记录 id;首次拉取传 null
  62 + * @param limit 单次拉取条数
  63 + * @return 会话读位置列表,按更新时间、id 正序
  64 + */
  65 + List<ImConversationReadDO> pullConversationReadList(Long userId, Long lastUpdateTime, Long lastId, Integer limit);
  66 +
  67 +}
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ImConversationReadServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.im.service.conversation;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ImConversationReadDO;
  5 +import cn.iocoder.yudao.module.im.dal.mysql.conversation.ImConversationReadMapper;
  6 +import jakarta.annotation.Resource;
  7 +import lombok.extern.slf4j.Slf4j;
  8 +import org.springframework.dao.DuplicateKeyException;
  9 +import org.springframework.stereotype.Service;
  10 +
  11 +import java.time.LocalDateTime;
  12 +import java.util.Collection;
  13 +import java.util.Collections;
  14 +import java.util.List;
  15 +import java.util.Map;
  16 +
  17 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
  18 +
  19 +/**
  20 + * IM 会话读位置 Service 实现类
  21 + *
  22 + * @author 芋道源码
  23 + */
  24 +@Service
  25 +@Slf4j
  26 +public class ImConversationReadServiceImpl implements ImConversationReadService {
  27 +
  28 + @Resource
  29 + private ImConversationReadMapper conversationReadMapper;
  30 +
  31 + @Override
  32 + public boolean updateConversationReadPosition(Long userId, Integer conversationType, Long conversationId, Long readMessageId) {
  33 + LocalDateTime now = LocalDateTime.now();
  34 + // 1. 不存在则插入;并发下唯一键冲突,降级为回查 + CAS 更新
  35 + ImConversationReadDO existing = conversationReadMapper.selectByUserIdAndConversation(
  36 + userId, conversationType, conversationId);
  37 + if (existing == null) {
  38 + try {
  39 + conversationReadMapper.insert(new ImConversationReadDO().setUserId(userId)
  40 + .setConversationType(conversationType).setTargetId(conversationId)
  41 + .setMessageId(readMessageId).setReadTime(now));
  42 + return true;
  43 + } catch (DuplicateKeyException e) {
  44 + log.warn("[updateConversationReadPosition][userId({}) type({}) conversationId({}) 并发插入冲突,回查更新]",
  45 + userId, conversationType, conversationId);
  46 + existing = conversationReadMapper.selectByUserIdAndConversation(userId, conversationType, conversationId);
  47 + }
  48 + }
  49 + if (existing == null) {
  50 + return false;
  51 + }
  52 +
  53 + // 2. CAS 单调更新:mapper 内 WHERE message_id < ? 保证乱序 / 并发不回退;影响行数 > 0 即读位置前进
  54 + return conversationReadMapper.updateReadMessageIdToLarger(existing.getId(), readMessageId, now) > 0;
  55 + }
  56 +
  57 + @Override
  58 + public Long getConversationReadMessageId(Long userId, Integer conversationType, Long conversationId) {
  59 + ImConversationReadDO read = conversationReadMapper.selectByUserIdAndConversation(
  60 + userId, conversationType, conversationId);
  61 + return read != null ? read.getMessageId() : null;
  62 + }
  63 +
  64 + @Override
  65 + public Map<Long, Long> getUserReadMessageIdMap(Integer conversationType, Long conversationId) {
  66 + return convertMap(conversationReadMapper.selectListByConversation(conversationType, conversationId),
  67 + ImConversationReadDO::getUserId, ImConversationReadDO::getMessageId);
  68 + }
  69 +
  70 + @Override
  71 + public Map<Long, Long> getConversationReadMessageIdMap(Long userId, Integer conversationType,
  72 + Collection<Long> conversationIds) {
  73 + if (CollUtil.isEmpty(conversationIds)) {
  74 + return Collections.emptyMap();
  75 + }
  76 + List<ImConversationReadDO> list = conversationReadMapper.selectListByUserIdAndConversations(
  77 + userId, conversationType, conversationIds);
  78 + return convertMap(list, ImConversationReadDO::getTargetId, ImConversationReadDO::getMessageId);
  79 + }
  80 +
  81 + @Override
  82 + public List<ImConversationReadDO> pullConversationReadList(Long userId, Long lastUpdateTime, Long lastId, Integer limit) {
  83 + return conversationReadMapper.selectPullListByUserId(userId, lastUpdateTime, lastId, limit);
  84 + }
  85 +
  86 +}
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/friend/ImFriendRequestService.java
@@ -51,6 +51,17 @@ public interface ImFriendRequestService { @@ -51,6 +51,17 @@ public interface ImFriendRequestService {
51 List<ImFriendRequestDO> getMyFriendRequestList(Long userId, Long maxId, Integer limit); 51 List<ImFriendRequestDO> getMyFriendRequestList(Long userId, Long maxId, Integer limit);
52 52
53 /** 53 /**
  54 + * 增量拉取「我相关」的好友申请(重连 / 离线补偿:双向 OR,按 update_time + id 游标)
  55 + *
  56 + * @param userId 用户编号
  57 + * @param lastUpdateTime 上次拉取到的最新更新时间(毫秒时间戳);首次拉取传 null
  58 + * @param lastId 上次拉取到的最后一条记录 id;首次拉取传 null
  59 + * @param limit 单次拉取条数
  60 + * @return 申请记录列表,按更新时间、id 正序
  61 + */
  62 + List<ImFriendRequestDO> pullFriendRequestList(Long userId, Long lastUpdateTime, Long lastId, Integer limit);
  63 +
  64 + /**
54 * 按 id 单查申请记录;通用读接口,调用方自行做越权过滤 65 * 按 id 单查申请记录;通用读接口,调用方自行做越权过滤
55 */ 66 */
56 ImFriendRequestDO getFriendRequest(Long id); 67 ImFriendRequestDO getFriendRequest(Long id);
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/friend/ImFriendRequestServiceImpl.java
@@ -14,13 +14,13 @@ import cn.iocoder.yudao.module.im.dal.dataobject.friend.ImFriendRequestDO; @@ -14,13 +14,13 @@ import cn.iocoder.yudao.module.im.dal.dataobject.friend.ImFriendRequestDO;
14 import cn.iocoder.yudao.module.im.dal.mysql.friend.ImFriendRequestMapper; 14 import cn.iocoder.yudao.module.im.dal.mysql.friend.ImFriendRequestMapper;
15 import cn.iocoder.yudao.module.im.enums.friend.ImFriendRequestHandleResultEnum; 15 import cn.iocoder.yudao.module.im.enums.friend.ImFriendRequestHandleResultEnum;
16 import cn.iocoder.yudao.module.im.enums.friend.ImFriendStateEnum; 16 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.ImContentTypeEnum;
  18 +import cn.iocoder.yudao.module.im.enums.ImConversationTypeEnum;
18 import cn.iocoder.yudao.module.im.framework.config.ImProperties; 19 import cn.iocoder.yudao.module.im.framework.config.ImProperties;
19 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService; 20 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; 21 +import cn.iocoder.yudao.module.im.service.websocket.notification.friend.FriendRequestApprovedNotification;
  22 +import cn.iocoder.yudao.module.im.service.websocket.notification.friend.FriendRequestNotification;
  23 +import cn.iocoder.yudao.module.im.service.websocket.notification.friend.FriendRequestRejectedNotification;
24 import cn.iocoder.yudao.module.system.api.user.AdminUserApi; 24 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
25 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; 25 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
26 import jakarta.annotation.Resource; 26 import jakarta.annotation.Resource;
@@ -105,8 +105,8 @@ public class ImFriendRequestServiceImpl implements ImFriendRequestService { @@ -105,8 +105,8 @@ public class ImFriendRequestServiceImpl implements ImFriendRequestService {
105 if (fromUser != null) { 105 if (fromUser != null) {
106 payload.setFromNickname(fromUser.getNickname()).setFromAvatar(fromUser.getAvatar()); 106 payload.setFromNickname(fromUser.getNickname()).setFromAvatar(fromUser.getAvatar());
107 } 107 }
108 - websocketService.sendPrivateMessageAsync(toUserId, ImPrivateMessageDTO.ofFriendNotification(  
109 - ImMessageTypeEnum.FRIEND_REQUEST_RECEIVED.getType(), fromUserId, toUserId, payload)); 108 + websocketService.sendNotificationAsync(toUserId, ImConversationTypeEnum.NONE.getType(),
  109 + ImContentTypeEnum.FRIEND_REQUEST_RECEIVED.getType(), payload);
110 110
111 // 4. 全局自动通过开关:注册 afterCommit 回调,事务提交后再走同意流程 111 // 4. 全局自动通过开关:注册 afterCommit 回调,事务提交后再走同意流程
112 // 回调内 try/catch 兜底 —— afterCommit 异常会被 Spring 静默吞掉,否则同意失败时申请方永远等不到 APPROVED 112 // 回调内 try/catch 兜底 —— afterCommit 异常会被 Spring 静默吞掉,否则同意失败时申请方永远等不到 APPROVED
@@ -172,8 +172,6 @@ public class ImFriendRequestServiceImpl implements ImFriendRequestService { @@ -172,8 +172,6 @@ public class ImFriendRequestServiceImpl implements ImFriendRequestService {
172 public void agreeFriendRequest(Long userId, Long requestId) { 172 public void agreeFriendRequest(Long userId, Long requestId) {
173 // 1.1 校验申请存在、未处理、操作人是接收方 173 // 1.1 校验申请存在、未处理、操作人是接收方
174 ImFriendRequestDO request = validateRequestForHandle(userId, requestId); 174 ImFriendRequestDO request = validateRequestForHandle(userId, requestId);
175 - // 1.2 复验双方用户有效  
176 - adminUserApi.validateUserList(ListUtil.of(request.getFromUserId(), request.getToUserId()));  
177 175
178 // 2. 乐观锁更新申请处理结果 176 // 2. 乐观锁更新申请处理结果
179 ImFriendRequestDO updateObj = new ImFriendRequestDO() 177 ImFriendRequestDO updateObj = new ImFriendRequestDO()
@@ -192,8 +190,8 @@ public class ImFriendRequestServiceImpl implements ImFriendRequestService { @@ -192,8 +190,8 @@ public class ImFriendRequestServiceImpl implements ImFriendRequestService {
192 FriendRequestApprovedNotification payload = (FriendRequestApprovedNotification) 190 FriendRequestApprovedNotification payload = (FriendRequestApprovedNotification)
193 new FriendRequestApprovedNotification().setRequestId(request.getId()) 191 new FriendRequestApprovedNotification().setRequestId(request.getId())
194 .setOperatorUserId(userId).setFriendUserId(userId); 192 .setOperatorUserId(userId).setFriendUserId(userId);
195 - websocketService.sendPrivateMessageAsync(request.getFromUserId(), ImPrivateMessageDTO.ofFriendNotification(  
196 - ImMessageTypeEnum.FRIEND_REQUEST_APPROVED.getType(), userId, request.getFromUserId(), payload)); 193 + websocketService.sendNotificationAsync(request.getFromUserId(), ImConversationTypeEnum.NONE.getType(),
  194 + ImContentTypeEnum.FRIEND_REQUEST_APPROVED.getType(), payload);
197 } 195 }
198 196
199 @Override 197 @Override
@@ -217,8 +215,8 @@ public class ImFriendRequestServiceImpl implements ImFriendRequestService { @@ -217,8 +215,8 @@ public class ImFriendRequestServiceImpl implements ImFriendRequestService {
217 new FriendRequestRejectedNotification().setRequestId(request.getId()) 215 new FriendRequestRejectedNotification().setRequestId(request.getId())
218 .setHandleContent(handleContent) 216 .setHandleContent(handleContent)
219 .setOperatorUserId(userId).setFriendUserId(userId); 217 .setOperatorUserId(userId).setFriendUserId(userId);
220 - websocketService.sendPrivateMessageAsync(request.getFromUserId(), ImPrivateMessageDTO.ofFriendNotification(  
221 - ImMessageTypeEnum.FRIEND_REQUEST_REJECTED.getType(), userId, request.getFromUserId(), payload)); 218 + websocketService.sendNotificationAsync(request.getFromUserId(), ImConversationTypeEnum.NONE.getType(),
  219 + ImContentTypeEnum.FRIEND_REQUEST_REJECTED.getType(), payload);
222 } 220 }
223 221
224 @Override 222 @Override
@@ -234,6 +232,11 @@ public class ImFriendRequestServiceImpl implements ImFriendRequestService { @@ -234,6 +232,11 @@ public class ImFriendRequestServiceImpl implements ImFriendRequestService {
234 } 232 }
235 233
236 @Override 234 @Override
  235 + public List<ImFriendRequestDO> pullFriendRequestList(Long userId, Long lastUpdateTime, Long lastId, Integer limit) {
  236 + return friendRequestMapper.selectPullListByUserId(userId, lastUpdateTime, lastId, limit);
  237 + }
  238 +
  239 + @Override
237 public ImFriendRequestDO getFriendRequest(Long id) { 240 public ImFriendRequestDO getFriendRequest(Long id) {
238 return friendRequestMapper.selectById(id); 241 return friendRequestMapper.selectById(id);
239 } 242 }
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/friend/ImFriendService.java
@@ -43,6 +43,11 @@ public interface ImFriendService { @@ -43,6 +43,11 @@ public interface ImFriendService {
43 List<ImFriendDO> getFriendList(Long userId); 43 List<ImFriendDO> getFriendList(Long userId);
44 44
45 /** 45 /**
  46 + * 增量拉取当前用户的好友关系(重连 / 离线补偿:含已删除,按 update_time + id 游标)
  47 + */
  48 + List<ImFriendDO> pullFriendList(Long userId, Long lastUpdateTime, Long lastId, Integer limit);
  49 +
  50 + /**
46 * 获得当前用户的有效好友列表(仅 ENABLE 状态) 51 * 获得当前用户的有效好友列表(仅 ENABLE 状态)
47 */ 52 */
48 List<ImFriendDO> getEnableFriendList(Long userId); 53 List<ImFriendDO> getEnableFriendList(Long userId);
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/friend/ImFriendServiceImpl.java
@@ -11,12 +11,12 @@ import cn.iocoder.yudao.module.im.dal.dataobject.friend.ImFriendDO; @@ -11,12 +11,12 @@ import cn.iocoder.yudao.module.im.dal.dataobject.friend.ImFriendDO;
11 import cn.iocoder.yudao.module.im.dal.dataobject.friend.ImFriendRequestDO; 11 import cn.iocoder.yudao.module.im.dal.dataobject.friend.ImFriendRequestDO;
12 import cn.iocoder.yudao.module.im.dal.mysql.friend.ImFriendMapper; 12 import cn.iocoder.yudao.module.im.dal.mysql.friend.ImFriendMapper;
13 import cn.iocoder.yudao.module.im.enums.friend.ImFriendStateEnum; 13 import cn.iocoder.yudao.module.im.enums.friend.ImFriendStateEnum;
14 -import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum; 14 +import cn.iocoder.yudao.module.im.enums.ImContentTypeEnum;
  15 +import cn.iocoder.yudao.module.im.enums.ImConversationTypeEnum;
15 import cn.iocoder.yudao.module.im.service.message.ImPrivateMessageService; 16 import cn.iocoder.yudao.module.im.service.message.ImPrivateMessageService;
16 import cn.iocoder.yudao.module.im.service.message.dto.ImPrivateMessageSendDTO; 17 import cn.iocoder.yudao.module.im.service.message.dto.ImPrivateMessageSendDTO;
17 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService; 18 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService;
18 -import cn.iocoder.yudao.module.im.service.websocket.dto.ImPrivateMessageDTO;  
19 -import cn.iocoder.yudao.module.im.service.websocket.dto.notification.friend.*; 19 +import cn.iocoder.yudao.module.im.service.websocket.notification.friend.*;
20 import jakarta.annotation.Resource; 20 import jakarta.annotation.Resource;
21 import lombok.extern.slf4j.Slf4j; 21 import lombok.extern.slf4j.Slf4j;
22 import org.springframework.cache.annotation.CacheEvict; 22 import org.springframework.cache.annotation.CacheEvict;
@@ -99,6 +99,11 @@ public class ImFriendServiceImpl implements ImFriendService { @@ -99,6 +99,11 @@ public class ImFriendServiceImpl implements ImFriendService {
99 } 99 }
100 100
101 @Override 101 @Override
  102 + public List<ImFriendDO> pullFriendList(Long userId, Long lastUpdateTime, Long lastId, Integer limit) {
  103 + return friendMapper.selectPullListByUserId(userId, lastUpdateTime, lastId, limit);
  104 + }
  105 +
  106 + @Override
102 public List<ImFriendDO> getEnableFriendList(Long userId) { 107 public List<ImFriendDO> getEnableFriendList(Long userId) {
103 return friendMapper.selectListByUserIdAndStatus(userId, CommonStatusEnum.ENABLE.getStatus()); 108 return friendMapper.selectListByUserIdAndStatus(userId, CommonStatusEnum.ENABLE.getStatus());
104 } 109 }
@@ -155,8 +160,8 @@ public class ImFriendServiceImpl implements ImFriendService { @@ -155,8 +160,8 @@ public class ImFriendServiceImpl implements ImFriendService {
155 FriendUpdateNotification payload = (FriendUpdateNotification) new FriendUpdateNotification() 160 FriendUpdateNotification payload = (FriendUpdateNotification) new FriendUpdateNotification()
156 .setDisplayName(reqVO.getDisplayName()).setSilent(reqVO.getSilent()).setPinned(reqVO.getPinned()) 161 .setDisplayName(reqVO.getDisplayName()).setSilent(reqVO.getSilent()).setPinned(reqVO.getPinned())
157 .setOperatorUserId(userId).setFriendUserId(reqVO.getFriendUserId()); 162 .setOperatorUserId(userId).setFriendUserId(reqVO.getFriendUserId());
158 - websocketService.sendPrivateMessageAsync(userId, ImPrivateMessageDTO.ofFriendNotification(  
159 - ImMessageTypeEnum.FRIEND_UPDATE.getType(), userId, userId, payload)); 163 + websocketService.sendNotificationAsync(userId, ImConversationTypeEnum.NONE.getType(),
  164 + ImContentTypeEnum.FRIEND_UPDATE.getType(), payload);
160 } 165 }
161 166
162 @Override 167 @Override
@@ -178,7 +183,7 @@ public class ImFriendServiceImpl implements ImFriendService { @@ -178,7 +183,7 @@ public class ImFriendServiceImpl implements ImFriendService {
178 FriendAddNotification payload = (FriendAddNotification) new FriendAddNotification() 183 FriendAddNotification payload = (FriendAddNotification) new FriendAddNotification()
179 .setOperatorUserId(fromUserId).setFriendUserId(toUserId); 184 .setOperatorUserId(fromUserId).setFriendUserId(toUserId);
180 privateMessageService.sendPrivateMessage(fromUserId, new ImPrivateMessageSendDTO() 185 privateMessageService.sendPrivateMessage(fromUserId, new ImPrivateMessageSendDTO()
181 - .setReceiverId(toUserId).setType(ImMessageTypeEnum.FRIEND_ADD.getType()).setContent(payload)); 186 + .setReceiverId(toUserId).setType(ImContentTypeEnum.FRIEND_ADD.getType()).setContent(payload));
182 } 187 }
183 188
184 @Override 189 @Override
@@ -197,7 +202,7 @@ public class ImFriendServiceImpl implements ImFriendService { @@ -197,7 +202,7 @@ public class ImFriendServiceImpl implements ImFriendService {
197 FriendAddNotification payload = (FriendAddNotification) new FriendAddNotification() 202 FriendAddNotification payload = (FriendAddNotification) new FriendAddNotification()
198 .setOperatorUserId(friendUserId).setFriendUserId(friendUserId); 203 .setOperatorUserId(friendUserId).setFriendUserId(friendUserId);
199 privateMessageService.sendPrivateMessage(userId, new ImPrivateMessageSendDTO() 204 privateMessageService.sendPrivateMessage(userId, new ImPrivateMessageSendDTO()
200 - .setReceiverId(friendUserId).setType(ImMessageTypeEnum.FRIEND_ADD.getType()) 205 + .setReceiverId(friendUserId).setType(ImContentTypeEnum.FRIEND_ADD.getType())
201 .setContent(payload).setPersistent(false)); 206 .setContent(payload).setPersistent(false));
202 } 207 }
203 208
@@ -219,7 +224,7 @@ public class ImFriendServiceImpl implements ImFriendService { @@ -219,7 +224,7 @@ public class ImFriendServiceImpl implements ImFriendService {
219 FriendDeleteNotification payload = ((FriendDeleteNotification) new FriendDeleteNotification() 224 FriendDeleteNotification payload = ((FriendDeleteNotification) new FriendDeleteNotification()
220 .setOperatorUserId(userId).setFriendUserId(friendUserId)).setClear(clear); 225 .setOperatorUserId(userId).setFriendUserId(friendUserId)).setClear(clear);
221 privateMessageService.sendPrivateMessage(userId, new ImPrivateMessageSendDTO() 226 privateMessageService.sendPrivateMessage(userId, new ImPrivateMessageSendDTO()
222 - .setReceiverId(friendUserId).setType(ImMessageTypeEnum.FRIEND_DELETE.getType()) 227 + .setReceiverId(friendUserId).setType(ImContentTypeEnum.FRIEND_DELETE.getType())
223 .setContent(payload).setPersistent(false)); 228 .setContent(payload).setPersistent(false));
224 } 229 }
225 230
@@ -245,8 +250,8 @@ public class ImFriendServiceImpl implements ImFriendService { @@ -245,8 +250,8 @@ public class ImFriendServiceImpl implements ImFriendService {
245 // 3. 推 FRIEND_BLOCK 给 A 多端 250 // 3. 推 FRIEND_BLOCK 给 A 多端
246 FriendBlockNotification payload = (FriendBlockNotification) new FriendBlockNotification() 251 FriendBlockNotification payload = (FriendBlockNotification) new FriendBlockNotification()
247 .setOperatorUserId(userId).setFriendUserId(friendUserId); 252 .setOperatorUserId(userId).setFriendUserId(friendUserId);
248 - websocketService.sendPrivateMessageAsync(userId, ImPrivateMessageDTO.ofFriendNotification(  
249 - ImMessageTypeEnum.FRIEND_BLOCK.getType(), userId, userId, payload)); 253 + websocketService.sendNotificationAsync(userId, ImConversationTypeEnum.NONE.getType(),
  254 + ImContentTypeEnum.FRIEND_BLOCK.getType(), payload);
250 } 255 }
251 256
252 @Override 257 @Override
@@ -271,8 +276,8 @@ public class ImFriendServiceImpl implements ImFriendService { @@ -271,8 +276,8 @@ public class ImFriendServiceImpl implements ImFriendService {
271 // 3. 推 FRIEND_UNBLOCK 给 A 多端 276 // 3. 推 FRIEND_UNBLOCK 给 A 多端
272 FriendUnblockNotification payload = (FriendUnblockNotification) new FriendUnblockNotification() 277 FriendUnblockNotification payload = (FriendUnblockNotification) new FriendUnblockNotification()
273 .setOperatorUserId(userId).setFriendUserId(friendUserId); 278 .setOperatorUserId(userId).setFriendUserId(friendUserId);
274 - websocketService.sendPrivateMessageAsync(userId, ImPrivateMessageDTO.ofFriendNotification(  
275 - ImMessageTypeEnum.FRIEND_UNBLOCK.getType(), userId, userId, payload)); 279 + websocketService.sendNotificationAsync(userId, ImConversationTypeEnum.NONE.getType(),
  280 + ImContentTypeEnum.FRIEND_UNBLOCK.getType(), payload);
276 } 281 }
277 282
278 /** 283 /**
@@ -294,7 +299,8 @@ public class ImFriendServiceImpl implements ImFriendService { @@ -294,7 +299,8 @@ public class ImFriendServiceImpl implements ImFriendService {
294 } 299 }
295 // 情况二:复用 DISABLE 旧记录 → 恢复 ENABLE + 重置 silent / pinned / blocked,对齐"重新加好友"语义 300 // 情况二:复用 DISABLE 旧记录 → 恢复 ENABLE + 重置 silent / pinned / blocked,对齐"重新加好友"语义
296 if (exists != null) { 301 if (exists != null) {
297 - friendMapper.updateReAddFields(exists.getId(), CommonStatusEnum.ENABLE.getStatus(), LocalDateTime.now(), 302 + LocalDateTime now = LocalDateTime.now();
  303 + friendMapper.updateReAddFields(exists.getId(), CommonStatusEnum.ENABLE.getStatus(), now, now,
298 false, false, false, displayName, addSource); 304 false, false, false, displayName, addSource);
299 return; 305 return;
300 } 306 }
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupMemberService.java
@@ -87,13 +87,12 @@ public interface ImGroupMemberService { @@ -87,13 +87,12 @@ public interface ImGroupMemberService {
87 List<ImGroupMemberDO> getActiveGroupMemberListByUserId(Long userId); 87 List<ImGroupMemberDO> getActiveGroupMemberListByUserId(Long userId);
88 88
89 /** 89 /**
90 - * 查询用户已退群的群成员记录(DISABLE 状态) 90 + * 查询用户曾经加入的所有群成员记录(含已退群)
91 * 91 *
92 - * @param userId 用户编号,必传  
93 - * @param minQuitTime 最早退群时间(含),可空  
94 - * @return 已退群成员记录列表 92 + * @param userId 用户编号
  93 + * @return 群成员记录列表
95 */ 94 */
96 - List<ImGroupMemberDO> getQuitGroupMemberListByUserId(Long userId, LocalDateTime minQuitTime); 95 + List<ImGroupMemberDO> getGroupMemberListByUserId(Long userId);
97 96
98 /** 97 /**
99 * 添加群成员(入群),角色默认 MEMBER 98 * 添加群成员(入群),角色默认 MEMBER
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupMemberServiceImpl.java
@@ -77,7 +77,6 @@ public class ImGroupMemberServiceImpl implements ImGroupMemberService { @@ -77,7 +77,6 @@ public class ImGroupMemberServiceImpl implements ImGroupMemberService {
77 77
78 @Override 78 @Override
79 public List<ImGroupMemberDO> getGroupMemberListByOwnerAndAdmin(Long groupId) { 79 public List<ImGroupMemberDO> getGroupMemberListByOwnerAndAdmin(Long groupId) {
80 - // TODO DONE @AI:把条件往下传;这样减少加载数据量!  
81 return groupMemberMapper.selectListByGroupIdAndStatusAndRoles(groupId, CommonStatusEnum.ENABLE.getStatus(), 80 return groupMemberMapper.selectListByGroupIdAndStatusAndRoles(groupId, CommonStatusEnum.ENABLE.getStatus(),
82 ListUtil.of(ImGroupMemberRoleEnum.OWNER.getRole(), ImGroupMemberRoleEnum.ADMIN.getRole())); 81 ListUtil.of(ImGroupMemberRoleEnum.OWNER.getRole(), ImGroupMemberRoleEnum.ADMIN.getRole()));
83 } 82 }
@@ -106,8 +105,8 @@ public class ImGroupMemberServiceImpl implements ImGroupMemberService { @@ -106,8 +105,8 @@ public class ImGroupMemberServiceImpl implements ImGroupMemberService {
106 } 105 }
107 106
108 @Override 107 @Override
109 - public List<ImGroupMemberDO> getQuitGroupMemberListByUserId(Long userId, LocalDateTime minQuitTime) {  
110 - return groupMemberMapper.selectQuitListByUserId(userId, minQuitTime); 108 + public List<ImGroupMemberDO> getGroupMemberListByUserId(Long userId) {
  109 + return groupMemberMapper.selectListByUserId(userId);
111 } 110 }
112 111
113 @Override 112 @Override
@@ -259,7 +258,7 @@ public class ImGroupMemberServiceImpl implements ImGroupMemberService { @@ -259,7 +258,7 @@ public class ImGroupMemberServiceImpl implements ImGroupMemberService {
259 .setId(member.getId()); 258 .setId(member.getId());
260 groupMemberMapper.updateById(updateObj); 259 groupMemberMapper.updateById(updateObj);
261 260
262 - // 3.1 displayUserName 是公开字段,单独走 GROUP_MEMBER_NICKNAME_UPDATE 广播给全员;空串视为「清空昵称」也要广播;与旧值相同跳过 261 + // 3.1 displayUserName 是公开字段,单独走 GROUP_MEMBER_NICKNAME_UPDATE 在线同步给全员;空串视为「清空昵称」也要同步;与旧值相同跳过
263 if (updateReqVO.getDisplayUserName() != null 262 if (updateReqVO.getDisplayUserName() != null
264 && ObjUtil.notEqual(updateReqVO.getDisplayUserName(), member.getDisplayUserName())) { 263 && ObjUtil.notEqual(updateReqVO.getDisplayUserName(), member.getDisplayUserName())) {
265 groupMessageService.sendGroupMessage(userId, ImGroupMessageSendDTO.ofGroupMemberNicknameUpdate( 264 groupMessageService.sendGroupMessage(userId, ImGroupMessageSendDTO.ofGroupMemberNicknameUpdate(
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupRequestService.java
@@ -64,6 +64,19 @@ public interface ImGroupRequestService { @@ -64,6 +64,19 @@ public interface ImGroupRequestService {
64 List<ImGroupRequestDO> getUnhandledRequestListByOwnerOrAdmin(Long userId); 64 List<ImGroupRequestDO> getUnhandledRequestListByOwnerOrAdmin(Long userId);
65 65
66 /** 66 /**
  67 + * 增量拉取「我管理的群」下的加群申请(重连 / 离线补偿:含已处理,按 update_time + id 游标)
  68 + * <p>
  69 + * 作用域与 {@link #getUnhandledRequestListByOwnerOrAdmin} 一致:按 ImGroupMember.role 取我作为 OWNER / ADMIN 的群
  70 + *
  71 + * @param userId 当前用户编号
  72 + * @param lastUpdateTime 游标:上次拉取的最后一条更新时间戳(毫秒)
  73 + * @param lastId 游标:上次拉取的最后一条申请编号
  74 + * @param limit 单次拉取条数
  75 + * @return 申请记录列表
  76 + */
  77 + List<ImGroupRequestDO> pullGroupRequestList(Long userId, Long lastUpdateTime, Long lastId, Integer limit);
  78 +
  79 + /**
67 * 拉取指定群下的全部加群申请(含已处理);仅群主 / 管理员可查 80 * 拉取指定群下的全部加群申请(含已处理);仅群主 / 管理员可查
68 * <p> 81 * <p>
69 * 用于群「进群申请」子页:最新一条卡片化突出 + 历史申请按 id 倒序 82 * 用于群「进群申请」子页:最新一条卡片化突出 + 历史申请按 id 倒序
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupRequestServiceImpl.java
@@ -13,15 +13,15 @@ import cn.iocoder.yudao.module.im.dal.mysql.group.ImGroupRequestMapper; @@ -13,15 +13,15 @@ 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.enums.ImConversationTypeEnum;
17 import cn.iocoder.yudao.module.im.service.message.ImGroupMessageService; 18 import cn.iocoder.yudao.module.im.service.message.ImGroupMessageService;
18 import cn.iocoder.yudao.module.im.service.message.dto.ImGroupMessageSendDTO; 19 import cn.iocoder.yudao.module.im.service.message.dto.ImGroupMessageSendDTO;
19 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService; 20 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; 21 +import cn.iocoder.yudao.module.im.service.websocket.notification.group.BaseGroupNotification;
  22 +import cn.iocoder.yudao.module.im.service.websocket.notification.group.GroupRequestApprovedNotification;
  23 +import cn.iocoder.yudao.module.im.service.websocket.notification.group.GroupRequestReceivedNotification;
  24 +import cn.iocoder.yudao.module.im.service.websocket.notification.group.GroupRequestRejectedNotification;
25 import cn.iocoder.yudao.module.system.api.user.AdminUserApi; 25 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
26 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; 26 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
27 import jakarta.annotation.Resource; 27 import jakarta.annotation.Resource;
@@ -97,12 +97,12 @@ public class ImGroupRequestServiceImpl implements ImGroupRequestService { @@ -97,12 +97,12 @@ public class ImGroupRequestServiceImpl implements ImGroupRequestService {
97 // 3. 情况二:群开启了审批,创建或复用一条主动申请记录 97 // 3. 情况二:群开启了审批,创建或复用一条主动申请记录
98 ImGroupRequestDO request = createOrResetApplyRequest(groupId, userId, reqVO); 98 ImGroupRequestDO request = createOrResetApplyRequest(groupId, userId, reqVO);
99 99
100 - // 4. 1503 私聊定向推群主 + 全部管理员(多端同步);payload 携带申请方昵称 / 头像 100 + // 4. 1503 定向推群主 + 全部管理员(多端同步);payload 携带申请方昵称 / 头像
101 AdminUserRespDTO applyUser = adminUserApi.getUser(userId); 101 AdminUserRespDTO applyUser = adminUserApi.getUser(userId);
102 GroupRequestReceivedNotification payload = buildRequestNotification(group, request, applyUser); 102 GroupRequestReceivedNotification payload = buildRequestNotification(group, request, applyUser);
103 for (Long receiverUserId : getGroupMemberListByOwnerAndAdminUserIds(group)) { 103 for (Long receiverUserId : getGroupMemberListByOwnerAndAdminUserIds(group)) {
104 - websocketService.sendPrivateMessageAsync(receiverUserId, ImPrivateMessageDTO.ofGroupNotification(  
105 - ImMessageTypeEnum.GROUP_REQUEST_RECEIVED.getType(), userId, receiverUserId, payload)); 104 + websocketService.sendNotificationAsync(receiverUserId, ImConversationTypeEnum.NONE.getType(),
  105 + ImContentTypeEnum.GROUP_REQUEST_RECEIVED.getType(), payload);
106 } 106 }
107 return request; 107 return request;
108 } 108 }
@@ -139,12 +139,12 @@ public class ImGroupRequestServiceImpl implements ImGroupRequestService { @@ -139,12 +139,12 @@ public class ImGroupRequestServiceImpl implements ImGroupRequestService {
139 groupMemberService.addGroupMember(request.getGroupId(), request.getUserId(), 139 groupMemberService.addGroupMember(request.getGroupId(), request.getUserId(),
140 ImGroupMemberRoleEnum.NORMAL.getRole(), request.getAddSource(), request.getInviterUserId()); 140 ImGroupMemberRoleEnum.NORMAL.getRole(), request.getAddSource(), request.getInviterUserId());
141 141
142 - // 5.1 1505 私聊推送给申请人 + 群主 + 全部管理员(每端单推) 142 + // 5.1 1505 定向推送给申请人 + 群主 + 全部管理员(每端单推)
143 GroupRequestApprovedNotification payload = (GroupRequestApprovedNotification) new GroupRequestApprovedNotification() 143 GroupRequestApprovedNotification payload = (GroupRequestApprovedNotification) new GroupRequestApprovedNotification()
144 .setRequestId(request.getId()).setGroupId(request.getGroupId()).setUserId(request.getUserId()) 144 .setRequestId(request.getId()).setGroupId(request.getGroupId()).setUserId(request.getUserId())
145 .setOperatorUserId(userId); 145 .setOperatorUserId(userId);
146 broadcastToOwnerAdminsAndApplicant(request.getGroupId(), request.getUserId(), payload, 146 broadcastToOwnerAdminsAndApplicant(request.getGroupId(), request.getUserId(), payload,
147 - ImMessageTypeEnum.GROUP_REQUEST_APPROVED.getType(), userId); 147 + ImContentTypeEnum.GROUP_REQUEST_APPROVED.getType(), userId);
148 // 5.2 群事件:主动申请 → 1510 自由进群;被邀请 → 1509 成员加入 148 // 5.2 群事件:主动申请 → 1510 自由进群;被邀请 → 1509 成员加入
149 if (request.getInviterUserId() == null) { 149 if (request.getInviterUserId() == null) {
150 groupMessageService.sendGroupMessage(userId, 150 groupMessageService.sendGroupMessage(userId,
@@ -174,12 +174,12 @@ public class ImGroupRequestServiceImpl implements ImGroupRequestService { @@ -174,12 +174,12 @@ public class ImGroupRequestServiceImpl implements ImGroupRequestService {
174 throw exception(GROUP_REQUEST_HANDLED); 174 throw exception(GROUP_REQUEST_HANDLED);
175 } 175 }
176 176
177 - // 3. 1506 私聊推送给申请人 + 群主 + 全部管理员 177 + // 3. 1506 定向推送给申请人 + 群主 + 全部管理员
178 GroupRequestRejectedNotification payload = (GroupRequestRejectedNotification) new GroupRequestRejectedNotification() 178 GroupRequestRejectedNotification payload = (GroupRequestRejectedNotification) new GroupRequestRejectedNotification()
179 .setRequestId(request.getId()).setGroupId(request.getGroupId()).setUserId(request.getUserId()) 179 .setRequestId(request.getId()).setGroupId(request.getGroupId()).setUserId(request.getUserId())
180 .setHandleContent(handleContent).setOperatorUserId(userId); 180 .setHandleContent(handleContent).setOperatorUserId(userId);
181 broadcastToOwnerAdminsAndApplicant(request.getGroupId(), request.getUserId(), payload, 181 broadcastToOwnerAdminsAndApplicant(request.getGroupId(), request.getUserId(), payload,
182 - ImMessageTypeEnum.GROUP_REQUEST_REJECTED.getType(), userId); 182 + ImContentTypeEnum.GROUP_REQUEST_REJECTED.getType(), userId);
183 } 183 }
184 184
185 @Override 185 @Override
@@ -201,8 +201,8 @@ public class ImGroupRequestServiceImpl implements ImGroupRequestService { @@ -201,8 +201,8 @@ public class ImGroupRequestServiceImpl implements ImGroupRequestService {
201 AdminUserRespDTO applyUser = userMap.get(request.getUserId()); 201 AdminUserRespDTO applyUser = userMap.get(request.getUserId());
202 GroupRequestReceivedNotification payload = buildRequestNotification(group, request, applyUser); 202 GroupRequestReceivedNotification payload = buildRequestNotification(group, request, applyUser);
203 for (Long receiverUserId : ownerAndAdmins) { 203 for (Long receiverUserId : ownerAndAdmins) {
204 - websocketService.sendPrivateMessageAsync(receiverUserId, ImPrivateMessageDTO.ofGroupNotification(  
205 - ImMessageTypeEnum.GROUP_REQUEST_RECEIVED.getType(), inviterUserId, receiverUserId, payload)); 204 + websocketService.sendNotificationAsync(receiverUserId, ImConversationTypeEnum.NONE.getType(),
  205 + ImContentTypeEnum.GROUP_REQUEST_RECEIVED.getType(), payload);
206 } 206 }
207 } 207 }
208 } 208 }
@@ -212,8 +212,7 @@ public class ImGroupRequestServiceImpl implements ImGroupRequestService { @@ -212,8 +212,7 @@ public class ImGroupRequestServiceImpl implements ImGroupRequestService {
212 // 1. 找出当前用户作为 OWNER / ADMIN 的所有群 212 // 1. 找出当前用户作为 OWNER / ADMIN 的所有群
213 List<ImGroupMemberDO> myMembers = groupMemberService.getActiveGroupMemberListByUserId(userId); 213 List<ImGroupMemberDO> myMembers = groupMemberService.getActiveGroupMemberListByUserId(userId);
214 Set<Long> ownerOrAdminGroupIds = convertSet(myMembers, 214 Set<Long> ownerOrAdminGroupIds = convertSet(myMembers,
215 - ImGroupMemberDO::getGroupId,  
216 - m -> ImGroupMemberRoleEnum.isOwnerOrAdmin(m.getRole())); 215 + ImGroupMemberDO::getGroupId, member -> ImGroupMemberRoleEnum.isOwnerOrAdmin(member.getRole()));
217 if (CollUtil.isEmpty(ownerOrAdminGroupIds)) { 216 if (CollUtil.isEmpty(ownerOrAdminGroupIds)) {
218 return Collections.emptyList(); 217 return Collections.emptyList();
219 } 218 }
@@ -223,6 +222,19 @@ public class ImGroupRequestServiceImpl implements ImGroupRequestService { @@ -223,6 +222,19 @@ public class ImGroupRequestServiceImpl implements ImGroupRequestService {
223 } 222 }
224 223
225 @Override 224 @Override
  225 + public List<ImGroupRequestDO> pullGroupRequestList(Long userId, Long lastUpdateTime, Long lastId, Integer limit) {
  226 + // 1. 找出当前用户作为 OWNER / ADMIN 的所有群
  227 + List<ImGroupMemberDO> myMembers = groupMemberService.getActiveGroupMemberListByUserId(userId);
  228 + Set<Long> ownerOrAdminGroupIds = convertSet(myMembers,
  229 + ImGroupMemberDO::getGroupId, member -> ImGroupMemberRoleEnum.isOwnerOrAdmin(member.getRole()));
  230 + if (CollUtil.isEmpty(ownerOrAdminGroupIds)) {
  231 + return Collections.emptyList();
  232 + }
  233 + // 2. 按游标增量拉取这些群下的申请
  234 + return groupRequestMapper.selectPullListByGroupIds(ownerOrAdminGroupIds, lastUpdateTime, lastId, limit);
  235 + }
  236 +
  237 + @Override
226 public List<ImGroupRequestDO> getGroupRequestListByGroupId(Long userId, Long groupId) { 238 public List<ImGroupRequestDO> getGroupRequestListByGroupId(Long userId, Long groupId) {
227 // 1. 校验群存在 + 当前用户是群主 / 管理员 239 // 1. 校验群存在 + 当前用户是群主 / 管理员
228 groupService.validateGroupExists(groupId); 240 groupService.validateGroupExists(groupId);
@@ -383,7 +395,7 @@ public class ImGroupRequestServiceImpl implements ImGroupRequestService { @@ -383,7 +395,7 @@ public class ImGroupRequestServiceImpl implements ImGroupRequestService {
383 } 395 }
384 396
385 /** 397 /**
386 - * 1505 / 1506 受众:申请人 + 群主 + 全部管理员;每端单独推一帧,前端按 receiver 是否申请人区分文案 398 + * 1505 / 1506 受众:申请人 + 群主 + 全部管理员
387 */ 399 */
388 private void broadcastToOwnerAdminsAndApplicant(Long groupId, Long applicantUserId, BaseGroupNotification payload, 400 private void broadcastToOwnerAdminsAndApplicant(Long groupId, Long applicantUserId, BaseGroupNotification payload,
389 Integer messageType, Long operatorUserId) { 401 Integer messageType, Long operatorUserId) {
@@ -394,8 +406,8 @@ public class ImGroupRequestServiceImpl implements ImGroupRequestService { @@ -394,8 +406,8 @@ public class ImGroupRequestServiceImpl implements ImGroupRequestService {
394 Set<Long> receivers = new LinkedHashSet<>(getGroupMemberListByOwnerAndAdminUserIds(group)); 406 Set<Long> receivers = new LinkedHashSet<>(getGroupMemberListByOwnerAndAdminUserIds(group));
395 receivers.add(applicantUserId); 407 receivers.add(applicantUserId);
396 for (Long receiverUserId : receivers) { 408 for (Long receiverUserId : receivers) {
397 - websocketService.sendPrivateMessageAsync(receiverUserId, ImPrivateMessageDTO.ofGroupNotification(  
398 - messageType, operatorUserId, receiverUserId, payload)); 409 + websocketService.sendNotificationAsync(receiverUserId, ImConversationTypeEnum.NONE.getType(),
  410 + messageType, payload);
399 } 411 }
400 } 412 }
401 413
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;
@@ -149,7 +149,9 @@ public class ImGroupServiceImpl implements ImGroupService { @@ -149,7 +149,9 @@ public class ImGroupServiceImpl implements ImGroupService {
149 boolean nameChanged = StrUtil.isNotEmpty(updateReqVO.getName()); 149 boolean nameChanged = StrUtil.isNotEmpty(updateReqVO.getName());
150 boolean noticeChanged = updateReqVO.getNotice() != null; 150 boolean noticeChanged = updateReqVO.getNotice() != null;
151 boolean avatarChanged = StrUtil.isNotEmpty(updateReqVO.getAvatar()); 151 boolean avatarChanged = StrUtil.isNotEmpty(updateReqVO.getAvatar());
152 - if (nameChanged || noticeChanged || avatarChanged) { 152 + boolean joinApprovalChanged = updateReqVO.getJoinApproval() != null
  153 + && ObjUtil.notEqual(group.getJoinApproval(), updateReqVO.getJoinApproval());
  154 + if (nameChanged || noticeChanged || avatarChanged || joinApprovalChanged) {
153 List<Long> memberUserIds = groupMemberService.getActiveGroupMemberUserIdsByGroupId(groupId); 155 List<Long> memberUserIds = groupMemberService.getActiveGroupMemberUserIdsByGroupId(groupId);
154 if (nameChanged) { 156 if (nameChanged) {
155 groupMessageService.sendGroupMessage(userId, memberUserIds, ImGroupMessageSendDTO.ofGroupNameUpdate( 157 groupMessageService.sendGroupMessage(userId, memberUserIds, ImGroupMessageSendDTO.ofGroupNameUpdate(
@@ -161,7 +163,11 @@ public class ImGroupServiceImpl implements ImGroupService { @@ -161,7 +163,11 @@ public class ImGroupServiceImpl implements ImGroupService {
161 } 163 }
162 if (avatarChanged) { 164 if (avatarChanged) {
163 groupMessageService.sendGroupMessage(userId, memberUserIds, ImGroupMessageSendDTO.ofGroupInfoUpdate( 165 groupMessageService.sendGroupMessage(userId, memberUserIds, ImGroupMessageSendDTO.ofGroupInfoUpdate(
164 - groupId, userId, group.getAvatar(), updateReqVO.getAvatar())); 166 + groupId, userId, group.getAvatar(), updateReqVO.getAvatar(), null, null));
  167 + }
  168 + if (joinApprovalChanged) {
  169 + groupMessageService.sendGroupMessage(userId, memberUserIds, ImGroupMessageSendDTO.ofGroupInfoUpdate(
  170 + groupId, userId, null, null, group.getJoinApproval(), updateReqVO.getJoinApproval()));
165 } 171 }
166 } 172 }
167 173
@@ -193,8 +199,6 @@ public class ImGroupServiceImpl implements ImGroupService { @@ -193,8 +199,6 @@ public class ImGroupServiceImpl implements ImGroupService {
193 .setStatus(CommonStatusEnum.DISABLE.getStatus()).setDissolvedTime(LocalDateTime.now())); 199 .setStatus(CommonStatusEnum.DISABLE.getStatus()).setDissolvedTime(LocalDateTime.now()));
194 // 2.2 移除全部群成员 200 // 2.2 移除全部群成员
195 groupMemberService.removeGroupMembersByGroupId(id); 201 groupMemberService.removeGroupMembersByGroupId(id);
196 - // 2.3 清理已读缓存  
197 - groupMessageService.deleteReadMaxMessageIdMap(id);  
198 } 202 }
199 203
200 // ==================== 群成员的写操作 ==================== 204 // ==================== 群成员的写操作 ====================
@@ -267,10 +271,8 @@ public class ImGroupServiceImpl implements ImGroupService { @@ -267,10 +271,8 @@ public class ImGroupServiceImpl implements ImGroupService {
267 // 2. 先发广播,后移成员(见类 javadoc) 271 // 2. 先发广播,后移成员(见类 javadoc)
268 groupMessageService.sendGroupMessage(userId, ImGroupMessageSendDTO.ofGroupMemberQuit(groupId, userId)); 272 groupMessageService.sendGroupMessage(userId, ImGroupMessageSendDTO.ofGroupMemberQuit(groupId, userId));
269 273
270 - // 3.1 移除群成员 274 + // 3. 移除群成员
271 groupMemberService.removeGroupMember(groupId, userId); 275 groupMemberService.removeGroupMember(groupId, userId);
272 - // 3.2 清理已读缓存  
273 - groupMessageService.deleteReadMaxMessageId(groupId, userId);  
274 } 276 }
275 277
276 @Override 278 @Override
@@ -307,10 +309,8 @@ public class ImGroupServiceImpl implements ImGroupService { @@ -307,10 +309,8 @@ public class ImGroupServiceImpl implements ImGroupService {
307 groupMessageService.sendGroupMessage(userId, 309 groupMessageService.sendGroupMessage(userId,
308 ImGroupMessageSendDTO.ofGroupMemberKick(groupId, userId, validTargetUserIds)); 310 ImGroupMessageSendDTO.ofGroupMemberKick(groupId, userId, validTargetUserIds));
309 311
310 - // 3.1 批量移除群成员 312 + // 3. 批量移除群成员;不清理读位置(保留退群前历史已读,供离线补偿)
311 groupMemberService.removeGroupMembers(groupId, validTargetUserIds); 313 groupMemberService.removeGroupMembers(groupId, validTargetUserIds);
312 - // 3.2 批量清理已读缓存  
313 - groupMessageService.deleteReadMaxMessageIds(groupId, validTargetUserIds);  
314 } 314 }
315 315
316 @Override 316 @Override
@@ -442,7 +442,7 @@ public class ImGroupServiceImpl implements ImGroupService { @@ -442,7 +442,7 @@ public class ImGroupServiceImpl implements ImGroupService {
442 if (message == null || ObjUtil.notEqual(message.getGroupId(), groupId)) { 442 if (message == null || ObjUtil.notEqual(message.getGroupId(), groupId)) {
443 throw exception(MESSAGE_NOT_IN_GROUP); 443 throw exception(MESSAGE_NOT_IN_GROUP);
444 } 444 }
445 - if (!ImMessageTypeEnum.validate(message.getType()).isNormal() 445 + if (!ImContentTypeEnum.validate(message.getType()).isNormal()
446 || ImMessageStatusEnum.RECALL.getStatus().equals(message.getStatus())) { 446 || ImMessageStatusEnum.RECALL.getStatus().equals(message.getStatus())) {
447 throw exception(MESSAGE_NOT_IN_GROUP); 447 throw exception(MESSAGE_NOT_IN_GROUP);
448 } 448 }
@@ -601,11 +601,8 @@ public class ImGroupServiceImpl implements ImGroupService { @@ -601,11 +601,8 @@ public class ImGroupServiceImpl implements ImGroupService {
601 601
602 @Override 602 @Override
603 public List<ImGroupDO> getMyGroupList(Long userId) { 603 public List<ImGroupDO> getMyGroupList(Long userId) {
604 - // 1.1 查用户所在的、仍有效的群成员记录(仅 ENABLE 状态)  
605 - List<ImGroupMemberDO> members = groupMemberService.getActiveGroupMemberListByUserId(userId);  
606 - // 1.2 再查最近 N 天(与群消息离线拉取窗口一致)内退群的成员记录(退群前可能有离线消息需要展示,一并返回作为前端缓存)  
607 - LocalDateTime minQuitTime = LocalDateTime.now().minusDays(imProperties.getMessage().getGroupPullMaxDays());  
608 - members.addAll(groupMemberService.getQuitGroupMemberListByUserId(userId, minQuitTime)); 604 + // 1. 查用户曾经加入的所有群(含退群,前端按需过滤);退群前的离线消息也要能展示
  605 + List<ImGroupMemberDO> members = groupMemberService.getGroupMemberListByUserId(userId);
609 if (CollUtil.isEmpty(members)) { 606 if (CollUtil.isEmpty(members)) {
610 return Collections.emptyList(); 607 return Collections.emptyList();
611 } 608 }
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/message/ImChannelMessageService.java
@@ -27,7 +27,7 @@ public interface ImChannelMessageService { @@ -27,7 +27,7 @@ public interface ImChannelMessageService {
27 * @param size 返回条数 27 * @param size 返回条数
28 * @return 频道消息列表;按 id 升序 28 * @return 频道消息列表;按 id 升序
29 */ 29 */
30 - List<ImChannelMessageDO> getMessageListForPull(Long userId, Long minId, Integer size); 30 + List<ImChannelMessageDO> pullChannelMessageList(Long userId, Long minId, Integer size);
31 31
32 /** 32 /**
33 * 上报频道消息已读位置;同步推 READ 事件给自己多端 33 * 上报频道消息已读位置;同步推 READ 事件给自己多端
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/message/ImChannelMessageServiceImpl.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.im.service.message; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.im.service.message;
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;
  5 +import cn.hutool.core.util.ObjUtil;
5 import cn.hutool.extra.spring.SpringUtil; 6 import cn.hutool.extra.spring.SpringUtil;
6 import cn.iocoder.yudao.framework.common.pojo.PageResult; 7 import cn.iocoder.yudao.framework.common.pojo.PageResult;
7 import cn.iocoder.yudao.framework.common.util.json.JsonUtils; 8 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
@@ -11,12 +12,14 @@ import cn.iocoder.yudao.module.im.controller.admin.manager.message.vo.channel.Im @@ -11,12 +12,14 @@ import cn.iocoder.yudao.module.im.controller.admin.manager.message.vo.channel.Im
11 import cn.iocoder.yudao.module.im.dal.dataobject.channel.ImChannelMaterialDO; 12 import cn.iocoder.yudao.module.im.dal.dataobject.channel.ImChannelMaterialDO;
12 import cn.iocoder.yudao.module.im.dal.dataobject.message.ImChannelMessageDO; 13 import cn.iocoder.yudao.module.im.dal.dataobject.message.ImChannelMessageDO;
13 import cn.iocoder.yudao.module.im.dal.mysql.message.ImChannelMessageMapper; 14 import cn.iocoder.yudao.module.im.dal.mysql.message.ImChannelMessageMapper;
14 -import cn.iocoder.yudao.module.im.dal.redis.message.ImChannelMessageReadRedisDAO;  
15 -import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum; 15 +import cn.iocoder.yudao.module.im.enums.ImConversationTypeEnum;
  16 +import cn.iocoder.yudao.module.im.enums.ImContentTypeEnum;
16 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;
17 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService; 19 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService;
18 -import cn.iocoder.yudao.module.im.service.websocket.dto.ImChannelMessageDTO;  
19 -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;
20 import jakarta.annotation.Resource; 23 import jakarta.annotation.Resource;
21 import org.springframework.scheduling.annotation.Async; 24 import org.springframework.scheduling.annotation.Async;
22 import org.springframework.stereotype.Service; 25 import org.springframework.stereotype.Service;
@@ -25,7 +28,6 @@ import org.springframework.validation.annotation.Validated; @@ -25,7 +28,6 @@ import org.springframework.validation.annotation.Validated;
25 28
26 import java.time.LocalDateTime; 29 import java.time.LocalDateTime;
27 import java.util.Collection; 30 import java.util.Collection;
28 -import java.util.HashMap;  
29 import java.util.List; 31 import java.util.List;
30 import java.util.Map; 32 import java.util.Map;
31 33
@@ -50,39 +52,41 @@ public class ImChannelMessageServiceImpl implements ImChannelMessageService { @@ -50,39 +52,41 @@ public class ImChannelMessageServiceImpl implements ImChannelMessageService {
50 private ImWebSocketService webSocketService; 52 private ImWebSocketService webSocketService;
51 53
52 @Resource 54 @Resource
53 - private ImChannelMessageReadRedisDAO channelMessageReadRedisDAO; 55 + private ImConversationReadService conversationReadService;
54 56
55 // ==================== 用户端 ==================== 57 // ==================== 用户端 ====================
56 58
57 @Override 59 @Override
58 - public List<ImChannelMessageDO> getMessageListForPull(Long userId, Long minId, Integer size) { 60 + public List<ImChannelMessageDO> pullChannelMessageList(Long userId, Long minId, Integer size) {
59 return channelMessageMapper.selectListByUserAndMinId(userId, minId, size); 61 return channelMessageMapper.selectListByUserAndMinId(userId, minId, size);
60 } 62 }
61 63
62 @Override 64 @Override
63 public Map<Long, Long> getChannelReadMaxMessageIdMap(Long userId, Collection<Long> channelIds) { 65 public Map<Long, Long> getChannelReadMaxMessageIdMap(Long userId, Collection<Long> channelIds) {
64 - Map<Long, Long> result = new HashMap<>(channelIds.size());  
65 - for (Long channelId : channelIds) {  
66 - Long max = channelMessageReadRedisDAO.getReadMaxMessageId(channelId, userId);  
67 - if (max != null) {  
68 - result.put(channelId, max);  
69 - }  
70 - }  
71 - return result; 66 + return conversationReadService.getConversationReadMessageIdMap(
  67 + userId, ImConversationTypeEnum.CHANNEL.getType(), channelIds);
72 } 68 }
73 69
74 @Override 70 @Override
75 public void readChannelMessages(Long userId, Long channelId, Long messageId) { 71 public void readChannelMessages(Long userId, Long channelId, Long messageId) {
76 Assert.notNull(channelId, "频道编号不能为空"); 72 Assert.notNull(channelId, "频道编号不能为空");
77 Assert.notNull(messageId, "已读消息编号不能为空"); 73 Assert.notNull(messageId, "已读消息编号不能为空");
78 - // 1. 已读位置未前进,直接返回  
79 - Long prevMaxMessageId = channelMessageReadRedisDAO.getReadMaxMessageId(channelId, userId);  
80 - if (prevMaxMessageId != null && prevMaxMessageId >= messageId) { 74 + // 1.1 校验消息真实存在且属于该频道,避免未来 / 伪造 messageId 污染读位置
  75 + ImChannelMessageDO message = channelMessageMapper.selectById(messageId);
  76 + if (message == null || ObjUtil.notEqual(message.getChannelId(), channelId)) {
  77 + return;
  78 + }
  79 + // 1.2 定向消息校验对当前用户可见(receiver_user_ids 为空表示全员可见)
  80 + if (CollUtil.isNotEmpty(message.getReceiverUserIds()) && !message.getReceiverUserIds().contains(userId)) {
81 return; 81 return;
82 } 82 }
83 83
84 - // 2. 更新 Redis 频道已读位置  
85 - channelMessageReadRedisDAO.updateReadMaxMessageId(channelId, userId, messageId); 84 + // 2. 更新频道已读位置;读位置未前进则不推
  85 + boolean advanced = conversationReadService.updateConversationReadPosition(
  86 + userId, ImConversationTypeEnum.CHANNEL.getType(), channelId, messageId);
  87 + if (!advanced) {
  88 + return;
  89 + }
86 90
87 // 3. 异步推 READ 事件给自己多端同步 91 // 3. 异步推 READ 事件给自己多端同步
88 getSelf().readChannelMessageEvent(userId, channelId, messageId); 92 getSelf().readChannelMessageEvent(userId, channelId, messageId);
@@ -93,7 +97,8 @@ public class ImChannelMessageServiceImpl implements ImChannelMessageService { @@ -93,7 +97,8 @@ public class ImChannelMessageServiceImpl implements ImChannelMessageService {
93 */ 97 */
94 @Async 98 @Async
95 public void readChannelMessageEvent(Long userId, Long channelId, Long readId) { 99 public void readChannelMessageEvent(Long userId, Long channelId, Long readId) {
96 - webSocketService.sendChannelMessageAsync(userId, ImChannelMessageDTO.ofRead(channelId, readId)); 100 + webSocketService.sendNotificationAsync(userId, ImConversationTypeEnum.CHANNEL.getType(),
  101 + ImContentTypeEnum.READ.getType(), ImMessageReadNotification.ofChannel(channelId, readId));
97 } 102 }
98 103
99 private ImChannelMessageServiceImpl getSelf() { 104 private ImChannelMessageServiceImpl getSelf() {
@@ -113,15 +118,16 @@ public class ImChannelMessageServiceImpl implements ImChannelMessageService { @@ -113,15 +118,16 @@ public class ImChannelMessageServiceImpl implements ImChannelMessageService {
113 String payloadJson = JsonUtils.toJsonString(payload); 118 String payloadJson = JsonUtils.toJsonString(payload);
114 // 2.2 落库 1 行 message;reqVO 同名字段(materialId / receiverUserIds)自动拷贝,剩余字段补 set 119 // 2.2 落库 1 行 message;reqVO 同名字段(materialId / receiverUserIds)自动拷贝,剩余字段补 set
115 ImChannelMessageDO message = BeanUtils.toBean(reqVO, ImChannelMessageDO.class).setChannelId(material.getChannelId()) 120 ImChannelMessageDO message = BeanUtils.toBean(reqVO, ImChannelMessageDO.class).setChannelId(material.getChannelId())
116 - .setType(ImMessageTypeEnum.MATERIAL.getType()).setContent(payloadJson).setSendTime(LocalDateTime.now()); 121 + .setType(ImContentTypeEnum.MATERIAL.getType()).setContent(payloadJson).setSendTime(LocalDateTime.now());
117 channelMessageMapper.insert(message); 122 channelMessageMapper.insert(message);
118 123
119 // 3. 异步推 WebSocket:指定用户走点对点;全员(receiverUserIds 为空)走广播 124 // 3. 异步推 WebSocket:指定用户走点对点;全员(receiverUserIds 为空)走广播
120 - ImChannelMessageDTO dto = ImChannelMessageDTO.ofSend(message); 125 + ImChannelMessageNotification dto = ImChannelMessageNotification.ofSend(message);
121 if (CollUtil.isNotEmpty(reqVO.getReceiverUserIds())) { 126 if (CollUtil.isNotEmpty(reqVO.getReceiverUserIds())) {
122 - webSocketService.sendChannelMessageAsync(reqVO.getReceiverUserIds(), dto); 127 + webSocketService.sendNotificationAsync(reqVO.getReceiverUserIds(), ImConversationTypeEnum.CHANNEL.getType(),
  128 + dto.getType(), dto);
123 } else { 129 } else {
124 - webSocketService.broadcastChannelMessageAsync(dto); 130 + webSocketService.broadcastNotificationAsync(ImConversationTypeEnum.CHANNEL.getType(), dto.getType(), dto);
125 } 131 }
126 return message.getId(); 132 return message.getId();
127 } 133 }
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/message/ImGroupMessageService.java
@@ -98,35 +98,6 @@ public interface ImGroupMessageService { @@ -98,35 +98,6 @@ public interface ImGroupMessageService {
98 */ 98 */
99 List<ImGroupMessageDO> getGroupMessageList(Long userId, ImGroupMessageListReqVO reqVO); 99 List<ImGroupMessageDO> getGroupMessageList(Long userId, ImGroupMessageListReqVO reqVO);
100 100
101 - /**  
102 - * 清理用户在某群的已读位置缓存  
103 - * <p>  
104 - * 用于成员退群场景  
105 - *  
106 - * @param groupId 群编号  
107 - * @param userId 用户编号  
108 - */  
109 - void deleteReadMaxMessageId(Long groupId, Long userId);  
110 -  
111 - /**  
112 - * 批量清理用户在某群的已读位置缓存  
113 - * <p>  
114 - * 用于批量踢出场景  
115 - *  
116 - * @param groupId 群编号  
117 - * @param userIds 用户编号集合  
118 - */  
119 - void deleteReadMaxMessageIds(Long groupId, Collection<Long> userIds);  
120 -  
121 - /**  
122 - * 清理某群所有用户的已读位置缓存  
123 - * <p>  
124 - * 用于群解散场景  
125 - *  
126 - * @param groupId 群编号  
127 - */  
128 - void deleteReadMaxMessageIdMap(Long groupId);  
129 -  
130 // ==================== 管理后台 ==================== 101 // ==================== 管理后台 ====================
131 102
132 /** 103 /**
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/message/ImGroupMessageServiceImpl.java
@@ -6,7 +6,6 @@ import cn.hutool.core.util.BooleanUtil; @@ -6,7 +6,6 @@ import cn.hutool.core.util.BooleanUtil;
6 import cn.hutool.core.util.IdUtil; 6 import cn.hutool.core.util.IdUtil;
7 import cn.hutool.core.util.ObjUtil; 7 import cn.hutool.core.util.ObjUtil;
8 import cn.hutool.extra.spring.SpringUtil; 8 import cn.hutool.extra.spring.SpringUtil;
9 -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;  
10 import cn.iocoder.yudao.framework.common.pojo.PageResult; 9 import cn.iocoder.yudao.framework.common.pojo.PageResult;
11 import cn.iocoder.yudao.framework.common.util.json.JsonUtils; 10 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
12 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 11 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
@@ -17,23 +16,27 @@ import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupDO; @@ -17,23 +16,27 @@ import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupDO;
17 import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO; 16 import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO;
18 import cn.iocoder.yudao.module.im.dal.dataobject.message.ImGroupMessageDO; 17 import cn.iocoder.yudao.module.im.dal.dataobject.message.ImGroupMessageDO;
19 import cn.iocoder.yudao.module.im.dal.mysql.message.ImGroupMessageMapper; 18 import cn.iocoder.yudao.module.im.dal.mysql.message.ImGroupMessageMapper;
20 -import cn.iocoder.yudao.module.im.dal.redis.message.ImGroupMessageReadRedisDAO; 19 +import cn.iocoder.yudao.module.im.enums.ImConversationTypeEnum;
21 import cn.iocoder.yudao.module.im.enums.group.ImGroupMemberRoleEnum; 20 import cn.iocoder.yudao.module.im.enums.group.ImGroupMemberRoleEnum;
22 -import cn.iocoder.yudao.module.im.enums.message.ImGroupMessageReceiptStatusEnum; 21 +import cn.iocoder.yudao.module.im.enums.message.ImMessageReceiptStatusEnum;
23 import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum; 22 import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum;
24 -import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum; 23 +import cn.iocoder.yudao.module.im.enums.ImContentTypeEnum;
25 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;
26 import cn.iocoder.yudao.module.im.service.group.ImGroupMemberService; 26 import cn.iocoder.yudao.module.im.service.group.ImGroupMemberService;
27 import cn.iocoder.yudao.module.im.service.group.ImGroupService; 27 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;
  39 +import org.springframework.dao.DuplicateKeyException;
37 import org.springframework.scheduling.annotation.Async; 40 import org.springframework.scheduling.annotation.Async;
38 import org.springframework.stereotype.Service; 41 import org.springframework.stereotype.Service;
39 import org.springframework.transaction.annotation.Transactional; 42 import org.springframework.transaction.annotation.Transactional;
@@ -41,7 +44,6 @@ import org.springframework.validation.annotation.Validated; @@ -41,7 +44,6 @@ import org.springframework.validation.annotation.Validated;
41 44
42 import java.time.LocalDateTime; 45 import java.time.LocalDateTime;
43 import java.util.*; 46 import java.util.*;
44 -import java.util.stream.Collectors;  
45 47
46 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 48 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
47 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; 49 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
@@ -57,17 +59,8 @@ import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.*; @@ -57,17 +59,8 @@ import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.*;
57 @Slf4j 59 @Slf4j
58 public class ImGroupMessageServiceImpl implements ImGroupMessageService { 60 public class ImGroupMessageServiceImpl implements ImGroupMessageService {
59 61
60 - /**  
61 - * 仅用于规避群消息 pull 的"假空页":  
62 - * 首批消息可能因入群时间或定向接收过滤后变成空列表,但后续更大的 id 仍然存在可见消息。  
63 - * 因此仅在过滤结果为空时,按本轮消息最大 id 向后再试几次。  
64 - */  
65 - private static final int PULL_GROUP_MESSAGE_EMPTY_RETRY_TIMES = 3;  
66 -  
67 @Resource 62 @Resource
68 private ImGroupMessageMapper groupMessageMapper; 63 private ImGroupMessageMapper groupMessageMapper;
69 - @Resource  
70 - private ImGroupMessageReadRedisDAO groupMessageReadRedisDAO;  
71 64
72 @Resource 65 @Resource
73 private ImGroupService groupService; 66 private ImGroupService groupService;
@@ -75,6 +68,8 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { @@ -75,6 +68,8 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService {
75 private ImGroupMemberService groupMemberService; 68 private ImGroupMemberService groupMemberService;
76 @Resource 69 @Resource
77 private ImSensitiveWordService sensitiveWordService; 70 private ImSensitiveWordService sensitiveWordService;
  71 + @Resource
  72 + private ImConversationReadService conversationReadService;
78 73
79 @Resource 74 @Resource
80 private ImWebSocketService imWebSocketService; 75 private ImWebSocketService imWebSocketService;
@@ -100,34 +95,44 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { @@ -100,34 +95,44 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService {
100 // 1.4 禁言校验 95 // 1.4 禁言校验
101 validateMuteStatus(group, senderMember); 96 validateMuteStatus(group, senderMember);
102 // 1.5 文本消息敏感词过滤 97 // 1.5 文本消息敏感词过滤
103 - if (ImMessageTypeEnum.TEXT.getType().equals(reqVO.getType())) { 98 + if (ImContentTypeEnum.TEXT.getType().equals(reqVO.getType())) {
104 sensitiveWordService.validateText(reqVO.getContent()); 99 sensitiveWordService.validateText(reqVO.getContent());
105 } 100 }
106 101
107 - // 2.1 引用 quote 消息规范化  
108 - reqVO.setContent(normalizeQuoteContent(reqVO, senderMember));  
109 - // 2.2 构建并保存消息 102 + // 2.1 固化发送当时可见成员快照:用户发送均为全员广播;getReceiverUserIds 兜底纳入发送者,钉死发送者必可见
  103 + List<Long> memberUserIds = groupMemberService.getActiveGroupMemberUserIdsByGroupId(reqVO.getGroupId());
  104 + Set<Long> receiverUserIds = getReceiverUserIds(null, senderId, memberUserIds);
  105 + // 2.2 引用 quote 消息规范化(含可见性子集校验,防止定向消息内容被广播引用泄漏)
  106 + reqVO.setContent(normalizeQuoteContent(reqVO, senderMember, receiverUserIds));
  107 + // 2.3 构建并保存消息;唯一键冲突时回查已存在消息返回
110 ImGroupMessageDO message = BeanUtils.toBean(reqVO, ImGroupMessageDO.class, m -> m 108 ImGroupMessageDO message = BeanUtils.toBean(reqVO, ImGroupMessageDO.class, m -> m
111 - .setSenderId(senderId).setStatus(ImMessageStatusEnum.UNREAD.getStatus()).setSendTime(LocalDateTime.now()) 109 + .setSenderId(senderId).setStatus(ImMessageStatusEnum.NORMAL.getStatus()).setSendTime(LocalDateTime.now())
  110 + .setReceiverUserIds(new ArrayList<>(receiverUserIds))
112 .setReceiptStatus(resolveReceiptStatus(reqVO.getReceipt()))); 111 .setReceiptStatus(resolveReceiptStatus(reqVO.getReceipt())));
113 - groupMessageMapper.insert(message); 112 + try {
  113 + groupMessageMapper.insert(message);
  114 + } catch (DuplicateKeyException e) {
  115 + log.warn("[sendGroupMessage][senderId({}) clientMessageId({}) 并发插入冲突,回查返回]",
  116 + senderId, reqVO.getClientMessageId());
  117 + return groupMessageMapper.selectBySenderIdAndClientMessageId(senderId, reqVO.getClientMessageId());
  118 + }
114 119
115 - // 3. WebSocket 异步推送(群内可见成员 + 发送方多端同步)  
116 - List<Long> memberUserIds = groupMemberService.getActiveGroupMemberUserIdsByGroupId(message.getGroupId());  
117 - Set<Long> targetUserIds = getVisibleUserIds(message.getReceiverUserIds(), senderId, memberUserIds);  
118 - imWebSocketService.sendGroupMessageAsync(targetUserIds, ImGroupMessageDTO.ofSend(message)); 120 + // 3. WebSocket 异步推送(快照内可见成员 + 发送方多端同步)
  121 + ImGroupMessageNotification notification = ImGroupMessageNotification.ofSend(message);
  122 + imWebSocketService.sendNotificationAsync(receiverUserIds, ImConversationTypeEnum.GROUP.getType(),
  123 + notification.getType(), notification);
119 return message; 124 return message;
120 } 125 }
121 126
122 @Override 127 @Override
123 public ImGroupMessageDO sendGroupMessage(Long senderId, ImGroupMessageSendDTO dto) { 128 public ImGroupMessageDO sendGroupMessage(Long senderId, ImGroupMessageSendDTO dto) {
124 List<Long> memberUserIds = groupMemberService.getActiveGroupMemberUserIdsByGroupId(dto.getGroupId()); 129 List<Long> memberUserIds = groupMemberService.getActiveGroupMemberUserIdsByGroupId(dto.getGroupId());
125 - Set<Long> targetUserIds = getVisibleUserIds(dto.getReceiverUserIds(), senderId, memberUserIds);  
126 - return sendGroupMessage(senderId, targetUserIds, dto); 130 + Set<Long> receiverUserIds = getReceiverUserIds(dto.getReceiverUserIds(), senderId, memberUserIds);
  131 + return sendGroupMessage(senderId, receiverUserIds, dto);
127 } 132 }
128 133
129 @Override 134 @Override
130 - public ImGroupMessageDO sendGroupMessage(Long senderId, Collection<Long> targetUserIds, ImGroupMessageSendDTO dto) { 135 + public ImGroupMessageDO sendGroupMessage(Long senderId, Collection<Long> receiverUserIds, ImGroupMessageSendDTO dto) {
131 // 1.1 content 序列化:null / String 透传,POJO 走 JSON 136 // 1.1 content 序列化:null / String 透传,POJO 走 JSON
132 Object payload = dto.getContent(); 137 Object payload = dto.getContent();
133 String contentString = payload == null || payload instanceof String 138 String contentString = payload == null || payload instanceof String
@@ -137,16 +142,18 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { @@ -137,16 +142,18 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService {
137 ImGroupMessageDO message = new ImGroupMessageDO().setClientMessageId(IdUtil.fastSimpleUUID()) 142 ImGroupMessageDO message = new ImGroupMessageDO().setClientMessageId(IdUtil.fastSimpleUUID())
138 .setSenderId(senderId).setGroupId(dto.getGroupId()) 143 .setSenderId(senderId).setGroupId(dto.getGroupId())
139 .setType(dto.getType()).setContent(contentString) 144 .setType(dto.getType()).setContent(contentString)
140 - .setStatus(ImMessageStatusEnum.UNREAD.getStatus()).setSendTime(LocalDateTime.now())  
141 - .setAtUserIds(dto.getAtUserIds()).setReceiverUserIds(dto.getReceiverUserIds()) 145 + .setStatus(ImMessageStatusEnum.NORMAL.getStatus()).setSendTime(LocalDateTime.now())
  146 + .setAtUserIds(dto.getAtUserIds()).setReceiverUserIds(new ArrayList<>(receiverUserIds))
142 .setReceiptStatus(resolveReceiptStatus(dto.getReceipt())); 147 .setReceiptStatus(resolveReceiptStatus(dto.getReceipt()));
143 // 1.3 按 type.persistent 决定是否入库 148 // 1.3 按 type.persistent 决定是否入库
144 - if (ImMessageTypeEnum.validate(dto.getType()).isPersistent()) { 149 + if (ImContentTypeEnum.validate(dto.getType()).isPersistent()) {
145 groupMessageMapper.insert(message); 150 groupMessageMapper.insert(message);
146 } 151 }
147 152
148 // 2. WebSocket 异步推送 153 // 2. WebSocket 异步推送
149 - imWebSocketService.sendGroupMessageAsync(targetUserIds, ImGroupMessageDTO.ofSend(message)); 154 + ImGroupMessageNotification notification = ImGroupMessageNotification.ofSend(message);
  155 + imWebSocketService.sendNotificationAsync(receiverUserIds, ImConversationTypeEnum.GROUP.getType(),
  156 + notification.getType(), notification);
150 return message; 157 return message;
151 } 158 }
152 159
@@ -180,7 +187,7 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { @@ -180,7 +187,7 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService {
180 187
181 // 3. 发送撤回事件 188 // 3. 发送撤回事件
182 return sendGroupMessage(userId, new ImGroupMessageSendDTO().setGroupId(message.getGroupId()) 189 return sendGroupMessage(userId, new ImGroupMessageSendDTO().setGroupId(message.getGroupId())
183 - .setType(ImMessageTypeEnum.RECALL.getType()) 190 + .setType(ImContentTypeEnum.RECALL.getType())
184 .setReceiverUserIds(message.getReceiverUserIds()) 191 .setReceiverUserIds(message.getReceiverUserIds())
185 .setContent(new RecallMessage().setMessageId(messageId))); 192 .setContent(new RecallMessage().setMessageId(messageId)));
186 } 193 }
@@ -195,155 +202,53 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { @@ -195,155 +202,53 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService {
195 // 0. 拉取时间窗;超过窗口的老消息不再通过离线通道推送 202 // 0. 拉取时间窗;超过窗口的老消息不再通过离线通道推送
196 LocalDateTime minSendTime = LocalDateTime.now().minusDays(imProperties.getMessage().getGroupPullMaxDays()); 203 LocalDateTime minSendTime = LocalDateTime.now().minusDays(imProperties.getMessage().getGroupPullMaxDays());
197 204
198 - // 1.1 主查询:仅用"当前仍在群"的成员记录驱动;若首批消息过滤后为空,则允许内部重试  
199 - List<ImGroupMemberDO> activeMembers = groupMemberService.getActiveGroupMemberListByUserId(userId);  
200 - Map<Long, ImGroupMemberDO> memberMap = convertMap(activeMembers, ImGroupMemberDO::getGroupId);  
201 - List<ImGroupMessageDO> messages = new ArrayList<>();  
202 - if (CollUtil.isNotEmpty(activeMembers)) {  
203 - List<Long> groupIds = convertList(activeMembers, ImGroupMemberDO::getGroupId);  
204 - messages.addAll(pullActiveGroupMessageList(userId, groupIds, minId, size, minSendTime, memberMap));  
205 - }  
206 - // 1.2 补齐"退群前"的消息:  
207 - // - 继续基于用户原始 minId 单次查询,不能被主查询内部探测游标带着前进;  
208 - // - 若 minId > 0 且能查到对应消息,则进一步把下限抬到该消息的 sendTime,避免把客户端已拥有的老消息再次推送。  
209 - messages.addAll(pullQuitGroupMessageList(userId, minId, size, minSendTime, memberMap));  
210 -  
211 - // 2. 合并后统一过滤,得到当前用户可见的结果  
212 - List<ImGroupMessageDO> result = filterGroupMessageList(messages, memberMap, userId, size);  
213 -  
214 - // 3. 按当前用户补齐:消息已读态(相对 Redis 已读游标)、本人发送的回执消息的已读人数  
215 - appendMessageStatusAndReceipt(userId, result);  
216 - log.info("[pullGroupMessageList][userId({}) minId({}) size({}) result({})]", userId, minId, size, result.size());  
217 - return result;  
218 - }  
219 -  
220 - /**  
221 - * 拉取当前仍在群的主路径消息。  
222 - *  
223 - * 仅当首批消息过滤后仍无可见消息时,才按消息最大 id 继续向后探测,  
224 - * 直到命中可见消息或确认该来源已耗尽。  
225 - */  
226 - private List<ImGroupMessageDO> pullActiveGroupMessageList(Long userId, List<Long> groupIds, Long minId,  
227 - Integer size, LocalDateTime minSendTime,  
228 - Map<Long, ImGroupMemberDO> memberMap) {  
229 - // 1. 主查询内部探测游标:仅用于向后探测,不代表客户端真实已送达边界  
230 - Long activeMinId = minId;  
231 - for (int retryCount = 0; retryCount <= PULL_GROUP_MESSAGE_EMPTY_RETRY_TIMES; retryCount++) {  
232 - // 2. 查询本轮消息;若已无更多消息,则当前主路径直接结束  
233 - List<ImGroupMessageDO> messages = groupMessageMapper.selectListByMinId(groupIds, activeMinId,  
234 - minSendTime, size);  
235 - if (CollUtil.isEmpty(messages)) {  
236 - return Collections.emptyList();  
237 - }  
238 - boolean hasVisibleMessage = CollUtil.anyMatch(messages,  
239 - message -> isMessageVisible(message, memberMap.get(message.getGroupId()), userId));  
240 - boolean sourceExhausted = messages.size() < size;  
241 - // 3. 本轮已命中可见消息,或主查询来源已耗尽,直接返回这一轮消息  
242 - if (hasVisibleMessage || sourceExhausted) {  
243 - return messages;  
244 - }  
245 -  
246 - // 4. 按本轮消息最大 id 推进内部游标,跳过这段不可见区间;若游标未前进则直接停止  
247 - Long maxMessageId = getMaxValue(messages, ImGroupMessageDO::getId);  
248 - if (maxMessageId == null || maxMessageId <= activeMinId) {  
249 - return Collections.emptyList();  
250 - }  
251 - activeMinId = maxMessageId; 205 + // 1. 候选群 = 用户曾经加入的所有群(含退群);可见性与时间窗都交给 SQL,退群群最多贡献 0 条
  206 + Set<Long> groupIds = convertSet(groupMemberService.getGroupMemberListByUserId(userId),
  207 + ImGroupMemberDO::getGroupId);
  208 + if (CollUtil.isEmpty(groupIds)) {
  209 + return Collections.emptyList();
252 } 210 }
253 - return Collections.emptyList();  
254 - }  
255 211
256 - /**  
257 - * 拉取已离开群路径的消息(退群前消息)  
258 - */  
259 - private List<ImGroupMessageDO> pullQuitGroupMessageList(Long userId, Long minId, Integer size,  
260 - LocalDateTime minSendTime,  
261 - Map<Long, ImGroupMemberDO> memberMap) {  
262 - // 1. 退群补齐始终基于用户原始 minId 计算时间边界,避免被主查询内部重试游标误伤  
263 - LocalDateTime minQuitTime = minSendTime;  
264 - if (minId != null && minId > 0) {  
265 - ImGroupMessageDO minMessage = groupMessageMapper.selectById(minId);  
266 - if (minMessage != null && minMessage.getSendTime() != null  
267 - && minMessage.getSendTime().isAfter(minSendTime)) {  
268 - minQuitTime = minMessage.getSendTime();  
269 - }  
270 - }  
271 - // 2. 查询用户离开的群记录;若原始 minId 对应消息仍在窗口内,则用它的发送时间抬升退群筛选下限  
272 - List<ImGroupMessageDO> messages = new ArrayList<>();  
273 - List<ImGroupMemberDO> quitMembers = groupMemberService.getQuitGroupMemberListByUserId(userId, minQuitTime);  
274 - for (ImGroupMemberDO quitMember : quitMembers) {  
275 - // 3. 按原始 minId + 退群时间补齐该群退群前消息,并把成员记录写回 memberMap 供统一可见性过滤使用  
276 - List<ImGroupMessageDO> quitGroupMessages = groupMessageMapper.selectListByGroupIdAndMinIdAndQuitTimeBefore(  
277 - quitMember.getGroupId(), minId, minSendTime, quitMember.getQuitTime(), size);  
278 - if (CollUtil.isEmpty(quitGroupMessages)) {  
279 - continue;  
280 - }  
281 - messages.addAll(quitGroupMessages);  
282 - memberMap.put(quitMember.getGroupId(), quitMember);  
283 - }  
284 - return messages;  
285 - } 212 + // 2. 按 receiver_user_ids 快照过滤可见性,结果按 id 升序
  213 + List<ImGroupMessageDO> messages = groupMessageMapper.selectListByMinId(userId, groupIds, minId, minSendTime, size);
286 214
287 - /**  
288 - * 过滤一批原始群消息,得到当前用户可见的返回结果  
289 - */  
290 - private List<ImGroupMessageDO> filterGroupMessageList(List<ImGroupMessageDO> messages,  
291 - Map<Long, ImGroupMemberDO> memberMap,  
292 - Long userId, Integer size) {  
293 - // 按可见性过滤(入群前不可见、定向消息排除),按 id 升序后仅取本页 size 条,  
294 - // 避免「在群 + 退群前」多路合并时一次响应跨度过大、游标直接跳到全局最大 id 而漏拉中间消息  
295 - return messages.stream()  
296 - .filter(msg -> isMessageVisible(msg, memberMap.get(msg.getGroupId()), userId))  
297 - .sorted(Comparator.comparing(ImGroupMessageDO::getId))  
298 - .limit(size)  
299 - .collect(Collectors.toList()); 215 + // 3. 补齐本人发送的回执消息的已读人数
  216 + appendMessageReceipt(userId, messages);
  217 + log.info("[pullGroupMessageList][userId({}) minId({}) size({}) result({})]", userId, minId, size, messages.size());
  218 + return messages;
300 } 219 }
301 220
302 /** 221 /**
303 - * 补全消息已读态和回执已读人数  
304 - *  
305 - * 1. 消息已读态(status):根据 Redis 已读游标判断 READ / UNREAD  
306 - * 2. 回执已读人数(readCount):仅对本人发送的回执消息,计算可见成员中的已读人数 222 + * 补全本人发送消息的回执已读人数(readCount)
  223 + * <p>
  224 + * 仅对本人发送、且需要回执(非 NO_RECEIPT)的消息,按 receiver_user_ids 快照 ∩ 当前有效成员 - 发送者 算已读人数
307 */ 225 */
308 - @SuppressWarnings({"StatementWithEmptyBody", "DataFlowIssue"})  
309 - private void appendMessageStatusAndReceipt(Long userId, List<ImGroupMessageDO> messages) { 226 + @SuppressWarnings("DataFlowIssue")
  227 + private void appendMessageReceipt(Long userId, List<ImGroupMessageDO> messages) {
310 if (CollUtil.isEmpty(messages)) { 228 if (CollUtil.isEmpty(messages)) {
311 return; 229 return;
312 } 230 }
313 - // 群已读关闭:不查 Redis 已读游标,status 保持 DB 原值(含撤回),readCount 不补齐 231 + // 群已读关闭:不补 readCount
314 if (BooleanUtil.isFalse(imProperties.getMessage().isGroupReadEnabled())) { 232 if (BooleanUtil.isFalse(imProperties.getMessage().isGroupReadEnabled())) {
315 return; 233 return;
316 } 234 }
317 - Map<Long, Long> readMaxMessageIdsByGroup = new HashMap<>(); // 群 → 已读位置  
318 Map<Long, Map<Long, Long>> readPositionsByGroup = new HashMap<>(); // 群 → (用户 → 已读位置) 235 Map<Long, Map<Long, Long>> readPositionsByGroup = new HashMap<>(); // 群 → (用户 → 已读位置)
319 Map<Long, List<ImGroupMemberDO>> membersByGroup = new HashMap<>(); // 群 → 全部成员列表 236 Map<Long, List<ImGroupMemberDO>> membersByGroup = new HashMap<>(); // 群 → 全部成员列表
320 for (ImGroupMessageDO message : messages) { 237 for (ImGroupMessageDO message : messages) {
321 - // 消息已读态(status):撤回 > 已读 > 未读  
322 - Long groupId = message.getGroupId();  
323 - long readMaxMessageId = readMaxMessageIdsByGroup.computeIfAbsent(groupId, gid -> {  
324 - Long readMaxMsgId = groupMessageReadRedisDAO.getReadMaxMessageId(gid, userId);  
325 - return readMaxMsgId != null ? readMaxMsgId : -1L;  
326 - });  
327 - if (ImMessageStatusEnum.RECALL.getStatus().equals(message.getStatus())) {  
328 - // 保持撤回态  
329 - } else if (readMaxMessageId >= message.getId()) {  
330 - message.setStatus(ImMessageStatusEnum.READ.getStatus());  
331 - } else {  
332 - message.setStatus(ImMessageStatusEnum.UNREAD.getStatus());  
333 - }  
334 -  
335 - // 回执消息的已读人数(readCount):仅补齐本人发送的,其他消息不处理(回执消息才关心已读人数,且只对发送者可见) 238 + // 仅补本人发送、且需要回执(非 NO_RECEIPT)的消息
336 if (ObjUtil.notEqual(message.getSenderId(), userId) 239 if (ObjUtil.notEqual(message.getSenderId(), userId)
337 - || ImGroupMessageReceiptStatusEnum.NO_RECEIPT.getStatus().equals(message.getReceiptStatus())) { 240 + || ImMessageReceiptStatusEnum.NO_RECEIPT.getStatus().equals(message.getReceiptStatus())) {
338 continue; 241 continue;
339 } 242 }
  243 + Long groupId = message.getGroupId();
340 Map<Long, Long> positions = readPositionsByGroup.computeIfAbsent(groupId, 244 Map<Long, Long> positions = readPositionsByGroup.computeIfAbsent(groupId,
341 - gid -> groupMessageReadRedisDAO.getReadMaxMessageIdMap(gid));  
342 - List<ImGroupMemberDO> allMembers = membersByGroup.computeIfAbsent(groupId,  
343 - groupMemberService::getGroupMemberListByGroupId);  
344 - Set<Long> visibleUserIds = getVisibleUserIds(message, allMembers);  
345 - visibleUserIds.remove(message.getSenderId());  
346 - int readCount = getSumValue(visibleUserIds, 245 + gid -> conversationReadService.getUserReadMessageIdMap(ImConversationTypeEnum.GROUP.getType(), gid));
  246 + // 应读分母取当前有效成员(剔除已退群),与异步回执刷新、前端已读弹层口径一致
  247 + List<ImGroupMemberDO> activeMembers = membersByGroup.computeIfAbsent(groupId,
  248 + groupMemberService::getActiveGroupMemberListByGroupId);
  249 + Set<Long> receiverUserIds = getReceiverUserIds(message, activeMembers);
  250 + receiverUserIds.remove(message.getSenderId());
  251 + int readCount = getSumValue(receiverUserIds,
347 uid -> positions.getOrDefault(uid, -1L) >= message.getId() ? 1 : null, 252 uid -> positions.getOrDefault(uid, -1L) >= message.getId() ? 1 : null,
348 Integer::sum, 0); 253 Integer::sum, 0);
349 message.setReadCount(readCount); 254 message.setReadCount(readCount);
@@ -357,25 +262,24 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { @@ -357,25 +262,24 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService {
357 throw exception(MESSAGE_GROUP_READ_DISABLED); 262 throw exception(MESSAGE_GROUP_READ_DISABLED);
358 } 263 }
359 Assert.notNull(messageId, "已读消息编号不能为空"); 264 Assert.notNull(messageId, "已读消息编号不能为空");
360 - // 1.1 获取群成员记录  
361 - ImGroupMemberDO member = groupMemberService.getGroupMember(groupId, userId);  
362 - // 1.2 校验消息属于当前群,且对当前用户可见 265 + // 1. 校验消息属于当前群,且对当前用户可见(按快照)
363 ImGroupMessageDO message = groupMessageMapper.selectById(messageId); 266 ImGroupMessageDO message = groupMessageMapper.selectById(messageId);
364 if (message == null 267 if (message == null
365 || ObjUtil.notEqual(message.getGroupId(), groupId) 268 || ObjUtil.notEqual(message.getGroupId(), groupId)
366 - || !isMessageVisible(message, member, userId)) { 269 + || !isMessageReceived(message, userId)) {
367 throw exception(MESSAGE_NOT_IN_GROUP); 270 throw exception(MESSAGE_NOT_IN_GROUP);
368 } 271 }
369 272
370 - // 2. 已读位置未前进,直接返回  
371 - Long prevMaxMessageId = groupMessageReadRedisDAO.getReadMaxMessageId(groupId, userId);  
372 - if (prevMaxMessageId != null && prevMaxMessageId >= messageId) { 273 + // 2. 取旧读位置(用于回执刷新区间),再更新群已读位置;读位置未前进则不推
  274 + Long prevMaxMessageId = conversationReadService.getConversationReadMessageId(
  275 + userId, ImConversationTypeEnum.GROUP.getType(), groupId);
  276 + boolean advanced = conversationReadService.updateConversationReadPosition(
  277 + userId, ImConversationTypeEnum.GROUP.getType(), groupId, messageId);
  278 + if (!advanced) {
373 return; 279 return;
374 } 280 }
375 - // 3. 更新 Redis 群已读位置  
376 - groupMessageReadRedisDAO.updateReadMaxMessageId(groupId, userId, messageId);  
377 281
378 - // 4. 异步发送 READ 事件 + 刷新范围内的群回执 282 + // 3. 异步发送 READ 事件 + 刷新范围内的群回执
379 getSelf().readGroupMessageEvent(userId, groupId, prevMaxMessageId, messageId); 283 getSelf().readGroupMessageEvent(userId, groupId, prevMaxMessageId, messageId);
380 } 284 }
381 285
@@ -386,13 +290,13 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { @@ -386,13 +290,13 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService {
386 throw exception(MESSAGE_GROUP_READ_DISABLED); 290 throw exception(MESSAGE_GROUP_READ_DISABLED);
387 } 291 }
388 // 1.1 校验用户在群中(权限校验) 292 // 1.1 校验用户在群中(权限校验)
389 - ImGroupMemberDO operator = groupMemberService.validateMemberInGroup(groupId, userId); 293 + groupMemberService.validateMemberInGroup(groupId, userId);
390 // 1.2 获取消息;并校验消息归属于该群、对调用者可见、调用者是发送方 294 // 1.2 获取消息;并校验消息归属于该群、对调用者可见、调用者是发送方
391 ImGroupMessageDO message = groupMessageMapper.selectById(messageId); 295 ImGroupMessageDO message = groupMessageMapper.selectById(messageId);
392 if (message == null || ObjUtil.notEqual(message.getGroupId(), groupId)) { 296 if (message == null || ObjUtil.notEqual(message.getGroupId(), groupId)) {
393 return Collections.emptyList(); 297 return Collections.emptyList();
394 } 298 }
395 - if (!isMessageVisible(message, operator, userId)) { 299 + if (!isMessageReceived(message, userId)) {
396 return Collections.emptyList(); 300 return Collections.emptyList();
397 } 301 }
398 // 1.3 仅消息发送方关心已读人数;非发送方查询直接返回空 302 // 1.3 仅消息发送方关心已读人数;非发送方查询直接返回空
@@ -400,18 +304,19 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { @@ -400,18 +304,19 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService {
400 return Collections.emptyList(); 304 return Collections.emptyList();
401 } 305 }
402 306
403 - // 2. 获取所有成员和已读位置  
404 - List<ImGroupMemberDO> allMembers = groupMemberService.getGroupMemberListByGroupId(groupId);  
405 - Map<Long, Long> allPositions = groupMessageReadRedisDAO.getReadMaxMessageIdMap(groupId); 307 + // 2. 获取当前有效成员和已读位置(剔除已退群,与回执分母口径一致)
  308 + List<ImGroupMemberDO> activeMembers = groupMemberService.getActiveGroupMemberListByGroupId(groupId);
  309 + Map<Long, Long> allPositions = conversationReadService.getUserReadMessageIdMap(
  310 + ImConversationTypeEnum.GROUP.getType(), groupId);
406 311
407 // 3. 计算该消息的可见成员集合(排除发送者自己) 312 // 3. 计算该消息的可见成员集合(排除发送者自己)
408 - Set<Long> visibleUserIds = getVisibleUserIds(message, allMembers);  
409 - visibleUserIds.remove(message.getSenderId()); 313 + Set<Long> receiverUserIds = getReceiverUserIds(message, activeMembers);
  314 + receiverUserIds.remove(message.getSenderId());
410 315
411 // 4. 只返回在可见范围内且已读位置 >= messageId 的用户 316 // 4. 只返回在可见范围内且已读位置 >= messageId 的用户
412 List<Long> readUserIds = new ArrayList<>(); 317 List<Long> readUserIds = new ArrayList<>();
413 allPositions.forEach((uid, readMaxMessageId) -> { 318 allPositions.forEach((uid, readMaxMessageId) -> {
414 - if (visibleUserIds.contains(uid) && readMaxMessageId >= messageId) { 319 + if (receiverUserIds.contains(uid) && readMaxMessageId >= messageId) {
415 readUserIds.add(uid); 320 readUserIds.add(uid);
416 } 321 }
417 }); 322 });
@@ -420,15 +325,14 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { @@ -420,15 +325,14 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService {
420 325
421 @Override 326 @Override
422 public List<ImGroupMessageDO> getGroupMessageList(Long userId, ImGroupMessageListReqVO reqVO) { 327 public List<ImGroupMessageDO> getGroupMessageList(Long userId, ImGroupMessageListReqVO reqVO) {
423 - // 1. 校验用户在群中  
424 - ImGroupMemberDO member = groupMemberService.validateMemberInGroup(reqVO.getGroupId(), userId);  
425 -  
426 - // 2. 查询历史消息(仅入群之后)  
427 - List<ImGroupMessageDO> messages = groupMessageMapper.selectHistoryList(  
428 - reqVO.getGroupId(), reqVO.getMaxId(), reqVO.getLimit(), member.getJoinTime()); 328 + // 1. 校验用户曾经在群(当前在群或已退群),与 pull 退群窗口口径一致;内容仍由 receiver_user_ids 快照过滤
  329 + if (groupMemberService.getGroupMember(reqVO.getGroupId(), userId) == null) {
  330 + throw exception(GROUP_MEMBER_NOT_IN_GROUP);
  331 + }
429 332
430 - // 3. 过滤定向消息:仅保留当前用户可见的(receiverUserIds 为空 / 含当前用户 / 本人发送)  
431 - return filterList(messages, message -> isMessageVisible(message, member, userId)); 333 + // 2. 查询历史消息:SQL 已按 receiver_user_ids 快照过滤当前用户可见
  334 + return groupMessageMapper.selectHistoryListByUser(
  335 + userId, reqVO.getGroupId(), reqVO.getMaxId(), reqVO.getLimit());
432 } 336 }
433 337
434 // ========== 异步 WebSocket 推送 ========== 338 // ========== 异步 WebSocket 推送 ==========
@@ -445,8 +349,9 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { @@ -445,8 +349,9 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService {
445 @SuppressWarnings("DataFlowIssue") 349 @SuppressWarnings("DataFlowIssue")
446 public void readGroupMessageEvent(Long userId, Long groupId, Long prevMaxMessageId, Long newMaxMessageId) { 350 public void readGroupMessageEvent(Long userId, Long groupId, Long prevMaxMessageId, Long newMaxMessageId) {
447 // 1. 发送 READ 事件给自己的其他终端(多端同步) 351 // 1. 发送 READ 事件给自己的其他终端(多端同步)
448 - imWebSocketService.sendGroupMessageAsync(userId,  
449 - ImGroupMessageDTO.ofRead(userId, groupId, newMaxMessageId)); 352 + imWebSocketService.sendNotificationAsync(userId, ImConversationTypeEnum.GROUP.getType(),
  353 + ImContentTypeEnum.READ.getType(),
  354 + ImMessageReadNotification.ofGroup(userId, groupId, newMaxMessageId));
450 355
451 // 2. 刷新 (prevMaxMessageId, newMaxMessageId] 区间内的待回执消息 356 // 2. 刷新 (prevMaxMessageId, newMaxMessageId] 区间内的待回执消息
452 List<ImGroupMessageDO> pendingMessages = groupMessageMapper.selectListByGroupIdAndPendingReceipt( 357 List<ImGroupMessageDO> pendingMessages = groupMessageMapper.selectListByGroupIdAndPendingReceipt(
@@ -455,28 +360,30 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { @@ -455,28 +360,30 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService {
455 return; 360 return;
456 } 361 }
457 List<ImGroupMemberDO> activeMembers = groupMemberService.getActiveGroupMemberListByGroupId(groupId); 362 List<ImGroupMemberDO> activeMembers = groupMemberService.getActiveGroupMemberListByGroupId(groupId);
458 - Map<Long, Long> allPositions = groupMessageReadRedisDAO.getReadMaxMessageIdMap(groupId); 363 + Map<Long, Long> allPositions = conversationReadService.getUserReadMessageIdMap(
  364 + ImConversationTypeEnum.GROUP.getType(), groupId);
459 for (ImGroupMessageDO message : pendingMessages) { 365 for (ImGroupMessageDO message : pendingMessages) {
460 - // 2.1.1 统计可见成员中的已读人数  
461 - Set<Long> visibleUserIds = getVisibleUserIds(message, activeMembers);  
462 - visibleUserIds.remove(message.getSenderId()); // 发送者自己不算已读  
463 - if (CollUtil.isEmpty(visibleUserIds)) { 366 + // 2.1.1 统计可见成员中的已读人数(应读分母 = 快照 ∩ 当前有效成员 - sender)
  367 + Set<Long> receiverUserIds = getReceiverUserIds(message, activeMembers);
  368 + receiverUserIds.remove(message.getSenderId()); // 发送者自己不算已读
  369 + if (CollUtil.isEmpty(receiverUserIds)) {
464 continue; 370 continue;
465 } 371 }
466 - int readCount = getSumValue(visibleUserIds, 372 + int readCount = getSumValue(receiverUserIds,
467 uid -> allPositions.getOrDefault(uid, -1L) >= message.getId() ? 1 : null, 373 uid -> allPositions.getOrDefault(uid, -1L) >= message.getId() ? 1 : null,
468 Integer::sum, 0); 374 Integer::sum, 0);
469 // 2.1.2 全部已读 → 标记回执完成 375 // 2.1.2 全部已读 → 标记回执完成
470 - Integer newReceiptStatus = ImGroupMessageReceiptStatusEnum.PENDING.getStatus();  
471 - if (readCount >= visibleUserIds.size()) {  
472 - newReceiptStatus = ImGroupMessageReceiptStatusEnum.DONE.getStatus(); 376 + Integer newReceiptStatus = ImMessageReceiptStatusEnum.PENDING.getStatus();
  377 + if (readCount >= receiverUserIds.size()) {
  378 + newReceiptStatus = ImMessageReceiptStatusEnum.DONE.getStatus();
473 groupMessageMapper.updateById(new ImGroupMessageDO().setId(message.getId()) 379 groupMessageMapper.updateById(new ImGroupMessageDO().setId(message.getId())
474 .setReceiptStatus(newReceiptStatus)); 380 .setReceiptStatus(newReceiptStatus));
475 } 381 }
476 382
477 // 2.2 发送 RECEIPT 事件给消息发送方(只有 ta 关心已读进度) 383 // 2.2 发送 RECEIPT 事件给消息发送方(只有 ta 关心已读进度)
478 - imWebSocketService.sendGroupMessageAsync(message.getSenderId(),  
479 - ImGroupMessageDTO.ofReceipt(message.getId(), groupId, readCount, newReceiptStatus)); 384 + imWebSocketService.sendNotificationAsync(message.getSenderId(), ImConversationTypeEnum.GROUP.getType(),
  385 + ImContentTypeEnum.RECEIPT.getType(),
  386 + ImMessageReceiptNotification.ofGroup(message.getId(), groupId, readCount, newReceiptStatus));
480 } 387 }
481 } 388 }
482 389
@@ -487,9 +394,11 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { @@ -487,9 +394,11 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService {
487 * 394 *
488 * @param reqVO 发送请求 395 * @param reqVO 发送请求
489 * @param senderMember 发送人成员 396 * @param senderMember 发送人成员
  397 + * @param newAudience 新消息可见成员集合(发送当时快照)
490 * @return 规范化后的 content 398 * @return 规范化后的 content
491 */ 399 */
492 - private String normalizeQuoteContent(ImGroupMessageSendReqVO reqVO, ImGroupMemberDO senderMember) { 400 + private String normalizeQuoteContent(ImGroupMessageSendReqVO reqVO, ImGroupMemberDO senderMember,
  401 + Set<Long> newAudience) {
493 // 解析客户端 content 里的 quote.messageId 402 // 解析客户端 content 里的 quote.messageId
494 Long quoteMessageId = ImMessageUtils.parseQuoteMessageId(reqVO.getContent()); 403 Long quoteMessageId = ImMessageUtils.parseQuoteMessageId(reqVO.getContent());
495 404
@@ -508,12 +417,13 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { @@ -508,12 +417,13 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService {
508 if (ObjUtil.notEqual(original.getGroupId(), reqVO.getGroupId())) { 417 if (ObjUtil.notEqual(original.getGroupId(), reqVO.getGroupId())) {
509 throw exception(MESSAGE_QUOTE_INVALID); 418 throw exception(MESSAGE_QUOTE_INVALID);
510 } 419 }
511 - // 拒绝定向消息(仅发送人可见的内容若被全员广播 quote.content,会泄漏给原本看不到的成员)  
512 - if (CollUtil.isNotEmpty(original.getReceiverUserIds())) { 420 + // 校验对发送人可见(按快照)
  421 + if (!isMessageReceived(original, senderMember.getUserId())) {
513 throw exception(MESSAGE_QUOTE_INVALID); 422 throw exception(MESSAGE_QUOTE_INVALID);
514 } 423 }
515 - // 校验对发送人可见(入群时间 / 退群时间)  
516 - if (!isMessageVisible(original, senderMember, senderMember.getUserId())) { 424 + // 防泄漏:新消息可见集合必须是被引用消息可见集合的子集,否则禁止引用;
  425 + // 否则只对部分成员可见的定向消息内容,会随广播引用泄漏给原本看不到的成员
  426 + if (!new HashSet<>(original.getReceiverUserIds()).containsAll(newAudience)) {
517 throw exception(MESSAGE_QUOTE_INVALID); 427 throw exception(MESSAGE_QUOTE_INVALID);
518 } 428 }
519 // 构建 quote 对象并注入 content 429 // 构建 quote 对象并注入 content
@@ -537,87 +447,48 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { @@ -537,87 +447,48 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService {
537 } 447 }
538 448
539 /** 449 /**
540 - * 判断一条群消息对某个群成员是否可见 450 + * 判断一条群消息是否被某个用户接收到
  451 + * <p>
  452 + * 接收范围以发送当时固化的 receiver_user_ids 快照为准;发送者也在快照内。
541 * 453 *
542 - * @param msg 消息  
543 - * @param member 群成员  
544 - * @param userId 当前用户编号(用于定向消息过滤)  
545 - * @return 是否可见 454 + * @param message 消息
  455 + * @param userId 当前用户编号
  456 + * @return 是否接收到
546 */ 457 */
547 - private boolean isMessageVisible(ImGroupMessageDO msg, ImGroupMemberDO member, Long userId) {  
548 - if (member == null) {  
549 - return false;  
550 - }  
551 - // 1. 入群时间晚于消息发送时间 → 不可见  
552 - if (member.getJoinTime() != null && msg.getSendTime().isBefore(member.getJoinTime())) {  
553 - return false;  
554 - }  
555 - // 2. 已退群且退群时间早于消息发送时间 → 不可见  
556 - if (CommonStatusEnum.DISABLE.getStatus().equals(member.getStatus())  
557 - && member.getQuitTime() != null && msg.getSendTime().isAfter(member.getQuitTime())) {  
558 - return false;  
559 - }  
560 - // 3.1 无定向接收列表 → 全员可见  
561 - if (CollUtil.isEmpty(msg.getReceiverUserIds())) {  
562 - return true;  
563 - }  
564 - // 3.2 当前用户在定向列表中,或本人即发送者 → 可见  
565 - return msg.getReceiverUserIds().contains(userId)  
566 - || ObjUtil.equal(msg.getSenderId(), userId); 458 + @SuppressWarnings("BooleanMethodIsAlwaysInverted")
  459 + private boolean isMessageReceived(ImGroupMessageDO message, Long userId) {
  460 + return CollUtil.contains(message.getReceiverUserIds(), userId);
567 } 461 }
568 462
569 /** 463 /**
570 - * 计算一条群消息的可见成员集合(含发送者) 464 + * 计算一条群消息的可见成员集合(快照与传入成员的交集,含发送者)
571 */ 465 */
572 - private Set<Long> getVisibleUserIds(ImGroupMessageDO message, List<ImGroupMemberDO> members) {  
573 - return convertSet(members, ImGroupMemberDO::getUserId,  
574 - member -> isMessageVisible(message, member, member.getUserId())); 466 + private Set<Long> getReceiverUserIds(ImGroupMessageDO message, List<ImGroupMemberDO> members) {
  467 + if (CollUtil.isEmpty(message.getReceiverUserIds())) {
  468 + return new HashSet<>();
  469 + }
  470 + Set<Long> snapshot = new HashSet<>(message.getReceiverUserIds());
  471 + return convertSet(members, ImGroupMemberDO::getUserId, member -> snapshot.contains(member.getUserId()));
575 } 472 }
576 473
577 /** 474 /**
578 - * 基于群成员 userId 列表,过滤出一条新消息的可见成员集合(含发送者)。 475 + * 基于群成员 userId 列表,计算一条新消息的可见成员快照(含发送者)。
579 * <p> 476 * <p>
580 - * 仅适用于「新消息」推送场景({@code sendTime = now}),不涉及 joinTime / quitTime 判定,  
581 - * 只应用 {@code receiverUserIds} 定向过滤;语义与  
582 - * {@link #isMessageVisible(ImGroupMessageDO, ImGroupMemberDO, Long)} 的第 3 步保持一致。 477 + * 仅适用于「新消息」发送场景:无定向接收列表则全员可见,否则取定向用户与当前成员的交集;
  478 + * 发送者始终纳入快照,保证 receiver_user_ids 非空且发送方可见。
583 */ 479 */
584 - private Set<Long> getVisibleUserIds(List<Long> receiverUserIds, Long senderId, Collection<Long> memberUserIds) {  
585 - if (CollUtil.isEmpty(memberUserIds)) {  
586 - return new HashSet<>();  
587 - }  
588 - // 无定向接收列表 → 全员可见  
589 - if (CollUtil.isEmpty(receiverUserIds)) {  
590 - return new HashSet<>(memberUserIds);  
591 - }  
592 - // 有定向接收列表 → 仅定向用户可见;发送者自己也能看到自己的消息(多端同步)  
593 - Set<Long> allowed = new HashSet<>(receiverUserIds); 480 + private Set<Long> getReceiverUserIds(List<Long> directedUserIds, Long senderId, Collection<Long> memberUserIds) {
  481 + // 无定向接收列表 → 全员可见;否则取定向用户与当前成员的交集
  482 + Set<Long> result = CollUtil.isEmpty(directedUserIds)
  483 + ? new HashSet<>(memberUserIds)
  484 + : new HashSet<>(CollUtil.intersection(memberUserIds, directedUserIds));
  485 + // 发送者始终可见(多端同步),即便成员缓存暂未包含
594 if (senderId != null) { 486 if (senderId != null) {
595 - allowed.add(senderId);  
596 - }  
597 - Set<Long> result = new HashSet<>();  
598 - for (Long userId : memberUserIds) {  
599 - if (allowed.contains(userId)) {  
600 - result.add(userId);  
601 - } 487 + result.add(senderId);
602 } 488 }
603 return result; 489 return result;
604 } 490 }
605 491
606 - @Override  
607 - public void deleteReadMaxMessageId(Long groupId, Long userId) {  
608 - groupMessageReadRedisDAO.deleteReadMaxMessageId(groupId, userId);  
609 - }  
610 -  
611 - @Override  
612 - public void deleteReadMaxMessageIds(Long groupId, Collection<Long> userIds) {  
613 - groupMessageReadRedisDAO.deleteReadMaxMessageIds(groupId, userIds);  
614 - }  
615 -  
616 - @Override  
617 - public void deleteReadMaxMessageIdMap(Long groupId) {  
618 - groupMessageReadRedisDAO.deleteReadMaxMessageIdMap(groupId);  
619 - }  
620 -  
621 // ==================== 管理后台 ==================== 492 // ==================== 管理后台 ====================
622 493
623 @Override 494 @Override
@@ -652,11 +523,11 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { @@ -652,11 +523,11 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService {
652 */ 523 */
653 private Integer resolveReceiptStatus(Boolean receipt) { 524 private Integer resolveReceiptStatus(Boolean receipt) {
654 if (BooleanUtil.isFalse(imProperties.getMessage().isGroupReadEnabled())) { 525 if (BooleanUtil.isFalse(imProperties.getMessage().isGroupReadEnabled())) {
655 - return ImGroupMessageReceiptStatusEnum.NO_RECEIPT.getStatus(); 526 + return ImMessageReceiptStatusEnum.NO_RECEIPT.getStatus();
656 } 527 }
657 return BooleanUtil.isTrue(receipt) 528 return BooleanUtil.isTrue(receipt)
658 - ? ImGroupMessageReceiptStatusEnum.PENDING.getStatus()  
659 - : ImGroupMessageReceiptStatusEnum.NO_RECEIPT.getStatus(); 529 + ? ImMessageReceiptStatusEnum.PENDING.getStatus()
  530 + : ImMessageReceiptStatusEnum.NO_RECEIPT.getStatus();
660 } 531 }
661 532
662 /** 533 /**
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/message/ImPrivateMessageService.java
@@ -59,8 +59,8 @@ public interface ImPrivateMessageService { @@ -59,8 +59,8 @@ public interface ImPrivateMessageService {
59 /** 59 /**
60 * 标记私聊消息已读 60 * 标记私聊消息已读
61 * <p> 61 * <p>
62 - * 语义:将「对方发给当前用户、id <= messageId 的未读消息」一次性翻转为已读,  
63 - * 与群聊 readGroupMessages 对称,避免"select-then-update"两步式带来的竞态。 62 + * 语义:把「对方发给当前用户、id <= messageId 的待回执消息」一次性更新为已完成(DONE)并前进读位置,
  63 + * 与群聊 readGroupMessages 对称,避免「select-then-update」两步式带来的竞态。
64 * 64 *
65 * @param userId 当前用户编号 65 * @param userId 当前用户编号
66 * @param receiverId 接收方用户编号(对方) 66 * @param receiverId 接收方用户编号(对方)
@@ -72,7 +72,7 @@ public interface ImPrivateMessageService { @@ -72,7 +72,7 @@ public interface ImPrivateMessageService {
72 * 查询对方已读到我发的最大消息 id 72 * 查询对方已读到我发的最大消息 id
73 * <p> 73 * <p>
74 * 用于多端 / 离线场景下的已读位置补齐:客户端进入会话或断线重连后, 74 * 用于多端 / 离线场景下的已读位置补齐:客户端进入会话或断线重连后,
75 - * 调用此接口拿到对方的 maxReadId,再按 id <= maxReadId 翻转本地自发消息为已读,弥补离线期间错过的 RECEIPT 推送事件。 75 + * 调用此接口拿到对方的 maxReadId,再按 id <= maxReadId 更新本地自发消息的回执状态,弥补离线期间错过的 RECEIPT 推送事件。
76 * 76 *
77 * @param userId 当前用户编号 77 * @param userId 当前用户编号
78 * @param peerId 对方用户编号 78 * @param peerId 对方用户编号
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/message/ImPrivateMessageServiceImpl.java
@@ -12,19 +12,25 @@ import cn.iocoder.yudao.module.im.controller.admin.message.vo.privates.ImPrivate @@ -12,19 +12,25 @@ import cn.iocoder.yudao.module.im.controller.admin.message.vo.privates.ImPrivate
12 import cn.iocoder.yudao.module.im.controller.admin.message.vo.privates.ImPrivateMessageSendReqVO; 12 import cn.iocoder.yudao.module.im.controller.admin.message.vo.privates.ImPrivateMessageSendReqVO;
13 import cn.iocoder.yudao.module.im.dal.dataobject.message.ImPrivateMessageDO; 13 import cn.iocoder.yudao.module.im.dal.dataobject.message.ImPrivateMessageDO;
14 import cn.iocoder.yudao.module.im.dal.mysql.message.ImPrivateMessageMapper; 14 import cn.iocoder.yudao.module.im.dal.mysql.message.ImPrivateMessageMapper;
  15 +import cn.iocoder.yudao.module.im.enums.ImConversationTypeEnum;
  16 +import cn.iocoder.yudao.module.im.enums.message.ImMessageReceiptStatusEnum;
15 import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum; 17 import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum;
16 -import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum; 18 +import cn.iocoder.yudao.module.im.enums.ImContentTypeEnum;
17 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;
18 import cn.iocoder.yudao.module.im.service.friend.ImFriendService; 21 import cn.iocoder.yudao.module.im.service.friend.ImFriendService;
19 import cn.iocoder.yudao.module.im.service.message.dto.ImPrivateMessageSendDTO; 22 import cn.iocoder.yudao.module.im.service.message.dto.ImPrivateMessageSendDTO;
20 import cn.iocoder.yudao.module.im.service.sensitiveword.ImSensitiveWordService; 23 import cn.iocoder.yudao.module.im.service.sensitiveword.ImSensitiveWordService;
21 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService; 24 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService;
22 -import cn.iocoder.yudao.module.im.service.websocket.dto.ImPrivateMessageDTO;  
23 -import cn.iocoder.yudao.module.im.service.websocket.dto.message.QuoteMessage;  
24 -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;
25 import cn.iocoder.yudao.module.im.util.ImMessageUtils; 30 import cn.iocoder.yudao.module.im.util.ImMessageUtils;
26 import jakarta.annotation.Resource; 31 import jakarta.annotation.Resource;
27 import lombok.extern.slf4j.Slf4j; 32 import lombok.extern.slf4j.Slf4j;
  33 +import org.springframework.dao.DuplicateKeyException;
28 import org.springframework.stereotype.Service; 34 import org.springframework.stereotype.Service;
29 import org.springframework.transaction.annotation.Transactional; 35 import org.springframework.transaction.annotation.Transactional;
30 import org.springframework.validation.annotation.Validated; 36 import org.springframework.validation.annotation.Validated;
@@ -52,6 +58,8 @@ public class ImPrivateMessageServiceImpl implements ImPrivateMessageService { @@ -52,6 +58,8 @@ public class ImPrivateMessageServiceImpl implements ImPrivateMessageService {
52 private ImFriendService friendService; 58 private ImFriendService friendService;
53 @Resource 59 @Resource
54 private ImSensitiveWordService sensitiveWordService; 60 private ImSensitiveWordService sensitiveWordService;
  61 + @Resource
  62 + private ImConversationReadService conversationReadService;
55 63
56 @Resource 64 @Resource
57 private ImWebSocketService imWebSocketService; 65 private ImWebSocketService imWebSocketService;
@@ -74,21 +82,32 @@ public class ImPrivateMessageServiceImpl implements ImPrivateMessageService { @@ -74,21 +82,32 @@ public class ImPrivateMessageServiceImpl implements ImPrivateMessageService {
74 // 1.3 好友校验 82 // 1.3 好友校验
75 friendService.validateFriend(senderId, reqVO.getReceiverId()); 83 friendService.validateFriend(senderId, reqVO.getReceiverId());
76 // 1.4 文本消息敏感词过滤 84 // 1.4 文本消息敏感词过滤
77 - if (ImMessageTypeEnum.TEXT.getType().equals(reqVO.getType())) { 85 + if (ImContentTypeEnum.TEXT.getType().equals(reqVO.getType())) {
78 sensitiveWordService.validateText(reqVO.getContent()); 86 sensitiveWordService.validateText(reqVO.getContent());
79 } 87 }
80 88
81 // 2.1 引用 quote 消息规范化 89 // 2.1 引用 quote 消息规范化
82 reqVO.setContent(normalizeQuoteContent(reqVO, senderId)); 90 reqVO.setContent(normalizeQuoteContent(reqVO, senderId));
83 - // 2.2 构建并保存消息 91 + // 2.2 构建并保存消息;唯一键冲突时回查已存在消息返回
  92 + // 用户私聊消息默认需要回执(receipt 不传按 true);系统通知走 DTO 通道,默认不回执
  93 + Boolean receipt = reqVO.getReceipt() != null ? reqVO.getReceipt() : Boolean.TRUE;
84 ImPrivateMessageDO message = BeanUtils.toBean(reqVO, ImPrivateMessageDO.class, m -> m 94 ImPrivateMessageDO message = BeanUtils.toBean(reqVO, ImPrivateMessageDO.class, m -> m
85 - .setSenderId(senderId).setStatus(ImMessageStatusEnum.UNREAD.getStatus()).setSendTime(LocalDateTime.now()));  
86 - privateMessageMapper.insert(message); 95 + .setSenderId(senderId).setStatus(ImMessageStatusEnum.NORMAL.getStatus())
  96 + .setReceiptStatus(resolveReceiptStatus(receipt)).setSendTime(LocalDateTime.now()));
  97 + try {
  98 + privateMessageMapper.insert(message);
  99 + } catch (DuplicateKeyException e) {
  100 + log.warn("[sendPrivateMessage][senderId({}) clientMessageId({}) 并发插入冲突,回查返回]",
  101 + senderId, reqVO.getClientMessageId());
  102 + return privateMessageMapper.selectBySenderIdAndClientMessageId(senderId, reqVO.getClientMessageId());
  103 + }
87 104
88 // 3. WebSocket 异步推送:接收方 + 发送方多端同步 105 // 3. WebSocket 异步推送:接收方 + 发送方多端同步
89 - ImPrivateMessageDTO websocketMessage = ImPrivateMessageDTO.ofSend(message);  
90 - imWebSocketService.sendPrivateMessageAsync(message.getReceiverId(), websocketMessage);  
91 - imWebSocketService.sendPrivateMessageAsync(senderId, websocketMessage); 106 + ImPrivateMessageNotification notification = ImPrivateMessageNotification.ofSend(message);
  107 + imWebSocketService.sendNotificationAsync(message.getReceiverId(), ImConversationTypeEnum.PRIVATE.getType(),
  108 + notification.getType(), notification);
  109 + imWebSocketService.sendNotificationAsync(senderId, ImConversationTypeEnum.PRIVATE.getType(),
  110 + notification.getType(), notification);
92 return message; 111 return message;
93 } 112 }
94 113
@@ -103,24 +122,39 @@ public class ImPrivateMessageServiceImpl implements ImPrivateMessageService { @@ -103,24 +122,39 @@ public class ImPrivateMessageServiceImpl implements ImPrivateMessageService {
103 ImPrivateMessageDO message = new ImPrivateMessageDO().setClientMessageId(IdUtil.fastSimpleUUID()) 122 ImPrivateMessageDO message = new ImPrivateMessageDO().setClientMessageId(IdUtil.fastSimpleUUID())
104 .setSenderId(senderId).setReceiverId(dto.getReceiverId()) 123 .setSenderId(senderId).setReceiverId(dto.getReceiverId())
105 .setType(dto.getType()).setContent(contentString) 124 .setType(dto.getType()).setContent(contentString)
106 - .setStatus(ImMessageStatusEnum.UNREAD.getStatus()).setSendTime(LocalDateTime.now()); 125 + .setStatus(ImMessageStatusEnum.NORMAL.getStatus())
  126 + .setReceiptStatus(resolveReceiptStatus(dto.getReceipt())).setSendTime(LocalDateTime.now());
107 // 1.3 决定是否持久化:dto.persistent 优先;为 null 时按 type 默认 127 // 1.3 决定是否持久化:dto.persistent 优先;为 null 时按 type 默认
108 boolean persistent = dto.getPersistent() != null 128 boolean persistent = dto.getPersistent() != null
109 ? dto.getPersistent() 129 ? dto.getPersistent()
110 - : ImMessageTypeEnum.validate(dto.getType()).isPersistent(); 130 + : ImContentTypeEnum.validate(dto.getType()).isPersistent();
111 if (persistent) { 131 if (persistent) {
112 privateMessageMapper.insert(message); 132 privateMessageMapper.insert(message);
113 } 133 }
114 134
115 // 2. WebSocket 异步推送:双向(默认);单边语义(persistent=false)下仅推 sender 多端,对方不感知 135 // 2. WebSocket 异步推送:双向(默认);单边语义(persistent=false)下仅推 sender 多端,对方不感知
116 - ImPrivateMessageDTO websocketMessage = ImPrivateMessageDTO.ofSend(message); 136 + ImPrivateMessageNotification notification = ImPrivateMessageNotification.ofSend(message);
117 if (persistent) { 137 if (persistent) {
118 - imWebSocketService.sendPrivateMessageAsync(dto.getReceiverId(), websocketMessage); 138 + imWebSocketService.sendNotificationAsync(dto.getReceiverId(), ImConversationTypeEnum.PRIVATE.getType(),
  139 + notification.getType(), notification);
119 } 140 }
120 - imWebSocketService.sendPrivateMessageAsync(senderId, websocketMessage); 141 + imWebSocketService.sendNotificationAsync(senderId, ImConversationTypeEnum.PRIVATE.getType(),
  142 + notification.getType(), notification);
121 return message; 143 return message;
122 } 144 }
123 145
  146 + /**
  147 + * 计算私聊消息回执 status:私聊已读关闭时强制 NO_RECEIPT,忽略发送方传入的 receipt(receipt 为 null 等价 false)
  148 + */
  149 + private Integer resolveReceiptStatus(Boolean receipt) {
  150 + if (BooleanUtil.isFalse(imProperties.getMessage().isPrivateReadEnabled())) {
  151 + return ImMessageReceiptStatusEnum.NO_RECEIPT.getStatus();
  152 + }
  153 + return BooleanUtil.isTrue(receipt)
  154 + ? ImMessageReceiptStatusEnum.PENDING.getStatus()
  155 + : ImMessageReceiptStatusEnum.NO_RECEIPT.getStatus();
  156 + }
  157 +
124 @Override 158 @Override
125 @Transactional(rollbackFor = Exception.class) 159 @Transactional(rollbackFor = Exception.class)
126 public ImPrivateMessageDO recallPrivateMessage(Long userId, Long messageId) { 160 public ImPrivateMessageDO recallPrivateMessage(Long userId, Long messageId) {
@@ -149,7 +183,7 @@ public class ImPrivateMessageServiceImpl implements ImPrivateMessageService { @@ -149,7 +183,7 @@ public class ImPrivateMessageServiceImpl implements ImPrivateMessageService {
149 183
150 // 3. 发送撤回事件 184 // 3. 发送撤回事件
151 return sendPrivateMessage(userId, new ImPrivateMessageSendDTO().setReceiverId(message.getReceiverId()) 185 return sendPrivateMessage(userId, new ImPrivateMessageSendDTO().setReceiverId(message.getReceiverId())
152 - .setType(ImMessageTypeEnum.RECALL.getType()).setContent(new RecallMessage().setMessageId(messageId))); 186 + .setType(ImContentTypeEnum.RECALL.getType()).setContent(new RecallMessage().setMessageId(messageId)));
153 } 187 }
154 188
155 /** 189 /**
@@ -211,20 +245,26 @@ public class ImPrivateMessageServiceImpl implements ImPrivateMessageService { @@ -211,20 +245,26 @@ public class ImPrivateMessageServiceImpl implements ImPrivateMessageService {
211 throw exception(MESSAGE_PRIVATE_READ_DISABLED); 245 throw exception(MESSAGE_PRIVATE_READ_DISABLED);
212 } 246 }
213 Assert.notNull(messageId, "已读消息编号不能为空"); 247 Assert.notNull(messageId, "已读消息编号不能为空");
214 - // 2. 把 (receiverId → userId) 这条会话上、id <= messageId 的未读消息一步更新为已读  
215 - // 仅 UNREAD 行被命中,避免覆盖已撤回/已读的状态;select-then-update 合成单条 SQL 后也消除了竞态窗口  
216 - int updated = privateMessageMapper.updateBySenderIdAndReceiverIdAndIdLeAndStatus(  
217 - receiverId, userId, messageId, ImMessageStatusEnum.UNREAD.getStatus(),  
218 - new ImPrivateMessageDO().setStatus(ImMessageStatusEnum.READ.getStatus()));  
219 - if (updated == 0) { 248 +
  249 + // 2. 回执置 DONE:把 (receiverId → userId) 上 id <= messageId、待回执(PENDING) 的消息标记为已完成
  250 + // status 不再表达已读(保持 NORMAL);只翻 PENDING 行,避免覆盖 NO_RECEIPT / 已 DONE
  251 + privateMessageMapper.updateBySenderIdAndReceiverIdAndIdLeAndReceiptStatus(
  252 + receiverId, userId, messageId, ImMessageReceiptStatusEnum.PENDING.getStatus(),
  253 + new ImPrivateMessageDO().setReceiptStatus(ImMessageReceiptStatusEnum.DONE.getStatus()));
  254 +
  255 + // 3. 同步写 im_conversation_read(读位置唯一权威,单调递增);读位置前进才下发事件
  256 + boolean advanced = conversationReadService.updateConversationReadPosition(
  257 + userId, ImConversationTypeEnum.PRIVATE.getType(), receiverId, messageId);
  258 + if (!advanced) {
220 return; 259 return;
221 } 260 }
222 261
223 - // 3. 异步发送 READ + RECEIPT 事件(已读位置以前端上报为准,与多端 / 对方 UI 显示一致)  
224 - imWebSocketService.sendPrivateMessageAsync(userId,  
225 - ImPrivateMessageDTO.ofRead(userId, receiverId, messageId));  
226 - imWebSocketService.sendPrivateMessageAsync(receiverId,  
227 - ImPrivateMessageDTO.ofReceipt(userId, receiverId, messageId)); 262 + // 4. 异步发送 READ + RECEIPT 事件(已读位置以前端上报为准,与多端 / 对方 UI 显示一致)
  263 + imWebSocketService.sendNotificationAsync(userId, ImConversationTypeEnum.PRIVATE.getType(),
  264 + ImContentTypeEnum.READ.getType(), ImMessageReadNotification.ofPrivate(userId, receiverId, messageId));
  265 + imWebSocketService.sendNotificationAsync(receiverId, ImConversationTypeEnum.PRIVATE.getType(),
  266 + ImContentTypeEnum.RECEIPT.getType(),
  267 + ImMessageReceiptNotification.ofPrivate(userId, receiverId, messageId));
228 } 268 }
229 269
230 @Override 270 @Override
@@ -232,8 +272,9 @@ public class ImPrivateMessageServiceImpl implements ImPrivateMessageService { @@ -232,8 +272,9 @@ public class ImPrivateMessageServiceImpl implements ImPrivateMessageService {
232 if (BooleanUtil.isFalse(imProperties.getMessage().isPrivateReadEnabled())) { 272 if (BooleanUtil.isFalse(imProperties.getMessage().isPrivateReadEnabled())) {
233 throw exception(MESSAGE_PRIVATE_READ_DISABLED); 273 throw exception(MESSAGE_PRIVATE_READ_DISABLED);
234 } 274 }
235 - return privateMessageMapper.selectMaxIdBySenderIdAndReceiverIdAndStatus(  
236 - userId, peerId, ImMessageStatusEnum.READ.getStatus()); 275 + // 对端 peer 在「与 userId 的会话」里的读位置 = peer 把 userId 发的消息读到哪
  276 + return conversationReadService.getConversationReadMessageId(
  277 + peerId, ImConversationTypeEnum.PRIVATE.getType(), userId);
237 } 278 }
238 279
239 @Override 280 @Override
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,30 +53,34 @@ public class ImGroupMessageSendDTO { @@ -53,30 +53,34 @@ 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,
  67 + String oldAvatar, String newAvatar,
  68 + Boolean oldJoinApproval, Boolean newJoinApproval) {
67 GroupInfoUpdateNotification notification = new GroupInfoUpdateNotification(); 69 GroupInfoUpdateNotification notification = new GroupInfoUpdateNotification();
68 notification.setOperatorUserId(operatorUserId); 70 notification.setOperatorUserId(operatorUserId);
69 notification.setOldAvatar(oldAvatar); 71 notification.setOldAvatar(oldAvatar);
70 notification.setNewAvatar(newAvatar); 72 notification.setNewAvatar(newAvatar);
  73 + notification.setOldJoinApproval(oldJoinApproval);
  74 + notification.setNewJoinApproval(newJoinApproval);
71 return new ImGroupMessageSendDTO().setGroupId(groupId) 75 return new ImGroupMessageSendDTO().setGroupId(groupId)
72 - .setType(ImMessageTypeEnum.GROUP_INFO_UPDATE.getType()).setContent(notification); 76 + .setType(ImContentTypeEnum.GROUP_INFO_UPDATE.getType()).setContent(notification);
73 } 77 }
74 78
75 public static ImGroupMessageSendDTO ofGroupMemberQuit(Long groupId, Long operatorUserId) { 79 public static ImGroupMessageSendDTO ofGroupMemberQuit(Long groupId, Long operatorUserId) {
76 GroupMemberQuitNotification notification = new GroupMemberQuitNotification(); 80 GroupMemberQuitNotification notification = new GroupMemberQuitNotification();
77 notification.setOperatorUserId(operatorUserId); 81 notification.setOperatorUserId(operatorUserId);
78 return new ImGroupMessageSendDTO().setGroupId(groupId) 82 return new ImGroupMessageSendDTO().setGroupId(groupId)
79 - .setType(ImMessageTypeEnum.GROUP_MEMBER_QUIT.getType()).setContent(notification); 83 + .setType(ImContentTypeEnum.GROUP_MEMBER_QUIT.getType()).setContent(notification);
80 } 84 }
81 85
82 public static ImGroupMessageSendDTO ofGroupOwnerTransfer(Long groupId, Long operatorUserId, Long newOwnerUserId) { 86 public static ImGroupMessageSendDTO ofGroupOwnerTransfer(Long groupId, Long operatorUserId, Long newOwnerUserId) {
@@ -84,7 +88,7 @@ public class ImGroupMessageSendDTO { @@ -84,7 +88,7 @@ public class ImGroupMessageSendDTO {
84 notification.setOperatorUserId(operatorUserId); 88 notification.setOperatorUserId(operatorUserId);
85 notification.setNewOwnerUserId(newOwnerUserId); 89 notification.setNewOwnerUserId(newOwnerUserId);
86 return new ImGroupMessageSendDTO().setGroupId(groupId) 90 return new ImGroupMessageSendDTO().setGroupId(groupId)
87 - .setType(ImMessageTypeEnum.GROUP_OWNER_TRANSFER.getType()).setContent(notification); 91 + .setType(ImContentTypeEnum.GROUP_OWNER_TRANSFER.getType()).setContent(notification);
88 } 92 }
89 93
90 public static ImGroupMessageSendDTO ofGroupMemberKick(Long groupId, Long operatorUserId, Collection<Long> memberUserIds) { 94 public static ImGroupMessageSendDTO ofGroupMemberKick(Long groupId, Long operatorUserId, Collection<Long> memberUserIds) {
@@ -92,7 +96,7 @@ public class ImGroupMessageSendDTO { @@ -92,7 +96,7 @@ public class ImGroupMessageSendDTO {
92 notification.setOperatorUserId(operatorUserId); 96 notification.setOperatorUserId(operatorUserId);
93 notification.setMemberUserIds(new ArrayList<>(memberUserIds)); 97 notification.setMemberUserIds(new ArrayList<>(memberUserIds));
94 return new ImGroupMessageSendDTO().setGroupId(groupId) 98 return new ImGroupMessageSendDTO().setGroupId(groupId)
95 - .setType(ImMessageTypeEnum.GROUP_MEMBER_KICK.getType()).setContent(notification); 99 + .setType(ImContentTypeEnum.GROUP_MEMBER_KICK.getType()).setContent(notification);
96 } 100 }
97 101
98 public static ImGroupMessageSendDTO ofGroupMemberInvite(Long groupId, Long operatorUserId, Collection<Long> memberUserIds) { 102 public static ImGroupMessageSendDTO ofGroupMemberInvite(Long groupId, Long operatorUserId, Collection<Long> memberUserIds) {
@@ -100,7 +104,7 @@ public class ImGroupMessageSendDTO { @@ -100,7 +104,7 @@ public class ImGroupMessageSendDTO {
100 notification.setOperatorUserId(operatorUserId); 104 notification.setOperatorUserId(operatorUserId);
101 notification.setMemberUserIds(new ArrayList<>(memberUserIds)); 105 notification.setMemberUserIds(new ArrayList<>(memberUserIds));
102 return new ImGroupMessageSendDTO().setGroupId(groupId) 106 return new ImGroupMessageSendDTO().setGroupId(groupId)
103 - .setType(ImMessageTypeEnum.GROUP_MEMBER_INVITE.getType()).setContent(notification); 107 + .setType(ImContentTypeEnum.GROUP_MEMBER_INVITE.getType()).setContent(notification);
104 } 108 }
105 109
106 public static ImGroupMessageSendDTO ofGroupMemberEnter(Long groupId, Long entrantUserId, Integer addSource) { 110 public static ImGroupMessageSendDTO ofGroupMemberEnter(Long groupId, Long entrantUserId, Integer addSource) {
@@ -109,14 +113,14 @@ public class ImGroupMessageSendDTO { @@ -109,14 +113,14 @@ public class ImGroupMessageSendDTO {
109 notification.setEntrantUserId(entrantUserId); 113 notification.setEntrantUserId(entrantUserId);
110 notification.setAddSource(addSource); 114 notification.setAddSource(addSource);
111 return new ImGroupMessageSendDTO().setGroupId(groupId) 115 return new ImGroupMessageSendDTO().setGroupId(groupId)
112 - .setType(ImMessageTypeEnum.GROUP_MEMBER_ENTER.getType()).setContent(notification); 116 + .setType(ImContentTypeEnum.GROUP_MEMBER_ENTER.getType()).setContent(notification);
113 } 117 }
114 118
115 public static ImGroupMessageSendDTO ofGroupDissolve(Long groupId, Long operatorUserId) { 119 public static ImGroupMessageSendDTO ofGroupDissolve(Long groupId, Long operatorUserId) {
116 GroupDissolveNotification notification = new GroupDissolveNotification(); 120 GroupDissolveNotification notification = new GroupDissolveNotification();
117 notification.setOperatorUserId(operatorUserId); 121 notification.setOperatorUserId(operatorUserId);
118 return new ImGroupMessageSendDTO().setGroupId(groupId) 122 return new ImGroupMessageSendDTO().setGroupId(groupId)
119 - .setType(ImMessageTypeEnum.GROUP_DISSOLVE.getType()).setContent(notification); 123 + .setType(ImContentTypeEnum.GROUP_DISSOLVE.getType()).setContent(notification);
120 } 124 }
121 125
122 public static ImGroupMessageSendDTO ofGroupMemberNicknameUpdate(Long groupId, Long operatorUserId, String displayUserName) { 126 public static ImGroupMessageSendDTO ofGroupMemberNicknameUpdate(Long groupId, Long operatorUserId, String displayUserName) {
@@ -124,7 +128,7 @@ public class ImGroupMessageSendDTO { @@ -124,7 +128,7 @@ public class ImGroupMessageSendDTO {
124 notification.setOperatorUserId(operatorUserId); 128 notification.setOperatorUserId(operatorUserId);
125 notification.setDisplayUserName(displayUserName); 129 notification.setDisplayUserName(displayUserName);
126 return new ImGroupMessageSendDTO().setGroupId(groupId) 130 return new ImGroupMessageSendDTO().setGroupId(groupId)
127 - .setType(ImMessageTypeEnum.GROUP_MEMBER_NICKNAME_UPDATE.getType()).setContent(notification); 131 + .setType(ImContentTypeEnum.GROUP_MEMBER_NICKNAME_UPDATE.getType()).setContent(notification);
128 } 132 }
129 133
130 public static ImGroupMessageSendDTO ofGroupAdminAdd(Long groupId, Long operatorUserId, Collection<Long> memberUserIds) { 134 public static ImGroupMessageSendDTO ofGroupAdminAdd(Long groupId, Long operatorUserId, Collection<Long> memberUserIds) {
@@ -132,7 +136,7 @@ public class ImGroupMessageSendDTO { @@ -132,7 +136,7 @@ public class ImGroupMessageSendDTO {
132 notification.setOperatorUserId(operatorUserId); 136 notification.setOperatorUserId(operatorUserId);
133 notification.setMemberUserIds(new ArrayList<>(memberUserIds)); 137 notification.setMemberUserIds(new ArrayList<>(memberUserIds));
134 return new ImGroupMessageSendDTO().setGroupId(groupId) 138 return new ImGroupMessageSendDTO().setGroupId(groupId)
135 - .setType(ImMessageTypeEnum.GROUP_ADMIN_ADD.getType()).setContent(notification); 139 + .setType(ImContentTypeEnum.GROUP_ADMIN_ADD.getType()).setContent(notification);
136 } 140 }
137 141
138 public static ImGroupMessageSendDTO ofGroupAdminRemove(Long groupId, Long operatorUserId, Collection<Long> memberUserIds) { 142 public static ImGroupMessageSendDTO ofGroupAdminRemove(Long groupId, Long operatorUserId, Collection<Long> memberUserIds) {
@@ -140,7 +144,7 @@ public class ImGroupMessageSendDTO { @@ -140,7 +144,7 @@ public class ImGroupMessageSendDTO {
140 notification.setOperatorUserId(operatorUserId); 144 notification.setOperatorUserId(operatorUserId);
141 notification.setMemberUserIds(new ArrayList<>(memberUserIds)); 145 notification.setMemberUserIds(new ArrayList<>(memberUserIds));
142 return new ImGroupMessageSendDTO().setGroupId(groupId) 146 return new ImGroupMessageSendDTO().setGroupId(groupId)
143 - .setType(ImMessageTypeEnum.GROUP_ADMIN_REMOVE.getType()).setContent(notification); 147 + .setType(ImContentTypeEnum.GROUP_ADMIN_REMOVE.getType()).setContent(notification);
144 } 148 }
145 149
146 public static ImGroupMessageSendDTO ofGroupNoticeUpdate(Long groupId, Long operatorUserId, String oldNotice, String newNotice) { 150 public static ImGroupMessageSendDTO ofGroupNoticeUpdate(Long groupId, Long operatorUserId, String oldNotice, String newNotice) {
@@ -148,7 +152,7 @@ public class ImGroupMessageSendDTO { @@ -148,7 +152,7 @@ public class ImGroupMessageSendDTO {
148 notification.setOperatorUserId(operatorUserId); 152 notification.setOperatorUserId(operatorUserId);
149 notification.setOldNotice(oldNotice).setNewNotice(newNotice); 153 notification.setOldNotice(oldNotice).setNewNotice(newNotice);
150 return new ImGroupMessageSendDTO().setGroupId(groupId) 154 return new ImGroupMessageSendDTO().setGroupId(groupId)
151 - .setType(ImMessageTypeEnum.GROUP_NOTICE_UPDATE.getType()).setContent(notification); 155 + .setType(ImContentTypeEnum.GROUP_NOTICE_UPDATE.getType()).setContent(notification);
152 } 156 }
153 157
154 public static ImGroupMessageSendDTO ofGroupNameUpdate(Long groupId, Long operatorUserId, String oldName, String newName) { 158 public static ImGroupMessageSendDTO ofGroupNameUpdate(Long groupId, Long operatorUserId, String oldName, String newName) {
@@ -156,7 +160,7 @@ public class ImGroupMessageSendDTO { @@ -156,7 +160,7 @@ public class ImGroupMessageSendDTO {
156 notification.setOperatorUserId(operatorUserId); 160 notification.setOperatorUserId(operatorUserId);
157 notification.setOldName(oldName).setNewName(newName); 161 notification.setOldName(oldName).setNewName(newName);
158 return new ImGroupMessageSendDTO().setGroupId(groupId) 162 return new ImGroupMessageSendDTO().setGroupId(groupId)
159 - .setType(ImMessageTypeEnum.GROUP_NAME_UPDATE.getType()).setContent(notification); 163 + .setType(ImContentTypeEnum.GROUP_NAME_UPDATE.getType()).setContent(notification);
160 } 164 }
161 165
162 public static ImGroupMessageSendDTO ofGroupMemberSettingUpdate(Long groupId, Long operatorUserId, Boolean silent, String groupRemark) { 166 public static ImGroupMessageSendDTO ofGroupMemberSettingUpdate(Long groupId, Long operatorUserId, Boolean silent, String groupRemark) {
@@ -164,7 +168,7 @@ public class ImGroupMessageSendDTO { @@ -164,7 +168,7 @@ public class ImGroupMessageSendDTO {
164 notification.setOperatorUserId(operatorUserId); 168 notification.setOperatorUserId(operatorUserId);
165 notification.setSilent(silent).setGroupRemark(groupRemark); 169 notification.setSilent(silent).setGroupRemark(groupRemark);
166 return new ImGroupMessageSendDTO().setGroupId(groupId) 170 return new ImGroupMessageSendDTO().setGroupId(groupId)
167 - .setType(ImMessageTypeEnum.GROUP_MEMBER_SETTING_UPDATE.getType()).setContent(notification); 171 + .setType(ImContentTypeEnum.GROUP_MEMBER_SETTING_UPDATE.getType()).setContent(notification);
168 } 172 }
169 173
170 public static ImGroupMessageSendDTO ofGroupMessagePin(Long groupId, Long operatorUserId, ImGroupMessageDO message) { 174 public static ImGroupMessageSendDTO ofGroupMessagePin(Long groupId, Long operatorUserId, ImGroupMessageDO message) {
@@ -176,7 +180,7 @@ public class ImGroupMessageSendDTO { @@ -176,7 +180,7 @@ public class ImGroupMessageSendDTO {
176 notification.setOperatorUserId(operatorUserId); 180 notification.setOperatorUserId(operatorUserId);
177 notification.setMessageId(message.getId()).setMessage(pinnedMessage); 181 notification.setMessageId(message.getId()).setMessage(pinnedMessage);
178 return new ImGroupMessageSendDTO().setGroupId(groupId) 182 return new ImGroupMessageSendDTO().setGroupId(groupId)
179 - .setType(ImMessageTypeEnum.GROUP_MESSAGE_PIN.getType()).setContent(notification); 183 + .setType(ImContentTypeEnum.GROUP_MESSAGE_PIN.getType()).setContent(notification);
180 } 184 }
181 185
182 public static ImGroupMessageSendDTO ofGroupMessageUnpin(Long groupId, Long operatorUserId, Long messageId) { 186 public static ImGroupMessageSendDTO ofGroupMessageUnpin(Long groupId, Long operatorUserId, Long messageId) {
@@ -184,7 +188,7 @@ public class ImGroupMessageSendDTO { @@ -184,7 +188,7 @@ public class ImGroupMessageSendDTO {
184 notification.setOperatorUserId(operatorUserId); 188 notification.setOperatorUserId(operatorUserId);
185 notification.setMessageId(messageId); 189 notification.setMessageId(messageId);
186 return new ImGroupMessageSendDTO().setGroupId(groupId) 190 return new ImGroupMessageSendDTO().setGroupId(groupId)
187 - .setType(ImMessageTypeEnum.GROUP_MESSAGE_UNPIN.getType()).setContent(notification); 191 + .setType(ImContentTypeEnum.GROUP_MESSAGE_UNPIN.getType()).setContent(notification);
188 } 192 }
189 193
190 public static ImGroupMessageSendDTO ofGroupMemberMuted(Long groupId, Long operatorUserId, 194 public static ImGroupMessageSendDTO ofGroupMemberMuted(Long groupId, Long operatorUserId,
@@ -195,7 +199,7 @@ public class ImGroupMessageSendDTO { @@ -195,7 +199,7 @@ public class ImGroupMessageSendDTO {
195 notification.setMutedUserId(mutedUserId); 199 notification.setMutedUserId(mutedUserId);
196 notification.setMuteEndTime(muteEndTime); 200 notification.setMuteEndTime(muteEndTime);
197 return new ImGroupMessageSendDTO().setGroupId(groupId) 201 return new ImGroupMessageSendDTO().setGroupId(groupId)
198 - .setType(ImMessageTypeEnum.GROUP_MEMBER_MUTED.getType()).setContent(notification); 202 + .setType(ImContentTypeEnum.GROUP_MEMBER_MUTED.getType()).setContent(notification);
199 } 203 }
200 204
201 public static ImGroupMessageSendDTO ofGroupMemberCancelMuted(Long groupId, Long operatorUserId, Long mutedUserId) { 205 public static ImGroupMessageSendDTO ofGroupMemberCancelMuted(Long groupId, Long operatorUserId, Long mutedUserId) {
@@ -203,21 +207,21 @@ public class ImGroupMessageSendDTO { @@ -203,21 +207,21 @@ public class ImGroupMessageSendDTO {
203 notification.setOperatorUserId(operatorUserId); 207 notification.setOperatorUserId(operatorUserId);
204 notification.setMutedUserId(mutedUserId); 208 notification.setMutedUserId(mutedUserId);
205 return new ImGroupMessageSendDTO().setGroupId(groupId) 209 return new ImGroupMessageSendDTO().setGroupId(groupId)
206 - .setType(ImMessageTypeEnum.GROUP_MEMBER_CANCEL_MUTED.getType()).setContent(notification); 210 + .setType(ImContentTypeEnum.GROUP_MEMBER_CANCEL_MUTED.getType()).setContent(notification);
207 } 211 }
208 212
209 public static ImGroupMessageSendDTO ofGroupMuted(Long groupId, Long operatorUserId) { 213 public static ImGroupMessageSendDTO ofGroupMuted(Long groupId, Long operatorUserId) {
210 GroupMutedNotification notification = new GroupMutedNotification(); 214 GroupMutedNotification notification = new GroupMutedNotification();
211 notification.setOperatorUserId(operatorUserId); 215 notification.setOperatorUserId(operatorUserId);
212 return new ImGroupMessageSendDTO().setGroupId(groupId) 216 return new ImGroupMessageSendDTO().setGroupId(groupId)
213 - .setType(ImMessageTypeEnum.GROUP_MUTED.getType()).setContent(notification); 217 + .setType(ImContentTypeEnum.GROUP_MUTED.getType()).setContent(notification);
214 } 218 }
215 219
216 public static ImGroupMessageSendDTO ofGroupCancelMuted(Long groupId, Long operatorUserId) { 220 public static ImGroupMessageSendDTO ofGroupCancelMuted(Long groupId, Long operatorUserId) {
217 GroupCancelMutedNotification notification = new GroupCancelMutedNotification(); 221 GroupCancelMutedNotification notification = new GroupCancelMutedNotification();
218 notification.setOperatorUserId(operatorUserId); 222 notification.setOperatorUserId(operatorUserId);
219 return new ImGroupMessageSendDTO().setGroupId(groupId) 223 return new ImGroupMessageSendDTO().setGroupId(groupId)
220 - .setType(ImMessageTypeEnum.GROUP_CANCEL_MUTED.getType()).setContent(notification); 224 + .setType(ImContentTypeEnum.GROUP_CANCEL_MUTED.getType()).setContent(notification);
221 } 225 }
222 226
223 public static ImGroupMessageSendDTO ofGroupBanned(Long groupId, Long operatorUserId, boolean banned) { 227 public static ImGroupMessageSendDTO ofGroupBanned(Long groupId, Long operatorUserId, boolean banned) {
@@ -225,7 +229,7 @@ public class ImGroupMessageSendDTO { @@ -225,7 +229,7 @@ public class ImGroupMessageSendDTO {
225 notification.setOperatorUserId(operatorUserId); 229 notification.setOperatorUserId(operatorUserId);
226 notification.setBanned(banned); 230 notification.setBanned(banned);
227 return new ImGroupMessageSendDTO().setGroupId(groupId) 231 return new ImGroupMessageSendDTO().setGroupId(groupId)
228 - .setType(ImMessageTypeEnum.GROUP_BANNED.getType()).setContent(notification); 232 + .setType(ImContentTypeEnum.GROUP_BANNED.getType()).setContent(notification);
229 } 233 }
230 234
231 } 235 }
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,10 +30,14 @@ public class ImPrivateMessageSendDTO { @@ -30,10 +30,14 @@ 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 */
37 private Boolean persistent; 37 private Boolean persistent;
  38 + /**
  39 + * 是否需要回执;null 等价 false(系统消息默认不需要回执)
  40 + */
  41 + private Boolean receipt;
38 42
39 } 43 }
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;
@@ -57,7 +56,7 @@ import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.*; @@ -57,7 +56,7 @@ import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.*;
57 * 并发幂等:同好友对 / 同群活跃唯一性走 {@link ImRtcCallLockRedisDAO} 分布式锁 + 锁内 SELECT 兜底;webhook 兜底走条件 UPDATE; 56 * 并发幂等:同好友对 / 同群活跃唯一性走 {@link ImRtcCallLockRedisDAO} 分布式锁 + 锁内 SELECT 兜底;webhook 兜底走条件 UPDATE;
58 * <p> 57 * <p>
59 * 推送通道分流: 58 * 推送通道分流:
60 - * 1601 RTC_CALL(INVITING / JOINED / REJECTED / NO_ANSWER / LEFT 子类型)→ {@link ImWebSocketService#sendPrivateMessageAsync} 仅推参与方; 59 + * 1601 RTC_CALL(INVITING / JOINED / REJECTED / NO_ANSWER / LEFT 子类型)→ {@link ImWebSocketService#sendNotificationAsync} 仅推参与方;
61 * 1602 / 1603 PARTICIPANT_CONNECTED / DISCONNECTED → {@link ImWebSocketService} 推参与方 + 群通话场景广播全群; 60 * 1602 / 1603 PARTICIPANT_CONNECTED / DISCONNECTED → {@link ImWebSocketService} 推参与方 + 群通话场景广播全群;
62 * 1610 RTC_CALL_START + 1611 RTC_CALL_END → {@link ImPrivateMessageService} / {@link ImGroupMessageService} 入消息流当聊天 tip 61 * 1610 RTC_CALL_START + 1611 RTC_CALL_END → {@link ImPrivateMessageService} / {@link ImGroupMessageService} 入消息流当聊天 tip
63 * (START 仅群通话;两者分别在 invite / cancel(leave) 事务里 INSERT,自增 id 自然保证顺序) 62 * (START 仅群通话;两者分别在 invite / cancel(leave) 事务里 INSERT,自增 id 自然保证顺序)
@@ -707,7 +706,6 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -707,7 +706,6 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
707 } 706 }
708 707
709 // 3.1 群通话:推 RTC_CALL(NO_ANSWER) 让前端 banner 移除该人 + 级联关房判定 708 // 3.1 群通话:推 RTC_CALL(NO_ANSWER) 让前端 banner 移除该人 + 级联关房判定
710 - // TODO DONE @AI:拆分独立 NO_ANSWER 信令,不再复用 REJECT  
711 if (ImConversationTypeEnum.isGroup(call.getConversationType())) { 709 if (ImConversationTypeEnum.isGroup(call.getConversationType())) {
712 pushCallNoAnswerNotification(call, userId, userMap.get(userId)); 710 pushCallNoAnswerNotification(call, userId, userMap.get(userId));
713 endSessionIfTerminal(call, userId); 711 endSessionIfTerminal(call, userId);
@@ -1003,8 +1001,8 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -1003,8 +1001,8 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
1003 String token = signToken(inviteeId, resolveDisplayName(invitee, inviteeId), call.getRoom()); 1001 String token = signToken(inviteeId, resolveDisplayName(invitee, inviteeId), call.getRoom());
1004 ImRtcCallNotification payload = ImRtcCallNotification.ofInvite( 1002 ImRtcCallNotification payload = ImRtcCallNotification.ofInvite(
1005 call, inviter, imProperties.getRtc().getLivekitUrl(), token, inviteeIds); 1003 call, inviter, imProperties.getRtc().getLivekitUrl(), token, inviteeIds);
1006 - webSocketService.sendPrivateMessageAsync(inviteeId, ImPrivateMessageDTO.ofRtcNotification(  
1007 - ImMessageTypeEnum.RTC_CALL.getType(), call.getInviterUserId(), inviteeId, payload)); 1004 + webSocketService.sendNotificationAsync(inviteeId, ImConversationTypeEnum.NONE.getType(),
  1005 + ImContentTypeEnum.RTC_CALL.getType(), payload);
1008 } 1006 }
1009 1007
1010 /** 1008 /**
@@ -1019,8 +1017,8 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -1019,8 +1017,8 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
1019 AdminUserRespDTO operator = operatorUserId != null ? adminUserApi.getUser(operatorUserId) : null; 1017 AdminUserRespDTO operator = operatorUserId != null ? adminUserApi.getUser(operatorUserId) : null;
1020 ImRtcCallNotification payload = ImRtcCallNotification.ofReject(call, operatorUserId, operator); 1018 ImRtcCallNotification payload = ImRtcCallNotification.ofReject(call, operatorUserId, operator);
1021 for (Long receiverUserId : getCallAudienceUserIdList(call)) { 1019 for (Long receiverUserId : getCallAudienceUserIdList(call)) {
1022 - webSocketService.sendPrivateMessageAsync(receiverUserId, ImPrivateMessageDTO.ofRtcNotification(  
1023 - ImMessageTypeEnum.RTC_CALL.getType(), operatorUserId, receiverUserId, payload)); 1020 + webSocketService.sendNotificationAsync(receiverUserId, ImConversationTypeEnum.NONE.getType(),
  1021 + ImContentTypeEnum.RTC_CALL.getType(), payload);
1024 } 1022 }
1025 } 1023 }
1026 1024
@@ -1036,8 +1034,8 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -1036,8 +1034,8 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
1036 private void pushCallNoAnswerNotification(ImRtcCallDO call, Long operatorUserId, AdminUserRespDTO operator) { 1034 private void pushCallNoAnswerNotification(ImRtcCallDO call, Long operatorUserId, AdminUserRespDTO operator) {
1037 ImRtcCallNotification payload = ImRtcCallNotification.ofNoAnswer(call, operatorUserId, operator); 1035 ImRtcCallNotification payload = ImRtcCallNotification.ofNoAnswer(call, operatorUserId, operator);
1038 for (Long receiverUserId : getCallAudienceUserIdList(call)) { 1036 for (Long receiverUserId : getCallAudienceUserIdList(call)) {
1039 - webSocketService.sendPrivateMessageAsync(receiverUserId, ImPrivateMessageDTO.ofRtcNotification(  
1040 - ImMessageTypeEnum.RTC_CALL.getType(), operatorUserId, receiverUserId, payload)); 1037 + webSocketService.sendNotificationAsync(receiverUserId, ImConversationTypeEnum.NONE.getType(),
  1038 + ImContentTypeEnum.RTC_CALL.getType(), payload);
1041 } 1039 }
1042 } 1040 }
1043 1041
@@ -1048,7 +1046,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -1048,7 +1046,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
1048 * @param userId 加入的参与者用户编号 1046 * @param userId 加入的参与者用户编号
1049 */ 1047 */
1050 private void pushParticipantConnectedNotification(ImRtcCallDO call, Long userId) { 1048 private void pushParticipantConnectedNotification(ImRtcCallDO call, Long userId) {
1051 - pushParticipantNotification(call, ImMessageTypeEnum.RTC_PARTICIPANT_CONNECTED.getType(), userId, 1049 + pushParticipantNotification(call, ImContentTypeEnum.RTC_PARTICIPANT_CONNECTED.getType(), userId,
1052 ImRtcParticipantConnectedNotification.of(call, userId)); 1050 ImRtcParticipantConnectedNotification.of(call, userId));
1053 } 1051 }
1054 1052
@@ -1059,7 +1057,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -1059,7 +1057,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
1059 * @param userId 离开的参与者用户编号 1057 * @param userId 离开的参与者用户编号
1060 */ 1058 */
1061 private void pushParticipantDisconnectedNotification(ImRtcCallDO call, Long userId) { 1059 private void pushParticipantDisconnectedNotification(ImRtcCallDO call, Long userId) {
1062 - pushParticipantNotification(call, ImMessageTypeEnum.RTC_PARTICIPANT_DISCONNECTED.getType(), userId, 1060 + pushParticipantNotification(call, ImContentTypeEnum.RTC_PARTICIPANT_DISCONNECTED.getType(), userId,
1063 ImRtcParticipantDisconnectedNotification.of(call, userId)); 1061 ImRtcParticipantDisconnectedNotification.of(call, userId));
1064 } 1062 }
1065 1063
@@ -1076,8 +1074,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -1076,8 +1074,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
1076 if (CollUtil.isEmpty(receivers)) { 1074 if (CollUtil.isEmpty(receivers)) {
1077 return; 1075 return;
1078 } 1076 }
1079 - ImPrivateMessageDTO dto = ImPrivateMessageDTO.ofRtcNotification(type, actorUserId, null, payload);  
1080 - webSocketService.sendPrivateMessageAsync(receivers, dto); 1077 + webSocketService.sendNotificationAsync(receivers, ImConversationTypeEnum.NONE.getType(), type, payload);
1081 } 1078 }
1082 1079
1083 /** 1080 /**
@@ -1092,7 +1089,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -1092,7 +1089,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
1092 private void pushCallStartNotification(ImRtcCallDO call, AdminUserRespDTO inviter, Set<Long> invitees) { 1089 private void pushCallStartNotification(ImRtcCallDO call, AdminUserRespDTO inviter, Set<Long> invitees) {
1093 ImRtcCallStartNotification payload = ImRtcCallStartNotification.of(call, inviter); 1090 ImRtcCallStartNotification payload = ImRtcCallStartNotification.of(call, inviter);
1094 Long peerUserId = ImConversationTypeEnum.isGroup(call.getConversationType()) ? null : CollUtil.getFirst(invitees); 1091 Long peerUserId = ImConversationTypeEnum.isGroup(call.getConversationType()) ? null : CollUtil.getFirst(invitees);
1095 - pushCallChatMessage(call, ImMessageTypeEnum.RTC_CALL_START, payload, peerUserId); 1092 + pushCallChatMessage(call, ImContentTypeEnum.RTC_CALL_START, payload, peerUserId);
1096 } 1093 }
1097 1094
1098 /** 1095 /**
@@ -1116,7 +1113,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -1116,7 +1113,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
1116 p -> ObjUtil.notEqual(p.getUserId(), call.getInviterUserId())); 1113 p -> ObjUtil.notEqual(p.getUserId(), call.getInviterUserId()));
1117 peerUserId = peer != null ? peer.getUserId() : null; 1114 peerUserId = peer != null ? peer.getUserId() : null;
1118 } 1115 }
1119 - pushCallChatMessage(call, ImMessageTypeEnum.RTC_CALL_END, payload, peerUserId); 1116 + pushCallChatMessage(call, ImContentTypeEnum.RTC_CALL_END, payload, peerUserId);
1120 } 1117 }
1121 1118
1122 /** 1119 /**
@@ -1129,7 +1126,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -1129,7 +1126,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
1129 * @param payload 推送 payload 1126 * @param payload 推送 payload
1130 * @param peerUserId 私聊对端用户编号;群聊忽略,私聊缺失时回退为 senderId 1127 * @param peerUserId 私聊对端用户编号;群聊忽略,私聊缺失时回退为 senderId
1131 */ 1128 */
1132 - private void pushCallChatMessage(ImRtcCallDO call, ImMessageTypeEnum type, Object payload, Long peerUserId) { 1129 + private void pushCallChatMessage(ImRtcCallDO call, ImContentTypeEnum type, Object payload, Long peerUserId) {
1133 Long senderId = call.getInviterUserId(); 1130 Long senderId = call.getInviterUserId();
1134 if (ImConversationTypeEnum.isGroup(call.getConversationType())) { 1131 if (ImConversationTypeEnum.isGroup(call.getConversationType())) {
1135 ImGroupMessageSendDTO dto = new ImGroupMessageSendDTO().setGroupId(call.getGroupId()) 1132 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;
@@ -36,83 +34,51 @@ public class ImWebSocketServiceImpl implements ImWebSocketService { @@ -36,83 +34,51 @@ public class ImWebSocketServiceImpl implements ImWebSocketService {
36 private WebSocketSenderApi webSocketSenderApi; 34 private WebSocketSenderApi webSocketSenderApi;
37 35
38 @Override 36 @Override
39 - public void sendPrivateMessageAsync(Collection<Long> userIds, ImPrivateMessageDTO dto) {  
40 - // 说明:通过 executeAfterTransaction 保证事务提交后再推送,避免客户端收到消息后查询数据库时事务尚未提交  
41 - // 通过 getSelf() 获取 Spring 代理对象调用 @Async 方法,确保异步 AOP 生效(直接 this 调用会绕过代理)  
42 - executeAfterTransaction(() -> getSelf().doSendPrivateMessage(userIds, dto)); 37 + public void sendNotificationAsync(Collection<Long> userIds, Integer conversationType, Integer contentType,
  38 + Object payload) {
  39 + ImNotificationWebSocketDTO notification = buildNotification(conversationType, contentType, payload);
  40 + executeAfterTransaction(() -> getSelf().doSendNotification(userIds, notification));
43 } 41 }
44 42
45 @Override 43 @Override
46 - public void sendGroupMessageAsync(Collection<Long> userIds, ImGroupMessageDTO dto) {  
47 - executeAfterTransaction(() -> getSelf().doSendGroupMessage(userIds, dto)); 44 + public void broadcastNotificationAsync(Integer conversationType, Integer contentType, Object payload) {
  45 + ImNotificationWebSocketDTO notification = buildNotification(conversationType, contentType, payload);
  46 + executeAfterTransaction(() -> getSelf().doBroadcastNotification(notification));
48 } 47 }
49 48
50 - @Override  
51 - public void sendChannelMessageAsync(Collection<Long> userIds, ImChannelMessageDTO dto) {  
52 - executeAfterTransaction(() -> getSelf().doSendChannelMessage(userIds, dto));  
53 - }  
54 -  
55 - @Override  
56 - public void broadcastChannelMessageAsync(ImChannelMessageDTO dto) {  
57 - executeAfterTransaction(() -> getSelf().doBroadcastChannelMessage(dto));  
58 - }  
59 -  
60 - /**  
61 - * 异步发送私聊 WebSocket 消息;多收件人共享同一 dto,避免按收件人重复注册 afterCommit 回调  
62 - */  
63 - @Async  
64 - public void doSendPrivateMessage(Collection<Long> userIds, ImPrivateMessageDTO dto) {  
65 - for (Long userId : getDistinctUserIds(userIds)) {  
66 - try {  
67 - webSocketSenderApi.sendObject(UserTypeEnum.ADMIN.getValue(), userId,  
68 - ImPrivateMessageDTO.TYPE, dto);  
69 - } catch (Exception e) {  
70 - log.error("[doSendPrivateMessage][userId({}) dto({}) 发送失败]", userId, dto, e);  
71 - }  
72 - }  
73 - }  
74 -  
75 - /**  
76 - * 异步发送群聊 WebSocket 消息  
77 - */  
78 - @Async  
79 - public void doSendGroupMessage(Collection<Long> userIds, ImGroupMessageDTO dto) {  
80 - for (Long userId : getDistinctUserIds(userIds)) {  
81 - try {  
82 - webSocketSenderApi.sendObject(UserTypeEnum.ADMIN.getValue(), userId,  
83 - ImGroupMessageDTO.TYPE, dto);  
84 - } catch (Exception e) {  
85 - log.error("[doSendGroupMessage][userId({}) dto({}) 发送失败]", userId, dto, e);  
86 - }  
87 - } 49 + private static ImNotificationWebSocketDTO buildNotification(Integer conversationType, Integer contentType,
  50 + Object payload) {
  51 + return new ImNotificationWebSocketDTO()
  52 + .setConversationType(conversationType)
  53 + .setContentType(contentType)
  54 + .setPayload(payload);
88 } 55 }
89 56
90 /** 57 /**
91 - * 异步发送频道 WebSocket 消息 58 + * 异步发送 WebSocket 通知
92 */ 59 */
93 @Async 60 @Async
94 - public void doSendChannelMessage(Collection<Long> userIds, ImChannelMessageDTO dto) { 61 + public void doSendNotification(Collection<Long> userIds, ImNotificationWebSocketDTO notification) {
95 for (Long userId : getDistinctUserIds(userIds)) { 62 for (Long userId : getDistinctUserIds(userIds)) {
96 try { 63 try {
97 webSocketSenderApi.sendObject(UserTypeEnum.ADMIN.getValue(), userId, 64 webSocketSenderApi.sendObject(UserTypeEnum.ADMIN.getValue(), userId,
98 - ImChannelMessageDTO.TYPE, dto); 65 + ImNotificationWebSocketDTO.TYPE, notification);
99 } catch (Exception e) { 66 } catch (Exception e) {
100 - log.error("[doSendChannelMessage][userId({}) dto({}) 发送失败]", userId, dto, e); 67 + log.error("[doSendNotification][userId({}) notification({}) 发送失败]", userId, notification, e);
101 } 68 }
102 } 69 }
103 } 70 }
104 71
105 /** 72 /**
106 - * 异步广播频道 WebSocket 消息给当前所有在线管理端用户;  
107 - * 依赖 infra WebSocketSenderApi 按 UserType 广播能力,离线用户由客户端上线 pull 兜底 73 + * 异步广播 WebSocket 通知
108 */ 74 */
109 @Async 75 @Async
110 - public void doBroadcastChannelMessage(ImChannelMessageDTO dto) { 76 + public void doBroadcastNotification(ImNotificationWebSocketDTO notification) {
111 try { 77 try {
112 webSocketSenderApi.sendObject(UserTypeEnum.ADMIN.getValue(), 78 webSocketSenderApi.sendObject(UserTypeEnum.ADMIN.getValue(),
113 - ImChannelMessageDTO.TYPE, dto); 79 + ImNotificationWebSocketDTO.TYPE, notification);
114 } catch (Exception e) { 80 } catch (Exception e) {
115 - log.error("[doBroadcastChannelMessage][dto({}) 广播失败]", dto, e); 81 + log.error("[doBroadcastNotification][notification({}) 广播失败]", notification, e);
116 } 82 }
117 } 83 }
118 84
@@ -121,19 +87,15 @@ public class ImWebSocketServiceImpl implements ImWebSocketService { @@ -121,19 +87,15 @@ public class ImWebSocketServiceImpl implements ImWebSocketService {
121 } 87 }
122 88
123 /** 89 /**
124 - * 事务感知的任务调度:  
125 - * - 有事务:注册 afterCommit 回调,事务提交后再执行,防止客户端拿到消息去查库时数据还没落盘  
126 - * - 无事务:直接执行(如非 @Transactional 方法中的调用) 90 + * 事务感知的任务调度
127 * 91 *
128 - * @param task 待执行的推送任务(内部通过 getSelf() 走 @Async 异步执行) 92 + * @param task 待执行的推送任务
129 */ 93 */
130 private void executeAfterTransaction(Runnable task) { 94 private void executeAfterTransaction(Runnable task) {
131 - // 情况一:没有事务,直接执行  
132 if (!TransactionSynchronizationManager.isSynchronizationActive()) { 95 if (!TransactionSynchronizationManager.isSynchronizationActive()) {
133 task.run(); 96 task.run();
134 return; 97 return;
135 } 98 }
136 - // 情况二:有事务,注册 afterCommit 事件,在事务提交后执行  
137 TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() { 99 TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
138 100
139 @Override 101 @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 LocalDateTime sendTime;  
66 -  
67 - // ========== 静态工厂方法 ==========  
68 -  
69 - /**  
70 - * 构建发送消息 DTO  
71 - *  
72 - * @param message 私聊消息 DO  
73 - * @return 私聊 DTO  
74 - */  
75 - public static ImPrivateMessageDTO ofSend(ImPrivateMessageDO message) {  
76 - return BeanUtils.toBean(message, ImPrivateMessageDTO.class);  
77 - }  
78 -  
79 - /**  
80 - * 构建已读同步 DTO(多端同步:通知自己的其他终端"我已经读了某个会话")  
81 - *  
82 - * @param senderId 当前用户编号  
83 - * @param receiverId 对方用户编号  
84 - * @param readId 已读位置(最大已读消息编号)  
85 - * @return 私聊 DTO  
86 - */  
87 - public static ImPrivateMessageDTO ofRead(Long senderId, Long receiverId, Long readId) {  
88 - return new ImPrivateMessageDTO()  
89 - .setId(readId).setType(ImMessageTypeEnum.READ.getType())  
90 - .setSenderId(senderId).setReceiverId(receiverId);  
91 - }  
92 -  
93 - /**  
94 - * 构建已读回执 DTO(通知对方"我已读了你的消息")  
95 - *  
96 - * @param senderId 已读方的用户编号  
97 - * @param receiverId 对方用户编号  
98 - * @param readId 已读位置(最大已读消息编号)  
99 - * @return 私聊 DTO  
100 - */  
101 - public static ImPrivateMessageDTO ofReceipt(Long senderId, Long receiverId, Long readId) {  
102 - return new ImPrivateMessageDTO()  
103 - .setId(readId).setType(ImMessageTypeEnum.RECEIPT.getType())  
104 - .setSenderId(senderId).setReceiverId(receiverId);  
105 - }  
106 -  
107 - // ==================== 好友变更相关 ====================  
108 -  
109 - /**  
110 - * 构建好友通知推送 DTO(统一入口)  
111 - *  
112 - * @param type 消息类型;取自 {@link ImMessageTypeEnum} 中的 FRIEND_* 段  
113 - * @param operatorUserId 操作人用户编号;同时作为帧的 senderId 用于定位接收端 friendUserId  
114 - * @param receiverUserId 推送目标用户编号  
115 - * @param payload 好友通知 payload(继承 {@link BaseFriendNotification})  
116 - * @return 私聊 DTO  
117 - */  
118 - public static ImPrivateMessageDTO ofFriendNotification(Integer type, Long operatorUserId,  
119 - Long receiverUserId, BaseFriendNotification payload) {  
120 - validateNotification(type, payload, ImMessageTypeEnum.isFriendNotification(type));  
121 - return new ImPrivateMessageDTO().setType(type)  
122 - .setSenderId(operatorUserId).setReceiverId(receiverUserId)  
123 - .setContent(JsonUtils.toJsonString(payload)).setSendTime(LocalDateTime.now());  
124 - }  
125 -  
126 - // ==================== 群定向私聊通知 ====================  
127 -  
128 - // TODO DONE @AI:群申请定向通知继续走私聊通道  
129 - /**  
130 - * 构建群通知推送 DTO(走私聊通道定向推送,不入群消息流)  
131 - * <p>  
132 - * 用于 GROUP_REQUEST_RECEIVED / GROUP_REQUEST_APPROVED / GROUP_REQUEST_REJECTED 段位;  
133 - * 与 {@link cn.iocoder.yudao.module.im.service.message.dto.ImGroupMessageSendDTO} 走 sendGroupMessage 群广播路径不同  
134 - *  
135 - * @param type 消息类型;取自 {@link ImMessageTypeEnum} 中的 GROUP_REQUEST_* 段  
136 - * @param operatorUserId 操作人用户编号;同时作为帧的 senderId  
137 - * @param receiverUserId 推送目标用户编号  
138 - * @param payload 群事件 payload(继承 {@link BaseGroupNotification})  
139 - * @return 私聊 DTO  
140 - */  
141 - public static ImPrivateMessageDTO ofGroupNotification(Integer type, Long operatorUserId,  
142 - Long receiverUserId, BaseGroupNotification payload) {  
143 - validateNotification(type, payload, ImMessageTypeEnum.isGroupRequestNotification(type));  
144 - return new ImPrivateMessageDTO().setType(type)  
145 - .setSenderId(operatorUserId).setReceiverId(receiverUserId)  
146 - .setContent(JsonUtils.toJsonString(payload)).setSendTime(LocalDateTime.now());  
147 - }  
148 -  
149 - // ==================== 实时通话信令 ====================  
150 -  
151 - /**  
152 - * 构建通话信令推送 DTO(走私聊通道仅推参与方,不入消息流)  
153 - * <p>  
154 - * 用于 RTC_CALL(INVITE / REJECT 等)/ RTC_PARTICIPANT_CONNECTED / RTC_PARTICIPANT_DISCONNECTED  
155 - *  
156 - * @param type 消息类型;取自 {@link ImMessageTypeEnum} 中的 RTC_* 段  
157 - * @param senderId 发送人编号;INVITE 时为发起人,REJECT 时为拒绝者,参与者事件时为加入 / 离开者  
158 - * @param receiverUserId 推送目标用户编号  
159 - * @param payload 通话事件 payload(任意 RTC 通知 DTO)  
160 - * @return 私聊 DTO  
161 - */  
162 - public static ImPrivateMessageDTO ofRtcNotification(Integer type, Long senderId,  
163 - Long receiverUserId, Object payload) {  
164 - validateNotification(type, payload, ImMessageTypeEnum.isRtcNotification(type));  
165 - return new ImPrivateMessageDTO().setType(type)  
166 - .setSenderId(senderId).setReceiverId(receiverUserId)  
167 - .setContent(JsonUtils.toJsonString(payload)).setSendTime(LocalDateTime.now());  
168 - }  
169 -  
170 - private static void validateNotification(Integer type, Object payload, boolean supported) {  
171 - Assert.notNull(type, "消息类型不能为空");  
172 - Assert.notNull(payload, "消息内容不能为空");  
173 - Assert.isTrue(supported, "消息类型不匹配 type={}", type);  
174 - }  
175 -  
176 -}  
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 含创建者 + 初始邀请成员)