Files
wucaixing-backend/驾驶员默认角色缺失排查与修复.md

6.7 KiB
Raw Permalink Blame History

驾驶员默认角色缺失排查与修复

1. 背景

驾驶员默认角色常量定义见 ISysUserLoginPortService.java:L29-L37

  • 默认驾驶员角色 ID2010339247320825857
  • 驾驶员登录端口:port-driver

源码定义:

Long DRIVER_ROLE_ID = 2010339247320825857L;
String DRIVER_PORT = "port-driver";

2. 表结构确认

已核对同步库 sys_user_role 表结构,核心字段如下:

  • user_id
  • role_id
  • company_id
  • login_port

说明:

  • 该表当前只需要写入以上 4 个字段即可完成角色补齐。
  • 因此修复 SQL 可直接对 sys_user_role 执行 insert into ... select ...

3. 排查 SQL

3.1 统计缺失默认驾驶员角色的数量

select count(*) as missing_driver_default_role_count
from (
    select
        sulp.user_id,
        sulp.company_id
    from sys_user_login_port sulp
    left join sys_user_role sur
        on sur.user_id = sulp.user_id
       and sur.company_id = sulp.company_id
       and sur.login_port = sulp.login_port
       and sur.role_id = 2010339247320825857
    where sulp.login_port = 'port-driver'
      and sulp.status = 1
    group by sulp.user_id, sulp.company_id
    having count(sur.role_id) = 0
) t;

3.2 查看具体是哪个公司、哪个驾驶员账号缺失

select
    sulp.company_id,
    c.company_name as company_name,
    sulp.user_id,
    sulp.username,
    d.id as driver_id,
    d.name as driver_name,
    d.phone as driver_phone,
    sulp.login_port
from sys_user_login_port sulp
left join sys_user_role sur
    on sur.user_id = sulp.user_id
   and sur.company_id = sulp.company_id
   and sur.login_port = sulp.login_port
   and sur.role_id = 2010339247320825857
left join hot_driver d
    on d.company_id = sulp.company_id
   and (
        convert(d.phone using utf8mb4) collate utf8mb4_general_ci =
            convert(sulp.username using utf8mb4) collate utf8mb4_general_ci
        or convert(d.id using utf8mb4) collate utf8mb4_general_ci =
            cast(sulp.user_id as char character set utf8mb4) collate utf8mb4_general_ci
   )
left join sys_company c
    on c.id = sulp.company_id
where sulp.login_port = 'port-driver'
  and sulp.status = 1
group by
    sulp.company_id,
    c.company_name,
    sulp.user_id,
    sulp.username,
    d.id,
    d.name,
    d.phone,
    sulp.login_port
having count(sur.role_id) = 0
order by sulp.company_id, d.name, sulp.user_id;

说明:

  • 该 SQL 以 sys_user_login_port 为准,筛选已开通驾驶员端口的账号。
  • 再检查 sys_user_role 中是否缺失默认驾驶员角色。
  • 通过 sys_company 补充公司名,通过 hot_driver 尝试补充驾驶员姓名和手机号。
  • 如果库中 hot_driversys_user_login_port 的字符集排序规则不一致,需要像上面这样显式 collate,否则会报 Illegal mix of collations

4. 修复 SQL

4.1 建议先预览待插入数据

select distinct
    sulp.user_id,
    2010339247320825857 as role_id,
    sulp.company_id,
    sulp.login_port
from sys_user_login_port sulp
where sulp.login_port = 'port-driver'
  and sulp.status = 1
  and not exists (
        select 1
        from sys_user_role sur
        where sur.user_id = sulp.user_id
          and sur.company_id = sulp.company_id
          and sur.login_port = sulp.login_port
          and sur.role_id = 2010339247320825857
  )
order by sulp.company_id, sulp.user_id;

4.2 正式修复缺失默认驾驶员角色

insert into sys_user_role (
    user_id,
    role_id,
    company_id,
    login_port
)
select distinct
    sulp.user_id,
    2010339247320825857 as role_id,
    sulp.company_id,
    sulp.login_port
from sys_user_login_port sulp
where sulp.login_port = 'port-driver'
  and sulp.status = 1
  and not exists (
        select 1
        from sys_user_role sur
        where sur.user_id = sulp.user_id
          and sur.company_id = sulp.company_id
          and sur.login_port = sulp.login_port
          and sur.role_id = 2010339247320825857
  );

说明:

  • 该 SQL 只补缺失数据,不会重复插入已存在的默认驾驶员角色。
  • 使用 not exists 作为幂等保护。
  • 使用 distinct 避免 sys_user_login_port 中重复数据导致重复插入。

5. 修复后校验 SQL

5.1 再次统计缺失数量

select count(*) as missing_driver_default_role_count
from (
    select
        sulp.user_id,
        sulp.company_id
    from sys_user_login_port sulp
    left join sys_user_role sur
        on sur.user_id = sulp.user_id
       and sur.company_id = sulp.company_id
       and sur.login_port = sulp.login_port
       and sur.role_id = 2010339247320825857
    where sulp.login_port = 'port-driver'
      and sulp.status = 1
    group by sulp.user_id, sulp.company_id
    having count(sur.role_id) = 0
) t;

预期:

  • 结果应为 0

5.2 抽样检查修复后的角色记录

select
    sur.user_id,
    sur.role_id,
    sur.company_id,
    sur.login_port
from sys_user_role sur
where sur.role_id = 2010339247320825857
  and sur.login_port = 'port-driver'
order by sur.company_id, sur.user_id;

6. 回滚 SQL

如果本次补齐后需要回滚,只回滚本次补的默认驾驶员角色数据,可使用:

delete sur
from sys_user_role sur
where sur.role_id = 2010339247320825857
  and sur.login_port = 'port-driver'
  and exists (
        select 1
        from sys_user_login_port sulp
        where sulp.user_id = sur.user_id
          and sulp.company_id = sur.company_id
          and sulp.login_port = sur.login_port
          and sulp.login_port = 'port-driver'
          and sulp.status = 1
  );

注意:

  • 这条回滚 SQL 会删除所有驾驶员端口上的默认驾驶员角色。
  • 如果线上本来就有正确数据,不建议直接使用该回滚 SQL。
  • 更稳妥的方式是:先把本次待插入数据导出备份,再按备份名单精确回滚。

7. 推荐执行顺序

  1. 先执行 3.1,确认缺失数量
  2. 再执行 3.2,确认具体公司和驾驶员账号
  3. 执行 4.1,预览待补数据
  4. 执行 4.2,正式插入
  5. 执行 5.1 和 5.2,确认修复完成

8. 风险说明

  • 当前修复只补齐“默认驾驶员角色”本身,不会补菜单权限。
  • 如果默认驾驶员角色本身未绑定菜单权限,还需要继续检查:
    • sys_role_permission
    • sys_menu
  • 如果 hot_driver 与登录账号的关联规则不是 phone = usernamedriver.id = cast(user_id as char),则 3.2 中驾驶员姓名可能为空,但不影响角色修复 SQL 的执行。