You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

93 lines
3.5 KiB

-- ============================================================
-- 数据权限按业务模块可配:一次性迁移脚本(单事务)
-- 工单 03 决策:建两表 + 插内置模块 + CROSS JOIN 旧值 + DROP 旧列
-- 部署时手动执行,单事务保证原子性
-- ============================================================
BEGIN;
-- 1. 建模块注册表
CREATE TABLE IF NOT EXISTS sys_data_scope_module (
id bigint NOT NULL AUTO_INCREMENT,
code varchar(50) NOT NULL COMMENT '模块编码(稳定标识)',
name varchar(100) NOT NULL COMMENT '模块名称',
sort int NOT NULL DEFAULT 0 COMMENT '排序',
status varchar(10) NOT NULL DEFAULT 'enabled' COMMENT '状态:enabled/disabled',
builtin boolean NOT NULL DEFAULT false COMMENT '内置模块标记',
create_time datetime DEFAULT NULL,
update_time datetime DEFAULT NULL,
creator_id varchar(36) DEFAULT NULL,
updater_id varchar(36) DEFAULT NULL,
deleted boolean DEFAULT false,
PRIMARY KEY (id),
UNIQUE KEY uk_module_code (code)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='数据权限模块注册表';
-- 2. 插入内置模块
INSERT INTO sys_data_scope_module (code, name, sort, builtin)
SELECT * FROM (
SELECT 'lead' AS code, '线索' AS name, 1 AS sort, true AS builtin
UNION ALL
SELECT 'opportunity', '商机', 2, true
UNION ALL
SELECT 'customer', '客户', 3, true
UNION ALL
SELECT 'project', '项目', 4, true
) AS new_modules
WHERE NOT EXISTS (
SELECT 1 FROM sys_data_scope_module WHERE code = new_modules.code
);
-- 3. 建角色×模块档位表
CREATE TABLE IF NOT EXISTS sys_role_data_scope (
id bigint NOT NULL AUTO_INCREMENT,
role_id bigint NOT NULL COMMENT '角色ID',
module_code varchar(50) NOT NULL COMMENT '模块编码(引用 sys_data_scope_module.code)',
data_scope tinyint NOT NULL COMMENT '数据范围 1=本人 2=本部门 3=本部门及子部门 4=全部',
create_time datetime DEFAULT NULL,
update_time datetime DEFAULT NULL,
creator_id varchar(36) DEFAULT NULL,
updater_id varchar(36) DEFAULT NULL,
deleted boolean DEFAULT false,
PRIMARY KEY (id),
UNIQUE KEY uk_role_module (role_id, module_code)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色×模块数据范围档位';
-- 4. 迁移:旧单值复制到每模块(仅迁移 sys_role 有 data_scope 列时执行)
-- 使用 INFORMATION_SCHEMA 检查列是否存在,避免列已删除后重复执行报错
SET @col_exists = (
SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'sys_role'
AND COLUMN_NAME = 'data_scope'
);
-- 构建动态 SQL 执行迁移
SET @sql = IF(@col_exists > 0,
'INSERT INTO sys_role_data_scope (role_id, module_code, data_scope, create_time, update_time, deleted)
SELECT r.id, m.code, r.data_scope, NOW(), NOW(), false
FROM sys_role r
CROSS JOIN sys_data_scope_module m
WHERE r.data_scope IS NOT NULL
AND NOT EXISTS (
SELECT 1 FROM sys_role_data_scope rsd
WHERE rsd.role_id = r.id AND rsd.module_code = m.code
)',
'SELECT "sys_role.data_scope column already removed, skipping migration" AS msg'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 5. 删旧列(仅在列存在时执行)
SET @sql2 = IF(@col_exists > 0,
'ALTER TABLE sys_role DROP COLUMN data_scope',
'SELECT "sys_role.data_scope column already removed" AS msg'
);
PREPARE stmt2 FROM @sql2;
EXECUTE stmt2;
DEALLOCATE PREPARE stmt2;
COMMIT;