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.3 KiB

02 · 角色 × 模块档位存储

Type: grilling Status: resolved Blocked by: 01

Question

角色对每个模块的档位怎么存?现在是 sys_role.data_scope 单列(一个全局档位)。

要定的点:

  • 子表结构:如 sys_role_data_scope(role_id, module_id, level),role×module 唯一。
  • sys_role.data_scope 列的处置:删除 / 保留作某种默认 / 迁移后废弃(迁移策略在 03)。
  • 角色对某模块未配档位时的语义:沿用「无角色/未配按最窄档 SELF」(现 PermissionResolverImpl 的约定),还是别的默认?
  • DataScopeEnum / CUSTOM(5) 是否仍适用(现角色不用 CUSTOM)。

依赖 01 定下的模块标识(module_id 指向什么)。

Answer

1. 子表结构

sys_role_data_scope (
    id bigint PK AUTO_INCREMENT,
    role_id bigint NOT NULL,
    module_code varchar(50) NOT NULL,  -- 引用 sys_data_scope_module.code,不引用 id
    data_scope tinyint NOT NULL,       -- 1=SELF, 2=DEPT, 3=DEPT_AND_CHILDREN, 4=ALL
    UNIQUE KEY uk_role_module (role_id, module_code)
)
  • module_code 用 string 而非 bigint id,与 @DataScope(module = "...") 注解同源,与 crm-dict「业务数据只存字典编码」约定一致。
  • PermissionResolver 查角色×模块档位时直接拿到 code,不需 join 注册表。
  • data_scope 存 1-4(tinyint),与现有 sys_role.data_scope 存储格式一致。

2. 旧 sys_role.data_scope 列:迁移后删除

  • 新存储完全取代旧列。
  • 迁移过程(03 票负责):把旧 sys_role.data_scope 的值复制到新表每个已知模块的行,然后删除旧列与 SysRole.dataScope 字段。
  • 终态:sys_role 表不再有 data_scope 列,SysRole 实体不再有 dataScope 字段。

3. 角色对某模块未配档位时:默认 SELF(最窄档)

  • 角色×模块无行 = SELF(与现有「无角色 = SELF」约定一致)。
  • 多角色取最宽时,未配模块的角色贡献 SELF(不放宽任何人的可见范围)。
  • 新增模块后存量角色自动走 SELF(fail safe),管理员再按需放宽。

4. CUSTOM(5):删除

  • DataScopeEnum 移除 CUSTOM(5),只保留 SELF(1)/DEPT(2)/DEPT_AND_CHILD(3)/ALL(4),与 DataScopeLevel 对齐。
  • SysRoleServiceImplfilter(e != DataScopeEnum.CUSTOM) 可简化为直接用全部枚举值。
  • DataScopeEnum 仍保留(用于初始化与校验),不与 DataScopeLevel 合并(二者分层不同:DataScopeEnum 在 crm-auth 应用层有 label,DataScopeLevel 在 crm-base 基础设施层无 label)。

对下游工单的影响

  • 03(迁移):依赖 02 的存储结构已定,可以设计迁移规则——把旧 sys_role.data_scope 复制到新表每个已知模块的行。03 现已解阻(was Blocked by 02)。
  • 04(上下文值对象):PermissionResolver 需改为对每个模块在所有角色的该模块档位里取最宽(未配 = SELF)。sys_role_data_scope 表的查询:按 role_id 批量取所有行,按 module_code 分组取最宽。
  • 05(拦截器):拦截器需从上下文按 module_codeVisibilityScope,不再取单一全局 scope。
  • 07(API 契约):角色保存接口从传单个 dataScope 改为传 List<{moduleCode, dataScope}>;角色详情接口返回 per-module 档位列表。