-- ===================================================================================== -- 【已改为代码修复,本文件的 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 查一次全量,避免以后再出现「登录成功但下拉空」 -- -------------------------------------------------------------------------------------