-- =====================================================================================
|
-- 【已改为代码修复,本文件的 INSERT 不需要执行】
|
-- 2026-11-06 决定:管理员天然拥有全部科室权限,直接查 sys_dept,不再往 sys_user_dept 补数据。
|
-- 代码改动见:
|
-- SysDeptMapper.xml#selectSysDeptListBySysUserDept(userId 为空时只查 sys_dept)
|
-- SysDeptServiceImpl#selectLeafSysDeptListBySysUserDept(userId 为空时不做叶子过滤)
|
-- SysUserServiceImpl#selectLeafSysDeptList / selectLeafSysDeptForAdmin / selectUserByUserName
|
-- SysLoginController#getInfo(管理员不传 userId、不按院区过滤)
|
-- 本文件保留下来只作为「诊断口径」参考:第 0 步和第 3 步的查询仍可用于核对
|
-- 「某个用户到底能查到多少科室/病区」,第 1、2 步的写入可以忽略。
|
-- =====================================================================================
|
|
-- =====================================================================================
|
-- 修复:admin 登录后没有科室/病区(belongDepts / belongWards 为空),创建任务选不到科室病区
|
-- 日期:2026-11-06 库:smartor_nhfy
|
--
|
-- 结论(代码 + 数据链路已核对,加索引不会改变结果,因为这不是慢,是查不到):
|
-- 前端下拉用的是 /getInfo 返回的 belongDepts / belongWards:
|
-- SysLoginController#getInfo(L243-254)
|
-- → SysDeptServiceImpl#selectLeafSysDeptListBySysUserDept(L335-341)
|
-- → SysDeptMapper#selectSysDeptListBySysUserDept(SysDeptMapper.xml L286-298)
|
-- 核心是 INNER JOIN sys_user_dept ud ON d.dept_code = ud.dept_code
|
-- 并且这次带上了 userId(sysUserDept.setUserId(user.getUserId()))。
|
-- 而 HIS 采集写入 sys_user_dept 时明确排除了 admin:
|
-- CollectHISMapper.xml yhyksxx(L494)/ yhybfxx(L513)/ yhyyqxx(L536)都有 `ud.user_id != 'admin'`
|
-- 所以 admin 在 sys_user_dept 里没有任何行 → 上面这条 join 返回 0 行 → 两个列表都是空。
|
-- (登录 token 走的那条 selectUserByUserName2 里 admin 分支不带 userId,所以那条反而是有数据的,
|
-- 这也是为什么“登录成功但还是没有科室病区”——登录返回的和 /getInfo 覆盖的不一致。)
|
--
|
-- 顺带两个坑:
|
-- a) sys_dept.campusid 为空的部门会被 `and d.campusid = #{campusid}` 过滤掉;
|
-- b) sys_config 里没有 sys.authority.campus.all(已查证为空),所以 admin 的 campusid 不会被清空。
|
-- =====================================================================================
|
|
|
-- -------------------------------------------------------------------------------------
|
-- 第 0 步:先确认(只读;这三条跑完就知道是不是这个原因)
|
-- -------------------------------------------------------------------------------------
|
-- 0.1 admin 在 sys_user_dept 里到底有没有数据(预期 0 行)
|
SELECT u.user_id, u.user_name, u.orgid, u.campusid, u.searchscope,
|
(SELECT COUNT(*) FROM sys_user_dept ud
|
WHERE ud.user_id = u.user_id AND ud.del_flag = '0') AS 有效关系数,
|
(SELECT COUNT(*) FROM sys_user_dept ud WHERE ud.user_id = u.user_id) AS 含已删关系数
|
FROM sys_user u
|
WHERE u.user_name = 'admin';
|
|
-- 0.2 复刻 /getInfo 的 SQL(带 userId)—— 预期 0 行
|
SELECT d.dept_type, COUNT(*) AS rows_, COUNT(DISTINCT d.dept_code) AS codes
|
FROM sys_dept d
|
INNER JOIN sys_user_dept ud ON d.dept_code = ud.dept_code
|
WHERE d.del_flag = '0' AND ud.del_flag = '0'
|
AND d.orgid = '20001001' AND ud.orgid = '20001001' -- 换成 admin 的 orgid
|
AND ud.user_id = (SELECT user_id FROM sys_user WHERE user_name = 'admin')
|
AND d.campusid = '30001002' -- 换成 admin 的 campusid
|
GROUP BY d.dept_type;
|
|
-- 0.3 同一套 SQL 去掉 userId / campusid 之后能查到多少(预期几百行 = 应该看到的量)
|
SELECT d.dept_type, COUNT(*) AS rows_, COUNT(DISTINCT d.dept_code) AS codes
|
FROM sys_dept d
|
WHERE d.del_flag = '0' AND d.orgid = '20001001'
|
GROUP BY d.dept_type;
|
|
|
-- -------------------------------------------------------------------------------------
|
-- 第 1 步(推荐,立刻生效、不用发版):给 admin 补全 sys_user_dept
|
-- 把该机构下所有科室(dept_type='1')和病区(dept_type='2')都挂到 admin 名下,
|
-- 之后 /getInfo 那条 join 就有数据了;配合刚加的索引,查询也是毫秒级。
|
-- 幂等:重复执行不会插重复行(NOT EXISTS 按 user_id + dept_code + dept_type 判重)。
|
-- -------------------------------------------------------------------------------------
|
-- 1.1 先看会插多少行(不插,先确认数量合理)
|
SELECT u.user_name, d.dept_type, COUNT(*) AS will_insert
|
FROM sys_user u
|
JOIN sys_dept d ON d.del_flag = '0'
|
AND d.orgid = u.orgid
|
AND d.dept_type IN ('1', '2')
|
WHERE u.user_name = 'admin'
|
AND NOT EXISTS (SELECT 1 FROM sys_user_dept x
|
WHERE x.user_id = u.user_id
|
AND x.dept_code = d.dept_code
|
AND x.dept_type = d.dept_type
|
AND IFNULL(x.orgid, '') = IFNULL(d.orgid, ''))
|
GROUP BY u.user_name, d.dept_type;
|
|
-- 1.2 正式插入(要跨院区看全部就把 campusid 一并按 sys_dept 带过去)
|
INSERT INTO sys_user_dept
|
(user_id, dept_id, dept_code, dept_name, dept_type, orgid, campusid, del_flag, create_time, update_time)
|
SELECT u.user_id, d.dept_id, d.dept_code, d.dept_name, d.dept_type, d.orgid, d.campusid,
|
'0', NOW(), NOW()
|
FROM sys_user u
|
JOIN sys_dept d ON d.del_flag = '0'
|
AND d.orgid = u.orgid
|
AND d.dept_type IN ('1', '2')
|
WHERE u.user_name = 'admin'
|
AND NOT EXISTS (SELECT 1 FROM sys_user_dept x
|
WHERE x.user_id = u.user_id
|
AND x.dept_code = d.dept_code
|
AND x.dept_type = d.dept_type
|
AND IFNULL(x.orgid, '') = IFNULL(d.orgid, ''));
|
|
-- 1.3 回滚 1.2(如果插多了):按插入时间精确删
|
-- DELETE FROM sys_user_dept
|
-- WHERE user_id = (SELECT user_id FROM sys_user WHERE user_name = 'admin')
|
-- AND create_time >= '2026-11-06 00:00:00'
|
-- AND update_time = create_time;
|
|
|
-- -------------------------------------------------------------------------------------
|
-- 第 2 步(可选,让它看到全部院区):把 admin 加进「不限院区」白名单
|
-- SysLoginController#getInfo L227-233 会读这个配置,命中就把 campusid 置空,
|
-- 于是 `and d.campusid = #{campusid}` 这条过滤不再拼,跨院区的科室病区也能出来。
|
-- 现在 sys_config 里没有这个 key(已查证),需要手工加一条。
|
-- -------------------------------------------------------------------------------------
|
-- INSERT INTO sys_config (config_name, config_key, config_value, config_type, create_by, create_time, remark)
|
-- VALUES ('不限院区的账号', 'sys.authority.campus.all', 'admin', 'N', 'admin', NOW(),
|
-- '多个账号用英文逗号分隔,命中后登录不按院区过滤');
|
-- 改完要清缓存:重启或调用 /system/config/refreshCache(若前端有该按钮)。
|
|
|
-- -------------------------------------------------------------------------------------
|
-- 第 3 步:验证(重启/刷新前端后跑;期望两条都有几百条)
|
-- -------------------------------------------------------------------------------------
|
-- 3.1 模拟 /getInfo 的两个查询
|
SELECT d.dept_type, COUNT(DISTINCT d.dept_code) AS visible_codes
|
FROM sys_dept d
|
INNER JOIN sys_user_dept ud ON d.dept_code = ud.dept_code
|
WHERE d.del_flag = '0' AND ud.del_flag = '0'
|
AND d.orgid = '20001001' AND ud.orgid = '20001001'
|
AND ud.user_id = (SELECT user_id FROM sys_user WHERE user_name = 'admin')
|
AND d.campusid = '30001002'
|
GROUP BY d.dept_type;
|
|
-- 3.2 直接看科室/病区名字前 10 条,确认是真实科室而不是测试数据
|
SELECT d.dept_type, d.dept_code, d.dept_name
|
FROM sys_dept d
|
INNER JOIN sys_user_dept ud ON d.dept_code = ud.dept_code
|
WHERE d.del_flag = '0' AND ud.del_flag = '0'
|
AND d.orgid = '20001001' AND ud.orgid = '20001001'
|
AND ud.user_id = (SELECT user_id FROM sys_user WHERE user_name = 'admin')
|
AND d.campusid = '30001002'
|
AND d.dept_type = '1'
|
LIMIT 10;
|
|
|
-- -------------------------------------------------------------------------------------
|
-- 第 4 步(根治,发版时做):代码里 admin 不该走 sys_user_dept
|
-- 4.1 SysDeptMapper.xml L286 按 userId 分支:无 userId 时直接查 sys_dept(见对话里的 diff)
|
-- 4.2 /getInfo 与 /system/user/getInfo 里判 admin,不传 userId
|
-- 4.3 campusid 条件改成 and (d.campusid is null or d.campusid = #{campusid})
|
-- 4.4 列表为空时兜底:再按 orgid 查一次全量,避免以后再出现「登录成功但下拉空」
|
-- -------------------------------------------------------------------------------------
|