6.7 KiB
6.7 KiB
驾驶员默认角色缺失排查与修复
1. 背景
驾驶员默认角色常量定义见 ISysUserLoginPortService.java:L29-L37
- 默认驾驶员角色 ID:
2010339247320825857 - 驾驶员登录端口:
port-driver
源码定义:
Long DRIVER_ROLE_ID = 2010339247320825857L;
String DRIVER_PORT = "port-driver";
2. 表结构确认
已核对同步库 sys_user_role 表结构,核心字段如下:
user_idrole_idcompany_idlogin_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_driver与sys_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. 推荐执行顺序
- 先执行 3.1,确认缺失数量
- 再执行 3.2,确认具体公司和驾驶员账号
- 执行 4.1,预览待补数据
- 执行 4.2,正式插入
- 执行 5.1 和 5.2,确认修复完成
8. 风险说明
- 当前修复只补齐“默认驾驶员角色”本身,不会补菜单权限。
- 如果默认驾驶员角色本身未绑定菜单权限,还需要继续检查:
sys_role_permissionsys_menu
- 如果
hot_driver与登录账号的关联规则不是phone = username或driver.id = cast(user_id as char),则 3.2 中驾驶员姓名可能为空,但不影响角色修复 SQL 的执行。