Files
im_manager/server/storage/data/im_registration_invite_hotgo.sql
T

228 lines
11 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- IM registration SMS switch and registration invite admin migration.
-- This file is idempotent for MySQL deployments using HotGo's default hg_ prefix.
-- im_tenant is the only tenant registry. Admin identities reference it directly.
SET @tenant_column_exists := (
SELECT COUNT(*) FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'hg_admin_member' AND COLUMN_NAME = 'tenant_id'
);
SET @ddl := IF(
@tenant_column_exists = 0,
'ALTER TABLE hg_admin_member ADD COLUMN tenant_id BIGINT NULL COMMENT ''IM tenant ID'' AFTER id',
'SELECT 1'
);
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- Preserve an existing deployment's old mapping before removing the redundant table.
SET @binding_table_exists := (
SELECT COUNT(*) FROM information_schema.TABLES
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'im_admin_tenant_binding'
);
SET @dml := IF(
@binding_table_exists > 0,
'UPDATE hg_admin_member AS m JOIN im_admin_tenant_binding AS b ON b.hotgo_tenant_id = m.id SET m.tenant_id = b.im_tenant_id WHERE b.status = 1 AND m.tenant_id IS NULL',
'SELECT 1'
);
PREPARE stmt FROM @dml;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
DROP TABLE IF EXISTS im_admin_tenant_binding;
SET @tenant_index_exists := (
SELECT COUNT(*) FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'hg_admin_member' AND INDEX_NAME = 'idx_hg_admin_member_tenant'
);
SET @ddl := IF(
@tenant_index_exists = 0,
'ALTER TABLE hg_admin_member ADD INDEX idx_hg_admin_member_tenant (tenant_id)',
'SELECT 1'
);
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @tenant_fk_exists := (
SELECT COUNT(*) FROM information_schema.REFERENTIAL_CONSTRAINTS
WHERE CONSTRAINT_SCHEMA = DATABASE() AND TABLE_NAME = 'hg_admin_member' AND CONSTRAINT_NAME = 'fk_hg_admin_member_im_tenant'
);
SET @ddl := IF(
@tenant_fk_exists = 0,
'ALTER TABLE hg_admin_member ADD CONSTRAINT fk_hg_admin_member_im_tenant FOREIGN KEY (tenant_id) REFERENCES im_tenant(id)',
'SELECT 1'
);
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
CREATE TABLE IF NOT EXISTS im_admin_operation_audit (
id BIGINT NOT NULL AUTO_INCREMENT,
request_id VARCHAR(64) NOT NULL,
tenant_id BIGINT NULL,
operator_id BIGINT NOT NULL,
action VARCHAR(64) NOT NULL,
target_type VARCHAR(32) NOT NULL,
target_id BIGINT NULL,
result VARCHAR(16) NOT NULL,
ip VARCHAR(64) NOT NULL DEFAULT '',
detail_json JSON NULL,
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
PRIMARY KEY (id),
KEY idx_im_admin_audit_tenant_time (tenant_id, created_at),
KEY idx_im_admin_audit_operator_time (operator_id, created_at),
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
'im', '注册短信发送', 'bool', 'register_sms_enabled', '1', '1', 10,
'控制 IM 注册验证码是否真实发送', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (
SELECT 1 FROM hg_sys_config WHERE `group` = 'im' AND `key` = 'register_sms_enabled'
);
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT
'im', 'UID加密密钥', 'string', 'uid_encryption_key', '', '', 20,
'IM Server UID_ENCRYPTION_KEY,用于工作台按 usr 用户ID解析用户资料', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (
SELECT 1 FROM hg_sys_config WHERE `group` = 'im' AND `key` = 'uid_encryption_key'
);
INSERT INTO hg_admin_menu
(pid, level, tree, title, name, path, icon, type, redirect, permissions, component, always_show, is_root, is_frame, keep_alive, hidden, affix, sort, status, created_at, updated_at)
SELECT
0, 1, '', 'IM管理', 'imManager', '/im', 'AppstoreOutlined', 1, '', '', 'LAYOUT', 0, 0, 1, 0, 0, 0, 125, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_admin_menu WHERE name = 'imManager');
SET @imRoot := (SELECT id FROM hg_admin_menu WHERE name = 'imManager' LIMIT 1);
UPDATE hg_admin_menu SET tree = CONCAT('tr_', id, ' '), component = 'LAYOUT' WHERE id = @imRoot;
INSERT INTO hg_admin_menu
(pid, level, tree, title, name, path, icon, type, redirect, permissions, component, always_show, is_root, is_frame, keep_alive, hidden, affix, sort, status, created_at, updated_at)
SELECT
@imRoot, 2, '', '注册邀请码', 'imRegistrationInviteIndex', 'registrationInvite', '', 2, '', '/imInvite/list', '/im/registrationInvite/index', 0, 0, 1, 0, 0, 0, 70, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_admin_menu WHERE name = 'imRegistrationInviteIndex');
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()
FROM (
SELECT '生成邀请码' title, 'imInviteCreate' name, '/imInvite/create' permissions, 10 sort UNION ALL
SELECT '批量生成邀请码', 'imInviteBatchCreate', '/imInvite/batchCreate', 20 UNION ALL
SELECT '批次详情', 'imInviteBatchView', '/imInvite/batchView', 30 UNION ALL
SELECT '撤销邀请码', 'imInviteRevoke', '/imInvite/revoke', 40 UNION ALL
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');