Merge branch 'main' into dev

# Conflicts:
#	docs/backstage/IM-Kafka接入方案.md
#	docs/backstage/IM-Kafka接入范围识别.md
#	server/api/admin/imconfiginternal/im_config.go
#	server/api/admin/imuser/im_user.go
#	server/internal/consts/im_kafka.go
#	server/internal/controller/admin/sys/im_user.go
#	server/internal/controller/internalapi/imconfig/im_config.go
#	server/internal/library/imadmin/client.go
#	server/internal/library/imadmin/client_test.go
#	server/internal/library/imadmin/internal.go
#	server/internal/library/imkafka/command.go
#	server/internal/library/imtenant/db.go
#	server/internal/library/imtenant/db_test.go
#	server/internal/library/queue/kafkamq.go
#	server/internal/library/queue/queue.go
#	server/internal/logic/admin/member.go
#	server/internal/logic/sys/im_dead_letter.go
#	server/internal/logic/sys/im_group.go
#	server/internal/logic/sys/im_invite.go
#	server/internal/logic/sys/im_kafka_audit.go
#	server/internal/logic/sys/im_kafka_command.go
#	server/internal/logic/sys/im_tenant.go
#	server/internal/logic/sys/im_user.go
#	server/internal/model/input/sysin/im_group.go
#	server/internal/model/input/sysin/im_invite.go
#	server/internal/model/input/sysin/im_user.go
#	server/internal/queues/im_admin_command_result.go
#	server/internal/queues/im_audit_event.go
#	server/internal/queues/im_dead_letter.go
#	server/internal/service/sys.go
#	server/manifest/config/config.example.yaml
#	server/storage/data/generate/im_group_menu.sql
#	server/storage/data/generate/im_user_menu.sql
#	server/storage/data/im_registration_invite_hotgo.sql
#	web/src/views/im/registrationInvite/BatchViewModal.vue
#	web/src/views/im/registrationInvite/index.vue
#	web/src/views/im/registrationInvite/model.ts
#	web/src/views/imDeadLetter/index.vue
#	web/src/views/imDeadLetter/model.ts
#	web/src/views/imGroup/governance.vue
#	web/src/views/imGroup/members.vue
#	web/src/views/imKafkaAudit/model.ts
#	web/src/views/imKafkaAudit/view.vue
#	web/src/views/imKafkaCommand/index.vue
#	web/src/views/imKafkaCommand/model.ts
#	web/src/views/imKafkaCommand/view.vue
#	web/src/views/imUser/ResetPasswordModal.vue
#	web/src/views/imUser/governance.vue
#	web/src/views/imUser/index.vue
#	web/src/views/imUser/model.ts
#	web/src/views/imUser/view.vue
This commit is contained in:
richjohnrambo
2026-09-13 23:43:51 +08:00
444 changed files with 46212 additions and 2158 deletions
@@ -0,0 +1,16 @@
SET @now := NOW();
SET @imRootId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'imManager' LIMIT 1);
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @imRootId, '举报原因', 'imAbuseReasonIndex', 'abuse-reason/index', '', '2', '', '/imAbuseReason/list', '', '/imAbuseReason/index', '1', 'imManager', '0', '0', '', '0', '0', '0', '2', CONCAT('tr_', @imRootId, ' '), '82', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imAbuseReasonIndex');
SET @imAbuseReasonId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'imAbuseReasonIndex' LIMIT 1);
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @imAbuseReasonId, '原因编辑', 'imAbuseReasonEdit', '', '', '3', '', '/imAbuseReason/edit', '', '', '1', '', '0', '0', '', '0', '0', '0', '3', CONCAT('tr_', @imRootId, ' tr_', @imAbuseReasonId, ' '), '10', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imAbuseReasonEdit');
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @imAbuseReasonId, '原因禁用', 'imAbuseReasonDelete', '', '', '3', '', '/imAbuseReason/delete', '', '', '1', '', '0', '0', '', '0', '0', '0', '3', CONCAT('tr_', @imRootId, ' tr_', @imAbuseReasonId, ' '), '20', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imAbuseReasonDelete');
@@ -0,0 +1,43 @@
SET @now := NOW();
SET @imRootId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'imManager' LIMIT 1);
INSERT INTO `hg_admin_menu` (`id`,`pid`,`title`,`name`,`path`,`icon`,`type`,`redirect`,`permissions`,`permission_name`,`component`,`always_show`,`active_menu`,`is_root`,`is_frame`,`frame_src`,`keep_alive`,`hidden`,`affix`,`level`,`tree`,`sort`,`remark`,`status`,`created_at`,`updated_at`)
SELECT NULL,@imRootId,p.title,p.name,p.path,'','2','',p.permissions,'',p.component,'1','imManager','0','0','','0','0','0','2',CONCAT('tr_',@imRootId,' '),p.sort,'','1',@now,@now
FROM (
SELECT '数据概览' title,'imDashboardIndex' name,'dashboard/index' path,'/imDashboard/overview' permissions,'/imDashboard/index' component,5 sort UNION ALL
SELECT '单聊消息','imPrivateMessageIndex','private-message/index','/imPrivateMessage/list','/imPrivateMessage/index',40 UNION ALL
SELECT '群聊消息','imGroupMessageIndex','group-message/index','/imGroupMessage/list','/imGroupMessage/index',45 UNION ALL
SELECT '用户登录历史','imUserLoginHistoryIndex','user-login-history/index','/imUserLoginHistory/list','/imUserLoginHistory/index',50 UNION ALL
SELECT '登录失败日志','imLoginFailureLogIndex','login-failure-log/index','/imLoginFailureLog/list','/imLoginFailureLog/index',55
) p WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` m WHERE m.`name`=p.name);
UPDATE `hg_admin_menu`
SET `pid`=@imRootId, `icon`='DashboardOutlined', `type`=2, `level`=2,
`tree`=CONCAT('tr_',@imRootId,' '), `sort`=5, `updated_at`=@now
WHERE `name`='imDashboardIndex';
SET @dashboardId := (SELECT `id` FROM `hg_admin_menu` WHERE `name`='imDashboardIndex' LIMIT 1);
SET @privateMessageId := (SELECT `id` FROM `hg_admin_menu` WHERE `name`='imPrivateMessageIndex' LIMIT 1);
SET @groupMessageId := (SELECT `id` FROM `hg_admin_menu` WHERE `name`='imGroupMessageIndex' LIMIT 1);
SET @userLoginId := (SELECT `id` FROM `hg_admin_menu` WHERE `name`='imUserLoginHistoryIndex' LIMIT 1);
SET @loginFailureId := (SELECT `id` FROM `hg_admin_menu` WHERE `name`='imLoginFailureLogIndex' LIMIT 1);
INSERT INTO `hg_admin_menu` (`id`,`pid`,`title`,`name`,`path`,`icon`,`type`,`redirect`,`permissions`,`permission_name`,`component`,`always_show`,`active_menu`,`is_root`,`is_frame`,`frame_src`,`keep_alive`,`hidden`,`affix`,`level`,`tree`,`sort`,`remark`,`status`,`created_at`,`updated_at`)
SELECT NULL,x.pid,x.title,x.name,'','','3','',x.permissions,'','','1','','0','0','','0','0','0','3',CONCAT('tr_',@imRootId,' tr_',x.pid,' '),x.sort,'','1',@now,@now
FROM (
SELECT @dashboardId pid,'查看概览' title,'imDashboardOverview' name,'/imDashboard/overview' permissions,10 sort UNION ALL
SELECT @dashboardId,'查看趋势','imDashboardTrends','/imDashboard/trends',20 UNION ALL
SELECT @privateMessageId,'消息详情','imPrivateMessageView','/imPrivateMessage/view',10 UNION ALL
SELECT @privateMessageId,'隐藏消息','imPrivateMessageHide','/imPrivateMessage/hide',20 UNION ALL
SELECT @privateMessageId,'删除消息','imPrivateMessageDelete','/imPrivateMessage/delete',30 UNION ALL
SELECT @privateMessageId,'导出消息','imPrivateMessageExport','/imPrivateMessage/export',40 UNION ALL
SELECT @groupMessageId,'消息详情','imGroupMessageView','/imGroupMessage/view',10 UNION ALL
SELECT @groupMessageId,'隐藏消息','imGroupMessageHide','/imGroupMessage/hide',20 UNION ALL
SELECT @groupMessageId,'删除消息','imGroupMessageDelete','/imGroupMessage/delete',30 UNION ALL
SELECT @groupMessageId,'导出消息','imGroupMessageExport','/imGroupMessage/export',40 UNION ALL
SELECT @userLoginId,'导出登录历史','imUserLoginHistoryExport','/imUserLoginHistory/export',10 UNION ALL
SELECT @loginFailureId,'失败详情','imLoginFailureLogView','/imLoginFailureLog/view',10 UNION ALL
SELECT @loginFailureId,'导出失败日志','imLoginFailureLogExport','/imLoginFailureLog/export',20 UNION ALL
SELECT @loginFailureId,'加入IP黑名单','imLoginFailureLogAddBlacklist','/imLoginFailureLog/addBlacklist',30 UNION ALL
SELECT @loginFailureId,'封禁关联用户','imLoginFailureLogBanUser','/imLoginFailureLog/banUser',40
) x WHERE x.pid IS NOT NULL AND NOT EXISTS (SELECT 1 FROM `hg_admin_menu` m WHERE m.`name`=x.name);
@@ -0,0 +1,52 @@
SET @now := NOW();
SET @imRootId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'imManager' LIMIT 1);
INSERT INTO `hg_admin_menu` (`id`,`pid`,`title`,`name`,`path`,`icon`,`type`,`redirect`,`permissions`,`permission_name`,`component`,`always_show`,`active_menu`,`is_root`,`is_frame`,`frame_src`,`keep_alive`,`hidden`,`affix`,`level`,`tree`,`sort`,`remark`,`status`,`created_at`,`updated_at`)
SELECT NULL,@imRootId,'用户分组','imUserPolicyGroupIndex','user-policy-group/index','','2','','/imUserPolicyGroup/list','','/imUserPolicyGroup/index','1','imManager','0','0','','0','0','0','2',CONCAT('tr_',@imRootId,' '),'25','','1',@now,@now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name`='imUserPolicyGroupIndex');
SET @policyGroupId := (SELECT `id` FROM `hg_admin_menu` WHERE `name`='imUserPolicyGroupIndex' LIMIT 1);
INSERT INTO `hg_admin_menu` (`id`,`pid`,`title`,`name`,`path`,`icon`,`type`,`redirect`,`permissions`,`permission_name`,`component`,`always_show`,`active_menu`,`is_root`,`is_frame`,`frame_src`,`keep_alive`,`hidden`,`affix`,`level`,`tree`,`sort`,`remark`,`status`,`created_at`,`updated_at`)
SELECT NULL,@policyGroupId,p.title,p.name,'','','3','',p.permissions,'','','1','','0','0','','0','0','0','3',CONCAT('tr_',@imRootId,' tr_',@policyGroupId,' '),p.sort,'','1',@now,@now
FROM (
SELECT '分组详情' title,'imUserPolicyGroupView' name,'/imUserPolicyGroup/view' permissions,10 sort UNION ALL
SELECT '分组编辑','imUserPolicyGroupEdit','/imUserPolicyGroup/edit',20 UNION ALL
SELECT '分组删除','imUserPolicyGroupDelete','/imUserPolicyGroup/delete',30 UNION ALL
SELECT '状态更新','imUserPolicyGroupStatus','/imUserPolicyGroup/status',40 UNION ALL
SELECT '成员列表','imUserPolicyGroupMemberList','/imUserPolicyGroup/memberList',50 UNION ALL
SELECT '添加成员','imUserPolicyGroupMemberAdd','/imUserPolicyGroup/memberAdd',60 UNION ALL
SELECT '移除成员','imUserPolicyGroupMemberRemove','/imUserPolicyGroup/memberRemove',70
) p WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` m WHERE m.`name`=p.name);
INSERT INTO `hg_admin_menu` (`id`,`pid`,`title`,`name`,`path`,`icon`,`type`,`redirect`,`permissions`,`permission_name`,`component`,`always_show`,`active_menu`,`is_root`,`is_frame`,`frame_src`,`keep_alive`,`hidden`,`affix`,`level`,`tree`,`sort`,`remark`,`status`,`created_at`,`updated_at`)
SELECT NULL,@imRootId,'敏感词库','imSensitiveWordIndex','sensitive-word/index','','2','','/imSensitiveWord/list','','/imSensitiveWord/index','1','imManager','0','0','','0','0','0','2',CONCAT('tr_',@imRootId,' '),'90','','1',@now,@now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name`='imSensitiveWordIndex');
SET @sensitiveWordId := (SELECT `id` FROM `hg_admin_menu` WHERE `name`='imSensitiveWordIndex' LIMIT 1);
INSERT INTO `hg_admin_menu` (`id`,`pid`,`title`,`name`,`path`,`icon`,`type`,`redirect`,`permissions`,`permission_name`,`component`,`always_show`,`active_menu`,`is_root`,`is_frame`,`frame_src`,`keep_alive`,`hidden`,`affix`,`level`,`tree`,`sort`,`remark`,`status`,`created_at`,`updated_at`)
SELECT NULL,@sensitiveWordId,p.title,p.name,'','','3','',p.permissions,'','','1','','0','0','','0','0','0','3',CONCAT('tr_',@imRootId,' tr_',@sensitiveWordId,' '),p.sort,'','1',@now,@now
FROM (
SELECT '敏感词编辑' title,'imSensitiveWordEdit' name,'/imSensitiveWord/edit' permissions,10 sort UNION ALL
SELECT '敏感词删除','imSensitiveWordDelete','/imSensitiveWord/delete',20 UNION ALL
SELECT '状态更新','imSensitiveWordStatus','/imSensitiveWord/status',30 UNION ALL
SELECT '批量导入','imSensitiveWordBatchImport','/imSensitiveWord/batchImport',40 UNION ALL
SELECT '分组列表','imSensitiveWordGroupList','/imSensitiveWord/groupList',50 UNION ALL
SELECT '分组编辑','imSensitiveWordGroupEdit','/imSensitiveWord/groupEdit',60
) p WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` m WHERE m.`name`=p.name);
INSERT INTO `hg_admin_menu` (`id`,`pid`,`title`,`name`,`path`,`icon`,`type`,`redirect`,`permissions`,`permission_name`,`component`,`always_show`,`active_menu`,`is_root`,`is_frame`,`frame_src`,`keep_alive`,`hidden`,`affix`,`level`,`tree`,`sort`,`remark`,`status`,`created_at`,`updated_at`)
SELECT NULL,@imRootId,'安全策略','imSecurityPolicyIndex','security-policy/index','','2','','/imSecurityPolicy/list','','/imSecurityPolicy/index','1','imManager','0','0','','0','0','0','2',CONCAT('tr_',@imRootId,' '),'95','','1',@now,@now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name`='imSecurityPolicyIndex');
SET @securityPolicyId := (SELECT `id` FROM `hg_admin_menu` WHERE `name`='imSecurityPolicyIndex' LIMIT 1);
INSERT INTO `hg_admin_menu` (`id`,`pid`,`title`,`name`,`path`,`icon`,`type`,`redirect`,`permissions`,`permission_name`,`component`,`always_show`,`active_menu`,`is_root`,`is_frame`,`frame_src`,`keep_alive`,`hidden`,`affix`,`level`,`tree`,`sort`,`remark`,`status`,`created_at`,`updated_at`)
SELECT NULL,@securityPolicyId,p.title,p.name,'','','3','',p.permissions,'','','1','','0','0','','0','0','0','3',CONCAT('tr_',@imRootId,' tr_',@securityPolicyId,' '),p.sort,'','1',@now,@now
FROM (
SELECT '策略详情' title,'imSecurityPolicyView' name,'/imSecurityPolicy/view' permissions,10 sort UNION ALL
SELECT '保存草稿','imSecurityPolicySave','/imSecurityPolicy/save',20 UNION ALL
SELECT '发布策略','imSecurityPolicyPublish','/imSecurityPolicy/publish',30 UNION ALL
SELECT '恢复默认','imSecurityPolicyRestoreDefault','/imSecurityPolicy/restoreDefault',40 UNION ALL
SELECT 'IP规则列表','imSecurityPolicyIpRuleList','/imSecurityPolicy/ipRuleList',50 UNION ALL
SELECT 'IP规则编辑','imSecurityPolicyIpRuleEdit','/imSecurityPolicy/ipRuleEdit',60 UNION ALL
SELECT 'IP规则删除','imSecurityPolicyIpRuleDelete','/imSecurityPolicy/ipRuleDelete',70
) p WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` m WHERE m.`name`=p.name);
@@ -0,0 +1,12 @@
SET @now := NOW();
SET @imRootId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'imManager' LIMIT 1);
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @imRootId, '版本更新', 'imAppReleaseIndex', 'app-release/index', '', '2', '', '/imAppRelease/list', '', '/imAppRelease/index', '1', 'imManager', '0', '0', '', '0', '0', '0', '2', CONCAT('tr_', @imRootId, ' '), '81', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imAppReleaseIndex');
SET @imAppReleaseId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'imAppReleaseIndex' LIMIT 1);
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @imAppReleaseId, '版本编辑', 'imAppReleaseEdit', '', '', '3', '', '/imAppRelease/edit', '', '', '1', '', '0', '0', '', '0', '0', '0', '3', CONCAT('tr_', @imRootId, ' tr_', @imAppReleaseId, ' '), '10', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imAppReleaseEdit');
@@ -0,0 +1,26 @@
-- Global MeetingIM client release policy. This table belongs to hotgo and is not tenant-scoped.
CREATE TABLE IF NOT EXISTS `im_app_releases` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`platform` VARCHAR(32) NOT NULL,
`channel` VARCHAR(32) NOT NULL DEFAULT 'stable',
`latest_version` VARCHAR(64) NOT NULL,
`min_supported_version` VARCHAR(64) NOT NULL,
`update_type` VARCHAR(16) NOT NULL DEFAULT 'none',
`release_notes` TEXT NOT NULL,
`store_url` VARCHAR(512) NOT NULL DEFAULT '',
`package_url` VARCHAR(512) NOT NULL DEFAULT '',
`checksum` VARCHAR(128) NOT NULL DEFAULT '',
`remind_after_seconds` INT NOT NULL DEFAULT 0,
`published_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
`created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
`updated_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
PRIMARY KEY (`id`),
UNIQUE KEY `uk_im_app_releases_platform_channel` (`platform`, `channel`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='MeetingIM全局客户端版本策略';
INSERT INTO `im_app_releases`
(`platform`, `channel`, `latest_version`, `min_supported_version`, `update_type`, `release_notes`)
VALUES
('ios', 'stable', '1.0.0', '1.0.0', 'none', '当前已是最新版本。'),
('android', 'stable', '1.0.0', '1.0.0', 'none', '当前已是最新版本。')
ON DUPLICATE KEY UPDATE `platform` = VALUES(`platform`);
@@ -29,3 +29,7 @@ SELECT @auditListId := `id` FROM `hg_admin_menu` WHERE `name` = 'imAuditLogIndex
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @auditListId, '审计详情', 'imAuditLogView', '', '', '3', '', '/imAuditLog/view', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT('tr_', @imRootId, ' tr_', @auditDirId, ' tr_', @auditListId, ' '), '10', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imAuditLogView');
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @auditListId, '导出审计日志', 'imAuditLogExport', '', '', '3', '', '/imAuditLog/export', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT('tr_', @imRootId, ' tr_', @auditDirId, ' tr_', @auditListId, ' '), '20', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imAuditLogExport');
@@ -0,0 +1,50 @@
SET @now = NOW();
CREATE TABLE IF NOT EXISTS `im_external_config` (
`id` bigint NOT NULL AUTO_INCREMENT,
`tenant_id` bigint NOT NULL,
`service` varchar(32) NOT NULL,
`provider` varchar(64) NOT NULL DEFAULT '',
`endpoint` varchar(255) NOT NULL DEFAULT '',
`enabled` tinyint NOT NULL DEFAULT 0,
`status` varchar(32) NOT NULL DEFAULT 'unconfigured',
`config_json` json DEFAULT NULL,
`secret_json` json DEFAULT NULL,
`checked_at` datetime DEFAULT NULL,
`check_result` varchar(255) NOT NULL DEFAULT '',
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`created_by` bigint NOT NULL DEFAULT 0,
`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`updated_by` bigint NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_im_external_config_tenant_service` (`tenant_id`,`service`),
KEY `idx_im_external_config_service_status` (`service`,`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
SELECT @imRootId := `id` FROM `hg_admin_menu` WHERE `name` = 'imManager' LIMIT 1;
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, '0', 'IM管理', 'imManager', '/im', '', '1', '/im/tenant/index', '', '', 'LAYOUT', '1', '', '1', '0', '', '0', '0', '0', '1', '', '200', '', '1', @now, @now
WHERE @imRootId IS NULL;
SELECT @imRootId := `id` FROM `hg_admin_menu` WHERE `name` = 'imManager' LIMIT 1;
SELECT @configId := `id` FROM `hg_admin_menu` WHERE `name` = 'imExternalConfigIndex' LIMIT 1;
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @imRootId, '外部服务配置', 'imExternalConfigIndex', 'external-config/index', '', '2', '', '/imExternalConfig/list', '', '/imExternalConfig/index', '1', 'imManager', '0', '0', '', '0', '0', '0', '2', CONCAT('tr_', @imRootId, ' '), '80', '', '1', @now, @now
WHERE @configId IS NULL;
SELECT @configId := `id` FROM `hg_admin_menu` WHERE `name` = 'imExternalConfigIndex' LIMIT 1;
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @configId, '配置详情', 'imExternalConfigView', '', '', '3', '', '/imExternalConfig/view', '', '', '1', '', '0', '0', '', '0', '1', '0', '3', CONCAT('tr_', @imRootId, ' tr_', @configId, ' '), '10', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imExternalConfigView');
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @configId, '更新配置', 'imExternalConfigUpdate', '', '', '3', '', '/imExternalConfig/update', '', '', '1', '', '0', '0', '', '0', '1', '0', '3', CONCAT('tr_', @imRootId, ' tr_', @configId, ' '), '20', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imExternalConfigUpdate');
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @configId, '检查配置', 'imExternalConfigCheck', '', '', '3', '', '/imExternalConfig/check', '', '', '1', '', '0', '0', '', '0', '1', '0', '3', CONCAT('tr_', @imRootId, ' tr_', @configId, ' '), '30', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imExternalConfigCheck');
@@ -0,0 +1,31 @@
SET NAMES utf8mb4;
SET @now := NOW();
INSERT INTO `hg_admin_menu` (`pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT 0, '工作台管理', 'workbenchManager', '/workbench', 'AppstoreOutlined', 1, '/workbench/config/index', '', '', 'LAYOUT', 1, '', 1, 0, '', 0, 0, 0, 1, '', 126, '附加功能独立管理入口', 1, @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'workbenchManager');
SET @workbenchRootId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'workbenchManager' LIMIT 1);
INSERT INTO `hg_admin_menu` (`pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT @workbenchRootId, '意见反馈配置', 'imFeedbackConfigIndex', 'feedback-config/index', '', 2, '', '/imFeedbackConfig/get', '', '/imFeedbackConfig/index', 1, 'workbenchManager', 0, 0, '', 0, 0, 0, 2, CONCAT('tr_', @workbenchRootId, ' '), 40, '', 1, @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imFeedbackConfigIndex');
SET @imFeedbackConfigId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'imFeedbackConfigIndex' LIMIT 1);
UPDATE `hg_admin_menu`
SET `pid`=@workbenchRootId, `path`='feedback-config/index', `active_menu`='workbenchManager',
`level`=2, `tree`=CONCAT('tr_', @workbenchRootId, ' '), `sort`=40,
`status`=1, `hidden`=0, `updated_at`=@now
WHERE `id`=@imFeedbackConfigId;
INSERT INTO `hg_admin_menu` (`pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT @imFeedbackConfigId, '反馈配置更新', 'imFeedbackConfigUpdate', '', '', 3, '', '/imFeedbackConfig/update', '', '', 1, '', 0, 0, '', 0, 1, 0, 3, CONCAT('tr_', @workbenchRootId, ' tr_', @imFeedbackConfigId, ' '), 10, '', 1, @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imFeedbackConfigUpdate');
UPDATE `hg_admin_menu`
SET `level`=3, `tree`=CONCAT('tr_', @workbenchRootId, ' tr_', @imFeedbackConfigId, ' '), `updated_at`=@now
WHERE `pid`=@imFeedbackConfigId AND `type`=3;
INSERT IGNORE INTO `hg_admin_role_menu` (`role_id`, `menu_id`)
SELECT `role_id`, @workbenchRootId FROM `hg_admin_role_menu` WHERE `menu_id`=@imFeedbackConfigId;
@@ -0,0 +1,33 @@
SET @now = NOW();
SELECT @imRootId := `id` FROM `hg_admin_menu` WHERE `name` = 'imManager' LIMIT 1;
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, '0', 'IM管理', 'imManager', '/im', '', '1', '/im/tenant/index', '', '', 'LAYOUT', '1', '', '1', '0', '', '0', '0', '0', '1', '', '200', '', '1', @now, @now
WHERE @imRootId IS NULL;
SELECT @imRootId := `id` FROM `hg_admin_menu` WHERE `name` = 'imManager' LIMIT 1;
SELECT @fileId := `id` FROM `hg_admin_menu` WHERE `name` = 'imFileIndex' LIMIT 1;
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @imRootId, '文件治理', 'imFileIndex', 'file/index', '', '2', '', '/imFile/list', '', '/imFile/index', '1', 'imManager', '0', '0', '', '0', '0', '0', '2', CONCAT('tr_', @imRootId, ' '), '70', '', '1', @now, @now
WHERE @fileId IS NULL;
SELECT @fileId := `id` FROM `hg_admin_menu` WHERE `name` = 'imFileIndex' LIMIT 1;
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @fileId, '文件详情', 'imFileView', '', '', '3', '', '/imFile/view', '', '', '1', '', '0', '0', '', '0', '1', '0', '3', CONCAT('tr_', @imRootId, ' tr_', @fileId, ' '), '10', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imFileView');
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @fileId, '隔离文件', 'imFileQuarantine', '', '', '3', '', '/imFile/quarantine', '', '', '1', '', '0', '0', '', '0', '1', '0', '3', CONCAT('tr_', @imRootId, ' tr_', @fileId, ' '), '20', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imFileQuarantine');
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @fileId, '删除文件', 'imFileDelete', '', '', '3', '', '/imFile/delete', '', '', '1', '', '0', '0', '', '0', '1', '0', '3', CONCAT('tr_', @imRootId, ' tr_', @fileId, ' '), '30', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imFileDelete');
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @fileId, '清理孤儿文件', 'imFileCleanupOrphan', '', '', '3', '', '/imFile/cleanupOrphan', '', '', '1', '', '0', '0', '', '0', '1', '0', '3', CONCAT('tr_', @imRootId, ' tr_', @fileId, ' '), '40', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imFileCleanupOrphan');
@@ -0,0 +1,31 @@
SET @now := NOW();
SET @imRootId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'imManager' LIMIT 1);
CREATE TABLE IF NOT EXISTS `im_file_policy` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`tenant_id` BIGINT NOT NULL,
`purpose` VARCHAR(64) NOT NULL,
`max_size` BIGINT NOT NULL DEFAULT 0,
`retention_days` INT NOT NULL DEFAULT 0,
`allowed_mimes` JSON DEFAULT NULL,
`auto_cleanup` TINYINT NOT NULL DEFAULT 0,
`scan_enabled` TINYINT NOT NULL DEFAULT 0,
`remark` VARCHAR(255) NOT NULL DEFAULT '',
`created_by` BIGINT DEFAULT NULL,
`updated_by` BIGINT DEFAULT NULL,
`created_at` DATETIME DEFAULT NULL,
`updated_at` DATETIME DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_im_file_policy_tenant_purpose` (`tenant_id`, `purpose`),
KEY `idx_im_file_policy_tenant_cleanup` (`tenant_id`, `auto_cleanup`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='IM文件用途策略';
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @imRootId, '文件策略', 'imFilePolicyIndex', 'file-policy/index', '', '2', '', '/imFilePolicy/list', '', '/imFilePolicy/index', '1', 'imManager', '0', '0', '', '0', '0', '0', '2', CONCAT('tr_', @imRootId, ' '), '73', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imFilePolicyIndex');
SET @imFilePolicyId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'imFilePolicyIndex' LIMIT 1);
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @imFilePolicyId, '策略更新', 'imFilePolicyUpdate', '', '', '3', '', '/imFilePolicy/update', '', '', '1', '', '0', '0', '', '0', '0', '0', '3', CONCAT('tr_', @imRootId, ' tr_', @imFilePolicyId, ' '), '10', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imFilePolicyUpdate');
@@ -89,3 +89,13 @@ WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imGroupMemberRem
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @groupListId, '转让群主', 'imGroupOwnerTransfer', '', '', '3', '', '/imGroup/ownerTransfer', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT('tr_', @imRootId, ' tr_', @groupDirId, ' tr_', @groupListId, ' '), '160', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imGroupOwnerTransfer');
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @groupListId, '解散群', 'imGroupDissolve', '', '', '3', '', '/imGroup/dissolve', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT('tr_', @imRootId, ' tr_', @groupDirId, ' tr_', @groupListId, ' '), '170', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imGroupDissolve');
INSERT IGNORE INTO `hg_admin_role_menu` (`role_id`, `menu_id`)
SELECT source_role.`role_id`, dissolve_menu.`id`
FROM `hg_admin_role_menu` source_role
JOIN `hg_admin_menu` governance_update ON governance_update.`id` = source_role.`menu_id` AND governance_update.`name` = 'imGroupGovernanceUpdate'
JOIN `hg_admin_menu` dissolve_menu ON dissolve_menu.`name` = 'imGroupDissolve';
@@ -0,0 +1,31 @@
SET NAMES utf8mb4;
SET @now := NOW();
INSERT INTO `hg_admin_menu` (`pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT 0, '工作台管理', 'workbenchManager', '/workbench', 'AppstoreOutlined', 1, '/workbench/config/index', '', '', 'LAYOUT', 1, '', 1, 0, '', 0, 0, 0, 1, '', 126, '附加功能独立管理入口', 1, @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'workbenchManager');
SET @workbenchRootId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'workbenchManager' LIMIT 1);
INSERT INTO `hg_admin_menu` (`pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT @workbenchRootId, '总经理信箱配置', 'imMailboxConfigIndex', 'mailbox-config/index', '', 2, '', '/imMailboxConfig/get', '', '/imMailboxConfig/index', 1, 'workbenchManager', 0, 0, '', 0, 0, 0, 2, CONCAT('tr_', @workbenchRootId, ' '), 30, '', 1, @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imMailboxConfigIndex');
SET @imMailboxConfigId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'imMailboxConfigIndex' LIMIT 1);
UPDATE `hg_admin_menu`
SET `pid`=@workbenchRootId, `path`='mailbox-config/index', `active_menu`='workbenchManager',
`level`=2, `tree`=CONCAT('tr_', @workbenchRootId, ' '), `sort`=30,
`status`=1, `hidden`=0, `updated_at`=@now
WHERE `id`=@imMailboxConfigId;
INSERT INTO `hg_admin_menu` (`pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT @imMailboxConfigId, '信箱配置更新', 'imMailboxConfigUpdate', '', '', 3, '', '/imMailboxConfig/update', '', '', 1, '', 0, 0, '', 0, 1, 0, 3, CONCAT('tr_', @workbenchRootId, ' tr_', @imMailboxConfigId, ' '), 10, '', 1, @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imMailboxConfigUpdate');
UPDATE `hg_admin_menu`
SET `level`=3, `tree`=CONCAT('tr_', @workbenchRootId, ' tr_', @imMailboxConfigId, ' '), `updated_at`=@now
WHERE `pid`=@imMailboxConfigId AND `type`=3;
INSERT IGNORE INTO `hg_admin_role_menu` (`role_id`, `menu_id`)
SELECT `role_id`, @workbenchRootId FROM `hg_admin_role_menu` WHERE `menu_id`=@imMailboxConfigId;
@@ -0,0 +1,112 @@
-- Organize all visible IM admin pages under the GedaDa menu hierarchy.
-- This script is idempotent and preserves page/button menu IDs and permissions.
SET NAMES utf8mb4;
SET @now := NOW();
SET @imRootId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'imManager' LIMIT 1);
INSERT INTO `hg_admin_menu` (`pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT @imRootId, '用户与群组', 'imUserAndGroup', 'people', 'TeamOutlined', 1, '/im/people/user/index', '', '', 'ParentLayout', 1, '', 0, 0, '', 0, 0, 0, 2, CONCAT('tr_', @imRootId, ' '), 10, '', 1, @now, @now
WHERE @imRootId IS NOT NULL AND NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imUserAndGroup');
INSERT INTO `hg_admin_menu` (`pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT @imRootId, '内容审核', 'imContentAudit', 'content', 'FileSearchOutlined', 1, '/im/content/private-message/index', '', '', 'ParentLayout', 1, '', 0, 0, '', 0, 0, 0, 2, CONCAT('tr_', @imRootId, ' '), 20, '', 1, @now, @now
WHERE @imRootId IS NOT NULL AND NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imContentAudit');
INSERT INTO `hg_admin_menu` (`pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT @imRootId, '日志审计', 'imLogAudit', 'audit', 'AuditOutlined', 1, '/im/audit/operation/index', '', '', 'ParentLayout', 1, '', 0, 0, '', 0, 0, 0, 2, CONCAT('tr_', @imRootId, ' '), 30, '', 1, @now, @now
WHERE @imRootId IS NOT NULL AND NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imLogAudit');
INSERT INTO `hg_admin_menu` (`pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT @imRootId, '系统设置', 'imSystemSettings', 'settings', 'SettingOutlined', 1, '/im/settings/tenant/index', '', '', 'ParentLayout', 1, '', 0, 0, '', 0, 0, 0, 2, CONCAT('tr_', @imRootId, ' '), 40, '', 1, @now, @now
WHERE @imRootId IS NOT NULL AND NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imSystemSettings');
SET @peopleId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'imUserAndGroup' LIMIT 1);
SET @contentId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'imContentAudit' LIMIT 1);
SET @auditId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'imLogAudit' LIMIT 1);
SET @settingsId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'imSystemSettings' LIMIT 1);
UPDATE `hg_admin_menu` SET `pid`=@imRootId, `title`='用户与群组', `path`='people', `icon`='TeamOutlined', `type`=1, `redirect`='/im/people/user/index', `component`='ParentLayout', `always_show`=1, `hidden`=0, `status`=1, `level`=2, `tree`=CONCAT('tr_', @imRootId, ' '), `sort`=10, `updated_at`=@now WHERE `id`=@peopleId;
UPDATE `hg_admin_menu` SET `pid`=@imRootId, `title`='内容审核', `path`='content', `icon`='FileSearchOutlined', `type`=1, `redirect`='/im/content/private-message/index', `component`='ParentLayout', `always_show`=1, `hidden`=0, `status`=1, `level`=2, `tree`=CONCAT('tr_', @imRootId, ' '), `sort`=20, `updated_at`=@now WHERE `id`=@contentId;
UPDATE `hg_admin_menu` SET `pid`=@imRootId, `title`='日志审计', `path`='audit', `icon`='AuditOutlined', `type`=1, `redirect`='/im/audit/operation/index', `component`='ParentLayout', `always_show`=1, `hidden`=0, `status`=1, `level`=2, `tree`=CONCAT('tr_', @imRootId, ' '), `sort`=30, `updated_at`=@now WHERE `id`=@auditId;
UPDATE `hg_admin_menu` SET `pid`=@imRootId, `title`='系统设置', `path`='settings', `icon`='SettingOutlined', `type`=1, `redirect`='/im/settings/tenant/index', `component`='ParentLayout', `always_show`=1, `hidden`=0, `status`=1, `level`=2, `tree`=CONCAT('tr_', @imRootId, ' '), `sort`=40, `updated_at`=@now WHERE `id`=@settingsId;
UPDATE `hg_admin_menu` SET `pid`=@imRootId, `icon`='DashboardOutlined', `type`=2, `level`=2, `tree`=CONCAT('tr_', @imRootId, ' '), `sort`=5, `updated_at`=@now WHERE `name`='imDashboardIndex';
UPDATE `hg_admin_menu` SET `redirect`='/im/dashboard/index', `updated_at`=@now WHERE `id`=@imRootId;
-- User and group management.
UPDATE `hg_admin_menu` SET `pid`=@peopleId, `title`='用户管理', `path`='user/index', `level`=3, `tree`=CONCAT('tr_', @imRootId, ' tr_', @peopleId, ' '), `sort`=10, `updated_at`=@now WHERE `name`='imUserIndex';
UPDATE `hg_admin_menu` SET `pid`=@peopleId, `path`='user-policy-group/index', `level`=3, `tree`=CONCAT('tr_', @imRootId, ' tr_', @peopleId, ' '), `sort`=20, `updated_at`=@now WHERE `name`='imUserPolicyGroupIndex';
UPDATE `hg_admin_menu` SET `pid`=@peopleId, `title`='群组管理', `path`='group/index', `level`=3, `tree`=CONCAT('tr_', @imRootId, ' tr_', @peopleId, ' '), `sort`=30, `updated_at`=@now WHERE `name`='imGroupIndex';
UPDATE `hg_admin_menu` SET `pid`=@peopleId, `title`='邀请码管理', `path`='registration-invite/index', `level`=3, `tree`=CONCAT('tr_', @imRootId, ' tr_', @peopleId, ' '), `sort`=50, `updated_at`=@now WHERE `name`='imRegistrationInviteIndex';
-- Content review.
UPDATE `hg_admin_menu` SET `pid`=@contentId, `path`='private-message/index', `level`=3, `tree`=CONCAT('tr_', @imRootId, ' tr_', @contentId, ' '), `sort`=10, `updated_at`=@now WHERE `name`='imPrivateMessageIndex';
UPDATE `hg_admin_menu` SET `pid`=@contentId, `path`='group-message/index', `level`=3, `tree`=CONCAT('tr_', @imRootId, ' tr_', @contentId, ' '), `sort`=20, `updated_at`=@now WHERE `name`='imGroupMessageIndex';
UPDATE `hg_admin_menu` SET `pid`=@contentId, `path`='sensitive-word/index', `level`=3, `tree`=CONCAT('tr_', @imRootId, ' tr_', @contentId, ' '), `sort`=30, `updated_at`=@now WHERE `name`='imSensitiveWordIndex';
UPDATE `hg_admin_menu` SET `pid`=@contentId, `title`='文件管理', `path`='file/index', `level`=3, `tree`=CONCAT('tr_', @imRootId, ' tr_', @contentId, ' '), `sort`=40, `updated_at`=@now WHERE `name`='imFileIndex';
UPDATE `hg_admin_menu` SET `pid`=@contentId, `title`='用户反馈', `path`='feedback/index', `level`=3, `tree`=CONCAT('tr_', @imRootId, ' tr_', @contentId, ' '), `sort`=50, `updated_at`=@now WHERE `name`='imWorkOrderIndex';
UPDATE `hg_admin_menu` SET `pid`=@contentId, `title`='实名审核', `path`='realname/index', `level`=3, `tree`=CONCAT('tr_', @imRootId, ' tr_', @contentId, ' '), `sort`=60, `updated_at`=@now WHERE `name`='imRealnameIndex';
UPDATE `hg_admin_menu` SET `pid`=@contentId, `path`='abuse-reason/index', `level`=3, `tree`=CONCAT('tr_', @imRootId, ' tr_', @contentId, ' '), `sort`=70, `updated_at`=@now WHERE `name`='imAbuseReasonIndex';
-- Logs, audit and operations.
UPDATE `hg_admin_menu` SET `pid`=@auditId, `title`='操作日志', `path`='operation/index', `level`=3, `tree`=CONCAT('tr_', @imRootId, ' tr_', @auditId, ' '), `sort`=10, `updated_at`=@now WHERE `name`='imAuditLogIndex';
UPDATE `hg_admin_menu` SET `pid`=@auditId, `title`='用户登录', `path`='user-login/index', `level`=3, `tree`=CONCAT('tr_', @imRootId, ' tr_', @auditId, ' '), `sort`=20, `updated_at`=@now WHERE `name`='imUserLoginHistoryIndex';
UPDATE `hg_admin_menu` SET `pid`=@auditId, `path`='login-failure/index', `level`=3, `tree`=CONCAT('tr_', @imRootId, ' tr_', @auditId, ' '), `sort`=30, `updated_at`=@now WHERE `name`='imLoginFailureLogIndex';
UPDATE `hg_admin_menu` SET `pid`=@auditId, `path`='kafka-audit/index', `level`=3, `tree`=CONCAT('tr_', @imRootId, ' tr_', @auditId, ' '), `sort`=40, `updated_at`=@now WHERE `name`='imKafkaAuditIndex';
UPDATE `hg_admin_menu` SET `pid`=@auditId, `title`='事件队列', `path`='outbox/index', `level`=3, `tree`=CONCAT('tr_', @imRootId, ' tr_', @auditId, ' '), `sort`=50, `updated_at`=@now WHERE `name`='imOutboxIndex';
UPDATE `hg_admin_menu` SET `pid`=@auditId, `path`='kafka-command/index', `level`=3, `tree`=CONCAT('tr_', @imRootId, ' tr_', @auditId, ' '), `sort`=60, `updated_at`=@now WHERE `name`='imKafkaCommandIndex';
UPDATE `hg_admin_menu` SET `pid`=@auditId, `path`='dead-letter/index', `level`=3, `tree`=CONCAT('tr_', @imRootId, ' tr_', @auditId, ' '), `sort`=70, `updated_at`=@now WHERE `name`='imDeadLetterIndex';
UPDATE `hg_admin_menu` SET `pid`=@auditId, `path`='task-dashboard/index', `level`=3, `tree`=CONCAT('tr_', @imRootId, ' tr_', @auditId, ' '), `sort`=80, `updated_at`=@now WHERE `name`='imTaskDashboardIndex';
-- System and tenant settings.
UPDATE `hg_admin_menu` SET `pid`=@settingsId, `title`='商户管理', `path`='tenant/index', `level`=3, `tree`=CONCAT('tr_', @imRootId, ' tr_', @settingsId, ' '), `sort`=10, `updated_at`=@now WHERE `name`='imTenantIndex';
UPDATE `hg_admin_menu` SET `pid`=@settingsId, `path`='security-policy/index', `level`=3, `tree`=CONCAT('tr_', @imRootId, ' tr_', @settingsId, ' '), `sort`=20, `updated_at`=@now WHERE `name`='imSecurityPolicyIndex';
UPDATE `hg_admin_menu` SET `pid`=@settingsId, `path`='file-policy/index', `level`=3, `tree`=CONCAT('tr_', @imRootId, ' tr_', @settingsId, ' '), `sort`=30, `updated_at`=@now WHERE `name`='imFilePolicyIndex';
UPDATE `hg_admin_menu` SET `pid`=@settingsId, `path`='external-config/index', `level`=3, `tree`=CONCAT('tr_', @imRootId, ' tr_', @settingsId, ' '), `sort`=50, `updated_at`=@now WHERE `name`='imExternalConfigIndex';
UPDATE `hg_admin_menu` SET `pid`=@settingsId, `path`='notification/index', `level`=3, `tree`=CONCAT('tr_', @imRootId, ' tr_', @settingsId, ' '), `sort`=60, `updated_at`=@now WHERE `name`='imNotificationIndex';
UPDATE `hg_admin_menu` SET `pid`=@settingsId, `path`='app-release/index', `level`=3, `tree`=CONCAT('tr_', @imRootId, ' tr_', @settingsId, ' '), `sort`=70, `updated_at`=@now WHERE `name`='imAppReleaseIndex';
-- Remove one-page wrapper directories after their page has been moved.
UPDATE `hg_admin_menu` SET `status`=2, `hidden`=1, `updated_at`=@now
WHERE `name` IN ('imUser', 'imGroup', 'imTenant', 'imRealname', 'imWorkOrder', 'imAuditLog', 'imOutbox');
-- Rebuild button ancestry beneath the moved pages.
UPDATE `hg_admin_menu` child
JOIN `hg_admin_menu` page ON page.`id` = child.`pid`
SET child.`level` = page.`level` + 1,
child.`tree` = CONCAT(page.`tree`, 'tr_', page.`id`, ' '),
child.`updated_at` = @now
WHERE page.`pid` IN (@peopleId, @contentId, @auditId, @settingsId)
AND child.`type` = 3;
-- Give roles that already own pages in a section access to the new directory.
INSERT INTO `hg_admin_role_menu` (`role_id`, `menu_id`)
SELECT DISTINCT rm.`role_id`, section.`id`
FROM `hg_admin_role_menu` rm
JOIN `hg_admin_menu` page ON page.`id` = rm.`menu_id`
JOIN `hg_admin_menu` section ON section.`id` = page.`pid`
LEFT JOIN `hg_admin_role_menu` existing ON existing.`role_id` = rm.`role_id` AND existing.`menu_id` = section.`id`
WHERE section.`id` IN (@peopleId, @contentId, @auditId, @settingsId)
AND existing.`menu_id` IS NULL;
-- Optional features use their own top-level menu and can be replaced independently.
INSERT INTO `hg_admin_menu` (`pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT 0, '工作台管理', 'workbenchManager', '/workbench', 'AppstoreOutlined', 1, '/workbench/config/index', '', '', 'LAYOUT', 1, '', 1, 0, '', 0, 0, 0, 1, '', 126, '附加功能独立管理入口', 1, @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'workbenchManager');
SET @workbenchRootId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'workbenchManager' LIMIT 1);
SET @workbenchId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'imWorkbenchIndex' LIMIT 1);
SET @orgId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'imOrgIndex' LIMIT 1);
SET @mailboxConfigId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'imMailboxConfigIndex' LIMIT 1);
SET @feedbackConfigId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'imFeedbackConfigIndex' LIMIT 1);
UPDATE `hg_admin_menu` SET `pid`=0, `title`='工作台管理', `path`='/workbench', `icon`='AppstoreOutlined', `type`=1, `redirect`='/workbench/config/index', `component`='LAYOUT', `always_show`=1, `active_menu`='', `is_root`=1, `hidden`=0, `level`=1, `tree`=CONCAT('tr_', `id`, ' '), `sort`=126, `status`=1, `updated_at`=@now WHERE `id`=@workbenchRootId;
UPDATE `hg_admin_menu` SET `pid`=@workbenchRootId, `title`='工作台配置', `path`='config/index', `active_menu`='workbenchManager', `level`=2, `tree`=CONCAT('tr_', @workbenchRootId, ' '), `sort`=10, `status`=1, `hidden`=0, `updated_at`=@now WHERE `id`=@workbenchId;
UPDATE `hg_admin_menu` SET `pid`=@workbenchRootId, `title`='组织架构', `path`='org/index', `active_menu`='workbenchManager', `level`=2, `tree`=CONCAT('tr_', @workbenchRootId, ' '), `sort`=20, `status`=1, `hidden`=0, `updated_at`=@now WHERE `id`=@orgId;
UPDATE `hg_admin_menu` SET `pid`=@workbenchRootId, `path`='mailbox-config/index', `active_menu`='workbenchManager', `level`=2, `tree`=CONCAT('tr_', @workbenchRootId, ' '), `sort`=30, `status`=1, `hidden`=0, `updated_at`=@now WHERE `id`=@mailboxConfigId;
UPDATE `hg_admin_menu` SET `pid`=@workbenchRootId, `path`='feedback-config/index', `active_menu`='workbenchManager', `level`=2, `tree`=CONCAT('tr_', @workbenchRootId, ' '), `sort`=40, `status`=1, `hidden`=0, `updated_at`=@now WHERE `id`=@feedbackConfigId;
UPDATE `hg_admin_menu` SET `level`=3, `tree`=CONCAT('tr_', @workbenchRootId, ' tr_', @workbenchId, ' '), `updated_at`=@now WHERE `pid`=@workbenchId AND `type`=3;
UPDATE `hg_admin_menu` child JOIN `hg_admin_menu` page ON page.`id`=child.`pid` SET child.`level`=3, child.`tree`=CONCAT('tr_', @workbenchRootId, ' tr_', page.`id`, ' '), child.`updated_at`=@now WHERE page.`id` IN (@orgId, @mailboxConfigId, @feedbackConfigId) AND child.`type`=3;
INSERT IGNORE INTO `hg_admin_role_menu` (`role_id`, `menu_id`)
SELECT `role_id`, @workbenchRootId FROM `hg_admin_role_menu` WHERE `menu_id` IN (@workbenchId, @orgId, @mailboxConfigId, @feedbackConfigId);
@@ -0,0 +1,119 @@
SET NAMES utf8mb4;
UPDATE `hg_admin_menu` SET `title` = 'IM管理' WHERE `name` = 'imManager';
UPDATE `hg_admin_menu` SET `title` = '商户管理' WHERE `name` = 'imTenant';
UPDATE `hg_admin_menu` SET `title` = '商户列表' WHERE `name` = 'imTenantIndex';
UPDATE `hg_admin_menu` SET `title` = '商户详情' WHERE `name` = 'imTenantView';
UPDATE `hg_admin_menu` SET `title` = '新增/编辑商户' WHERE `name` = 'imTenantEdit';
UPDATE `hg_admin_menu` SET `title` = '启用/停用商户' WHERE `name` = 'imTenantStatus';
UPDATE `hg_admin_menu` SET `title` = '商户用量统计' WHERE `name` = 'imTenantUsage';
UPDATE `hg_admin_menu` SET `title` = '商户删除检查' WHERE `name` = 'imTenantDeletionCheck';
UPDATE `hg_admin_menu` SET `title` = '进入删除保护期' WHERE `name` = 'imTenantEnterDeleting';
UPDATE `hg_admin_menu` SET `title` = '恢复商户' WHERE `name` = 'imTenantRestore';
UPDATE `hg_admin_menu` SET `title` = '用户管理' WHERE `name` = 'imUser';
UPDATE `hg_admin_menu` SET `title` = '用户列表' WHERE `name` = 'imUserIndex';
UPDATE `hg_admin_menu` SET `title` = '用户详情' WHERE `name` = 'imUserView';
UPDATE `hg_admin_menu` SET `title` = '重置密码' WHERE `name` = 'imUserResetPassword';
UPDATE `hg_admin_menu` SET `title` = '封禁用户' WHERE `name` = 'imUserBan';
UPDATE `hg_admin_menu` SET `title` = '解封用户' WHERE `name` = 'imUserUnban';
UPDATE `hg_admin_menu` SET `title` = '冻结用户' WHERE `name` = 'imUserFreeze';
UPDATE `hg_admin_menu` SET `title` = '解冻用户' WHERE `name` = 'imUserUnfreeze';
UPDATE `hg_admin_menu` SET `title` = '踢出设备' WHERE `name` = 'imUserDeviceKick';
UPDATE `hg_admin_menu` SET `title` = '退出所有设备' WHERE `name` = 'imUserLogoutAll';
UPDATE `hg_admin_menu` SET `title` = '注销账号' WHERE `name` = 'imUserAccountCancel';
UPDATE `hg_admin_menu` SET `title` = '删除账号' WHERE `name` = 'imUserAccountDelete';
UPDATE `hg_admin_menu` SET `title` = '群组管理' WHERE `name` = 'imGroup';
UPDATE `hg_admin_menu` SET `title` = '群组列表' WHERE `name` = 'imGroupIndex';
UPDATE `hg_admin_menu` SET `title` = '群组详情' WHERE `name` = 'imGroupView';
UPDATE `hg_admin_menu` SET `title` = '群成员列表' WHERE `name` = 'imGroupMemberList';
UPDATE `hg_admin_menu` SET `title` = '群治理配置' WHERE `name` = 'imGroupGovernance';
UPDATE `hg_admin_menu` SET `title` = '入群审批列表' WHERE `name` = 'imGroupJoinRequestList';
UPDATE `hg_admin_menu` SET `title` = '群邀请列表' WHERE `name` = 'imGroupInvitationList';
UPDATE `hg_admin_menu` SET `title` = '群公告列表' WHERE `name` = 'imGroupAnnouncementList';
UPDATE `hg_admin_menu` SET `title` = '群禁言列表' WHERE `name` = 'imGroupMuteList';
UPDATE `hg_admin_menu` SET `title` = '群管理日志' WHERE `name` = 'imGroupAdminLogList';
UPDATE `hg_admin_menu` SET `title` = '更新群资料' WHERE `name` = 'imGroupProfileUpdate';
UPDATE `hg_admin_menu` SET `title` = '更新群治理配置' WHERE `name` = 'imGroupGovernanceUpdate';
UPDATE `hg_admin_menu` SET `title` = '设置群管理员' WHERE `name` = 'imGroupAdminSet';
UPDATE `hg_admin_menu` SET `title` = '移除群管理员' WHERE `name` = 'imGroupAdminRemove';
UPDATE `hg_admin_menu` SET `title` = '禁言群成员' WHERE `name` = 'imGroupMemberMute';
UPDATE `hg_admin_menu` SET `title` = '解除群成员禁言' WHERE `name` = 'imGroupMemberUnmute';
UPDATE `hg_admin_menu` SET `title` = '移除群成员' WHERE `name` = 'imGroupMemberRemove';
UPDATE `hg_admin_menu` SET `title` = '转让群主' WHERE `name` = 'imGroupOwnerTransfer';
UPDATE `hg_admin_menu` SET `title` = '注册邀请码' WHERE `name` = 'imRegistrationInviteIndex';
UPDATE `hg_admin_menu` SET `title` = '创建邀请码' WHERE `name` = 'imInviteCreate';
UPDATE `hg_admin_menu` SET `title` = '批量创建邀请码' WHERE `name` = 'imInviteBatchCreate';
UPDATE `hg_admin_menu` SET `title` = '批次详情' WHERE `name` = 'imInviteBatchView';
UPDATE `hg_admin_menu` SET `title` = '撤销邀请码' WHERE `name` = 'imInviteRevoke';
UPDATE `hg_admin_menu` SET `title` = '绑定用户' WHERE `name` = 'imInviteBindUser';
UPDATE `hg_admin_menu` SET `title` = '撤销批次邀请码' WHERE `name` = 'imInviteBatchRevoke';
UPDATE `hg_admin_menu` SET `title` = '导出邀请码' WHERE `name` = 'imInviteExport';
UPDATE `hg_admin_menu` SET `title` = '审计日志' WHERE `name` = 'imAuditLog';
UPDATE `hg_admin_menu` SET `title` = '审计列表' WHERE `name` = 'imAuditLogIndex';
UPDATE `hg_admin_menu` SET `title` = '审计详情' WHERE `name` = 'imAuditLogView';
UPDATE `hg_admin_menu` SET `title` = '导出审计日志' WHERE `name` = 'imAuditLogExport';
UPDATE `hg_admin_menu` SET `title` = '组织架构' WHERE `name` = 'imOrgIndex';
UPDATE `hg_admin_menu` SET `title` = '部门编辑' WHERE `name` = 'imOrgDepartmentEdit';
UPDATE `hg_admin_menu` SET `title` = '导出部门' WHERE `name` = 'imOrgDepartmentExport';
UPDATE `hg_admin_menu` SET `title` = '删除部门' WHERE `name` = 'imOrgDepartmentDelete';
UPDATE `hg_admin_menu` SET `title` = '成员列表' WHERE `name` = 'imOrgMemberList';
UPDATE `hg_admin_menu` SET `title` = '成员编辑' WHERE `name` = 'imOrgMemberEdit';
UPDATE `hg_admin_menu` SET `title` = '导出成员' WHERE `name` = 'imOrgMemberExport';
UPDATE `hg_admin_menu` SET `title` = '移除成员' WHERE `name` = 'imOrgMemberDelete';
UPDATE `hg_admin_menu` SET `title` = '组织搜索' WHERE `name` = 'imOrgSearch';
UPDATE `hg_admin_menu` SET `title` = '文件治理' WHERE `name` = 'imFileIndex';
UPDATE `hg_admin_menu` SET `title` = '文件详情' WHERE `name` = 'imFileView';
UPDATE `hg_admin_menu` SET `title` = '隔离文件' WHERE `name` = 'imFileQuarantine';
UPDATE `hg_admin_menu` SET `title` = '删除文件' WHERE `name` = 'imFileDelete';
UPDATE `hg_admin_menu` SET `title` = '清理孤儿文件' WHERE `name` = 'imFileCleanupOrphan';
UPDATE `hg_admin_menu` SET `title` = '文件策略' WHERE `name` = 'imFilePolicyIndex';
UPDATE `hg_admin_menu` SET `title` = '策略更新' WHERE `name` = 'imFilePolicyUpdate';
UPDATE `hg_admin_menu` SET `title` = '通知模板' WHERE `name` = 'imNotificationIndex';
UPDATE `hg_admin_menu` SET `title` = '模板更新' WHERE `name` = 'imNotificationTemplateUpdate';
UPDATE `hg_admin_menu` SET `title` = '外部服务配置' WHERE `name` = 'imExternalConfigIndex';
UPDATE `hg_admin_menu` SET `title` = '配置详情' WHERE `name` = 'imExternalConfigView';
UPDATE `hg_admin_menu` SET `title` = '更新配置' WHERE `name` = 'imExternalConfigUpdate';
UPDATE `hg_admin_menu` SET `title` = '检查配置' WHERE `name` = 'imExternalConfigCheck';
UPDATE `hg_admin_menu` SET `title` = '工作台配置' WHERE `name` = 'imWorkbenchIndex';
UPDATE `hg_admin_menu` SET `title` = '工作台管理' WHERE `name` = 'workbenchManager';
UPDATE `hg_admin_menu` SET `title` = '模块编辑' WHERE `name` = 'imWorkbenchEdit';
UPDATE `hg_admin_menu` SET `title` = '模块删除' WHERE `name` = 'imWorkbenchDelete';
UPDATE `hg_admin_menu` SET `title` = '模块排序' WHERE `name` = 'imWorkbenchReorder';
UPDATE `hg_admin_menu` SET `title` = '版本更新' WHERE `name` = 'imAppReleaseIndex';
UPDATE `hg_admin_menu` SET `title` = '版本编辑' WHERE `name` = 'imAppReleaseEdit';
UPDATE `hg_admin_menu` SET `title` = '举报原因' WHERE `name` = 'imAbuseReasonIndex';
UPDATE `hg_admin_menu` SET `title` = '原因编辑' WHERE `name` = 'imAbuseReasonEdit';
UPDATE `hg_admin_menu` SET `title` = '原因删除' WHERE `name` = 'imAbuseReasonDelete';
UPDATE `hg_admin_menu` SET `title` = '总经理信箱配置' WHERE `name` = 'imMailboxConfigIndex';
UPDATE `hg_admin_menu` SET `title` = '更新信箱配置' WHERE `name` = 'imMailboxConfigUpdate';
UPDATE `hg_admin_menu` SET `title` = '意见反馈配置' WHERE `name` = 'imFeedbackConfigIndex';
UPDATE `hg_admin_menu` SET `title` = '更新反馈配置' WHERE `name` = 'imFeedbackConfigUpdate';
UPDATE `hg_admin_menu` SET `title` = '任务看板' WHERE `name` = 'imTaskDashboardIndex';
UPDATE `hg_admin_menu` SET `title` = 'Kafka命令' WHERE `name` = 'imKafkaCommandIndex';
UPDATE `hg_admin_menu` SET `title` = '命令详情' WHERE `name` = 'imKafkaCommandView';
UPDATE `hg_admin_menu` SET `title` = '发送缓存失效测试' WHERE `name` = 'imKafkaCommandCacheInvalidate';
UPDATE `hg_admin_menu` SET `title` = '发送工作台测试事件' WHERE `name` = 'imKafkaCommandWorkbenchEvent';
UPDATE `hg_admin_menu` SET `title` = 'Kafka死信' WHERE `name` = 'imDeadLetterIndex';
UPDATE `hg_admin_menu` SET `title` = '死信详情' WHERE `name` = 'imDeadLetterView';
UPDATE `hg_admin_menu` SET `title` = '重放死信' WHERE `name` = 'imDeadLetterReplay';
UPDATE `hg_admin_menu` SET `title` = '忽略死信' WHERE `name` = 'imDeadLetterIgnore';
UPDATE `hg_admin_menu` SET `title` = '标记已处理' WHERE `name` = 'imDeadLetterResolve';
UPDATE `hg_admin_menu` SET `title` = 'Kafka审计事件' WHERE `name` = 'imKafkaAuditIndex';
UPDATE `hg_admin_menu` SET `title` = '审计事件详情' WHERE `name` = 'imKafkaAuditView';
@@ -0,0 +1,96 @@
SET @now = NOW();
SELECT @imRootId := `id` FROM `hg_admin_menu` WHERE `name` = 'imManager' LIMIT 1;
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, 0, 'IM管理', 'imManager', '/im', '', 1, '/im/tenant/index', '', '', 'LAYOUT', 1, '', 1, 0, '', 0, 0, 0, 1, '', 200, '', 1, @now, @now
WHERE @imRootId IS NULL;
SELECT @imRootId := `id` FROM `hg_admin_menu` WHERE `name` = 'imManager' LIMIT 1;
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @imRootId, title, name, path, '', 2, '', permissions, '', component, 1, 'imManager', 0, 0, '', 0, 0, 0, 2, CONCAT('tr_', @imRootId, ' '), sort, '', 1, @now, @now
FROM (
SELECT '组织架构' title, 'imOrgIndex' name, 'org/index' path, '/imOrg/departmentList' permissions, '/imOrg/index' component, 65 sort UNION ALL
SELECT '文件治理', 'imFileIndex', 'file/index', '/imFile/list', '/imFile/index', 70 UNION ALL
SELECT '文件策略', 'imFilePolicyIndex', 'file-policy/index', '/imFilePolicy/list', '/imFilePolicy/index', 73 UNION ALL
SELECT '通知模板', 'imNotificationIndex', 'notification/index', '/imNotification/templateList', '/imNotification/index', 75 UNION ALL
SELECT '外部服务配置', 'imExternalConfigIndex', 'external-config/index', '/imExternalConfig/list', '/imExternalConfig/index', 80 UNION ALL
SELECT '工作台配置', 'imWorkbenchIndex', 'workbench/index', '/imWorkbench/list', '/imWorkbench/index', 80 UNION ALL
SELECT '版本更新', 'imAppReleaseIndex', 'app-release/index', '/imAppRelease/list', '/imAppRelease/index', 81 UNION ALL
SELECT '举报原因', 'imAbuseReasonIndex', 'abuse-reason/index', '/imAbuseReason/list', '/imAbuseReason/index', 82 UNION ALL
SELECT '总经理信箱配置', 'imMailboxConfigIndex', 'mailbox-config/index', '/imMailboxConfig/get', '/imMailboxConfig/index', 83 UNION ALL
SELECT '意见反馈配置', 'imFeedbackConfigIndex', 'feedback-config/index', '/imFeedbackConfig/get', '/imFeedbackConfig/index', 84 UNION ALL
SELECT '任务看板', 'imTaskDashboardIndex', 'task-dashboard/index', '/imTaskDashboard/list', '/imTaskDashboard/index', 90
) p
WHERE @imRootId IS NOT NULL
AND NOT EXISTS (SELECT 1 FROM `hg_admin_menu` m WHERE m.`name` = p.name);
SELECT @imOrgId := `id` FROM `hg_admin_menu` WHERE `name` = 'imOrgIndex' LIMIT 1;
SELECT @fileId := `id` FROM `hg_admin_menu` WHERE `name` = 'imFileIndex' LIMIT 1;
SELECT @filePolicyId := `id` FROM `hg_admin_menu` WHERE `name` = 'imFilePolicyIndex' LIMIT 1;
SELECT @notificationId := `id` FROM `hg_admin_menu` WHERE `name` = 'imNotificationIndex' LIMIT 1;
SELECT @externalConfigId := `id` FROM `hg_admin_menu` WHERE `name` = 'imExternalConfigIndex' LIMIT 1;
SELECT @workbenchId := `id` FROM `hg_admin_menu` WHERE `name` = 'imWorkbenchIndex' LIMIT 1;
SELECT @appReleaseId := `id` FROM `hg_admin_menu` WHERE `name` = 'imAppReleaseIndex' LIMIT 1;
SELECT @abuseReasonId := `id` FROM `hg_admin_menu` WHERE `name` = 'imAbuseReasonIndex' LIMIT 1;
SELECT @mailboxConfigId := `id` FROM `hg_admin_menu` WHERE `name` = 'imMailboxConfigIndex' LIMIT 1;
SELECT @feedbackConfigId := `id` FROM `hg_admin_menu` WHERE `name` = 'imFeedbackConfigIndex' LIMIT 1;
SELECT @tenantListId := `id` FROM `hg_admin_menu` WHERE `name` = 'imTenantIndex' LIMIT 1;
SELECT @auditLogId := `id` FROM `hg_admin_menu` WHERE `name` = 'imAuditLogIndex' LIMIT 1;
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, parent_id, title, name, '', '', 3, '', permissions, '', '', 1, '', 0, 0, '', 0, 1, 0, level, tree, sort, '', 1, @now, @now
FROM (
SELECT @imOrgId parent_id, '部门编辑' title, 'imOrgDepartmentEdit' name, '/imOrg/departmentEdit' permissions, 3 level, CONCAT('tr_', @imRootId, ' tr_', @imOrgId, ' ') tree, 10 sort UNION ALL
SELECT @imOrgId, '部门导出', 'imOrgDepartmentExport', '/imOrg/departmentExport', 3, CONCAT('tr_', @imRootId, ' tr_', @imOrgId, ' '), 15 UNION ALL
SELECT @imOrgId, '部门删除', 'imOrgDepartmentDelete', '/imOrg/departmentDelete', 3, CONCAT('tr_', @imRootId, ' tr_', @imOrgId, ' '), 20 UNION ALL
SELECT @imOrgId, '成员列表', 'imOrgMemberList', '/imOrg/memberList', 3, CONCAT('tr_', @imRootId, ' tr_', @imOrgId, ' '), 30 UNION ALL
SELECT @imOrgId, '成员编辑', 'imOrgMemberEdit', '/imOrg/memberEdit', 3, CONCAT('tr_', @imRootId, ' tr_', @imOrgId, ' '), 40 UNION ALL
SELECT @imOrgId, '成员导出', 'imOrgMemberExport', '/imOrg/memberExport', 3, CONCAT('tr_', @imRootId, ' tr_', @imOrgId, ' '), 45 UNION ALL
SELECT @imOrgId, '成员移除', 'imOrgMemberDelete', '/imOrg/memberDelete', 3, CONCAT('tr_', @imRootId, ' tr_', @imOrgId, ' '), 50 UNION ALL
SELECT @imOrgId, '组织搜索', 'imOrgSearch', '/imOrg/search', 3, CONCAT('tr_', @imRootId, ' tr_', @imOrgId, ' '), 60 UNION ALL
SELECT @fileId, '文件详情', 'imFileView', '/imFile/view', 3, CONCAT('tr_', @imRootId, ' tr_', @fileId, ' '), 10 UNION ALL
SELECT @fileId, '隔离文件', 'imFileQuarantine', '/imFile/quarantine', 3, CONCAT('tr_', @imRootId, ' tr_', @fileId, ' '), 20 UNION ALL
SELECT @fileId, '删除文件', 'imFileDelete', '/imFile/delete', 3, CONCAT('tr_', @imRootId, ' tr_', @fileId, ' '), 30 UNION ALL
SELECT @fileId, '清理孤儿文件', 'imFileCleanupOrphan', '/imFile/cleanupOrphan', 3, CONCAT('tr_', @imRootId, ' tr_', @fileId, ' '), 40 UNION ALL
SELECT @filePolicyId, '策略更新', 'imFilePolicyUpdate', '/imFilePolicy/update', 3, CONCAT('tr_', @imRootId, ' tr_', @filePolicyId, ' '), 10 UNION ALL
SELECT @notificationId, '模板更新', 'imNotificationTemplateUpdate', '/imNotification/templateUpdate', 3, CONCAT('tr_', @imRootId, ' tr_', @notificationId, ' '), 10 UNION ALL
SELECT @externalConfigId, '配置详情', 'imExternalConfigView', '/imExternalConfig/view', 3, CONCAT('tr_', @imRootId, ' tr_', @externalConfigId, ' '), 10 UNION ALL
SELECT @externalConfigId, '更新配置', 'imExternalConfigUpdate', '/imExternalConfig/update', 3, CONCAT('tr_', @imRootId, ' tr_', @externalConfigId, ' '), 20 UNION ALL
SELECT @externalConfigId, '检查配置', 'imExternalConfigCheck', '/imExternalConfig/check', 3, CONCAT('tr_', @imRootId, ' tr_', @externalConfigId, ' '), 30 UNION ALL
SELECT @workbenchId, '工作台编辑', 'imWorkbenchEdit', '/imWorkbench/edit', 3, CONCAT('tr_', @imRootId, ' tr_', @workbenchId, ' '), 10 UNION ALL
SELECT @workbenchId, '工作台禁用', 'imWorkbenchDelete', '/imWorkbench/delete', 3, CONCAT('tr_', @imRootId, ' tr_', @workbenchId, ' '), 20 UNION ALL
SELECT @workbenchId, '工作台排序', 'imWorkbenchReorder', '/imWorkbench/reorder', 3, CONCAT('tr_', @imRootId, ' tr_', @workbenchId, ' '), 30 UNION ALL
SELECT @appReleaseId, '版本编辑', 'imAppReleaseEdit', '/imAppRelease/edit', 3, CONCAT('tr_', @imRootId, ' tr_', @appReleaseId, ' '), 10 UNION ALL
SELECT @abuseReasonId, '原因编辑', 'imAbuseReasonEdit', '/imAbuseReason/edit', 3, CONCAT('tr_', @imRootId, ' tr_', @abuseReasonId, ' '), 10 UNION ALL
SELECT @abuseReasonId, '原因禁用', 'imAbuseReasonDelete', '/imAbuseReason/delete', 3, CONCAT('tr_', @imRootId, ' tr_', @abuseReasonId, ' '), 20 UNION ALL
SELECT @mailboxConfigId, '信箱配置更新', 'imMailboxConfigUpdate', '/imMailboxConfig/update', 3, CONCAT('tr_', @imRootId, ' tr_', @mailboxConfigId, ' '), 10 UNION ALL
SELECT @feedbackConfigId, '反馈配置更新', 'imFeedbackConfigUpdate', '/imFeedbackConfig/update', 3, CONCAT('tr_', @imRootId, ' tr_', @feedbackConfigId, ' '), 10 UNION ALL
SELECT @tenantListId, '商户用量与健康', 'imTenantUsage', '/imTenant/usage', 4, CONCAT('tr_', @imRootId, ' tr_', (SELECT `pid` FROM `hg_admin_menu` WHERE `id` = @tenantListId), ' tr_', @tenantListId, ' '), 40 UNION ALL
SELECT @tenantListId, '商户删除前检查', 'imTenantDeletionCheck', '/imTenant/deletionCheck', 4, CONCAT('tr_', @imRootId, ' tr_', (SELECT `pid` FROM `hg_admin_menu` WHERE `id` = @tenantListId), ' tr_', @tenantListId, ' '), 50 UNION ALL
SELECT @tenantListId, '商户进入删除流程', 'imTenantEnterDeleting', '/imTenant/enterDeleting', 4, CONCAT('tr_', @imRootId, ' tr_', (SELECT `pid` FROM `hg_admin_menu` WHERE `id` = @tenantListId), ' tr_', @tenantListId, ' '), 60 UNION ALL
SELECT @tenantListId, '恢复商户', 'imTenantRestore', '/imTenant/restore', 4, CONCAT('tr_', @imRootId, ' tr_', (SELECT `pid` FROM `hg_admin_menu` WHERE `id` = @tenantListId), ' tr_', @tenantListId, ' '), 70 UNION ALL
SELECT @auditLogId, '导出审计日志', 'imAuditLogExport', '/imAuditLog/export', 3, CONCAT('tr_', @imRootId, ' tr_', @auditLogId, ' '), 20
) p
WHERE parent_id IS NOT NULL
AND NOT EXISTS (SELECT 1 FROM `hg_admin_menu` m WHERE m.`name` = p.name);
INSERT IGNORE INTO `hg_admin_role_menu` (`role_id`, `menu_id`)
SELECT 1, `id` FROM `hg_admin_menu`
WHERE `name` LIKE 'im%' OR `path` LIKE '/im%' OR `path` LIKE 'im/%';
-- Move replaceable workbench features out of the core IM menu.
INSERT INTO `hg_admin_menu` (`pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT 0, '工作台管理', 'workbenchManager', '/workbench', 'AppstoreOutlined', 1, '/workbench/config/index', '', '', 'LAYOUT', 1, '', 1, 0, '', 0, 0, 0, 1, '', 126, '附加功能独立管理入口', 1, @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name`='workbenchManager');
SET @workbenchRootId := (SELECT `id` FROM `hg_admin_menu` WHERE `name`='workbenchManager' LIMIT 1);
UPDATE `hg_admin_menu` SET `pid`=@workbenchRootId, `path`='config/index', `active_menu`='workbenchManager', `level`=2, `tree`=CONCAT('tr_', @workbenchRootId, ' '), `sort`=10, `updated_at`=@now WHERE `id`=@workbenchId;
UPDATE `hg_admin_menu` SET `pid`=@workbenchRootId, `title`='组织架构', `path`='org/index', `active_menu`='workbenchManager', `level`=2, `tree`=CONCAT('tr_', @workbenchRootId, ' '), `sort`=20, `updated_at`=@now WHERE `id`=@imOrgId;
UPDATE `hg_admin_menu` SET `pid`=@workbenchRootId, `path`='mailbox-config/index', `active_menu`='workbenchManager', `level`=2, `tree`=CONCAT('tr_', @workbenchRootId, ' '), `sort`=30, `updated_at`=@now WHERE `id`=@mailboxConfigId;
UPDATE `hg_admin_menu` SET `pid`=@workbenchRootId, `path`='feedback-config/index', `active_menu`='workbenchManager', `level`=2, `tree`=CONCAT('tr_', @workbenchRootId, ' '), `sort`=40, `updated_at`=@now WHERE `id`=@feedbackConfigId;
UPDATE `hg_admin_menu` child JOIN `hg_admin_menu` page ON page.`id`=child.`pid` SET child.`level`=3, child.`tree`=CONCAT('tr_', @workbenchRootId, ' tr_', page.`id`, ' '), child.`updated_at`=@now WHERE page.`id` IN (@workbenchId, @imOrgId, @mailboxConfigId, @feedbackConfigId) AND child.`type`=3;
INSERT IGNORE INTO `hg_admin_role_menu` (`role_id`, `menu_id`)
SELECT `role_id`, @workbenchRootId FROM `hg_admin_role_menu` WHERE `menu_id` IN (@workbenchId, @imOrgId, @mailboxConfigId, @feedbackConfigId);
@@ -0,0 +1,31 @@
SET @now := NOW();
SET @imRootId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'imManager' LIMIT 1);
CREATE TABLE IF NOT EXISTS `im_notification_template` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`tenant_id` BIGINT NOT NULL,
`scene` VARCHAR(64) NOT NULL,
`name` VARCHAR(64) NOT NULL DEFAULT '',
`in_app_enabled` TINYINT NOT NULL DEFAULT 1,
`push_enabled` TINYINT NOT NULL DEFAULT 1,
`sms_enabled` TINYINT NOT NULL DEFAULT 0,
`status` TINYINT NOT NULL DEFAULT 1,
`title_template` VARCHAR(255) NOT NULL DEFAULT '',
`content_template` TEXT NOT NULL,
`payload_json` JSON DEFAULT NULL,
`created_at` DATETIME DEFAULT NULL,
`updated_at` DATETIME DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_im_notification_template_tenant_scene` (`tenant_id`, `scene`),
KEY `idx_im_notification_template_tenant_status` (`tenant_id`, `status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='IM通知模板配置';
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @imRootId, '通知模板', 'imNotificationIndex', 'notification/index', '', '2', '', '/imNotification/templateList', '', '/imNotification/index', '1', 'imManager', '0', '0', '', '0', '0', '0', '2', CONCAT('tr_', @imRootId, ' '), '75', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imNotificationIndex');
SET @imNotificationId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'imNotificationIndex' LIMIT 1);
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @imNotificationId, '模板更新', 'imNotificationTemplateUpdate', '', '', '3', '', '/imNotification/templateUpdate', '', '', '1', '', '0', '0', '', '0', '0', '0', '3', CONCAT('tr_', @imRootId, ' tr_', @imNotificationId, ' '), '10', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imNotificationTemplateUpdate');
@@ -0,0 +1,60 @@
SET @now := NOW();
SET @imRootId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'imManager' LIMIT 1);
SET @workbenchRootId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'workbenchManager' LIMIT 1);
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, COALESCE(@workbenchRootId, @imRootId), '组织架构', 'imOrgIndex', 'org/index', '', '2', '', '/imOrg/departmentList', '', '/imOrg/index', '1', IF(@workbenchRootId IS NULL, 'imManager', 'workbenchManager'), '0', '0', '', '0', '0', '0', IF(@workbenchRootId IS NULL, '2', '2'), CONCAT('tr_', COALESCE(@workbenchRootId, @imRootId), ' '), '20', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imOrgIndex');
SET @imOrgId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'imOrgIndex' LIMIT 1);
UPDATE `hg_admin_menu`
SET `pid` = COALESCE(@workbenchRootId, @imRootId),
`title` = '组织架构',
`path` = 'org/index',
`active_menu` = IF(@workbenchRootId IS NULL, 'imManager', 'workbenchManager'),
`level` = 2,
`tree` = CONCAT('tr_', COALESCE(@workbenchRootId, @imRootId), ' '),
`sort` = 20,
`status` = 1,
`hidden` = 0,
`updated_at` = @now
WHERE `id` = @imOrgId;
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @imOrgId, '部门编辑', 'imOrgDepartmentEdit', '', '', '3', '', '/imOrg/departmentEdit', '', '', '1', '', '0', '0', '', '0', '0', '0', '3', CONCAT('tr_', COALESCE(@workbenchRootId, @imRootId), ' tr_', @imOrgId, ' '), '10', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imOrgDepartmentEdit');
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @imOrgId, '部门导出', 'imOrgDepartmentExport', '', '', '3', '', '/imOrg/departmentExport', '', '', '1', '', '0', '0', '', '0', '0', '0', '3', CONCAT('tr_', COALESCE(@workbenchRootId, @imRootId), ' tr_', @imOrgId, ' '), '15', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imOrgDepartmentExport');
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @imOrgId, '部门删除', 'imOrgDepartmentDelete', '', '', '3', '', '/imOrg/departmentDelete', '', '', '1', '', '0', '0', '', '0', '0', '0', '3', CONCAT('tr_', COALESCE(@workbenchRootId, @imRootId), ' tr_', @imOrgId, ' '), '20', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imOrgDepartmentDelete');
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @imOrgId, '成员列表', 'imOrgMemberList', '', '', '3', '', '/imOrg/memberList', '', '', '1', '', '0', '0', '', '0', '0', '0', '3', CONCAT('tr_', COALESCE(@workbenchRootId, @imRootId), ' tr_', @imOrgId, ' '), '30', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imOrgMemberList');
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @imOrgId, '成员编辑', 'imOrgMemberEdit', '', '', '3', '', '/imOrg/memberEdit', '', '', '1', '', '0', '0', '', '0', '0', '0', '3', CONCAT('tr_', COALESCE(@workbenchRootId, @imRootId), ' tr_', @imOrgId, ' '), '40', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imOrgMemberEdit');
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @imOrgId, '成员导出', 'imOrgMemberExport', '', '', '3', '', '/imOrg/memberExport', '', '', '1', '', '0', '0', '', '0', '0', '0', '3', CONCAT('tr_', COALESCE(@workbenchRootId, @imRootId), ' tr_', @imOrgId, ' '), '45', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imOrgMemberExport');
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @imOrgId, '成员移除', 'imOrgMemberDelete', '', '', '3', '', '/imOrg/memberDelete', '', '', '1', '', '0', '0', '', '0', '0', '0', '3', CONCAT('tr_', COALESCE(@workbenchRootId, @imRootId), ' tr_', @imOrgId, ' '), '50', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imOrgMemberDelete');
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @imOrgId, '组织搜索', 'imOrgSearch', '', '', '3', '', '/imOrg/search', '', '', '1', '', '0', '0', '', '0', '0', '0', '3', CONCAT('tr_', COALESCE(@workbenchRootId, @imRootId), ' tr_', @imOrgId, ' '), '60', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imOrgSearch');
UPDATE `hg_admin_menu`
SET `level` = 3,
`tree` = CONCAT('tr_', COALESCE(@workbenchRootId, @imRootId), ' tr_', @imOrgId, ' '),
`updated_at` = @now
WHERE `pid` = @imOrgId AND `type` = 3;
@@ -0,0 +1,16 @@
-- Outbox运维菜单已废弃。
-- 现架构 Kafka 事件直接落库,不再使用旧 `business_outbox` / `group_outbox` 运维入口。
SET @now = NOW();
UPDATE `hg_admin_menu`
SET `hidden` = 1,
`status` = 2,
`updated_at` = @now
WHERE `name` IN (
'imOutbox',
'imOutboxIndex',
'imOutboxView',
'imOutboxRetry',
'imOutboxDead'
);
@@ -0,0 +1,112 @@
-- Seed a compact, high-confidence Chinese moderation lexicon for tenant 1.
-- Category references:
-- https://github.com/konsheng/Sensitive-lexicon
-- https://github.com/fwwdn/sensitive-stop-words
-- This script is idempotent and restores matching soft-deleted seed rows.
SET NAMES utf8mb4;
SET @tenantId := 1;
SET @now := NOW(3);
INSERT INTO `im_sensitive_word_groups`
(`tenant_id`, `group_code`, `group_name`, `priority`, `status`, `remark`, `created_at`, `created_by`, `updated_at`, `updated_by`, `deleted_at`, `deleted_by`)
VALUES
(@tenantId, 'fraud', '诈骗风险', 100, 1, '诈骗、黑产引流和资金风险测试词', @now, 0, @now, 0, NULL, NULL),
(@tenantId, 'gambling', '赌博风险', 95, 1, '博彩、下注和赌资交易测试词', @now, 0, @now, 0, NULL, NULL),
(@tenantId, 'drugs', '涉毒风险', 90, 1, '毒品交易和吸食引流测试词', @now, 0, @now, 0, NULL, NULL),
(@tenantId, 'adult_trade', '色情交易', 85, 1, '色情交易和成人服务测试词', @now, 0, @now, 0, NULL, NULL),
(@tenantId, 'abuse', '辱骂攻击', 70, 1, '常见辱骂和人身攻击测试词', @now, 0, @now, 0, NULL, NULL),
(@tenantId, 'spam', '广告导流', 50, 1, '站外导流和垃圾广告测试词', @now, 0, @now, 0, NULL, NULL)
ON DUPLICATE KEY UPDATE
`group_name` = VALUES(`group_name`),
`priority` = VALUES(`priority`),
`status` = VALUES(`status`),
`remark` = VALUES(`remark`),
`updated_at` = VALUES(`updated_at`),
`deleted_at` = NULL,
`deleted_by` = NULL;
INSERT INTO `im_sensitive_words`
(`tenant_id`, `group_id`, `word`, `word_hash`, `match_type`, `scene_json`, `action`, `replacement`, `risk_level`, `priority`, `status`, `remark`, `created_at`, `created_by`, `updated_at`, `updated_by`, `deleted_at`, `deleted_by`)
SELECT
@tenantId,
g.`id`,
seed.`word`,
SHA2(LOWER(TRIM(seed.`word`)), 256),
'contains',
CAST(seed.`scenes` AS JSON),
seed.`action`,
seed.`replacement`,
seed.`risk_level`,
seed.`priority`,
1,
'公开词库筛选的内容审核测试词',
@now,
0,
@now,
0,
NULL,
NULL
FROM (
SELECT 'fraud' group_code, '刷单返利' word, '["private_message","group_message","user_profile","feedback"]' scenes, 'manual_review' action, '' replacement, 'high' risk_level, 100 priority
UNION ALL SELECT 'fraud', '兼职刷单', '["private_message","group_message","user_profile"]', 'manual_review', '', 'high', 100
UNION ALL SELECT 'fraud', '冒充客服退款', '["private_message","group_message"]', 'block', '', 'high', 100
UNION ALL SELECT 'fraud', '转账保证金', '["private_message","group_message"]', 'manual_review', '', 'high', 95
UNION ALL SELECT 'fraud', '征信修复', '["private_message","group_message","user_profile"]', 'manual_review', '', 'high', 95
UNION ALL SELECT 'fraud', '内幕荐股', '["private_message","group_message","user_profile"]', 'manual_review', '', 'high', 95
UNION ALL SELECT 'fraud', '杀猪盘', '["private_message","group_message","feedback","report"]', 'manual_review', '', 'high', 90
UNION ALL SELECT 'fraud', '裸聊敲诈', '["private_message","group_message","feedback","report"]', 'block', '', 'high', 90
UNION ALL SELECT 'gambling', '网络赌场', '["private_message","group_message","user_profile","group_profile"]', 'block', '', 'high', 100
UNION ALL SELECT 'gambling', '博彩平台', '["private_message","group_message","user_profile","group_profile"]', 'block', '', 'high', 100
UNION ALL SELECT 'gambling', '私彩平台', '["private_message","group_message","user_profile"]', 'block', '', 'high', 95
UNION ALL SELECT 'gambling', '在线下注', '["private_message","group_message","user_profile"]', 'block', '', 'high', 95
UNION ALL SELECT 'gambling', '赌资代充', '["private_message","group_message"]', 'block', '', 'high', 95
UNION ALL SELECT 'gambling', '真人百家乐', '["private_message","group_message","user_profile"]', 'block', '', 'high', 90
UNION ALL SELECT 'gambling', '老虎机赢钱', '["private_message","group_message","user_profile"]', 'block', '', 'high', 90
UNION ALL SELECT 'gambling', '跑分洗钱', '["private_message","group_message","feedback","report"]', 'block', '', 'high', 100
UNION ALL SELECT 'drugs', '冰毒出售', '["private_message","group_message","user_profile"]', 'block', '', 'high', 100
UNION ALL SELECT 'drugs', '海洛因出售', '["private_message","group_message","user_profile"]', 'block', '', 'high', 100
UNION ALL SELECT 'drugs', '麻古出售', '["private_message","group_message","user_profile"]', 'block', '', 'high', 100
UNION ALL SELECT 'drugs', '毒品交易', '["private_message","group_message","feedback","report"]', 'block', '', 'high', 100
UNION ALL SELECT 'drugs', '上门送毒', '["private_message","group_message"]', 'block', '', 'high', 95
UNION ALL SELECT 'adult_trade', '招嫖', '["private_message","group_message","user_profile","report"]', 'block', '', 'high', 100
UNION ALL SELECT 'adult_trade', '上门性服务', '["private_message","group_message","user_profile"]', 'block', '', 'high', 100
UNION ALL SELECT 'adult_trade', '裸聊服务', '["private_message","group_message","user_profile"]', 'manual_review', '', 'high', 95
UNION ALL SELECT 'adult_trade', '色情直播', '["private_message","group_message","user_profile","group_profile"]', 'manual_review', '', 'high', 95
UNION ALL SELECT 'adult_trade', '成人视频', '["private_message","group_message","user_profile","group_profile"]', 'manual_review', '', 'high', 90
UNION ALL SELECT 'adult_trade', '无码资源', '["private_message","group_message","user_profile"]', 'manual_review', '', 'high', 90
UNION ALL SELECT 'abuse', '操你妈', '["private_message","group_message","feedback"]', 'replace', '***', 'medium', 75
UNION ALL SELECT 'abuse', '傻逼', '["private_message","group_message","feedback"]', 'replace', '***', 'medium', 75
UNION ALL SELECT 'abuse', '狗娘养的', '["private_message","group_message","feedback"]', 'replace', '***', 'medium', 70
UNION ALL SELECT 'abuse', '去死吧', '["private_message","group_message","feedback"]', 'manual_review', '', 'medium', 70
UNION ALL SELECT 'abuse', '废物东西', '["private_message","group_message","feedback"]', 'replace', '***', 'medium', 65
UNION ALL SELECT 'abuse', '脑残玩意', '["private_message","group_message","feedback"]', 'replace', '***', 'medium', 65
UNION ALL SELECT 'spam', '加微信返现', '["private_message","group_message","user_profile"]', 'audit_only', '', 'low', 50
UNION ALL SELECT 'spam', '私聊加微信', '["private_message","group_message","user_profile"]', 'audit_only', '', 'low', 50
UNION ALL SELECT 'spam', '扫码领红包', '["private_message","group_message","user_profile"]', 'audit_only', '', 'low', 45
UNION ALL SELECT 'spam', '代理加盟', '["private_message","group_message","user_profile"]', 'audit_only', '', 'low', 45
UNION ALL SELECT 'spam', '日赚千元', '["private_message","group_message","user_profile"]', 'manual_review', '', 'medium', 50
UNION ALL SELECT 'spam', '低息套现', '["private_message","group_message","user_profile"]', 'manual_review', '', 'medium', 55
) seed
JOIN `im_sensitive_word_groups` g
ON g.`tenant_id` = @tenantId
AND g.`group_code` = seed.`group_code`
AND g.`deleted_at` IS NULL
ON DUPLICATE KEY UPDATE
`word` = VALUES(`word`),
`match_type` = VALUES(`match_type`),
`scene_json` = VALUES(`scene_json`),
`action` = VALUES(`action`),
`replacement` = VALUES(`replacement`),
`risk_level` = VALUES(`risk_level`),
`priority` = VALUES(`priority`),
`status` = VALUES(`status`),
`remark` = VALUES(`remark`),
`updated_at` = VALUES(`updated_at`),
`deleted_at` = NULL,
`deleted_by` = NULL;
@@ -0,0 +1,13 @@
SET @now = NOW();
SELECT @imRootId := `id` FROM `hg_admin_menu` WHERE `name` = 'imManager' LIMIT 1;
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, '0', 'IM管理', 'imManager', '/im', '', '1', '/im/tenant/index', '', '', 'LAYOUT', '1', '', '1', '0', '', '0', '0', '0', '1', '', '200', '', '1', @now, @now
WHERE @imRootId IS NULL;
SELECT @imRootId := `id` FROM `hg_admin_menu` WHERE `name` = 'imManager' LIMIT 1;
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @imRootId, '任务看板', 'imTaskDashboardIndex', 'task-dashboard/index', '', '2', '', '/imTaskDashboard/list', '', '/imTaskDashboard/index', '1', 'imManager', '0', '0', '', '0', '0', '0', '2', CONCAT('tr_', @imRootId, ' '), '90', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imTaskDashboardIndex');
@@ -0,0 +1,42 @@
-- Tenant-scoped APP/Web login IP whitelist and admin permissions.
-- Empty whitelist for a channel means unrestricted access.
SET NAMES utf8mb4;
USE `hotgo`;
CREATE TABLE IF NOT EXISTS `im_tenant_login_ip_whitelists` (
`id` bigint NOT NULL AUTO_INCREMENT,
`tenant_id` bigint NOT NULL COMMENT 'IM tenant ID',
`channel` varchar(16) NOT NULL COMMENT 'app or web',
`ip_cidr` varchar(64) NOT NULL COMMENT 'IPv4, IPv6 or CIDR',
`status` tinyint NOT NULL DEFAULT 1 COMMENT '1 enabled, 2 disabled',
`created_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
`created_by` bigint NOT NULL DEFAULT 0,
`updated_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
`updated_by` bigint NOT NULL DEFAULT 0,
`deleted_at` datetime(3) DEFAULT NULL,
`deleted_by` bigint DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_im_tenant_login_ip` (`tenant_id`, `channel`, `ip_cidr`),
KEY `idx_im_tenant_login_ip_active` (`tenant_id`, `channel`, `status`, `deleted_at`),
CONSTRAINT `chk_im_tenant_login_ip_channel` CHECK (`channel` IN ('app', 'web'))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='Tenant APP/Web login IP whitelist';
SET @now = NOW();
SELECT @groupMenuId := `id` FROM `hg_admin_menu` WHERE `name` = 'imUserPolicyGroupIndex' LIMIT 1;
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @groupMenuId, '查看商户登录IP白名单', 'imTenantLoginIPWhitelist', '', '', '3', '', '/imUserPolicyGroup/loginIPWhitelist', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT(`tree`, 'tr_', `id`, ' '), '9', '', '1', @now, @now
FROM `hg_admin_menu` WHERE `id` = @groupMenuId
AND NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imTenantLoginIPWhitelist');
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @groupMenuId, '保存商户登录IP白名单', 'imTenantLoginIPWhitelistSave', '', '', '3', '', '/imUserPolicyGroup/loginIPWhitelistSave', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT(`tree`, 'tr_', `id`, ' '), '10', '', '1', @now, @now
FROM `hg_admin_menu` WHERE `id` = @groupMenuId
AND NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imTenantLoginIPWhitelistSave');
INSERT IGNORE INTO `hg_admin_role_menu` (`role_id`, `menu_id`)
SELECT parent_role.`role_id`, child.`id`
FROM `hg_admin_role_menu` parent_role
JOIN `hg_admin_menu` parent ON parent.`id` = parent_role.`menu_id` AND parent.`name` = 'imUserPolicyGroupIndex'
JOIN `hg_admin_menu` child ON child.`pid` = parent.`id`
WHERE child.`name` IN ('imTenantLoginIPWhitelist', 'imTenantLoginIPWhitelistSave');
@@ -13,7 +13,7 @@ SELECT @imRootId := `id` FROM `hg_admin_menu` WHERE `name` = 'imManager' LIMIT 1
SELECT @tenantDirId := `id` FROM `hg_admin_menu` WHERE `name` = 'imTenant' LIMIT 1;
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @imRootId, '租户管理', 'imTenant', 'tenant', '', '1', '/im/tenant/index', '', '', 'ParentLayout', '1', '', '0', '0', '', '0', '0', '0', '2', CONCAT('tr_', @imRootId, ' '), '10', '', '1', @now, @now
SELECT NULL, @imRootId, '商户管理', 'imTenant', 'tenant', '', '1', '/im/tenant/index', '', '', 'ParentLayout', '1', '', '0', '0', '', '0', '0', '0', '2', CONCAT('tr_', @imRootId, ' '), '10', '', '1', @now, @now
WHERE @tenantDirId IS NULL;
SELECT @tenantDirId := `id` FROM `hg_admin_menu` WHERE `name` = 'imTenant' LIMIT 1;
@@ -21,19 +21,35 @@ SELECT @tenantDirId := `id` FROM `hg_admin_menu` WHERE `name` = 'imTenant' LIMIT
SELECT @tenantListId := `id` FROM `hg_admin_menu` WHERE `name` = 'imTenantIndex' LIMIT 1;
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @tenantDirId, '租户列表', 'imTenantIndex', 'index', '', '2', '', '/imTenant/list', '', '/imTenant/index', '1', 'imTenant', '0', '0', '', '0', '0', '0', '3', CONCAT('tr_', @imRootId, ' tr_', @tenantDirId, ' '), '10', '', '1', @now, @now
SELECT NULL, @tenantDirId, '商户列表', 'imTenantIndex', 'index', '', '2', '', '/imTenant/list', '', '/imTenant/index', '1', 'imTenant', '0', '0', '', '0', '0', '0', '3', CONCAT('tr_', @imRootId, ' tr_', @tenantDirId, ' '), '10', '', '1', @now, @now
WHERE @tenantListId IS NULL;
SELECT @tenantListId := `id` FROM `hg_admin_menu` WHERE `name` = 'imTenantIndex' LIMIT 1;
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @tenantListId, '租户详情', 'imTenantView', '', '', '3', '', '/imTenant/view', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT('tr_', @imRootId, ' tr_', @tenantDirId, ' tr_', @tenantListId, ' '), '10', '', '1', @now, @now
SELECT NULL, @tenantListId, '商户详情', 'imTenantView', '', '', '3', '', '/imTenant/view', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT('tr_', @imRootId, ' tr_', @tenantDirId, ' tr_', @tenantListId, ' '), '10', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imTenantView');
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @tenantListId, '编辑/新增租户', 'imTenantEdit', '', '', '3', '', '/imTenant/edit', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT('tr_', @imRootId, ' tr_', @tenantDirId, ' tr_', @tenantListId, ' '), '20', '', '1', @now, @now
SELECT NULL, @tenantListId, '编辑/新增商户', 'imTenantEdit', '', '', '3', '', '/imTenant/edit', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT('tr_', @imRootId, ' tr_', @tenantDirId, ' tr_', @tenantListId, ' '), '20', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imTenantEdit');
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @tenantListId, '修改租户状态', 'imTenantStatus', '', '', '3', '', '/imTenant/status', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT('tr_', @imRootId, ' tr_', @tenantDirId, ' tr_', @tenantListId, ' '), '30', '', '1', @now, @now
SELECT NULL, @tenantListId, '修改商户状态', 'imTenantStatus', '', '', '3', '', '/imTenant/status', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT('tr_', @imRootId, ' tr_', @tenantDirId, ' tr_', @tenantListId, ' '), '30', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imTenantStatus');
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @tenantListId, '商户用量与健康', 'imTenantUsage', '', '', '3', '', '/imTenant/usage', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT('tr_', @imRootId, ' tr_', @tenantDirId, ' tr_', @tenantListId, ' '), '40', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imTenantUsage');
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @tenantListId, '商户删除前检查', 'imTenantDeletionCheck', '', '', '3', '', '/imTenant/deletionCheck', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT('tr_', @imRootId, ' tr_', @tenantDirId, ' tr_', @tenantListId, ' '), '50', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imTenantDeletionCheck');
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @tenantListId, '商户进入删除流程', 'imTenantEnterDeleting', '', '', '3', '', '/imTenant/enterDeleting', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT('tr_', @imRootId, ' tr_', @tenantDirId, ' tr_', @tenantListId, ' '), '60', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imTenantEnterDeleting');
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @tenantListId, '恢复商户', 'imTenantRestore', '', '', '3', '', '/imTenant/restore', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT('tr_', @imRootId, ' tr_', @tenantDirId, ' tr_', @tenantListId, ' '), '70', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imTenantRestore');
@@ -26,10 +26,48 @@ WHERE @userListId IS NULL;
SELECT @userListId := `id` FROM `hg_admin_menu` WHERE `name` = 'imUserIndex' LIMIT 1;
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @userListId, '创建用户', 'imUserCreate', '', '', '3', '', '/imUser/create', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT('tr_', @imRootId, ' tr_', @userDirId, ' tr_', @userListId, ' '), '1', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imUserCreate');
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @userListId, '批量创建用户', 'imUserBatchCreate', '', '', '3', '', '/imUser/batchCreate', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT('tr_', @imRootId, ' tr_', @userDirId, ' tr_', @userListId, ' '), '2', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imUserBatchCreate');
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @userListId, '导入用户', 'imUserImport', '', '', '3', '', '/imUser/import', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT('tr_', @imRootId, ' tr_', @userDirId, ' tr_', @userListId, ' '), '3', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imUserImport');
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @userListId, '下载用户模板', 'imUserDownloadTemplate', '', '', '3', '', '/imUser/downloadTemplate', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT('tr_', @imRootId, ' tr_', @userDirId, ' tr_', @userListId, ' '), '4', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imUserDownloadTemplate');
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @userDirId, '用户列表', 'imUserIndex', 'index', '', '2', '', '/imUser/list', '', '/imUser/index', '1', 'imUser', '0', '0', '', '0', '0', '0', '3', CONCAT('tr_', @imRootId, ' tr_', @userDirId, ' '), '10', '', '1', @now, @now
WHERE @userListId IS NULL;
SELECT @userListId := `id` FROM `hg_admin_menu` WHERE `name` = 'imUserIndex' LIMIT 1;
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @userListId, '用户详情', 'imUserView', '', '', '3', '', '/imUser/view', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT('tr_', @imRootId, ' tr_', @userDirId, ' tr_', @userListId, ' '), '10', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imUserView');
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @userListId, '重置用户密码', 'imUserResetPassword', '', '', '3', '', '/imUser/resetPassword', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT('tr_', @imRootId, ' tr_', @userDirId, ' tr_', @userListId, ' '), '11', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imUserResetPassword');
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @userListId, '查看用户IP白名单', 'imUserIPWhitelist', '', '', '3', '', '/imUser/ipWhitelist', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT('tr_', @imRootId, ' tr_', @userDirId, ' tr_', @userListId, ' '), '12', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imUserIPWhitelist');
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @userListId, '保存用户IP白名单', 'imUserIPWhitelistSave', '', '', '3', '', '/imUser/ipWhitelistSave', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT('tr_', @imRootId, ' tr_', @userDirId, ' tr_', @userListId, ' '), '13', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imUserIPWhitelistSave');
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @userListId, '调整用户分组', 'imUserAdjustGroup', '', '', '3', '', '/imUser/adjustGroup', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT('tr_', @imRootId, ' tr_', @userDirId, ' tr_', @userListId, ' '), '14', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imUserAdjustGroup');
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @userListId, '封禁用户', 'imUserBan', '', '', '3', '', '/imUser/ban', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT('tr_', @imRootId, ' tr_', @userDirId, ' tr_', @userListId, ' '), '20', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imUserBan');
@@ -61,3 +99,12 @@ WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imUserAccountCan
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT NULL, @userListId, '删除账号', 'imUserAccountDelete', '', '', '3', '', '/imUser/accountDelete', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT('tr_', @imRootId, ' tr_', @userDirId, ' tr_', @userListId, ' '), '90', '', '1', @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imUserAccountDelete');
INSERT IGNORE INTO `hg_admin_role_menu` (`role_id`, `menu_id`)
SELECT parent_role.`role_id`, child.`id`
FROM `hg_admin_role_menu` parent_role
JOIN `hg_admin_menu` parent ON parent.`id` = parent_role.`menu_id` AND parent.`name` = 'imUserIndex'
JOIN `hg_admin_menu` child ON child.`pid` = parent.`id`
WHERE child.`name` IN ('imUserCreate', 'imUserBatchCreate', 'imUserImport', 'imUserDownloadTemplate',
'imUserView', 'imUserResetPassword', 'imUserIPWhitelist', 'imUserIPWhitelistSave', 'imUserAdjustGroup',
'imUserBan', 'imUserUnban', 'imUserLogoutAll', 'imUserAccountCancel');
@@ -0,0 +1,46 @@
-- Initialize assignable policy groups for every active IM tenant.
-- Safe to rerun: tenant_id + group_code is unique.
SET NAMES utf8mb4;
USE `hotgo`;
INSERT INTO `im_user_policy_groups`
(`tenant_id`, `group_code`, `group_name`, `priority`, `status`, `policy_json`, `ip_whitelist`, `ip_blacklist`, `version`, `remark`, `created_by`, `updated_by`)
SELECT
`id`, 'default_standard', '默认用户组', 100, 1,
JSON_OBJECT(
'allow_add_friend', TRUE, 'allow_join_group', TRUE, 'max_friend_count', 5000,
'allow_upload_file', TRUE, 'direct_add_friend', FALSE, 'allow_create_group', TRUE,
'allow_group_message', TRUE, 'allow_private_message', TRUE,
'allow_qrcode_add_friend', TRUE, 'allow_group_member_profile', TRUE,
'hide_profile_when_friend_disabled', TRUE
), JSON_ARRAY(), JSON_ARRAY(), 1, '系统初始化:默认用户权限', 0, 0
FROM `im_tenant` WHERE `state` = 1
ON DUPLICATE KEY UPDATE `group_name` = VALUES(`group_name`), `status` = 1, `updated_at` = CURRENT_TIMESTAMP(3);
INSERT INTO `im_user_policy_groups`
(`tenant_id`, `group_code`, `group_name`, `priority`, `status`, `policy_json`, `ip_whitelist`, `ip_blacklist`, `version`, `remark`, `created_by`, `updated_by`)
SELECT
`id`, 'default_trusted', '可信用户组', 90, 1,
JSON_OBJECT(
'allow_add_friend', TRUE, 'allow_join_group', TRUE, 'max_friend_count', 10000,
'allow_upload_file', TRUE, 'direct_add_friend', TRUE, 'allow_create_group', TRUE,
'allow_group_message', TRUE, 'allow_private_message', TRUE,
'allow_qrcode_add_friend', TRUE, 'allow_group_member_profile', TRUE,
'hide_profile_when_friend_disabled', TRUE
), JSON_ARRAY(), JSON_ARRAY(), 1, '系统初始化:可信用户权限', 0, 0
FROM `im_tenant` WHERE `state` = 1
ON DUPLICATE KEY UPDATE `group_name` = VALUES(`group_name`), `status` = 1, `updated_at` = CURRENT_TIMESTAMP(3);
INSERT INTO `im_user_policy_groups`
(`tenant_id`, `group_code`, `group_name`, `priority`, `status`, `policy_json`, `ip_whitelist`, `ip_blacklist`, `version`, `remark`, `created_by`, `updated_by`)
SELECT
`id`, 'default_guest', '访客用户组', 60, 1,
JSON_OBJECT(
'allow_add_friend', FALSE, 'allow_join_group', TRUE, 'max_friend_count', 0,
'allow_upload_file', FALSE, 'direct_add_friend', FALSE, 'allow_create_group', FALSE,
'allow_group_message', TRUE, 'allow_private_message', TRUE,
'allow_qrcode_add_friend', FALSE, 'allow_group_member_profile', FALSE,
'hide_profile_when_friend_disabled', TRUE
), JSON_ARRAY(), JSON_ARRAY(), 1, '系统初始化:访客用户权限', 0, 0
FROM `im_tenant` WHERE `state` = 1
ON DUPLICATE KEY UPDATE `group_name` = VALUES(`group_name`), `status` = 1, `updated_at` = CURRENT_TIMESTAMP(3);
@@ -0,0 +1,85 @@
-- Keep optional workbench features outside the core IM menu tree.
SET NAMES utf8mb4;
SET @now := NOW();
INSERT INTO `hg_admin_menu` (`pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT 0, '工作台管理', 'workbenchManager', '/workbench', 'AppstoreOutlined', 1, '/workbench/config/index', '', '', 'LAYOUT', 1, '', 1, 0, '', 0, 0, 0, 1, '', 126, '附加功能独立管理入口', 1, @now, @now
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'workbenchManager');
SET @workbenchRootId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'workbenchManager' LIMIT 1);
UPDATE `hg_admin_menu`
SET `pid` = 0, `title` = '工作台管理', `path` = '/workbench', `icon` = 'AppstoreOutlined',
`type` = 1, `redirect` = '/workbench/config/index', `component` = 'LAYOUT',
`always_show` = 1, `active_menu` = '', `is_root` = 1, `hidden` = 0,
`level` = 1, `tree` = CONCAT('tr_', `id`, ' '), `sort` = 126, `status` = 1,
`updated_at` = @now
WHERE `id` = @workbenchRootId;
INSERT INTO `hg_admin_menu` (`pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT @workbenchRootId, '工作台配置', 'imWorkbenchIndex', 'config/index', '', 2, '', '/imWorkbench/list', '', '/imWorkbench/index', 1, 'workbenchManager', 0, 0, '', 0, 0, 0, 2, CONCAT('tr_', @workbenchRootId, ' '), 10, '', 1, @now, @now
WHERE @workbenchRootId IS NOT NULL
AND NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imWorkbenchIndex');
SET @imWorkbenchId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'imWorkbenchIndex' LIMIT 1);
SET @imOrgId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'imOrgIndex' LIMIT 1);
UPDATE `hg_admin_menu`
SET `pid` = @workbenchRootId, `title` = '工作台配置', `path` = 'config/index',
`type` = 2, `permissions` = '/imWorkbench/list', `component` = '/imWorkbench/index',
`always_show` = 1, `active_menu` = 'workbenchManager', `is_root` = 0, `hidden` = 0,
`level` = 2, `tree` = CONCAT('tr_', @workbenchRootId, ' '), `sort` = 10, `status` = 1,
`updated_at` = @now
WHERE `id` = @imWorkbenchId;
UPDATE `hg_admin_menu`
SET `pid` = @workbenchRootId, `title` = '组织架构', `path` = 'org/index',
`type` = 2, `permissions` = '/imOrg/departmentList', `component` = '/imOrg/index',
`always_show` = 1, `active_menu` = 'workbenchManager', `is_root` = 0, `hidden` = 0,
`level` = 2, `tree` = CONCAT('tr_', @workbenchRootId, ' '), `sort` = 20, `status` = 1,
`updated_at` = @now
WHERE `id` = @imOrgId;
INSERT INTO `hg_admin_menu` (`pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT @imWorkbenchId, item.title, item.name, '', '', 3, '', item.permissions, '', '', 1, '', 0, 0, '', 0, 1, 0, 3, CONCAT('tr_', @workbenchRootId, ' tr_', @imWorkbenchId, ' '), item.sort, '', 1, @now, @now
FROM (
SELECT '模块编辑' title, 'imWorkbenchEdit' name, '/imWorkbench/edit' permissions, 10 sort UNION ALL
SELECT '模块删除', 'imWorkbenchDelete', '/imWorkbench/delete', 20 UNION ALL
SELECT '模块排序', 'imWorkbenchReorder', '/imWorkbench/reorder', 30
) item
WHERE @imWorkbenchId IS NOT NULL
AND NOT EXISTS (SELECT 1 FROM `hg_admin_menu` menu WHERE menu.`name` = item.name);
UPDATE `hg_admin_menu`
SET `level` = 3, `tree` = CONCAT('tr_', @workbenchRootId, ' tr_', @imWorkbenchId, ' '),
`hidden` = 1, `updated_at` = @now
WHERE `pid` = @imWorkbenchId AND `type` = 3;
SET @mailboxConfigId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'imMailboxConfigIndex' LIMIT 1);
SET @feedbackConfigId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'imFeedbackConfigIndex' LIMIT 1);
UPDATE `hg_admin_menu`
SET `pid` = @workbenchRootId, `path` = 'mailbox-config/index', `active_menu` = 'workbenchManager',
`level` = 2, `tree` = CONCAT('tr_', @workbenchRootId, ' '), `sort` = 30,
`status` = 1, `hidden` = 0, `updated_at` = @now
WHERE `id` = @mailboxConfigId;
UPDATE `hg_admin_menu`
SET `pid` = @workbenchRootId, `path` = 'feedback-config/index', `active_menu` = 'workbenchManager',
`level` = 2, `tree` = CONCAT('tr_', @workbenchRootId, ' '), `sort` = 40,
`status` = 1, `hidden` = 0, `updated_at` = @now
WHERE `id` = @feedbackConfigId;
UPDATE `hg_admin_menu` child
JOIN `hg_admin_menu` page ON page.`id` = child.`pid`
SET child.`level` = 3,
child.`tree` = CONCAT('tr_', @workbenchRootId, ' tr_', page.`id`, ' '),
child.`updated_at` = @now
WHERE page.`id` IN (@imOrgId, @mailboxConfigId, @feedbackConfigId)
AND child.`type` = 3;
-- Preserve access for every role which could already open a workbench feature.
INSERT IGNORE INTO `hg_admin_role_menu` (`role_id`, `menu_id`)
SELECT `role_id`, @workbenchRootId
FROM `hg_admin_role_menu`
WHERE `menu_id` IN (@imWorkbenchId, @imOrgId, @mailboxConfigId, @feedbackConfigId);
@@ -1,8 +1,6 @@
-- IM registration SMS switch and registration invite admin migration.
-- This file is idempotent for MySQL deployments using HotGo's default hg_ prefix.
SET NAMES utf8mb4;
-- im_tenant is the only tenant registry. Admin identities reference it directly.
SET @tenant_column_exists := (
SELECT COUNT(*) FROM information_schema.COLUMNS
@@ -77,6 +75,48 @@ CREATE TABLE IF NOT EXISTS im_admin_operation_audit (
UNIQUE KEY uk_im_admin_audit_request_action (request_id, action)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- Invitation definitions belong to the HotGo control database. Tenant
-- databases retain only im_registration_invite_uses.
CREATE TABLE IF NOT EXISTS im_registration_invite_batches (
id BIGINT NOT NULL,
tenant_id BIGINT NOT NULL,
quantity INT UNSIGNED NOT NULL,
max_uses_per_code INT UNSIGNED NOT NULL DEFAULT 0,
idempotency_key VARCHAR(128) NOT NULL,
expires_at DATETIME(3) NOT NULL,
created_by BIGINT NOT NULL,
remark VARCHAR(255) NOT NULL DEFAULT '',
created_at DATETIME(3) NOT NULL,
updated_at DATETIME(3) NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY uk_im_registration_invite_batch_tenant_idempotency (tenant_id, idempotency_key),
KEY idx_im_registration_invite_batch_tenant_created (tenant_id, created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS im_registration_invite_codes (
id BIGINT NOT NULL,
tenant_id BIGINT NOT NULL,
batch_id BIGINT NULL,
code CHAR(5) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
status VARCHAR(16) NOT NULL,
expires_at DATETIME(3) NOT NULL,
max_uses INT UNSIGNED NOT NULL DEFAULT 0,
bound_user_id BIGINT NULL,
bound_user_label VARCHAR(128) NOT NULL DEFAULT '',
usage_count INT UNSIGNED NOT NULL DEFAULT 0,
last_used_at DATETIME(3) NULL,
created_by BIGINT NOT NULL,
remark VARCHAR(255) NOT NULL DEFAULT '',
created_at DATETIME(3) NOT NULL,
updated_at DATETIME(3) NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY uk_im_registration_invite_code_tenant (tenant_id, code),
KEY idx_im_registration_invite_tenant_bound_user (tenant_id, bound_user_id),
KEY idx_im_registration_invite_tenant_status_expires (tenant_id, status, expires_at),
KEY idx_im_registration_invite_tenant_batch (tenant_id, batch_id),
KEY idx_im_registration_invite_tenant_created (tenant_id, created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT
@@ -104,6 +144,25 @@ WHERE NOT EXISTS (SELECT 1 FROM hg_admin_menu WHERE name = 'imRegistrationInvite
SET @invitePage := (SELECT id FROM hg_admin_menu WHERE name = 'imRegistrationInviteIndex' LIMIT 1);
UPDATE hg_admin_menu SET tree = CONCAT('tr_', id, ' tr_', @imRoot, ' ') WHERE id = @invitePage;
SET @imTenantPage := (SELECT id FROM hg_admin_menu WHERE name = 'imTenantIndex' LIMIT 1);
INSERT INTO hg_admin_menu
(pid, level, tree, title, name, path, icon, type, permissions, component, hidden, sort, status, created_at, updated_at)
SELECT @imTenantPage, 4, CONCAT('tr_', @imTenantPage, ' '), '租户用量与健康', 'imTenantUsage', '', '', 3,
'/imTenant/usage', '', 1, 40, 1, NOW(), NOW()
WHERE @imTenantPage IS NOT NULL
AND NOT EXISTS (SELECT 1 FROM hg_admin_menu WHERE name = 'imTenantUsage');
INSERT INTO hg_admin_menu
(pid, level, tree, title, name, path, icon, type, permissions, component, hidden, sort, status, created_at, updated_at)
SELECT @imTenantPage, 4, CONCAT('tr_', @imTenantPage, ' '), title, name, '', '', 3, permissions, '', 1, sort, 1, NOW(), NOW()
FROM (
SELECT '租户删除前检查' title, 'imTenantDeletionCheck' name, '/imTenant/deletionCheck' permissions, 50 sort UNION ALL
SELECT '租户进入删除流程', 'imTenantEnterDeleting', '/imTenant/enterDeleting', 60 UNION ALL
SELECT '恢复租户', 'imTenantRestore', '/imTenant/restore', 70
) p
WHERE @imTenantPage IS NOT NULL
AND NOT EXISTS (SELECT 1 FROM hg_admin_menu m WHERE m.name = p.name);
INSERT INTO hg_admin_menu
(pid, level, tree, title, name, path, icon, type, permissions, component, sort, status, created_at, updated_at)
SELECT @invitePage, 3, CONCAT('tr_', @invitePage, ' tr_', @imRoot, ' '), title, name, '', '', 3, permissions, '', sort, 1, NOW(), NOW()
@@ -112,7 +171,48 @@ FROM (
SELECT '批量生成邀请码', 'imInviteBatchCreate', '/imInvite/batchCreate', 20 UNION ALL
SELECT '批次详情', 'imInviteBatchView', '/imInvite/batchView', 30 UNION ALL
SELECT '撤销邀请码', 'imInviteRevoke', '/imInvite/revoke', 40 UNION ALL
SELECT '批量撤销邀请码', 'imInviteBatchRevoke', '/imInvite/batchRevoke', 50 UNION ALL
SELECT '导出邀请码', 'imInviteExport', '/imInvite/export', 60
SELECT '绑定用户', 'imInviteBindUser', '/imInvite/bindUser', 50 UNION ALL
SELECT '批量撤销邀请码', 'imInviteBatchRevoke', '/imInvite/batchRevoke', 60 UNION ALL
SELECT '导出邀请码', 'imInviteExport', '/imInvite/export', 70
) p
WHERE NOT EXISTS (SELECT 1 FROM hg_admin_menu m WHERE m.name = p.name);
SET @systemConfigPage := (SELECT id FROM hg_admin_menu WHERE name = 'system_config' LIMIT 1);
INSERT INTO hg_admin_menu
(pid, level, tree, title, name, path, icon, type, permissions, component, hidden, sort, status, created_at, updated_at)
SELECT @systemConfigPage, 3, CONCAT('tr_', @systemConfigPage, ' '), title, name, '', '', 3, permissions, '', 1, sort, 1, NOW(), NOW()
FROM (
SELECT '查看IM注册配置' title, 'imRegistrationConfigGet' name, '/imRegistration/config/get' permissions, 80 sort UNION ALL
SELECT '更新IM注册配置', 'imRegistrationConfigUpdate', '/imRegistration/config/update', 90
) p
WHERE @systemConfigPage IS NOT NULL
AND NOT EXISTS (SELECT 1 FROM hg_admin_menu m WHERE m.name = p.name);
SET @imUserPage := (SELECT id FROM hg_admin_menu WHERE name = 'imUserIndex' LIMIT 1);
INSERT INTO hg_admin_menu
(pid, level, tree, title, name, path, icon, type, permissions, component, hidden, sort, status, created_at, updated_at)
SELECT @imUserPage, 4, CONCAT('tr_', @imUserPage, ' '), '重置用户密码', 'imUserResetPassword', '', '', 3,
'/imUser/resetPassword', '', 1, 20, 1, NOW(), NOW()
WHERE @imUserPage IS NOT NULL
AND NOT EXISTS (SELECT 1 FROM hg_admin_menu WHERE name = 'imUserResetPassword');
INSERT INTO hg_admin_menu
(pid, level, tree, title, name, path, icon, type, permissions, component, hidden, sort, status, created_at, updated_at)
SELECT @imUserPage, 4, CONCAT('tr_', @imUserPage, ' '), '用户设备列表', 'imUserDevices', '', '', 3,
'/imUser/devices', '', 1, 30, 1, NOW(), NOW()
WHERE @imUserPage IS NOT NULL
AND NOT EXISTS (SELECT 1 FROM hg_admin_menu WHERE name = 'imUserDevices');
INSERT INTO hg_admin_menu
(pid, level, tree, title, name, path, icon, type, permissions, component, hidden, sort, status, created_at, updated_at)
SELECT @imUserPage, 4, CONCAT('tr_', @imUserPage, ' '), '撤销用户会话', 'imUserRevokeSessions', '', '', 3,
'/imUser/revokeSessions', '', 1, 40, 1, NOW(), NOW()
WHERE @imUserPage IS NOT NULL
AND NOT EXISTS (SELECT 1 FROM hg_admin_menu WHERE name = 'imUserRevokeSessions');
INSERT INTO hg_admin_menu
(pid, level, tree, title, name, path, icon, type, permissions, component, hidden, sort, status, created_at, updated_at)
SELECT @imUserPage, 4, CONCAT('tr_', @imUserPage, ' '), '更新用户状态', 'imUserStatus', '', '', 3,
'/imUser/status', '', 1, 50, 1, NOW(), NOW()
WHERE @imUserPage IS NOT NULL
AND NOT EXISTS (SELECT 1 FROM hg_admin_menu WHERE name = 'imUserStatus');