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.
 
 
 
 
 

3.1 KiB

03 · 迁移策略:现有角色单一档位 → 多模块档位

Type: grilling Status: resolved Blocked by: 02

Question

现有角色的单一 sys_role.data_scope 值,如何迁移到新的角色×模块档位存储?

要定的点:

  • 迁移规则:把老的单一档位复制到每个已知模块(四个都用这一档),还是别的映射?
  • 迁移时点/形式:Flyway/Liquibase 脚本?DataInitializer 里补?一次性 SQL? (查现状:本 repo 用什么做 schema 迁移。)
  • 内置角色(ADMIN,builtin=true,现 data_scope=ALL)迁移后各模块是否仍 ALL。
  • 迁移可逆性 / 回滚考量。

依赖 02 定下的新存储结构。

Answer

1. 迁移规则

sys_role.data_scope 单值复制到每个已知模块(lead / opportunity / customer / project),值相同。

  • ADMIN(builtin=true,ALL)→ 每模块各一行 ALL。
  • 其他角色同理:旧值是 DEPT 就四个模块都是 DEPT。
  • 旧值为 null 的角色不产生行(走默认 SELF,02 决策 3)。

2. 迁移机制:一次性 SQL 脚本(单事务)

本 repo 无 Flyway/Liquibase,无 SQL 迁移脚本目录。用一次性 SQL 脚本(手动执行,部署时跑):

BEGIN;

-- 1. 建模块注册表
CREATE TABLE sys_data_scope_module (
    id bigint PK AUTO_INCREMENT,
    code varchar(50) NOT NULL UNIQUE,
    name varchar(100) NOT NULL,
    sort int NOT NULL DEFAULT 0,
    status varchar(10) NOT NULL DEFAULT 'enabled',
    builtin boolean NOT NULL DEFAULT false
);

-- 2. 插入内置模块
INSERT INTO sys_data_scope_module (code, name, sort, builtin) VALUES
    ('lead', '线索', 1, true),
    ('opportunity', '商机', 2, true),
    ('customer', '客户', 3, true),
    ('project', '项目', 4, true);

-- 3. 建角色×模块档位表
CREATE TABLE sys_role_data_scope (
    id bigint PK AUTO_INCREMENT,
    role_id bigint NOT NULL,
    module_code varchar(50) NOT NULL,
    data_scope tinyint NOT NULL,
    UNIQUE KEY uk_role_module (role_id, module_code)
);

-- 4. 迁移:旧单值复制到每模块
INSERT INTO sys_role_data_scope (role_id, module_code, data_scope)
SELECT r.id, m.code, r.data_scope
FROM sys_role r
CROSS JOIN sys_data_scope_module m
WHERE r.data_scope IS NOT NULL;

-- 5. 删旧列
ALTER TABLE sys_role DROP COLUMN data_scope;

COMMIT;
  • 单事务保证原子性:要么全成功,要么全回滚。
  • CROSS JOIN 把旧值复制到每个模块。
  • 步骤 5 删旧列在同一个事务里——一步到位(用户决策)。

3. DataInitializer 同步改

  • adminRole.setDataScope(DataScopeEnum.ALL.getValue()) 删除。
  • ADMIN 角色创建后,往 sys_role_data_scope 为每个模块插 ALL 行(幂等检查:先查行是否存在)。
  • 新增内置模块初始化:往 sys_data_scope_module 插入四个内置模块(幂等检查)。
  • SysRole.dataScope 字段删除。

4. 回滚考量

  • SQL 脚本是单事务,失败自动回滚。
  • 成功后旧列已删,无法从 SQL 层面回滚。如需回滚:从备份恢复旧列,删新表数据,重跑 DataInitializer。
  • 实际风险低:CROSS JOIN 是确定性的,没有数据丢失风险。