Commit c24a3a02c28161e91672668037031c44bbf4f597
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 | 11 | Target Server Version : 80200 (8.2.0) |
| 12 | 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 | 17 | SET NAMES utf8mb4; |
| ... | ... | @@ -49,7 +49,7 @@ CREATE TABLE `infra_api_access_log` ( |
| 49 | 49 | `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', |
| 50 | 50 | PRIMARY KEY (`id`) USING BTREE, |
| 51 | 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 | 55 | -- Records of infra_api_access_log |
| ... | ... | @@ -92,7 +92,7 @@ CREATE TABLE `infra_api_error_log` ( |
| 92 | 92 | `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', |
| 93 | 93 | PRIMARY KEY (`id`) USING BTREE, |
| 94 | 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 | 98 | -- Records of infra_api_error_log |
| ... | ... | @@ -253,7 +253,7 @@ CREATE TABLE `infra_file` ( |
| 253 | 253 | `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', |
| 254 | 254 | `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', |
| 255 | 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 | 259 | -- Records of infra_file |
| ... | ... | @@ -462,7 +462,7 @@ CREATE TABLE `system_dict_data` ( |
| 462 | 462 | `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', |
| 463 | 463 | `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', |
| 464 | 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 | 468 | -- Records of system_dict_data |
| ... | ... | @@ -1374,14 +1374,14 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st |
| 1374 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 1482 | COMMIT; |
| 1498 | 1483 | |
| 1499 | 1484 | -- ---------------------------- |
| ... | ... | @@ -1651,7 +1636,7 @@ INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creat |
| 1651 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 1736 | PRIMARY KEY (`id`) USING BTREE, |
| 1752 | 1737 | INDEX `idx_username`(`username` ASC) USING BTREE, |
| 1753 | 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 | 1742 | -- Records of system_login_log |
| ... | ... | @@ -2229,7 +2214,7 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i |
| 2229 | 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 | 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 | 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 | 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 | 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 | 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 | 3438 | PRIMARY KEY (`id`) USING BTREE, |
| 3454 | 3439 | INDEX `idx_access_token`(`access_token` ASC) USING BTREE, |
| 3455 | 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 | 3444 | -- Records of system_oauth2_access_token |
| ... | ... | @@ -3526,7 +3511,7 @@ BEGIN; |
| 3526 | 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 | 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 | 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 | 3515 | COMMIT; |
| 3531 | 3516 | |
| 3532 | 3517 | -- ---------------------------- |
| ... | ... | @@ -3579,7 +3564,7 @@ CREATE TABLE `system_oauth2_refresh_token` ( |
| 3579 | 3564 | `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', |
| 3580 | 3565 | PRIMARY KEY (`id`) USING BTREE, |
| 3581 | 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 | 3570 | -- Records of system_oauth2_refresh_token |
| ... | ... | @@ -3615,7 +3600,7 @@ CREATE TABLE `system_operate_log` ( |
| 3615 | 3600 | PRIMARY KEY (`id`) USING BTREE, |
| 3616 | 3601 | INDEX `idx_user_id`(`user_id` ASC) USING BTREE, |
| 3617 | 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 | 3606 | -- Records of system_operate_log |
| ... | ... | @@ -3641,7 +3626,7 @@ CREATE TABLE `system_post` ( |
| 3641 | 3626 | `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', |
| 3642 | 3627 | `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', |
| 3643 | 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 | 3632 | -- Records of system_post |
| ... | ... | @@ -3685,7 +3670,7 @@ INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_sco |
| 3685 | 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 | 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 | 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 | 3674 | COMMIT; |
| 3690 | 3675 | |
| 3691 | 3676 | -- ---------------------------- |
| ... | ... | @@ -3704,7 +3689,7 @@ CREATE TABLE `system_role_menu` ( |
| 3704 | 3689 | `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', |
| 3705 | 3690 | PRIMARY KEY (`id`) USING BTREE, |
| 3706 | 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 | 3695 | -- Records of system_role_menu |
| ... | ... | @@ -3744,6 +3729,7 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t |
| 3744 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 4592 | COMMIT; |
| 4627 | 4593 | |
| 4628 | 4594 | -- ---------------------------- |
| ... | ... | @@ -4677,7 +4643,7 @@ CREATE TABLE `system_sms_code` ( |
| 4677 | 4643 | `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', |
| 4678 | 4644 | PRIMARY KEY (`id`) USING BTREE, |
| 4679 | 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 | 4649 | -- Records of system_sms_code |
| ... | ... | @@ -4718,7 +4684,7 @@ CREATE TABLE `system_sms_log` ( |
| 4718 | 4684 | `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', |
| 4719 | 4685 | `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', |
| 4720 | 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 | 4690 | -- Records of system_sms_log |
| ... | ... | @@ -4895,7 +4861,7 @@ CREATE TABLE `system_tenant` ( |
| 4895 | 4861 | BEGIN; |
| 4896 | 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 | 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 | 4865 | COMMIT; |
| 4900 | 4866 | |
| 4901 | 4867 | -- ---------------------------- |
| ... | ... | @@ -4914,14 +4880,13 @@ CREATE TABLE `system_tenant_package` ( |
| 4914 | 4880 | `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', |
| 4915 | 4881 | `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', |
| 4916 | 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 | 4886 | -- Records of system_tenant_package |
| 4921 | 4887 | -- ---------------------------- |
| 4922 | 4888 | BEGIN; |
| 4923 | 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 | 4890 | COMMIT; |
| 4926 | 4891 | |
| 4927 | 4892 | -- ---------------------------- |
| ... | ... | @@ -5039,26 +5004,26 @@ CREATE TABLE `system_users` ( |
| 5039 | 5004 | -- Records of system_users |
| 5040 | 5005 | -- ---------------------------- |
| 5041 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 17 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 18 | 18 | import jakarta.annotation.Resource; |
| 19 | 19 | import jakarta.validation.Valid; |
| 20 | +import jakarta.validation.constraints.Max; | |
| 21 | +import jakarta.validation.constraints.Min; | |
| 20 | 22 | import jakarta.validation.constraints.NotNull; |
| 21 | 23 | import org.springframework.validation.annotation.Validated; |
| 22 | 24 | import org.springframework.web.bind.annotation.*; |
| ... | ... | @@ -46,11 +48,25 @@ public class ImFriendController { |
| 46 | 48 | @GetMapping("/list") |
| 47 | 49 | @Operation(summary = "获得当前登录用户的好友列表") |
| 48 | 50 | public CommonResult<List<ImFriendRespVO>> getMyFriendList() { |
| 49 | - // 含 DISABLE 历史好友:保留给前端展示「已删除好友」的历史对话信息;前端按 status 决定会话级联清理 | |
| 50 | 51 | List<ImFriendDO> friends = friendService.getFriendList(getLoginUserId()); |
| 51 | 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 | 70 | @GetMapping("/get") |
| 55 | 71 | @Operation(summary = "获得好友详情") |
| 56 | 72 | @Parameter(name = "friendUserId", description = "好友的用户编号", required = true, example = "2048") |
| ... | ... | @@ -62,8 +78,8 @@ public class ImFriendController { |
| 62 | 78 | @DeleteMapping("/delete") |
| 63 | 79 | @Operation(summary = "删除好友(单向软删除)") |
| 64 | 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 | 84 | public CommonResult<Boolean> deleteFriend( |
| 69 | 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 | 13 | import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; |
| 14 | 14 | import io.swagger.v3.oas.annotations.Operation; |
| 15 | 15 | import io.swagger.v3.oas.annotations.Parameter; |
| 16 | +import io.swagger.v3.oas.annotations.Parameters; | |
| 16 | 17 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 17 | 18 | import jakarta.annotation.Resource; |
| 18 | 19 | import jakarta.validation.Valid; |
| ... | ... | @@ -79,15 +80,32 @@ public class ImFriendRequestController { |
| 79 | 80 | |
| 80 | 81 | @GetMapping("/list") |
| 81 | 82 | @Operation(summary = "查询「我相关」的好友申请列表(游标分页:传 maxId 加载更多)") |
| 83 | + @Parameters({ | |
| 84 | + @Parameter(name = "maxId", description = "当前列表最旧记录的 id;首页不传"), | |
| 85 | + @Parameter(name = "limit", description = "单次拉取条数", required = true) | |
| 86 | + }) | |
| 82 | 87 | public CommonResult<List<ImFriendRequestRespVO>> getMyFriendRequestList( |
| 83 | - @Parameter(description = "当前列表最旧记录的 id;首页不传") | |
| 84 | 88 | @RequestParam(value = "maxId", required = false) Long maxId, |
| 85 | - @Parameter(description = "单次拉取条数", required = true) | |
| 86 | 89 | @RequestParam("limit") @Min(1) @Max(200) Integer limit) { |
| 87 | 90 | List<ImFriendRequestDO> list = friendRequestService.getMyFriendRequestList(getLoginUserId(), maxId, limit); |
| 88 | 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 | 109 | @GetMapping("/get") |
| 92 | 110 | @Operation(summary = "按 id 单查「我相关」的申请记录(带越权过滤;WebSocket 通知到达后用)") |
| 93 | 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 | 47 | @Schema(description = "删除好友时间") |
| 48 | 48 | private LocalDateTime deleteTime; |
| 49 | 49 | |
| 50 | + @Schema(description = "最近更新时间(增量拉取游标用)") | |
| 51 | + private LocalDateTime updateTime; | |
| 52 | + | |
| 50 | 53 | // ========== 下面是聚合字段,方便前端显示 ========== |
| 51 | 54 | |
| 52 | 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 | 41 | @Schema(description = "申请创建时间") |
| 42 | 42 | private LocalDateTime createTime; |
| 43 | 43 | |
| 44 | + @Schema(description = "最近更新时间(增量拉取游标用)") | |
| 45 | + private LocalDateTime updateTime; | |
| 46 | + | |
| 44 | 47 | // ========== 下面是聚合字段,方便前端显示 ========== |
| 45 | 48 | |
| 46 | 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 | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | 4 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; |
| 5 | 5 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 6 | +import cn.iocoder.yudao.framework.common.util.collection.MapUtils; | |
| 6 | 7 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 7 | 8 | import cn.iocoder.yudao.module.im.controller.admin.group.vo.*; |
| 8 | 9 | import cn.iocoder.yudao.module.im.controller.admin.group.vo.member.ImGroupMemberInviteReqVO; |
| ... | ... | @@ -187,8 +188,10 @@ public class ImGroupController { |
| 187 | 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 | 195 | Set<Long> allMessageIds = convertSetByFlatMap(groups, group -> activeGroupIds.contains(group.getId()) |
| 193 | 196 | ? CollUtil.emptyIfNull(group.getPinnedMessageIds()).stream() : Stream.empty()); |
| 194 | 197 | Map<Long, ImGroupMessageDO> messageMap = groupMessageService.getGroupMessageMap(allMessageIds); |
| ... | ... | @@ -198,6 +201,8 @@ public class ImGroupController { |
| 198 | 201 | // 标记登录用户在该群的成员状态,供前端区分当前群与历史退群 |
| 199 | 202 | boolean joined = activeGroupIds.contains(group.getId()); |
| 200 | 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 | 206 | if (!joined || CollUtil.isEmpty(group.getPinnedMessageIds())) { |
| 202 | 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 | 21 | import org.springframework.validation.annotation.Validated; |
| 22 | 22 | import org.springframework.web.bind.annotation.*; |
| 23 | 23 | |
| 24 | +import java.util.Collections; | |
| 24 | 25 | import java.util.List; |
| 25 | 26 | import java.util.Map; |
| 26 | 27 | |
| ... | ... | @@ -88,7 +89,7 @@ public class ImGroupMemberController { |
| 88 | 89 | } |
| 89 | 90 | |
| 90 | 91 | @GetMapping("/list") |
| 91 | - @Operation(summary = "获得指定群的成员列表") | |
| 92 | + @Operation(summary = "获得指定群的成员列表(按群全量拉取,作为前端本地成员 cache 的完整基线)") | |
| 92 | 93 | @Parameter(name = "groupId", description = "群编号", required = true, example = "1024") |
| 93 | 94 | public CommonResult<List<ImGroupMemberRespVO>> getGroupMemberList(@RequestParam("groupId") Long groupId) { |
| 94 | 95 | // 1.1 查询群成员列表(包含 DISABLE 已退群的成员,不按时间过滤) |
| ... | ... | @@ -101,16 +102,30 @@ public class ImGroupMemberController { |
| 101 | 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 | 120 | Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap( |
| 106 | 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 | 125 | vo.setNickname(user.getNickname()).setAvatar(user.getAvatar())); |
| 111 | - hidePrivateFieldsIfNotSelf(vo, m.getUserId(), loginUserId); | |
| 126 | + hidePrivateFieldsIfNotSelf(vo, member.getUserId(), loginUserId); | |
| 112 | 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 | 19 | import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; |
| 20 | 20 | import io.swagger.v3.oas.annotations.Operation; |
| 21 | 21 | import io.swagger.v3.oas.annotations.Parameter; |
| 22 | +import io.swagger.v3.oas.annotations.Parameters; | |
| 22 | 23 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 23 | 24 | import jakarta.annotation.Resource; |
| 24 | 25 | import jakarta.validation.Valid; |
| 26 | +import jakarta.validation.constraints.Max; | |
| 27 | +import jakarta.validation.constraints.Min; | |
| 25 | 28 | import jakarta.validation.constraints.NotNull; |
| 26 | 29 | import jakarta.validation.constraints.Size; |
| 27 | 30 | import org.springframework.validation.annotation.Validated; |
| ... | ... | @@ -88,6 +91,22 @@ public class ImGroupRequestController { |
| 88 | 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 | 110 | @GetMapping("/list-by-group") |
| 92 | 111 | @Operation(summary = "查询指定群下的全部加群申请(含已处理);仅群主 / 管理员可查") |
| 93 | 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 | 50 | @Schema(description = "当前登录用户在该群的成员状态:在群 / 已退群(历史退群群仍返回,供前端展示离线消息的群名 / 头像)") |
| 51 | 51 | private Integer joinStatus; // 参见 CommonStatusEnum 枚举 |
| 52 | 52 | |
| 53 | + @Schema(description = "当前登录用户对该群的备注") | |
| 54 | + private String groupRemark; | |
| 55 | + | |
| 56 | + @Schema(description = "当前登录用户是否免打扰") | |
| 57 | + private Boolean silent; | |
| 58 | + | |
| 53 | 59 | @Schema(description = "群置顶消息列表,按 pin 顺序(最先置顶的在前);非该群有效成员时为空") |
| 54 | 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 | 42 | @Schema(description = "申请创建时间") |
| 43 | 43 | private LocalDateTime createTime; |
| 44 | 44 | |
| 45 | + @Schema(description = "申请更新时间;增量拉取游标") | |
| 46 | + private LocalDateTime updateTime; | |
| 47 | + | |
| 45 | 48 | // ========== 下面是聚合字段,方便前端显示 ========== |
| 46 | 49 | |
| 47 | 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 | 75 | @GetMapping("/simple-list") |
| 76 | 76 | @Operation(summary = "获得启用的频道精简列表;前端表单选择频道时调用") |
| 77 | 77 | public CommonResult<List<ImChannelRespVO>> getSimpleChannelList() { |
| 78 | - // TODO DONE @AI:getChannelListByStatus 统一命名 | |
| 79 | 78 | List<ImChannelDO> list = channelService.getChannelListByStatus(CommonStatusEnum.ENABLE.getStatus()); |
| 80 | 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 | 29 | private String materialCoverUrl; |
| 30 | 30 | |
| 31 | 31 | @Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "125") |
| 32 | - private Integer type; // 参见 ImMessageTypeEnum 枚举类 | |
| 32 | + private Integer type; // 参见 ImContentTypeEnum 枚举类 | |
| 33 | 33 | |
| 34 | 34 | @Schema(description = "消息内容;payload JSON 快照") |
| 35 | 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 | 22 | private Long senderId; |
| 23 | 23 | |
| 24 | 24 | @Schema(description = "消息类型", example = "1") |
| 25 | - private Integer type; // 参见 ImMessageTypeEnum 枚举类 | |
| 25 | + private Integer type; // 参见 ImContentTypeEnum 枚举类 | |
| 26 | 26 | |
| 27 | 27 | @Schema(description = "消息内容", example = "你好") |
| 28 | 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 | 29 | private String senderNickname; |
| 30 | 30 | |
| 31 | 31 | @Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| 32 | - private Integer type; // 参见 ImMessageTypeEnum 枚举类 | |
| 32 | + private Integer type; // 参见 ImContentTypeEnum 枚举类 | |
| 33 | 33 | |
| 34 | 34 | @Schema(description = "消息内容(JSON 格式)", requiredMode = Schema.RequiredMode.REQUIRED) |
| 35 | 35 | private String content; |
| ... | ... | @@ -43,7 +43,7 @@ public class ImGroupMessageManagerRespVO { |
| 43 | 43 | private List<String> atUserNicknames; |
| 44 | 44 | |
| 45 | 45 | @Schema(description = "回执状态", example = "0") |
| 46 | - private Integer receiptStatus; // 参见 ImGroupMessageReceiptStatusEnum 枚举类 | |
| 46 | + private Integer receiptStatus; // 参见 ImMessageReceiptStatusEnum 枚举类 | |
| 47 | 47 | |
| 48 | 48 | @Schema(description = "发送时间", requiredMode = Schema.RequiredMode.REQUIRED) |
| 49 | 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 | 22 | private Long receiverId; |
| 23 | 23 | |
| 24 | 24 | @Schema(description = "消息类型", example = "1") |
| 25 | - private Integer type; // 参见 ImMessageTypeEnum 枚举类 | |
| 25 | + private Integer type; // 参见 ImContentTypeEnum 枚举类 | |
| 26 | 26 | |
| 27 | 27 | @Schema(description = "消息内容", example = "你好") |
| 28 | 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 | 28 | private String receiverNickname; |
| 29 | 29 | |
| 30 | 30 | @Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| 31 | - private Integer type; // 参见 ImMessageTypeEnum 枚举类 | |
| 31 | + private Integer type; // 参见 ImContentTypeEnum 枚举类 | |
| 32 | 32 | |
| 33 | 33 | @Schema(description = "消息内容(JSON 格式)", requiredMode = Schema.RequiredMode.REQUIRED) |
| 34 | 34 | private String content; |
| ... | ... | @@ -36,6 +36,9 @@ public class ImPrivateMessageManagerRespVO { |
| 36 | 36 | @Schema(description = "消息状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") |
| 37 | 37 | private Integer status; // 参见 ImMessageStatusEnum 枚举类 |
| 38 | 38 | |
| 39 | + @Schema(description = "回执状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") | |
| 40 | + private Integer receiptStatus; // 参见 ImMessageReceiptStatusEnum 枚举类 | |
| 41 | + | |
| 39 | 42 | @Schema(description = "发送时间", requiredMode = Schema.RequiredMode.REQUIRED) |
| 40 | 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 | 112 | } |
| 113 | 113 | |
| 114 | 114 | @GetMapping("/message-type-distribution") |
| 115 | - @Operation(summary = "获得消息类型分布(最近 30 天)") | |
| 115 | + @Operation(summary = "获得内容类型分布(最近 30 天)") | |
| 116 | 116 | @PreAuthorize("@ss.hasPermission('im:manager:statistics:query')") |
| 117 | 117 | public CommonResult<List<ImStatisticsManagerMessageTypeRespVO>> getMessageTypeDistribution() { |
| 118 | 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 | 3 | import io.swagger.v3.oas.annotations.media.Schema; |
| 4 | 4 | import lombok.Data; |
| 5 | 5 | |
| 6 | -@Schema(description = "管理后台 - IM 数据看板消息类型分布项 Response VO") | |
| 6 | +@Schema(description = "管理后台 - IM 数据看板内容类型分布项 Response VO") | |
| 7 | 7 | @Data |
| 8 | 8 | public class ImStatisticsManagerMessageTypeRespVO { |
| 9 | 9 | |
| 10 | 10 | @Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") |
| 11 | - private Integer type; // 参见 ImMessageTypeEnum 枚举类 | |
| 11 | + private Integer type; // 参见 ImContentTypeEnum 枚举类 | |
| 12 | 12 | |
| 13 | 13 | @Schema(description = "消息数", requiredMode = Schema.RequiredMode.REQUIRED, example = "8000") |
| 14 | 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 | 5 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 6 | 6 | import cn.iocoder.yudao.module.im.controller.admin.message.vo.channel.ImChannelMessagePullRespVO; |
| 7 | 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 | 9 | import cn.iocoder.yudao.module.im.service.message.ImChannelMessageService; |
| 10 | 10 | import io.swagger.v3.oas.annotations.Operation; |
| 11 | 11 | import io.swagger.v3.oas.annotations.Parameter; |
| ... | ... | @@ -40,25 +40,25 @@ public class ImChannelMessageController { |
| 40 | 40 | |
| 41 | 41 | @GetMapping("/pull") |
| 42 | 42 | @Operation(summary = "拉取频道消息(离线增量);按 minId 游标分页") |
| 43 | - public CommonResult<List<ImChannelMessagePullRespVO>> pull( | |
| 43 | + public CommonResult<List<ImChannelMessagePullRespVO>> pullChannelMessageList( | |
| 44 | 44 | @RequestParam(value = "minId", defaultValue = "0") @PositiveOrZero(message = "minId 不能小于 0") Long minId, |
| 45 | 45 | @RequestParam(value = "size", defaultValue = "100") |
| 46 | 46 | @Min(value = 1, message = "size 必须大于 0") |
| 47 | 47 | @Max(value = 200, message = "size 一次最多 200 条") Integer size) { |
| 48 | 48 | // 1. 拉取消息列表 |
| 49 | 49 | Long userId = getLoginUserId(); |
| 50 | - List<ImChannelMessageDO> list = channelMessageService.getMessageListForPull(userId, minId, size); | |
| 50 | + List<ImChannelMessageDO> list = channelMessageService.pullChannelMessageList(userId, minId, size); | |
| 51 | 51 | if (CollUtil.isEmpty(list)) { |
| 52 | 52 | return success(Collections.emptyList()); |
| 53 | 53 | } |
| 54 | - // 2. 按 Redis 已读游标补 status;device A 已读后 device B 拉到这条不再算入未读 | |
| 54 | + // 2. 按已读游标补 receiptStatus(已读 DONE / 未读 PENDING) | |
| 55 | 55 | Map<Long, Long> readMaxByChannel = channelMessageService.getChannelReadMaxMessageIdMap( |
| 56 | 56 | userId, convertSet(list, ImChannelMessageDO::getChannelId)); |
| 57 | 57 | return success(BeanUtils.toBean(list, ImChannelMessagePullRespVO.class, vo -> { |
| 58 | 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 | 61 | |
| 62 | 62 | @GetMapping("/max-read-message-id") |
| 63 | 63 | @Operation(summary = "查询对方已读到我发的最大消息 id", |
| 64 | - description = "用于多端 / 离线场景下的已读位置补齐:进入会话或断线重连后调用,结果用于翻转本地自发消息状态") | |
| 64 | + description = "用于多端 / 离线场景下的已读位置补齐:进入会话或断线重连后调用,据此把本地自发消息更新为已读") | |
| 65 | 65 | @Parameter(name = "peerId", description = "对方用户编号", required = true, example = "2") |
| 66 | 66 | public CommonResult<Long> getMaxReadMessageId(@RequestParam("peerId") Long peerId) { |
| 67 | 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 | 24 | @Schema(description = "消息内容;payload JSON 快照", requiredMode = Schema.RequiredMode.REQUIRED) |
| 25 | 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 | 30 | @Schema(description = "发送时间", requiredMode = Schema.RequiredMode.REQUIRED) |
| 31 | 31 | private LocalDateTime sendTime; | ... | ... |
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/group/ImGroupMessageSendReqVO.java
| 1 | 1 | package cn.iocoder.yudao.module.im.controller.admin.message.vo.group; |
| 2 | 2 | |
| 3 | 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 | 5 | import com.fasterxml.jackson.annotation.JsonIgnore; |
| 6 | 6 | import io.swagger.v3.oas.annotations.media.Schema; |
| 7 | 7 | import jakarta.validation.constraints.AssertTrue; |
| ... | ... | @@ -28,7 +28,7 @@ public class ImGroupMessageSendReqVO { |
| 28 | 28 | |
| 29 | 29 | @Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") |
| 30 | 30 | @NotNull(message = "消息类型不能为空") |
| 31 | - @InEnum(ImMessageTypeEnum.class) | |
| 31 | + @InEnum(ImContentTypeEnum.class) | |
| 32 | 32 | private Integer type; |
| 33 | 33 | |
| 34 | 34 | @Schema(description = "消息内容,JSON 格式", requiredMode = Schema.RequiredMode.REQUIRED, example = "{\"content\":\"你好\"}") |
| ... | ... | @@ -47,7 +47,7 @@ public class ImGroupMessageSendReqVO { |
| 47 | 47 | @AssertTrue(message = "消息类型不允许") |
| 48 | 48 | @JsonIgnore |
| 49 | 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 | 31 | private String content; |
| 32 | 32 | |
| 33 | 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 | 39 | @Schema(description = "发送时间") |
| 37 | 40 | private LocalDateTime sendTime; | ... | ... |
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/privates/ImPrivateMessageSendReqVO.java
| 1 | 1 | package cn.iocoder.yudao.module.im.controller.admin.message.vo.privates; |
| 2 | 2 | |
| 3 | 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 | 5 | import com.fasterxml.jackson.annotation.JsonIgnore; |
| 6 | 6 | import io.swagger.v3.oas.annotations.media.Schema; |
| 7 | 7 | import jakarta.validation.constraints.AssertTrue; |
| ... | ... | @@ -26,20 +26,23 @@ public class ImPrivateMessageSendReqVO { |
| 26 | 26 | |
| 27 | 27 | @Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") |
| 28 | 28 | @NotNull(message = "消息类型不能为空") |
| 29 | - @InEnum(ImMessageTypeEnum.class) | |
| 29 | + @InEnum(ImContentTypeEnum.class) | |
| 30 | 30 | private Integer type; |
| 31 | 31 | |
| 32 | 32 | @Schema(description = "消息内容,JSON 格式", requiredMode = Schema.RequiredMode.REQUIRED, example = "{\"content\":\"你好\"}") |
| 33 | 33 | @NotEmpty(message = "消息内容不能为空") |
| 34 | 34 | private String content; |
| 35 | 35 | |
| 36 | + @Schema(description = "是否需要回执", example = "false") | |
| 37 | + private Boolean receipt; | |
| 38 | + | |
| 36 | 39 | /** |
| 37 | 40 | * 仅允许用户消息(normal)类型 |
| 38 | 41 | */ |
| 39 | 42 | @AssertTrue(message = "消息类型不允许") |
| 40 | 43 | @JsonIgnore |
| 41 | 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 | 4 | import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler; |
| 5 | 5 | import cn.iocoder.yudao.module.im.dal.dataobject.channel.ImChannelDO; |
| 6 | 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 | 8 | import com.baomidou.mybatisplus.annotation.KeySequence; |
| 9 | 9 | import com.baomidou.mybatisplus.annotation.TableField; |
| 10 | 10 | import com.baomidou.mybatisplus.annotation.TableId; |
| ... | ... | @@ -54,7 +54,7 @@ public class ImChannelMessageDO extends BaseDO { |
| 54 | 54 | /** |
| 55 | 55 | * 消息类型 |
| 56 | 56 | * <p> |
| 57 | - * 枚举 {@link ImMessageTypeEnum} | |
| 57 | + * 枚举 {@link ImContentTypeEnum} | |
| 58 | 58 | */ |
| 59 | 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 | 3 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 4 | 4 | import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler; |
| 5 | 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 | 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 | 9 | import com.baomidou.mybatisplus.annotation.KeySequence; |
| 10 | 10 | import com.baomidou.mybatisplus.annotation.TableField; |
| 11 | 11 | import com.baomidou.mybatisplus.annotation.TableId; |
| ... | ... | @@ -54,7 +54,7 @@ public class ImGroupMessageDO extends BaseDO { |
| 54 | 54 | /** |
| 55 | 55 | * 消息类型 |
| 56 | 56 | * <p> |
| 57 | - * 枚举 {@link ImMessageTypeEnum} | |
| 57 | + * 枚举 {@link ImContentTypeEnum} | |
| 58 | 58 | */ |
| 59 | 59 | private Integer type; |
| 60 | 60 | /** |
| ... | ... | @@ -67,8 +67,6 @@ public class ImGroupMessageDO extends BaseDO { |
| 67 | 67 | * 消息状态 |
| 68 | 68 | * <p> |
| 69 | 69 | * 枚举 {@link ImMessageStatusEnum} |
| 70 | - * | |
| 71 | - * 为什么没有 READ 状态?与单聊的差异:单聊用 UNREAD/READ 跟踪每条消息状态,群聊用 Redis 存储每个成员的已读位置(游标模型) | |
| 72 | 70 | */ |
| 73 | 71 | private Integer status; |
| 74 | 72 | /** |
| ... | ... | @@ -94,7 +92,7 @@ public class ImGroupMessageDO extends BaseDO { |
| 94 | 92 | /** |
| 95 | 93 | * 回执状态 |
| 96 | 94 | * <p> |
| 97 | - * 枚举 {@link ImGroupMessageReceiptStatusEnum} | |
| 95 | + * 枚举 {@link ImMessageReceiptStatusEnum} | |
| 98 | 96 | */ |
| 99 | 97 | private Integer receiptStatus; |
| 100 | 98 | ... | ... |
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/ImPrivateMessageDO.java
| 1 | 1 | package cn.iocoder.yudao.module.im.dal.dataobject.message; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 4 | +import cn.iocoder.yudao.module.im.enums.message.ImMessageReceiptStatusEnum; | |
| 4 | 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 | 7 | import com.baomidou.mybatisplus.annotation.KeySequence; |
| 7 | 8 | import com.baomidou.mybatisplus.annotation.TableId; |
| 8 | 9 | import com.baomidou.mybatisplus.annotation.TableName; |
| ... | ... | @@ -49,7 +50,7 @@ public class ImPrivateMessageDO extends BaseDO { |
| 49 | 50 | /** |
| 50 | 51 | * 消息类型 |
| 51 | 52 | * <p> |
| 52 | - * 枚举 {@link ImMessageTypeEnum} | |
| 53 | + * 枚举 {@link ImContentTypeEnum} | |
| 53 | 54 | */ |
| 54 | 55 | private Integer type; |
| 55 | 56 | /** |
| ... | ... | @@ -65,6 +66,12 @@ public class ImPrivateMessageDO extends BaseDO { |
| 65 | 66 | */ |
| 66 | 67 | private Integer status; |
| 67 | 68 | /** |
| 69 | + * 回执状态 | |
| 70 | + * <p> | |
| 71 | + * 枚举 {@link ImMessageReceiptStatusEnum} | |
| 72 | + */ | |
| 73 | + private Integer receiptStatus; | |
| 74 | + /** | |
| 68 | 75 | * 发送时间 |
| 69 | 76 | */ |
| 70 | 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
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
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
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
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
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
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 | 3 | import lombok.Data; |
| 4 | 4 | import lombok.experimental.Accessors; |
| ... | ... | @@ -6,7 +6,7 @@ import lombok.experimental.Accessors; |
| 6 | 6 | /** |
| 7 | 7 | * 频道素材消息 payload |
| 8 | 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 | 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 | 4 | import lombok.Data; |
| 5 | 5 | |
| 6 | 6 | import java.util.List; |
| ... | ... | @@ -47,7 +47,7 @@ public class MergeMessage { |
| 47 | 47 | /** |
| 48 | 48 | * 消息类型 |
| 49 | 49 | * <p> |
| 50 | - * 枚举 {@link ImMessageTypeEnum} | |
| 50 | + * 枚举 {@link ImContentTypeEnum} | |
| 51 | 51 | */ |
| 52 | 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 | 4 | import lombok.Data; |
| 5 | 5 | import lombok.experimental.Accessors; |
| 6 | 6 | |
| ... | ... | @@ -39,7 +39,7 @@ public class QuoteMessage { |
| 39 | 39 | /** |
| 40 | 40 | * 被引用消息类型 |
| 41 | 41 | * <p> |
| 42 | - * 枚举 {@link ImMessageTypeEnum} | |
| 42 | + * 枚举 {@link ImContentTypeEnum} | |
| 43 | 43 | */ |
| 44 | 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
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
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
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 | 1 | package cn.iocoder.yudao.module.im.dal.mysql.friend; |
| 2 | 2 | |
| 3 | +import cn.hutool.core.date.LocalDateTimeUtil; | |
| 3 | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | 5 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| 5 | 6 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| ... | ... | @@ -31,6 +32,28 @@ public interface ImFriendMapper extends BaseMapperX<ImFriendDO> { |
| 31 | 32 | .eq(ImFriendDO::getUserId, userId) |
| 32 | 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 | 57 | default List<ImFriendDO> selectListByUserIdAndStatus(Long userId, Integer status) { |
| 35 | 58 | return selectList(new LambdaQueryWrapperX<ImFriendDO>() |
| 36 | 59 | .eq(ImFriendDO::getUserId, userId) |
| ... | ... | @@ -68,12 +91,14 @@ public interface ImFriendMapper extends BaseMapperX<ImFriendDO> { |
| 68 | 91 | |
| 69 | 92 | @SuppressWarnings("UnusedReturnValue") |
| 70 | 93 | default int updateReAddFields(Long id, Integer status, LocalDateTime addTime, |
| 94 | + LocalDateTime updateTime, | |
| 71 | 95 | Boolean silent, Boolean pinned, Boolean blocked, |
| 72 | 96 | String displayName, Integer addSource) { |
| 73 | 97 | return update(null, Wrappers.<ImFriendDO>lambdaUpdate() |
| 74 | 98 | .eq(ImFriendDO::getId, id) |
| 75 | 99 | .set(ImFriendDO::getStatus, status) |
| 76 | 100 | .set(ImFriendDO::getAddTime, addTime) |
| 101 | + .set(ImFriendDO::getUpdateTime, updateTime) | |
| 77 | 102 | .set(ImFriendDO::getSilent, silent) |
| 78 | 103 | .set(ImFriendDO::getPinned, pinned) |
| 79 | 104 | .set(ImFriendDO::getBlocked, blocked) | ... | ... |
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/friend/ImFriendRequestMapper.java
| 1 | 1 | package cn.iocoder.yudao.module.im.dal.mysql.friend; |
| 2 | 2 | |
| 3 | +import cn.hutool.core.date.LocalDateTimeUtil; | |
| 3 | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | 5 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| 5 | 6 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| ... | ... | @@ -28,6 +29,12 @@ public interface ImFriendRequestMapper extends BaseMapperX<ImFriendRequestDO> { |
| 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 | 39 | default List<ImFriendRequestDO> selectMyList(Long userId, LocalDateTime maxRequestUpdateTime, |
| 33 | 40 | Long maxId, int limit) { |
| ... | ... | @@ -45,6 +52,28 @@ public interface ImFriendRequestMapper extends BaseMapperX<ImFriendRequestDO> { |
| 45 | 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 | 77 | default int updateByIdAndHandleResult(Long id, Integer handleResult, ImFriendRequestDO updateObj) { |
| 49 | 78 | return update(updateObj, new LambdaUpdateWrapper<ImFriendRequestDO>() |
| 50 | 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 | 1 | package cn.iocoder.yudao.module.im.dal.mysql.group; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | |
| 5 | 4 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| 6 | 5 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| 7 | 6 | import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO; |
| ... | ... | @@ -59,20 +58,8 @@ public interface ImGroupMemberMapper extends BaseMapperX<ImGroupMemberDO> { |
| 59 | 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 | 65 | @SuppressWarnings("UnusedReturnValue") |
| ... | ... | @@ -143,7 +130,8 @@ public interface ImGroupMemberMapper extends BaseMapperX<ImGroupMemberDO> { |
| 143 | 130 | .set(ImGroupMemberDO::getAddSource, addSource) |
| 144 | 131 | .set(ImGroupMemberDO::getInviterUserId, inviterUserId) |
| 145 | 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 | 1 | package cn.iocoder.yudao.module.im.dal.mysql.group; |
| 2 | 2 | |
| 3 | +import cn.hutool.core.date.LocalDateTimeUtil; | |
| 3 | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | 5 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| 5 | 6 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| ... | ... | @@ -43,6 +44,28 @@ public interface ImGroupRequestMapper extends BaseMapperX<ImGroupRequestDO> { |
| 43 | 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 | 69 | default int updateByIdAndHandleResult(Long id, Integer expectedHandleResult, ImGroupRequestDO updateObj) { |
| 47 | 70 | return update(updateObj, new LambdaUpdateWrapper<ImGroupRequestDO>() |
| 48 | 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 | 4 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| 5 | 5 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| 6 | 6 | import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX; |
| 7 | +import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils; | |
| 7 | 8 | import cn.iocoder.yudao.module.im.controller.admin.manager.message.vo.group.ImGroupMessageManagerPageReqVO; |
| 8 | 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 | 11 | import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum; |
| 11 | 12 | import org.apache.ibatis.annotations.Mapper; |
| 12 | 13 | |
| 13 | 14 | import java.time.LocalDateTime; |
| 15 | +import java.util.Collection; | |
| 14 | 16 | import java.util.List; |
| 15 | 17 | |
| 16 | 18 | /** |
| ... | ... | @@ -22,48 +24,22 @@ import java.util.List; |
| 22 | 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 | 31 | * @param minId 最小消息 id(不含) |
| 29 | 32 | * @param minSendTime 最早发送时间(不含),限制离线消息时间窗口 |
| 30 | 33 | * @param size 拉取数量 |
| 31 | 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 | 37 | LocalDateTime minSendTime, Integer size) { |
| 35 | 38 | QueryWrapperX<ImGroupMessageDO> wrapper = new QueryWrapperX<>(); |
| 36 | 39 | wrapper.in("group_id", groupIds) |
| 37 | 40 | .gt("id", minId) |
| 38 | 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 | 43 | .orderByAsc("id"); |
| 68 | 44 | wrapper.limitN(size); |
| 69 | 45 | return selectList(wrapper); |
| ... | ... | @@ -72,17 +48,17 @@ public interface ImGroupMessageMapper extends BaseMapperX<ImGroupMessageDO> { |
| 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 | 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 | 58 | QueryWrapperX<ImGroupMessageDO> wrapper = new QueryWrapperX<>(); |
| 83 | 59 | wrapper.eq("group_id", groupId) |
| 84 | 60 | .lt(maxId != null, "id", maxId) |
| 85 | - .ge(joinTime != null, "send_time", joinTime) | |
| 61 | + .apply(MyBatisUtils.findInSet("receiver_user_ids"), userId) | |
| 86 | 62 | .orderByDesc("id"); |
| 87 | 63 | wrapper.limitN(limit); |
| 88 | 64 | return selectList(wrapper); |
| ... | ... | @@ -108,7 +84,7 @@ public interface ImGroupMessageMapper extends BaseMapperX<ImGroupMessageDO> { |
| 108 | 84 | default List<ImGroupMessageDO> selectListByGroupIdAndPendingReceipt(Long groupId, Long minId, Long maxId) { |
| 109 | 85 | return selectList(new LambdaQueryWrapperX<ImGroupMessageDO>() |
| 110 | 86 | .eq(ImGroupMessageDO::getGroupId, groupId) |
| 111 | - .eq(ImGroupMessageDO::getReceiptStatus, ImGroupMessageReceiptStatusEnum.PENDING.getStatus()) | |
| 87 | + .eq(ImGroupMessageDO::getReceiptStatus, ImMessageReceiptStatusEnum.PENDING.getStatus()) | |
| 112 | 88 | .gt(minId != null, ImGroupMessageDO::getId, minId) |
| 113 | 89 | .le(ImGroupMessageDO::getId, maxId) |
| 114 | 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<ImPrivateMessageDO> |
| 67 | 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 | 72 | return update(updateObj, new LambdaQueryWrapperX<ImPrivateMessageDO>() |
| 83 | 73 | .eq(ImPrivateMessageDO::getSenderId, senderId) |
| 84 | 74 | .eq(ImPrivateMessageDO::getReceiverId, receiverId) |
| 85 | 75 | .le(ImPrivateMessageDO::getId, maxMessageId) |
| 86 | - .eq(ImPrivateMessageDO::getStatus, whereStatus)); | |
| 76 | + .eq(ImPrivateMessageDO::getReceiptStatus, whereReceiptStatus)); | |
| 87 | 77 | } |
| 88 | 78 | |
| 89 | 79 | default PageResult<ImPrivateMessageDO> selectPage(ImPrivateMessageManagerPageReqVO reqVO) { | ... | ... |
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/statistics/ImStatisticsManagerMapper.java
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 | 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 | 13 | * <p> |
| 28 | 14 | * KEY 格式:friend_state:{userId}_{friendUserId} |
| ... | ... | @@ -44,7 +30,7 @@ public interface RedisKeyConstants { |
| 44 | 30 | * KEY 格式:group_member_ids:{groupId} |
| 45 | 31 | * VALUE 数据类型:List<Long> |
| 46 | 32 | * <p> |
| 47 | - * 说明:只缓存轻量的 userId 列表,适合"群消息推送目标"这类只关心 userId 的场景。 | |
| 33 | + * 说明:只缓存轻量的 userId 列表,适合「群消息推送目标」这类只关心 userId 的场景 | |
| 48 | 34 | */ |
| 49 | 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 | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | 4 | import cn.hutool.core.lang.Assert; |
| ... | ... | @@ -11,13 +11,13 @@ import java.util.Arrays; |
| 11 | 11 | import java.util.Set; |
| 12 | 12 | |
| 13 | 13 | /** |
| 14 | - * IM 消息类型枚举 | |
| 14 | + * IM 内容类型枚举 | |
| 15 | 15 | * |
| 16 | 16 | * @author 芋道源码 |
| 17 | 17 | */ |
| 18 | 18 | @Getter |
| 19 | 19 | @RequiredArgsConstructor |
| 20 | -public enum ImMessageTypeEnum implements ArrayValuable<Integer> { | |
| 20 | +public enum ImContentTypeEnum implements ArrayValuable<Integer> { | |
| 21 | 21 | |
| 22 | 22 | // ========== 用户聊天消息(101-105 直接复用 OpenIM 段位编号) ========== |
| 23 | 23 | /** |
| ... | ... | @@ -128,10 +128,6 @@ public enum ImMessageTypeEnum implements ArrayValuable<Integer> { |
| 128 | 128 | RTC_CALL_END(1611, "通话结束", true, false), |
| 129 | 129 | |
| 130 | 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 | 132 | * 对应 OpenIM:FriendApplicationApprovedNotification 1201 |
| 137 | 133 | * 对应自己的类:FriendRequestApprovedNotification |
| ... | ... | @@ -285,9 +281,9 @@ public enum ImMessageTypeEnum implements ArrayValuable<Integer> { |
| 285 | 281 | /** |
| 286 | 282 | * 对应 OpenIM:sdkws.GroupMemberInfoSetTips(GroupMemberInfoSetNotification 1516,窄化到 displayUserName) |
| 287 | 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 | 288 | * 对应 OpenIM:GroupMemberSetToAdminNotification 1517 |
| 293 | 289 | * 对应自己的类:GroupAdminAddNotification |
| ... | ... | @@ -339,7 +335,7 @@ public enum ImMessageTypeEnum implements ArrayValuable<Integer> { |
| 339 | 335 | */ |
| 340 | 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 | 340 | private static final Set<Integer> FRIEND_NOTIFICATION_TYPES = CollUtil.newHashSet( |
| 345 | 341 | FRIEND_REQUEST_APPROVED.type, |
| ... | ... | @@ -396,8 +392,8 @@ public enum ImMessageTypeEnum implements ArrayValuable<Integer> { |
| 396 | 392 | * @param type 消息类型 |
| 397 | 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 | 397 | Assert.notNull(result, "未注册的消息类型 type={}", type); |
| 402 | 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 | 16 | @Getter |
| 17 | 17 | public enum ImConversationTypeEnum implements ArrayValuable<Integer> { |
| 18 | 18 | |
| 19 | + NONE(0, "无会话"), // 无会话 | |
| 19 | 20 | PRIVATE(1, "私聊"), // 私聊 |
| 20 | 21 | GROUP(2, "群聊"), // 群聊 |
| 21 | 22 | CHANNEL(3, "频道"); // 频道 / 公众号 |
| ... | ... | @@ -36,6 +37,10 @@ public enum ImConversationTypeEnum implements ArrayValuable<Integer> { |
| 36 | 37 | return ARRAYS; |
| 37 | 38 | } |
| 38 | 39 | |
| 40 | + public static boolean isNone(Integer type) { | |
| 41 | + return Objects.equals(NONE.type, type); | |
| 42 | + } | |
| 43 | + | |
| 39 | 44 | public static boolean isPrivate(Integer type) { |
| 40 | 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 | 7 | import java.util.Arrays; |
| 8 | 8 | |
| 9 | 9 | /** |
| 10 | - * IM 群消息回执状态枚举 | |
| 10 | + * IM 消息回执状态枚举 | |
| 11 | 11 | * |
| 12 | 12 | * @author 芋道源码 |
| 13 | 13 | */ |
| 14 | 14 | @Getter |
| 15 | 15 | @AllArgsConstructor |
| 16 | -public enum ImGroupMessageReceiptStatusEnum implements ArrayValuable<Integer> { | |
| 16 | +public enum ImMessageReceiptStatusEnum implements ArrayValuable<Integer> { | |
| 17 | 17 | |
| 18 | 18 | NO_RECEIPT(0, "不需要回执"), |
| 19 | 19 | PENDING(1, "待完成"), |
| 20 | 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 | 8 | |
| 9 | 9 | /** |
| 10 | 10 | * IM 消息状态枚举 |
| 11 | - * <p> | |
| 12 | - * 私聊:SENDING(-1, 仅客户端) / UNREAD(0) / RECALL(2) / READ(3) | |
| 13 | - * 群聊:SENDING(-1, 仅客户端) / UNREAD(0, 作为正常状态) / RECALL(2) | |
| 14 | 11 | * |
| 15 | 12 | * @author 芋道源码 |
| 16 | 13 | */ |
| ... | ... | @@ -19,9 +16,8 @@ import java.util.Arrays; |
| 19 | 16 | public enum ImMessageStatusEnum implements ArrayValuable<Integer> { |
| 20 | 17 | |
| 21 | 18 | SENDING(-1, "发送中"), // 仅客户端使用 |
| 22 | - UNREAD(0, "未读"), // 私聊=未读,群聊=正常(初始状态) | |
| 23 | - RECALL(2, "已撤回"), | |
| 24 | - READ(3, "已读"); // 仅私聊使用;群聊已读通过 Redis 已读位置实现 | |
| 19 | + NORMAL(0, "正常"), // 私聊 / 群聊的正常(初始)状态 | |
| 20 | + RECALL(2, "已撤回"); | |
| 25 | 21 | |
| 26 | 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 | 24 | @Getter |
| 25 | 25 | public enum ImRtcParticipantStatusEnum implements ArrayValuable<Integer> { |
| 26 | 26 | |
| 27 | - // TODO @芋艿:hand up 要不要也搞下。 | |
| 28 | 27 | INVITING(10, "邀请中"), // 已发出 invite,等被叫响应 |
| 29 | 28 | JOINED(20, "已加入"), // 已 connect 进 LiveKit 房间 |
| 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 | 2 | |
| 3 | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | 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 | 7 | import cn.iocoder.yudao.module.im.service.friend.ImFriendService; |
| 7 | 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 | 10 | import cn.iocoder.yudao.module.system.api.message.user.AdminUserProfileUpdateMessage; |
| 11 | 11 | import jakarta.annotation.Resource; |
| 12 | 12 | import lombok.extern.slf4j.Slf4j; |
| ... | ... | @@ -52,8 +52,9 @@ public class AdminUserProfileUpdateConsumer { |
| 52 | 52 | try { |
| 53 | 53 | FriendInfoUpdatedNotification payload = (FriendInfoUpdatedNotification) new FriendInfoUpdatedNotification() |
| 54 | 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 | 58 | successCount++; |
| 58 | 59 | } catch (Exception e) { |
| 59 | 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 | 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 | 65 | * 按 id 单查申请记录;通用读接口,调用方自行做越权过滤 |
| 55 | 66 | */ |
| 56 | 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 | 14 | import cn.iocoder.yudao.module.im.dal.mysql.friend.ImFriendRequestMapper; |
| 15 | 15 | import cn.iocoder.yudao.module.im.enums.friend.ImFriendRequestHandleResultEnum; |
| 16 | 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 | 19 | import cn.iocoder.yudao.module.im.framework.config.ImProperties; |
| 19 | 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 | 24 | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; |
| 25 | 25 | import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; |
| 26 | 26 | import jakarta.annotation.Resource; |
| ... | ... | @@ -105,8 +105,8 @@ public class ImFriendRequestServiceImpl implements ImFriendRequestService { |
| 105 | 105 | if (fromUser != null) { |
| 106 | 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 | 111 | // 4. 全局自动通过开关:注册 afterCommit 回调,事务提交后再走同意流程 |
| 112 | 112 | // 回调内 try/catch 兜底 —— afterCommit 异常会被 Spring 静默吞掉,否则同意失败时申请方永远等不到 APPROVED |
| ... | ... | @@ -172,8 +172,6 @@ public class ImFriendRequestServiceImpl implements ImFriendRequestService { |
| 172 | 172 | public void agreeFriendRequest(Long userId, Long requestId) { |
| 173 | 173 | // 1.1 校验申请存在、未处理、操作人是接收方 |
| 174 | 174 | ImFriendRequestDO request = validateRequestForHandle(userId, requestId); |
| 175 | - // 1.2 复验双方用户有效 | |
| 176 | - adminUserApi.validateUserList(ListUtil.of(request.getFromUserId(), request.getToUserId())); | |
| 177 | 175 | |
| 178 | 176 | // 2. 乐观锁更新申请处理结果 |
| 179 | 177 | ImFriendRequestDO updateObj = new ImFriendRequestDO() |
| ... | ... | @@ -192,8 +190,8 @@ public class ImFriendRequestServiceImpl implements ImFriendRequestService { |
| 192 | 190 | FriendRequestApprovedNotification payload = (FriendRequestApprovedNotification) |
| 193 | 191 | new FriendRequestApprovedNotification().setRequestId(request.getId()) |
| 194 | 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 | 197 | @Override |
| ... | ... | @@ -217,8 +215,8 @@ public class ImFriendRequestServiceImpl implements ImFriendRequestService { |
| 217 | 215 | new FriendRequestRejectedNotification().setRequestId(request.getId()) |
| 218 | 216 | .setHandleContent(handleContent) |
| 219 | 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 | 222 | @Override |
| ... | ... | @@ -234,6 +232,11 @@ public class ImFriendRequestServiceImpl implements ImFriendRequestService { |
| 234 | 232 | } |
| 235 | 233 | |
| 236 | 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 | 240 | public ImFriendRequestDO getFriendRequest(Long id) { |
| 238 | 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 | 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 | 51 | * 获得当前用户的有效好友列表(仅 ENABLE 状态) |
| 47 | 52 | */ |
| 48 | 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 | 11 | import cn.iocoder.yudao.module.im.dal.dataobject.friend.ImFriendRequestDO; |
| 12 | 12 | import cn.iocoder.yudao.module.im.dal.mysql.friend.ImFriendMapper; |
| 13 | 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 | 16 | import cn.iocoder.yudao.module.im.service.message.ImPrivateMessageService; |
| 16 | 17 | import cn.iocoder.yudao.module.im.service.message.dto.ImPrivateMessageSendDTO; |
| 17 | 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 | 20 | import jakarta.annotation.Resource; |
| 21 | 21 | import lombok.extern.slf4j.Slf4j; |
| 22 | 22 | import org.springframework.cache.annotation.CacheEvict; |
| ... | ... | @@ -99,6 +99,11 @@ public class ImFriendServiceImpl implements ImFriendService { |
| 99 | 99 | } |
| 100 | 100 | |
| 101 | 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 | 107 | public List<ImFriendDO> getEnableFriendList(Long userId) { |
| 103 | 108 | return friendMapper.selectListByUserIdAndStatus(userId, CommonStatusEnum.ENABLE.getStatus()); |
| 104 | 109 | } |
| ... | ... | @@ -155,8 +160,8 @@ public class ImFriendServiceImpl implements ImFriendService { |
| 155 | 160 | FriendUpdateNotification payload = (FriendUpdateNotification) new FriendUpdateNotification() |
| 156 | 161 | .setDisplayName(reqVO.getDisplayName()).setSilent(reqVO.getSilent()).setPinned(reqVO.getPinned()) |
| 157 | 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 | 167 | @Override |
| ... | ... | @@ -178,7 +183,7 @@ public class ImFriendServiceImpl implements ImFriendService { |
| 178 | 183 | FriendAddNotification payload = (FriendAddNotification) new FriendAddNotification() |
| 179 | 184 | .setOperatorUserId(fromUserId).setFriendUserId(toUserId); |
| 180 | 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 | 189 | @Override |
| ... | ... | @@ -197,7 +202,7 @@ public class ImFriendServiceImpl implements ImFriendService { |
| 197 | 202 | FriendAddNotification payload = (FriendAddNotification) new FriendAddNotification() |
| 198 | 203 | .setOperatorUserId(friendUserId).setFriendUserId(friendUserId); |
| 199 | 204 | privateMessageService.sendPrivateMessage(userId, new ImPrivateMessageSendDTO() |
| 200 | - .setReceiverId(friendUserId).setType(ImMessageTypeEnum.FRIEND_ADD.getType()) | |
| 205 | + .setReceiverId(friendUserId).setType(ImContentTypeEnum.FRIEND_ADD.getType()) | |
| 201 | 206 | .setContent(payload).setPersistent(false)); |
| 202 | 207 | } |
| 203 | 208 | |
| ... | ... | @@ -219,7 +224,7 @@ public class ImFriendServiceImpl implements ImFriendService { |
| 219 | 224 | FriendDeleteNotification payload = ((FriendDeleteNotification) new FriendDeleteNotification() |
| 220 | 225 | .setOperatorUserId(userId).setFriendUserId(friendUserId)).setClear(clear); |
| 221 | 226 | privateMessageService.sendPrivateMessage(userId, new ImPrivateMessageSendDTO() |
| 222 | - .setReceiverId(friendUserId).setType(ImMessageTypeEnum.FRIEND_DELETE.getType()) | |
| 227 | + .setReceiverId(friendUserId).setType(ImContentTypeEnum.FRIEND_DELETE.getType()) | |
| 223 | 228 | .setContent(payload).setPersistent(false)); |
| 224 | 229 | } |
| 225 | 230 | |
| ... | ... | @@ -245,8 +250,8 @@ public class ImFriendServiceImpl implements ImFriendService { |
| 245 | 250 | // 3. 推 FRIEND_BLOCK 给 A 多端 |
| 246 | 251 | FriendBlockNotification payload = (FriendBlockNotification) new FriendBlockNotification() |
| 247 | 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 | 257 | @Override |
| ... | ... | @@ -271,8 +276,8 @@ public class ImFriendServiceImpl implements ImFriendService { |
| 271 | 276 | // 3. 推 FRIEND_UNBLOCK 给 A 多端 |
| 272 | 277 | FriendUnblockNotification payload = (FriendUnblockNotification) new FriendUnblockNotification() |
| 273 | 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 | 299 | } |
| 295 | 300 | // 情况二:复用 DISABLE 旧记录 → 恢复 ENABLE + 重置 silent / pinned / blocked,对齐"重新加好友"语义 |
| 296 | 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 | 304 | false, false, false, displayName, addSource); |
| 299 | 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 | 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 | 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 | 77 | |
| 78 | 78 | @Override |
| 79 | 79 | public List<ImGroupMemberDO> getGroupMemberListByOwnerAndAdmin(Long groupId) { |
| 80 | - // TODO DONE @AI:把条件往下传;这样减少加载数据量! | |
| 81 | 80 | return groupMemberMapper.selectListByGroupIdAndStatusAndRoles(groupId, CommonStatusEnum.ENABLE.getStatus(), |
| 82 | 81 | ListUtil.of(ImGroupMemberRoleEnum.OWNER.getRole(), ImGroupMemberRoleEnum.ADMIN.getRole())); |
| 83 | 82 | } |
| ... | ... | @@ -106,8 +105,8 @@ public class ImGroupMemberServiceImpl implements ImGroupMemberService { |
| 106 | 105 | } |
| 107 | 106 | |
| 108 | 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 | 112 | @Override |
| ... | ... | @@ -259,7 +258,7 @@ public class ImGroupMemberServiceImpl implements ImGroupMemberService { |
| 259 | 258 | .setId(member.getId()); |
| 260 | 259 | groupMemberMapper.updateById(updateObj); |
| 261 | 260 | |
| 262 | - // 3.1 displayUserName 是公开字段,单独走 GROUP_MEMBER_NICKNAME_UPDATE 广播给全员;空串视为「清空昵称」也要广播;与旧值相同跳过 | |
| 261 | + // 3.1 displayUserName 是公开字段,单独走 GROUP_MEMBER_NICKNAME_UPDATE 在线同步给全员;空串视为「清空昵称」也要同步;与旧值相同跳过 | |
| 263 | 262 | if (updateReqVO.getDisplayUserName() != null |
| 264 | 263 | && ObjUtil.notEqual(updateReqVO.getDisplayUserName(), member.getDisplayUserName())) { |
| 265 | 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 | 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 | 81 | * <p> |
| 69 | 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 | 13 | import cn.iocoder.yudao.module.im.enums.group.ImGroupAddSourceEnum; |
| 14 | 14 | import cn.iocoder.yudao.module.im.enums.group.ImGroupMemberRoleEnum; |
| 15 | 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 | 18 | import cn.iocoder.yudao.module.im.service.message.ImGroupMessageService; |
| 18 | 19 | import cn.iocoder.yudao.module.im.service.message.dto.ImGroupMessageSendDTO; |
| 19 | 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 | 25 | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; |
| 26 | 26 | import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; |
| 27 | 27 | import jakarta.annotation.Resource; |
| ... | ... | @@ -97,12 +97,12 @@ public class ImGroupRequestServiceImpl implements ImGroupRequestService { |
| 97 | 97 | // 3. 情况二:群开启了审批,创建或复用一条主动申请记录 |
| 98 | 98 | ImGroupRequestDO request = createOrResetApplyRequest(groupId, userId, reqVO); |
| 99 | 99 | |
| 100 | - // 4. 1503 私聊定向推群主 + 全部管理员(多端同步);payload 携带申请方昵称 / 头像 | |
| 100 | + // 4. 1503 定向推群主 + 全部管理员(多端同步);payload 携带申请方昵称 / 头像 | |
| 101 | 101 | AdminUserRespDTO applyUser = adminUserApi.getUser(userId); |
| 102 | 102 | GroupRequestReceivedNotification payload = buildRequestNotification(group, request, applyUser); |
| 103 | 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 | 107 | return request; |
| 108 | 108 | } |
| ... | ... | @@ -139,12 +139,12 @@ public class ImGroupRequestServiceImpl implements ImGroupRequestService { |
| 139 | 139 | groupMemberService.addGroupMember(request.getGroupId(), request.getUserId(), |
| 140 | 140 | ImGroupMemberRoleEnum.NORMAL.getRole(), request.getAddSource(), request.getInviterUserId()); |
| 141 | 141 | |
| 142 | - // 5.1 1505 私聊推送给申请人 + 群主 + 全部管理员(每端单推) | |
| 142 | + // 5.1 1505 定向推送给申请人 + 群主 + 全部管理员(每端单推) | |
| 143 | 143 | GroupRequestApprovedNotification payload = (GroupRequestApprovedNotification) new GroupRequestApprovedNotification() |
| 144 | 144 | .setRequestId(request.getId()).setGroupId(request.getGroupId()).setUserId(request.getUserId()) |
| 145 | 145 | .setOperatorUserId(userId); |
| 146 | 146 | broadcastToOwnerAdminsAndApplicant(request.getGroupId(), request.getUserId(), payload, |
| 147 | - ImMessageTypeEnum.GROUP_REQUEST_APPROVED.getType(), userId); | |
| 147 | + ImContentTypeEnum.GROUP_REQUEST_APPROVED.getType(), userId); | |
| 148 | 148 | // 5.2 群事件:主动申请 → 1510 自由进群;被邀请 → 1509 成员加入 |
| 149 | 149 | if (request.getInviterUserId() == null) { |
| 150 | 150 | groupMessageService.sendGroupMessage(userId, |
| ... | ... | @@ -174,12 +174,12 @@ public class ImGroupRequestServiceImpl implements ImGroupRequestService { |
| 174 | 174 | throw exception(GROUP_REQUEST_HANDLED); |
| 175 | 175 | } |
| 176 | 176 | |
| 177 | - // 3. 1506 私聊推送给申请人 + 群主 + 全部管理员 | |
| 177 | + // 3. 1506 定向推送给申请人 + 群主 + 全部管理员 | |
| 178 | 178 | GroupRequestRejectedNotification payload = (GroupRequestRejectedNotification) new GroupRequestRejectedNotification() |
| 179 | 179 | .setRequestId(request.getId()).setGroupId(request.getGroupId()).setUserId(request.getUserId()) |
| 180 | 180 | .setHandleContent(handleContent).setOperatorUserId(userId); |
| 181 | 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 | 185 | @Override |
| ... | ... | @@ -201,8 +201,8 @@ public class ImGroupRequestServiceImpl implements ImGroupRequestService { |
| 201 | 201 | AdminUserRespDTO applyUser = userMap.get(request.getUserId()); |
| 202 | 202 | GroupRequestReceivedNotification payload = buildRequestNotification(group, request, applyUser); |
| 203 | 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 | 212 | // 1. 找出当前用户作为 OWNER / ADMIN 的所有群 |
| 213 | 213 | List<ImGroupMemberDO> myMembers = groupMemberService.getActiveGroupMemberListByUserId(userId); |
| 214 | 214 | Set<Long> ownerOrAdminGroupIds = convertSet(myMembers, |
| 215 | - ImGroupMemberDO::getGroupId, | |
| 216 | - m -> ImGroupMemberRoleEnum.isOwnerOrAdmin(m.getRole())); | |
| 215 | + ImGroupMemberDO::getGroupId, member -> ImGroupMemberRoleEnum.isOwnerOrAdmin(member.getRole())); | |
| 217 | 216 | if (CollUtil.isEmpty(ownerOrAdminGroupIds)) { |
| 218 | 217 | return Collections.emptyList(); |
| 219 | 218 | } |
| ... | ... | @@ -223,6 +222,19 @@ public class ImGroupRequestServiceImpl implements ImGroupRequestService { |
| 223 | 222 | } |
| 224 | 223 | |
| 225 | 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 | 238 | public List<ImGroupRequestDO> getGroupRequestListByGroupId(Long userId, Long groupId) { |
| 227 | 239 | // 1. 校验群存在 + 当前用户是群主 / 管理员 |
| 228 | 240 | groupService.validateGroupExists(groupId); |
| ... | ... | @@ -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 | 400 | private void broadcastToOwnerAdminsAndApplicant(Long groupId, Long applicantUserId, BaseGroupNotification payload, |
| 389 | 401 | Integer messageType, Long operatorUserId) { |
| ... | ... | @@ -394,8 +406,8 @@ public class ImGroupRequestServiceImpl implements ImGroupRequestService { |
| 394 | 406 | Set<Long> receivers = new LinkedHashSet<>(getGroupMemberListByOwnerAndAdminUserIds(group)); |
| 395 | 407 | receivers.add(applicantUserId); |
| 396 | 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 | 30 | import cn.iocoder.yudao.module.im.enums.group.ImGroupAddSourceEnum; |
| 31 | 31 | import cn.iocoder.yudao.module.im.enums.group.ImGroupMemberRoleEnum; |
| 32 | 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 | 34 | import cn.iocoder.yudao.module.im.framework.config.ImProperties; |
| 35 | 35 | import cn.iocoder.yudao.module.im.service.friend.ImFriendService; |
| 36 | 36 | import cn.iocoder.yudao.module.im.service.message.ImGroupMessageService; |
| ... | ... | @@ -149,7 +149,9 @@ public class ImGroupServiceImpl implements ImGroupService { |
| 149 | 149 | boolean nameChanged = StrUtil.isNotEmpty(updateReqVO.getName()); |
| 150 | 150 | boolean noticeChanged = updateReqVO.getNotice() != null; |
| 151 | 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 | 155 | List<Long> memberUserIds = groupMemberService.getActiveGroupMemberUserIdsByGroupId(groupId); |
| 154 | 156 | if (nameChanged) { |
| 155 | 157 | groupMessageService.sendGroupMessage(userId, memberUserIds, ImGroupMessageSendDTO.ofGroupNameUpdate( |
| ... | ... | @@ -161,7 +163,11 @@ public class ImGroupServiceImpl implements ImGroupService { |
| 161 | 163 | } |
| 162 | 164 | if (avatarChanged) { |
| 163 | 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 | 199 | .setStatus(CommonStatusEnum.DISABLE.getStatus()).setDissolvedTime(LocalDateTime.now())); |
| 194 | 200 | // 2.2 移除全部群成员 |
| 195 | 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 | 271 | // 2. 先发广播,后移成员(见类 javadoc) |
| 268 | 272 | groupMessageService.sendGroupMessage(userId, ImGroupMessageSendDTO.ofGroupMemberQuit(groupId, userId)); |
| 269 | 273 | |
| 270 | - // 3.1 移除群成员 | |
| 274 | + // 3. 移除群成员 | |
| 271 | 275 | groupMemberService.removeGroupMember(groupId, userId); |
| 272 | - // 3.2 清理已读缓存 | |
| 273 | - groupMessageService.deleteReadMaxMessageId(groupId, userId); | |
| 274 | 276 | } |
| 275 | 277 | |
| 276 | 278 | @Override |
| ... | ... | @@ -307,10 +309,8 @@ public class ImGroupServiceImpl implements ImGroupService { |
| 307 | 309 | groupMessageService.sendGroupMessage(userId, |
| 308 | 310 | ImGroupMessageSendDTO.ofGroupMemberKick(groupId, userId, validTargetUserIds)); |
| 309 | 311 | |
| 310 | - // 3.1 批量移除群成员 | |
| 312 | + // 3. 批量移除群成员;不清理读位置(保留退群前历史已读,供离线补偿) | |
| 311 | 313 | groupMemberService.removeGroupMembers(groupId, validTargetUserIds); |
| 312 | - // 3.2 批量清理已读缓存 | |
| 313 | - groupMessageService.deleteReadMaxMessageIds(groupId, validTargetUserIds); | |
| 314 | 314 | } |
| 315 | 315 | |
| 316 | 316 | @Override |
| ... | ... | @@ -442,7 +442,7 @@ public class ImGroupServiceImpl implements ImGroupService { |
| 442 | 442 | if (message == null || ObjUtil.notEqual(message.getGroupId(), groupId)) { |
| 443 | 443 | throw exception(MESSAGE_NOT_IN_GROUP); |
| 444 | 444 | } |
| 445 | - if (!ImMessageTypeEnum.validate(message.getType()).isNormal() | |
| 445 | + if (!ImContentTypeEnum.validate(message.getType()).isNormal() | |
| 446 | 446 | || ImMessageStatusEnum.RECALL.getStatus().equals(message.getStatus())) { |
| 447 | 447 | throw exception(MESSAGE_NOT_IN_GROUP); |
| 448 | 448 | } |
| ... | ... | @@ -601,11 +601,8 @@ public class ImGroupServiceImpl implements ImGroupService { |
| 601 | 601 | |
| 602 | 602 | @Override |
| 603 | 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 | 606 | if (CollUtil.isEmpty(members)) { |
| 610 | 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 | 27 | * @param size 返回条数 |
| 28 | 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 | 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 | 2 | |
| 3 | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | 4 | import cn.hutool.core.lang.Assert; |
| 5 | +import cn.hutool.core.util.ObjUtil; | |
| 5 | 6 | import cn.hutool.extra.spring.SpringUtil; |
| 6 | 7 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 7 | 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 | import cn.iocoder.yudao.module.im.dal.dataobject.channel.ImChannelMaterialDO; |
| 12 | 13 | import cn.iocoder.yudao.module.im.dal.dataobject.message.ImChannelMessageDO; |
| 13 | 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 | 17 | import cn.iocoder.yudao.module.im.service.channel.ImChannelMaterialService; |
| 18 | +import cn.iocoder.yudao.module.im.service.conversation.ImConversationReadService; | |
| 17 | 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 | 23 | import jakarta.annotation.Resource; |
| 21 | 24 | import org.springframework.scheduling.annotation.Async; |
| 22 | 25 | import org.springframework.stereotype.Service; |
| ... | ... | @@ -25,7 +28,6 @@ import org.springframework.validation.annotation.Validated; |
| 25 | 28 | |
| 26 | 29 | import java.time.LocalDateTime; |
| 27 | 30 | import java.util.Collection; |
| 28 | -import java.util.HashMap; | |
| 29 | 31 | import java.util.List; |
| 30 | 32 | import java.util.Map; |
| 31 | 33 | |
| ... | ... | @@ -50,39 +52,41 @@ public class ImChannelMessageServiceImpl implements ImChannelMessageService { |
| 50 | 52 | private ImWebSocketService webSocketService; |
| 51 | 53 | |
| 52 | 54 | @Resource |
| 53 | - private ImChannelMessageReadRedisDAO channelMessageReadRedisDAO; | |
| 55 | + private ImConversationReadService conversationReadService; | |
| 54 | 56 | |
| 55 | 57 | // ==================== 用户端 ==================== |
| 56 | 58 | |
| 57 | 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 | 61 | return channelMessageMapper.selectListByUserAndMinId(userId, minId, size); |
| 60 | 62 | } |
| 61 | 63 | |
| 62 | 64 | @Override |
| 63 | 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 | 70 | @Override |
| 75 | 71 | public void readChannelMessages(Long userId, Long channelId, Long messageId) { |
| 76 | 72 | Assert.notNull(channelId, "频道编号不能为空"); |
| 77 | 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 | 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 | 91 | // 3. 异步推 READ 事件给自己多端同步 |
| 88 | 92 | getSelf().readChannelMessageEvent(userId, channelId, messageId); |
| ... | ... | @@ -93,7 +97,8 @@ public class ImChannelMessageServiceImpl implements ImChannelMessageService { |
| 93 | 97 | */ |
| 94 | 98 | @Async |
| 95 | 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 | 104 | private ImChannelMessageServiceImpl getSelf() { |
| ... | ... | @@ -113,15 +118,16 @@ public class ImChannelMessageServiceImpl implements ImChannelMessageService { |
| 113 | 118 | String payloadJson = JsonUtils.toJsonString(payload); |
| 114 | 119 | // 2.2 落库 1 行 message;reqVO 同名字段(materialId / receiverUserIds)自动拷贝,剩余字段补 set |
| 115 | 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 | 122 | channelMessageMapper.insert(message); |
| 118 | 123 | |
| 119 | 124 | // 3. 异步推 WebSocket:指定用户走点对点;全员(receiverUserIds 为空)走广播 |
| 120 | - ImChannelMessageDTO dto = ImChannelMessageDTO.ofSend(message); | |
| 125 | + ImChannelMessageNotification dto = ImChannelMessageNotification.ofSend(message); | |
| 121 | 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 | 129 | } else { |
| 124 | - webSocketService.broadcastChannelMessageAsync(dto); | |
| 130 | + webSocketService.broadcastNotificationAsync(ImConversationTypeEnum.CHANNEL.getType(), dto.getType(), dto); | |
| 125 | 131 | } |
| 126 | 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 | 98 | */ |
| 99 | 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 | 6 | import cn.hutool.core.util.IdUtil; |
| 7 | 7 | import cn.hutool.core.util.ObjUtil; |
| 8 | 8 | import cn.hutool.extra.spring.SpringUtil; |
| 9 | -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | |
| 10 | 9 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 11 | 10 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; |
| 12 | 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 | 16 | import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO; |
| 18 | 17 | import cn.iocoder.yudao.module.im.dal.dataobject.message.ImGroupMessageDO; |
| 19 | 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 | 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 | 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 | 24 | import cn.iocoder.yudao.module.im.framework.config.ImProperties; |
| 25 | +import cn.iocoder.yudao.module.im.service.conversation.ImConversationReadService; | |
| 26 | 26 | import cn.iocoder.yudao.module.im.service.group.ImGroupMemberService; |
| 27 | 27 | import cn.iocoder.yudao.module.im.service.group.ImGroupService; |
| 28 | 28 | import cn.iocoder.yudao.module.im.service.message.dto.ImGroupMessageSendDTO; |
| 29 | 29 | import cn.iocoder.yudao.module.im.service.sensitiveword.ImSensitiveWordService; |
| 30 | 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 | 36 | import cn.iocoder.yudao.module.im.util.ImMessageUtils; |
| 35 | 37 | import jakarta.annotation.Resource; |
| 36 | 38 | import lombok.extern.slf4j.Slf4j; |
| 39 | +import org.springframework.dao.DuplicateKeyException; | |
| 37 | 40 | import org.springframework.scheduling.annotation.Async; |
| 38 | 41 | import org.springframework.stereotype.Service; |
| 39 | 42 | import org.springframework.transaction.annotation.Transactional; |
| ... | ... | @@ -41,7 +44,6 @@ import org.springframework.validation.annotation.Validated; |
| 41 | 44 | |
| 42 | 45 | import java.time.LocalDateTime; |
| 43 | 46 | import java.util.*; |
| 44 | -import java.util.stream.Collectors; | |
| 45 | 47 | |
| 46 | 48 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 47 | 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 | 59 | @Slf4j |
| 58 | 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 | 62 | @Resource |
| 68 | 63 | private ImGroupMessageMapper groupMessageMapper; |
| 69 | - @Resource | |
| 70 | - private ImGroupMessageReadRedisDAO groupMessageReadRedisDAO; | |
| 71 | 64 | |
| 72 | 65 | @Resource |
| 73 | 66 | private ImGroupService groupService; |
| ... | ... | @@ -75,6 +68,8 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { |
| 75 | 68 | private ImGroupMemberService groupMemberService; |
| 76 | 69 | @Resource |
| 77 | 70 | private ImSensitiveWordService sensitiveWordService; |
| 71 | + @Resource | |
| 72 | + private ImConversationReadService conversationReadService; | |
| 78 | 73 | |
| 79 | 74 | @Resource |
| 80 | 75 | private ImWebSocketService imWebSocketService; |
| ... | ... | @@ -100,34 +95,44 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { |
| 100 | 95 | // 1.4 禁言校验 |
| 101 | 96 | validateMuteStatus(group, senderMember); |
| 102 | 97 | // 1.5 文本消息敏感词过滤 |
| 103 | - if (ImMessageTypeEnum.TEXT.getType().equals(reqVO.getType())) { | |
| 98 | + if (ImContentTypeEnum.TEXT.getType().equals(reqVO.getType())) { | |
| 104 | 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 | 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 | 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 | 124 | return message; |
| 120 | 125 | } |
| 121 | 126 | |
| 122 | 127 | @Override |
| 123 | 128 | public ImGroupMessageDO sendGroupMessage(Long senderId, ImGroupMessageSendDTO dto) { |
| 124 | 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 | 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 | 136 | // 1.1 content 序列化:null / String 透传,POJO 走 JSON |
| 132 | 137 | Object payload = dto.getContent(); |
| 133 | 138 | String contentString = payload == null || payload instanceof String |
| ... | ... | @@ -137,16 +142,18 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { |
| 137 | 142 | ImGroupMessageDO message = new ImGroupMessageDO().setClientMessageId(IdUtil.fastSimpleUUID()) |
| 138 | 143 | .setSenderId(senderId).setGroupId(dto.getGroupId()) |
| 139 | 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 | 147 | .setReceiptStatus(resolveReceiptStatus(dto.getReceipt())); |
| 143 | 148 | // 1.3 按 type.persistent 决定是否入库 |
| 144 | - if (ImMessageTypeEnum.validate(dto.getType()).isPersistent()) { | |
| 149 | + if (ImContentTypeEnum.validate(dto.getType()).isPersistent()) { | |
| 145 | 150 | groupMessageMapper.insert(message); |
| 146 | 151 | } |
| 147 | 152 | |
| 148 | 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 | 157 | return message; |
| 151 | 158 | } |
| 152 | 159 | |
| ... | ... | @@ -180,7 +187,7 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { |
| 180 | 187 | |
| 181 | 188 | // 3. 发送撤回事件 |
| 182 | 189 | return sendGroupMessage(userId, new ImGroupMessageSendDTO().setGroupId(message.getGroupId()) |
| 183 | - .setType(ImMessageTypeEnum.RECALL.getType()) | |
| 190 | + .setType(ImContentTypeEnum.RECALL.getType()) | |
| 184 | 191 | .setReceiverUserIds(message.getReceiverUserIds()) |
| 185 | 192 | .setContent(new RecallMessage().setMessageId(messageId))); |
| 186 | 193 | } |
| ... | ... | @@ -195,155 +202,53 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { |
| 195 | 202 | // 0. 拉取时间窗;超过窗口的老消息不再通过离线通道推送 |
| 196 | 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 | 228 | if (CollUtil.isEmpty(messages)) { |
| 311 | 229 | return; |
| 312 | 230 | } |
| 313 | - // 群已读关闭:不查 Redis 已读游标,status 保持 DB 原值(含撤回),readCount 不补齐 | |
| 231 | + // 群已读关闭:不补 readCount | |
| 314 | 232 | if (BooleanUtil.isFalse(imProperties.getMessage().isGroupReadEnabled())) { |
| 315 | 233 | return; |
| 316 | 234 | } |
| 317 | - Map<Long, Long> readMaxMessageIdsByGroup = new HashMap<>(); // 群 → 已读位置 | |
| 318 | 235 | Map<Long, Map<Long, Long>> readPositionsByGroup = new HashMap<>(); // 群 → (用户 → 已读位置) |
| 319 | 236 | Map<Long, List<ImGroupMemberDO>> membersByGroup = new HashMap<>(); // 群 → 全部成员列表 |
| 320 | 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 | 239 | if (ObjUtil.notEqual(message.getSenderId(), userId) |
| 337 | - || ImGroupMessageReceiptStatusEnum.NO_RECEIPT.getStatus().equals(message.getReceiptStatus())) { | |
| 240 | + || ImMessageReceiptStatusEnum.NO_RECEIPT.getStatus().equals(message.getReceiptStatus())) { | |
| 338 | 241 | continue; |
| 339 | 242 | } |
| 243 | + Long groupId = message.getGroupId(); | |
| 340 | 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 | 252 | uid -> positions.getOrDefault(uid, -1L) >= message.getId() ? 1 : null, |
| 348 | 253 | Integer::sum, 0); |
| 349 | 254 | message.setReadCount(readCount); |
| ... | ... | @@ -357,25 +262,24 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { |
| 357 | 262 | throw exception(MESSAGE_GROUP_READ_DISABLED); |
| 358 | 263 | } |
| 359 | 264 | Assert.notNull(messageId, "已读消息编号不能为空"); |
| 360 | - // 1.1 获取群成员记录 | |
| 361 | - ImGroupMemberDO member = groupMemberService.getGroupMember(groupId, userId); | |
| 362 | - // 1.2 校验消息属于当前群,且对当前用户可见 | |
| 265 | + // 1. 校验消息属于当前群,且对当前用户可见(按快照) | |
| 363 | 266 | ImGroupMessageDO message = groupMessageMapper.selectById(messageId); |
| 364 | 267 | if (message == null |
| 365 | 268 | || ObjUtil.notEqual(message.getGroupId(), groupId) |
| 366 | - || !isMessageVisible(message, member, userId)) { | |
| 269 | + || !isMessageReceived(message, userId)) { | |
| 367 | 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 | 279 | return; |
| 374 | 280 | } |
| 375 | - // 3. 更新 Redis 群已读位置 | |
| 376 | - groupMessageReadRedisDAO.updateReadMaxMessageId(groupId, userId, messageId); | |
| 377 | 281 | |
| 378 | - // 4. 异步发送 READ 事件 + 刷新范围内的群回执 | |
| 282 | + // 3. 异步发送 READ 事件 + 刷新范围内的群回执 | |
| 379 | 283 | getSelf().readGroupMessageEvent(userId, groupId, prevMaxMessageId, messageId); |
| 380 | 284 | } |
| 381 | 285 | |
| ... | ... | @@ -386,13 +290,13 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { |
| 386 | 290 | throw exception(MESSAGE_GROUP_READ_DISABLED); |
| 387 | 291 | } |
| 388 | 292 | // 1.1 校验用户在群中(权限校验) |
| 389 | - ImGroupMemberDO operator = groupMemberService.validateMemberInGroup(groupId, userId); | |
| 293 | + groupMemberService.validateMemberInGroup(groupId, userId); | |
| 390 | 294 | // 1.2 获取消息;并校验消息归属于该群、对调用者可见、调用者是发送方 |
| 391 | 295 | ImGroupMessageDO message = groupMessageMapper.selectById(messageId); |
| 392 | 296 | if (message == null || ObjUtil.notEqual(message.getGroupId(), groupId)) { |
| 393 | 297 | return Collections.emptyList(); |
| 394 | 298 | } |
| 395 | - if (!isMessageVisible(message, operator, userId)) { | |
| 299 | + if (!isMessageReceived(message, userId)) { | |
| 396 | 300 | return Collections.emptyList(); |
| 397 | 301 | } |
| 398 | 302 | // 1.3 仅消息发送方关心已读人数;非发送方查询直接返回空 |
| ... | ... | @@ -400,18 +304,19 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { |
| 400 | 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 | 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 | 316 | // 4. 只返回在可见范围内且已读位置 >= messageId 的用户 |
| 412 | 317 | List<Long> readUserIds = new ArrayList<>(); |
| 413 | 318 | allPositions.forEach((uid, readMaxMessageId) -> { |
| 414 | - if (visibleUserIds.contains(uid) && readMaxMessageId >= messageId) { | |
| 319 | + if (receiverUserIds.contains(uid) && readMaxMessageId >= messageId) { | |
| 415 | 320 | readUserIds.add(uid); |
| 416 | 321 | } |
| 417 | 322 | }); |
| ... | ... | @@ -420,15 +325,14 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { |
| 420 | 325 | |
| 421 | 326 | @Override |
| 422 | 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 | 338 | // ========== 异步 WebSocket 推送 ========== |
| ... | ... | @@ -445,8 +349,9 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { |
| 445 | 349 | @SuppressWarnings("DataFlowIssue") |
| 446 | 350 | public void readGroupMessageEvent(Long userId, Long groupId, Long prevMaxMessageId, Long newMaxMessageId) { |
| 447 | 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 | 356 | // 2. 刷新 (prevMaxMessageId, newMaxMessageId] 区间内的待回执消息 |
| 452 | 357 | List<ImGroupMessageDO> pendingMessages = groupMessageMapper.selectListByGroupIdAndPendingReceipt( |
| ... | ... | @@ -455,28 +360,30 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { |
| 455 | 360 | return; |
| 456 | 361 | } |
| 457 | 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 | 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 | 370 | continue; |
| 465 | 371 | } |
| 466 | - int readCount = getSumValue(visibleUserIds, | |
| 372 | + int readCount = getSumValue(receiverUserIds, | |
| 467 | 373 | uid -> allPositions.getOrDefault(uid, -1L) >= message.getId() ? 1 : null, |
| 468 | 374 | Integer::sum, 0); |
| 469 | 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 | 379 | groupMessageMapper.updateById(new ImGroupMessageDO().setId(message.getId()) |
| 474 | 380 | .setReceiptStatus(newReceiptStatus)); |
| 475 | 381 | } |
| 476 | 382 | |
| 477 | 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 | 394 | * |
| 488 | 395 | * @param reqVO 发送请求 |
| 489 | 396 | * @param senderMember 发送人成员 |
| 397 | + * @param newAudience 新消息可见成员集合(发送当时快照) | |
| 490 | 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 | 402 | // 解析客户端 content 里的 quote.messageId |
| 494 | 403 | Long quoteMessageId = ImMessageUtils.parseQuoteMessageId(reqVO.getContent()); |
| 495 | 404 | |
| ... | ... | @@ -508,12 +417,13 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { |
| 508 | 417 | if (ObjUtil.notEqual(original.getGroupId(), reqVO.getGroupId())) { |
| 509 | 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 | 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 | 427 | throw exception(MESSAGE_QUOTE_INVALID); |
| 518 | 428 | } |
| 519 | 429 | // 构建 quote 对象并注入 content |
| ... | ... | @@ -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 | 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 | 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 | 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 | 494 | @Override |
| ... | ... | @@ -652,11 +523,11 @@ public class ImGroupMessageServiceImpl implements ImGroupMessageService { |
| 652 | 523 | */ |
| 653 | 524 | private Integer resolveReceiptStatus(Boolean receipt) { |
| 654 | 525 | if (BooleanUtil.isFalse(imProperties.getMessage().isGroupReadEnabled())) { |
| 655 | - return ImGroupMessageReceiptStatusEnum.NO_RECEIPT.getStatus(); | |
| 526 | + return ImMessageReceiptStatusEnum.NO_RECEIPT.getStatus(); | |
| 656 | 527 | } |
| 657 | 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 | 59 | /** |
| 60 | 60 | * 标记私聊消息已读 |
| 61 | 61 | * <p> |
| 62 | - * 语义:将「对方发给当前用户、id <= messageId 的未读消息」一次性翻转为已读, | |
| 63 | - * 与群聊 readGroupMessages 对称,避免"select-then-update"两步式带来的竞态。 | |
| 62 | + * 语义:把「对方发给当前用户、id <= messageId 的待回执消息」一次性更新为已完成(DONE)并前进读位置, | |
| 63 | + * 与群聊 readGroupMessages 对称,避免「select-then-update」两步式带来的竞态。 | |
| 64 | 64 | * |
| 65 | 65 | * @param userId 当前用户编号 |
| 66 | 66 | * @param receiverId 接收方用户编号(对方) |
| ... | ... | @@ -72,7 +72,7 @@ public interface ImPrivateMessageService { |
| 72 | 72 | * 查询对方已读到我发的最大消息 id |
| 73 | 73 | * <p> |
| 74 | 74 | * 用于多端 / 离线场景下的已读位置补齐:客户端进入会话或断线重连后, |
| 75 | - * 调用此接口拿到对方的 maxReadId,再按 id <= maxReadId 翻转本地自发消息为已读,弥补离线期间错过的 RECEIPT 推送事件。 | |
| 75 | + * 调用此接口拿到对方的 maxReadId,再按 id <= maxReadId 更新本地自发消息的回执状态,弥补离线期间错过的 RECEIPT 推送事件。 | |
| 76 | 76 | * |
| 77 | 77 | * @param userId 当前用户编号 |
| 78 | 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 | 12 | import cn.iocoder.yudao.module.im.controller.admin.message.vo.privates.ImPrivateMessageSendReqVO; |
| 13 | 13 | import cn.iocoder.yudao.module.im.dal.dataobject.message.ImPrivateMessageDO; |
| 14 | 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 | 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 | 19 | import cn.iocoder.yudao.module.im.framework.config.ImProperties; |
| 20 | +import cn.iocoder.yudao.module.im.service.conversation.ImConversationReadService; | |
| 18 | 21 | import cn.iocoder.yudao.module.im.service.friend.ImFriendService; |
| 19 | 22 | import cn.iocoder.yudao.module.im.service.message.dto.ImPrivateMessageSendDTO; |
| 20 | 23 | import cn.iocoder.yudao.module.im.service.sensitiveword.ImSensitiveWordService; |
| 21 | 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 | 30 | import cn.iocoder.yudao.module.im.util.ImMessageUtils; |
| 26 | 31 | import jakarta.annotation.Resource; |
| 27 | 32 | import lombok.extern.slf4j.Slf4j; |
| 33 | +import org.springframework.dao.DuplicateKeyException; | |
| 28 | 34 | import org.springframework.stereotype.Service; |
| 29 | 35 | import org.springframework.transaction.annotation.Transactional; |
| 30 | 36 | import org.springframework.validation.annotation.Validated; |
| ... | ... | @@ -52,6 +58,8 @@ public class ImPrivateMessageServiceImpl implements ImPrivateMessageService { |
| 52 | 58 | private ImFriendService friendService; |
| 53 | 59 | @Resource |
| 54 | 60 | private ImSensitiveWordService sensitiveWordService; |
| 61 | + @Resource | |
| 62 | + private ImConversationReadService conversationReadService; | |
| 55 | 63 | |
| 56 | 64 | @Resource |
| 57 | 65 | private ImWebSocketService imWebSocketService; |
| ... | ... | @@ -74,21 +82,32 @@ public class ImPrivateMessageServiceImpl implements ImPrivateMessageService { |
| 74 | 82 | // 1.3 好友校验 |
| 75 | 83 | friendService.validateFriend(senderId, reqVO.getReceiverId()); |
| 76 | 84 | // 1.4 文本消息敏感词过滤 |
| 77 | - if (ImMessageTypeEnum.TEXT.getType().equals(reqVO.getType())) { | |
| 85 | + if (ImContentTypeEnum.TEXT.getType().equals(reqVO.getType())) { | |
| 78 | 86 | sensitiveWordService.validateText(reqVO.getContent()); |
| 79 | 87 | } |
| 80 | 88 | |
| 81 | 89 | // 2.1 引用 quote 消息规范化 |
| 82 | 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 | 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 | 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 | 111 | return message; |
| 93 | 112 | } |
| 94 | 113 | |
| ... | ... | @@ -103,24 +122,39 @@ public class ImPrivateMessageServiceImpl implements ImPrivateMessageService { |
| 103 | 122 | ImPrivateMessageDO message = new ImPrivateMessageDO().setClientMessageId(IdUtil.fastSimpleUUID()) |
| 104 | 123 | .setSenderId(senderId).setReceiverId(dto.getReceiverId()) |
| 105 | 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 | 127 | // 1.3 决定是否持久化:dto.persistent 优先;为 null 时按 type 默认 |
| 108 | 128 | boolean persistent = dto.getPersistent() != null |
| 109 | 129 | ? dto.getPersistent() |
| 110 | - : ImMessageTypeEnum.validate(dto.getType()).isPersistent(); | |
| 130 | + : ImContentTypeEnum.validate(dto.getType()).isPersistent(); | |
| 111 | 131 | if (persistent) { |
| 112 | 132 | privateMessageMapper.insert(message); |
| 113 | 133 | } |
| 114 | 134 | |
| 115 | 135 | // 2. WebSocket 异步推送:双向(默认);单边语义(persistent=false)下仅推 sender 多端,对方不感知 |
| 116 | - ImPrivateMessageDTO websocketMessage = ImPrivateMessageDTO.ofSend(message); | |
| 136 | + ImPrivateMessageNotification notification = ImPrivateMessageNotification.ofSend(message); | |
| 117 | 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 | 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 | 158 | @Override |
| 125 | 159 | @Transactional(rollbackFor = Exception.class) |
| 126 | 160 | public ImPrivateMessageDO recallPrivateMessage(Long userId, Long messageId) { |
| ... | ... | @@ -149,7 +183,7 @@ public class ImPrivateMessageServiceImpl implements ImPrivateMessageService { |
| 149 | 183 | |
| 150 | 184 | // 3. 发送撤回事件 |
| 151 | 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 | 245 | throw exception(MESSAGE_PRIVATE_READ_DISABLED); |
| 212 | 246 | } |
| 213 | 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 | 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 | 270 | @Override |
| ... | ... | @@ -232,8 +272,9 @@ public class ImPrivateMessageServiceImpl implements ImPrivateMessageService { |
| 232 | 272 | if (BooleanUtil.isFalse(imProperties.getMessage().isPrivateReadEnabled())) { |
| 233 | 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 | 280 | @Override | ... | ... |
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/message/dto/ImGroupMessageSendDTO.java
| 1 | 1 | package cn.iocoder.yudao.module.im.service.message.dto; |
| 2 | 2 | |
| 3 | 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 | 6 | import jakarta.validation.constraints.NotNull; |
| 7 | 7 | import lombok.Data; |
| 8 | 8 | |
| ... | ... | @@ -26,7 +26,7 @@ public class ImGroupMessageSendDTO { |
| 26 | 26 | /** |
| 27 | 27 | * 消息类型 |
| 28 | 28 | * <p> |
| 29 | - * 枚举 {@link ImMessageTypeEnum} | |
| 29 | + * 枚举 {@link ImContentTypeEnum} | |
| 30 | 30 | */ |
| 31 | 31 | @NotNull(message = "消息类型不能为空") |
| 32 | 32 | private Integer type; |
| ... | ... | @@ -53,30 +53,34 @@ public class ImGroupMessageSendDTO { |
| 53 | 53 | */ |
| 54 | 54 | private Boolean receipt; |
| 55 | 55 | |
| 56 | - // ========== 群广播事件静态工厂(对应 ImMessageTypeEnum 群事件) ========== | |
| 56 | + // ========== 群广播事件静态工厂(对应 ImContentTypeEnum 群事件) ========== | |
| 57 | 57 | |
| 58 | 58 | public static ImGroupMessageSendDTO ofGroupCreate(Long groupId, Long operatorUserId, Collection<Long> memberUserIds) { |
| 59 | 59 | GroupCreateNotification notification = new GroupCreateNotification(); |
| 60 | 60 | notification.setOperatorUserId(operatorUserId); |
| 61 | 61 | notification.setMemberUserIds(new ArrayList<>(memberUserIds)); |
| 62 | 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 | 69 | GroupInfoUpdateNotification notification = new GroupInfoUpdateNotification(); |
| 68 | 70 | notification.setOperatorUserId(operatorUserId); |
| 69 | 71 | notification.setOldAvatar(oldAvatar); |
| 70 | 72 | notification.setNewAvatar(newAvatar); |
| 73 | + notification.setOldJoinApproval(oldJoinApproval); | |
| 74 | + notification.setNewJoinApproval(newJoinApproval); | |
| 71 | 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 | 79 | public static ImGroupMessageSendDTO ofGroupMemberQuit(Long groupId, Long operatorUserId) { |
| 76 | 80 | GroupMemberQuitNotification notification = new GroupMemberQuitNotification(); |
| 77 | 81 | notification.setOperatorUserId(operatorUserId); |
| 78 | 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 | 86 | public static ImGroupMessageSendDTO ofGroupOwnerTransfer(Long groupId, Long operatorUserId, Long newOwnerUserId) { |
| ... | ... | @@ -84,7 +88,7 @@ public class ImGroupMessageSendDTO { |
| 84 | 88 | notification.setOperatorUserId(operatorUserId); |
| 85 | 89 | notification.setNewOwnerUserId(newOwnerUserId); |
| 86 | 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 | 94 | public static ImGroupMessageSendDTO ofGroupMemberKick(Long groupId, Long operatorUserId, Collection<Long> memberUserIds) { |
| ... | ... | @@ -92,7 +96,7 @@ public class ImGroupMessageSendDTO { |
| 92 | 96 | notification.setOperatorUserId(operatorUserId); |
| 93 | 97 | notification.setMemberUserIds(new ArrayList<>(memberUserIds)); |
| 94 | 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 | 102 | public static ImGroupMessageSendDTO ofGroupMemberInvite(Long groupId, Long operatorUserId, Collection<Long> memberUserIds) { |
| ... | ... | @@ -100,7 +104,7 @@ public class ImGroupMessageSendDTO { |
| 100 | 104 | notification.setOperatorUserId(operatorUserId); |
| 101 | 105 | notification.setMemberUserIds(new ArrayList<>(memberUserIds)); |
| 102 | 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 | 110 | public static ImGroupMessageSendDTO ofGroupMemberEnter(Long groupId, Long entrantUserId, Integer addSource) { |
| ... | ... | @@ -109,14 +113,14 @@ public class ImGroupMessageSendDTO { |
| 109 | 113 | notification.setEntrantUserId(entrantUserId); |
| 110 | 114 | notification.setAddSource(addSource); |
| 111 | 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 | 119 | public static ImGroupMessageSendDTO ofGroupDissolve(Long groupId, Long operatorUserId) { |
| 116 | 120 | GroupDissolveNotification notification = new GroupDissolveNotification(); |
| 117 | 121 | notification.setOperatorUserId(operatorUserId); |
| 118 | 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 | 126 | public static ImGroupMessageSendDTO ofGroupMemberNicknameUpdate(Long groupId, Long operatorUserId, String displayUserName) { |
| ... | ... | @@ -124,7 +128,7 @@ public class ImGroupMessageSendDTO { |
| 124 | 128 | notification.setOperatorUserId(operatorUserId); |
| 125 | 129 | notification.setDisplayUserName(displayUserName); |
| 126 | 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 | 134 | public static ImGroupMessageSendDTO ofGroupAdminAdd(Long groupId, Long operatorUserId, Collection<Long> memberUserIds) { |
| ... | ... | @@ -132,7 +136,7 @@ public class ImGroupMessageSendDTO { |
| 132 | 136 | notification.setOperatorUserId(operatorUserId); |
| 133 | 137 | notification.setMemberUserIds(new ArrayList<>(memberUserIds)); |
| 134 | 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 | 142 | public static ImGroupMessageSendDTO ofGroupAdminRemove(Long groupId, Long operatorUserId, Collection<Long> memberUserIds) { |
| ... | ... | @@ -140,7 +144,7 @@ public class ImGroupMessageSendDTO { |
| 140 | 144 | notification.setOperatorUserId(operatorUserId); |
| 141 | 145 | notification.setMemberUserIds(new ArrayList<>(memberUserIds)); |
| 142 | 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 | 150 | public static ImGroupMessageSendDTO ofGroupNoticeUpdate(Long groupId, Long operatorUserId, String oldNotice, String newNotice) { |
| ... | ... | @@ -148,7 +152,7 @@ public class ImGroupMessageSendDTO { |
| 148 | 152 | notification.setOperatorUserId(operatorUserId); |
| 149 | 153 | notification.setOldNotice(oldNotice).setNewNotice(newNotice); |
| 150 | 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 | 158 | public static ImGroupMessageSendDTO ofGroupNameUpdate(Long groupId, Long operatorUserId, String oldName, String newName) { |
| ... | ... | @@ -156,7 +160,7 @@ public class ImGroupMessageSendDTO { |
| 156 | 160 | notification.setOperatorUserId(operatorUserId); |
| 157 | 161 | notification.setOldName(oldName).setNewName(newName); |
| 158 | 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 | 166 | public static ImGroupMessageSendDTO ofGroupMemberSettingUpdate(Long groupId, Long operatorUserId, Boolean silent, String groupRemark) { |
| ... | ... | @@ -164,7 +168,7 @@ public class ImGroupMessageSendDTO { |
| 164 | 168 | notification.setOperatorUserId(operatorUserId); |
| 165 | 169 | notification.setSilent(silent).setGroupRemark(groupRemark); |
| 166 | 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 | 174 | public static ImGroupMessageSendDTO ofGroupMessagePin(Long groupId, Long operatorUserId, ImGroupMessageDO message) { |
| ... | ... | @@ -176,7 +180,7 @@ public class ImGroupMessageSendDTO { |
| 176 | 180 | notification.setOperatorUserId(operatorUserId); |
| 177 | 181 | notification.setMessageId(message.getId()).setMessage(pinnedMessage); |
| 178 | 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 | 186 | public static ImGroupMessageSendDTO ofGroupMessageUnpin(Long groupId, Long operatorUserId, Long messageId) { |
| ... | ... | @@ -184,7 +188,7 @@ public class ImGroupMessageSendDTO { |
| 184 | 188 | notification.setOperatorUserId(operatorUserId); |
| 185 | 189 | notification.setMessageId(messageId); |
| 186 | 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 | 194 | public static ImGroupMessageSendDTO ofGroupMemberMuted(Long groupId, Long operatorUserId, |
| ... | ... | @@ -195,7 +199,7 @@ public class ImGroupMessageSendDTO { |
| 195 | 199 | notification.setMutedUserId(mutedUserId); |
| 196 | 200 | notification.setMuteEndTime(muteEndTime); |
| 197 | 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 | 205 | public static ImGroupMessageSendDTO ofGroupMemberCancelMuted(Long groupId, Long operatorUserId, Long mutedUserId) { |
| ... | ... | @@ -203,21 +207,21 @@ public class ImGroupMessageSendDTO { |
| 203 | 207 | notification.setOperatorUserId(operatorUserId); |
| 204 | 208 | notification.setMutedUserId(mutedUserId); |
| 205 | 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 | 213 | public static ImGroupMessageSendDTO ofGroupMuted(Long groupId, Long operatorUserId) { |
| 210 | 214 | GroupMutedNotification notification = new GroupMutedNotification(); |
| 211 | 215 | notification.setOperatorUserId(operatorUserId); |
| 212 | 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 | 220 | public static ImGroupMessageSendDTO ofGroupCancelMuted(Long groupId, Long operatorUserId) { |
| 217 | 221 | GroupCancelMutedNotification notification = new GroupCancelMutedNotification(); |
| 218 | 222 | notification.setOperatorUserId(operatorUserId); |
| 219 | 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 | 227 | public static ImGroupMessageSendDTO ofGroupBanned(Long groupId, Long operatorUserId, boolean banned) { |
| ... | ... | @@ -225,7 +229,7 @@ public class ImGroupMessageSendDTO { |
| 225 | 229 | notification.setOperatorUserId(operatorUserId); |
| 226 | 230 | notification.setBanned(banned); |
| 227 | 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 | 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 | 4 | import lombok.Data; |
| 5 | 5 | |
| 6 | 6 | /** |
| ... | ... | @@ -18,7 +18,7 @@ public class ImPrivateMessageSendDTO { |
| 18 | 18 | /** |
| 19 | 19 | * 消息类型 |
| 20 | 20 | * <p> |
| 21 | - * 枚举 {@link ImMessageTypeEnum} | |
| 21 | + * 枚举 {@link ImContentTypeEnum} | |
| 22 | 22 | */ |
| 23 | 23 | private Integer type; |
| 24 | 24 | /** |
| ... | ... | @@ -30,10 +30,14 @@ public class ImPrivateMessageSendDTO { |
| 30 | 30 | /** |
| 31 | 31 | * 是否持久化 + 推送给接收方(单边语义开关) |
| 32 | 32 | * <p> |
| 33 | - * null:默认按 {@link ImMessageTypeEnum#isPersistent()} 决定是否入库 + 双向 WS 推送(保持原行为)<br> | |
| 33 | + * null:默认按 {@link ImContentTypeEnum#isPersistent()} 决定是否入库 + 双向 WS 推送(保持原行为)<br> | |
| 34 | 34 | * false:覆盖为单边——不入库、仅推 sender 多端,对方不感知(如「你已删除 XXX」这类仅自己可见的 TIP)<br> |
| 35 | 35 | * true:覆盖为双向 + 入库 |
| 36 | 36 | */ |
| 37 | 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 | 15 | import cn.iocoder.yudao.module.im.dal.mysql.rtc.ImRtcParticipantMapper; |
| 16 | 16 | import cn.iocoder.yudao.module.im.dal.redis.rtc.ImRtcCallLockRedisDAO; |
| 17 | 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 | 19 | import cn.iocoder.yudao.module.im.enums.rtc.ImRtcCallEndReasonEnum; |
| 20 | 20 | import cn.iocoder.yudao.module.im.enums.rtc.ImRtcCallStatusEnum; |
| 21 | 21 | import cn.iocoder.yudao.module.im.enums.rtc.ImRtcParticipantRoleEnum; |
| ... | ... | @@ -30,8 +30,7 @@ import cn.iocoder.yudao.module.im.service.message.ImPrivateMessageService; |
| 30 | 30 | import cn.iocoder.yudao.module.im.service.message.dto.ImGroupMessageSendDTO; |
| 31 | 31 | import cn.iocoder.yudao.module.im.service.message.dto.ImPrivateMessageSendDTO; |
| 32 | 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 | 34 | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; |
| 36 | 35 | import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; |
| 37 | 36 | import jakarta.annotation.Resource; |
| ... | ... | @@ -57,7 +56,7 @@ import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.*; |
| 57 | 56 | * 并发幂等:同好友对 / 同群活跃唯一性走 {@link ImRtcCallLockRedisDAO} 分布式锁 + 锁内 SELECT 兜底;webhook 兜底走条件 UPDATE; |
| 58 | 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 | 60 | * 1602 / 1603 PARTICIPANT_CONNECTED / DISCONNECTED → {@link ImWebSocketService} 推参与方 + 群通话场景广播全群; |
| 62 | 61 | * 1610 RTC_CALL_START + 1611 RTC_CALL_END → {@link ImPrivateMessageService} / {@link ImGroupMessageService} 入消息流当聊天 tip |
| 63 | 62 | * (START 仅群通话;两者分别在 invite / cancel(leave) 事务里 INSERT,自增 id 自然保证顺序) |
| ... | ... | @@ -707,7 +706,6 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { |
| 707 | 706 | } |
| 708 | 707 | |
| 709 | 708 | // 3.1 群通话:推 RTC_CALL(NO_ANSWER) 让前端 banner 移除该人 + 级联关房判定 |
| 710 | - // TODO DONE @AI:拆分独立 NO_ANSWER 信令,不再复用 REJECT | |
| 711 | 709 | if (ImConversationTypeEnum.isGroup(call.getConversationType())) { |
| 712 | 710 | pushCallNoAnswerNotification(call, userId, userMap.get(userId)); |
| 713 | 711 | endSessionIfTerminal(call, userId); |
| ... | ... | @@ -1003,8 +1001,8 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { |
| 1003 | 1001 | String token = signToken(inviteeId, resolveDisplayName(invitee, inviteeId), call.getRoom()); |
| 1004 | 1002 | ImRtcCallNotification payload = ImRtcCallNotification.ofInvite( |
| 1005 | 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 | 1017 | AdminUserRespDTO operator = operatorUserId != null ? adminUserApi.getUser(operatorUserId) : null; |
| 1020 | 1018 | ImRtcCallNotification payload = ImRtcCallNotification.ofReject(call, operatorUserId, operator); |
| 1021 | 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 | 1034 | private void pushCallNoAnswerNotification(ImRtcCallDO call, Long operatorUserId, AdminUserRespDTO operator) { |
| 1037 | 1035 | ImRtcCallNotification payload = ImRtcCallNotification.ofNoAnswer(call, operatorUserId, operator); |
| 1038 | 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 | 1046 | * @param userId 加入的参与者用户编号 |
| 1049 | 1047 | */ |
| 1050 | 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 | 1050 | ImRtcParticipantConnectedNotification.of(call, userId)); |
| 1053 | 1051 | } |
| 1054 | 1052 | |
| ... | ... | @@ -1059,7 +1057,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { |
| 1059 | 1057 | * @param userId 离开的参与者用户编号 |
| 1060 | 1058 | */ |
| 1061 | 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 | 1061 | ImRtcParticipantDisconnectedNotification.of(call, userId)); |
| 1064 | 1062 | } |
| 1065 | 1063 | |
| ... | ... | @@ -1076,8 +1074,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { |
| 1076 | 1074 | if (CollUtil.isEmpty(receivers)) { |
| 1077 | 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 | 1089 | private void pushCallStartNotification(ImRtcCallDO call, AdminUserRespDTO inviter, Set<Long> invitees) { |
| 1093 | 1090 | ImRtcCallStartNotification payload = ImRtcCallStartNotification.of(call, inviter); |
| 1094 | 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 | 1113 | p -> ObjUtil.notEqual(p.getUserId(), call.getInviterUserId())); |
| 1117 | 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 | 1126 | * @param payload 推送 payload |
| 1130 | 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 | 1130 | Long senderId = call.getInviterUserId(); |
| 1134 | 1131 | if (ImConversationTypeEnum.isGroup(call.getConversationType())) { |
| 1135 | 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 | 80 | Map<LocalDateTime, Long> getGroupMessageDailyCountMap(LocalDateTime beginTime, LocalDateTime endTime); |
| 81 | 81 | |
| 82 | 82 | /** |
| 83 | - * 获取区间内消息类型分布 Map(key 为消息类型) | |
| 83 | + * 获取区间内内容类型分布 Map(key 为消息类型) | |
| 84 | 84 | */ |
| 85 | 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 | 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 | 3 | import java.util.Collection; |
| 8 | 4 | import java.util.Collections; |
| 9 | 5 | |
| 10 | 6 | /** |
| 11 | 7 | * IM WebSocket 推送 Service 接口 |
| 12 | 8 | * <p> |
| 13 | - * 统一封装 WebSocket 消息推送,事务内调用时提交后异步执行。 | |
| 9 | + * 统一封装 WebSocket 通知推送,事务内调用时提交后异步执行。 | |
| 14 | 10 | * |
| 15 | 11 | * @author 芋道源码 |
| 16 | 12 | */ |
| 17 | 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 | 2 | |
| 3 | 3 | import cn.hutool.extra.spring.SpringUtil; |
| 4 | 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 | 6 | import cn.iocoder.yudao.module.infra.api.websocket.WebSocketSenderApi; |
| 9 | 7 | import jakarta.annotation.Resource; |
| 10 | 8 | import lombok.extern.slf4j.Slf4j; |
| ... | ... | @@ -36,83 +34,51 @@ public class ImWebSocketServiceImpl implements ImWebSocketService { |
| 36 | 34 | private WebSocketSenderApi webSocketSenderApi; |
| 37 | 35 | |
| 38 | 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 | 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 | 60 | @Async |
| 94 | - public void doSendChannelMessage(Collection<Long> userIds, ImChannelMessageDTO dto) { | |
| 61 | + public void doSendNotification(Collection<Long> userIds, ImNotificationWebSocketDTO notification) { | |
| 95 | 62 | for (Long userId : getDistinctUserIds(userIds)) { |
| 96 | 63 | try { |
| 97 | 64 | webSocketSenderApi.sendObject(UserTypeEnum.ADMIN.getValue(), userId, |
| 98 | - ImChannelMessageDTO.TYPE, dto); | |
| 65 | + ImNotificationWebSocketDTO.TYPE, notification); | |
| 99 | 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 | 75 | @Async |
| 110 | - public void doBroadcastChannelMessage(ImChannelMessageDTO dto) { | |
| 76 | + public void doBroadcastNotification(ImNotificationWebSocketDTO notification) { | |
| 111 | 77 | try { |
| 112 | 78 | webSocketSenderApi.sendObject(UserTypeEnum.ADMIN.getValue(), |
| 113 | - ImChannelMessageDTO.TYPE, dto); | |
| 79 | + ImNotificationWebSocketDTO.TYPE, notification); | |
| 114 | 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 | 87 | } |
| 122 | 88 | |
| 123 | 89 | /** |
| 124 | - * 事务感知的任务调度: | |
| 125 | - * - 有事务:注册 afterCommit 回调,事务提交后再执行,防止客户端拿到消息去查库时数据还没落盘 | |
| 126 | - * - 无事务:直接执行(如非 @Transactional 方法中的调用) | |
| 90 | + * 事务感知的任务调度 | |
| 127 | 91 | * |
| 128 | - * @param task 待执行的推送任务(内部通过 getSelf() 走 @Async 异步执行) | |
| 92 | + * @param task 待执行的推送任务 | |
| 129 | 93 | */ |
| 130 | 94 | private void executeAfterTransaction(Runnable task) { |
| 131 | - // 情况一:没有事务,直接执行 | |
| 132 | 95 | if (!TransactionSynchronizationManager.isSynchronizationActive()) { |
| 133 | 96 | task.run(); |
| 134 | 97 | return; |
| 135 | 98 | } |
| 136 | - // 情况二:有事务,注册 afterCommit 事件,在事务提交后执行 | |
| 137 | 99 | TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() { |
| 138 | 100 | |
| 139 | 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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