菜单缓存整改

This commit is contained in:
2026-09-22 11:43:22 +08:00
parent b94d4aba2c
commit 5efff965f3
@@ -8,13 +8,9 @@ import io.v.nutz.sys.services.SysDictService;
import io.v.nutz.sys.services.SysMenuService;
import io.v.nutz.sys.services.SysRoleService;
import io.v.nutz.sys.services.SysUserService;
import io.v.nutz.web.commons.utils.ShiroUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
@@ -34,7 +30,6 @@ import org.nutz.plugins.wkcache.annotation.CacheRemove;
import org.nutz.plugins.wkcache.annotation.CacheRemoveAll;
import org.nutz.plugins.wkcache.annotation.CacheResult;
import java.io.Serializable;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;
@@ -291,78 +286,80 @@ public class SysUserServiceImpl extends BaseServiceImpl<Sys_user> implements Sys
//可以通过el表达式加 * 通配符来批量删除一批缓存
public void deleteCache(String userId) {
sysRoleService.clearCache();
//查询用户最新的菜单、角色信息
// Sys_user user = fetch(Cnd.where("id", "=", userId));
// fetchLinks(user, null);
// fillModuleMenus(user);
// fillUnitUnion(user);
//
// //更新principal信息
// PrincipalCollection principals = SecurityUtils.getSubject().getPrincipals();
// String realm = principals.getRealmNames().iterator().next();
// SimplePrincipalCollection simplePrincipalCollection = new SimplePrincipalCollection(user, realm);
// SecurityUtils.getSubject().runAs(simplePrincipalCollection);
flushUserPermissionById(userId);
}
@Override
public void deleteCacheAndUpdate(String userId) {
//删除sys_user_*,sys_role_*所有缓存
this.deleteCache(userId);
sysRoleService.clearCache();
//查询用户最新的菜单、角色信息
Sys_user user = fetch(Cnd.where("id", "=", ShiroUtil.getUserId()));
fetchLinks(user, null);
user = fillModuleMenus(user);
user = fillUnitUnion(user);
//更新principal信息
PrincipalCollection principals = SecurityUtils.getSubject().getPrincipals();
String realm = principals.getRealmNames().iterator().next();
SimplePrincipalCollection simplePrincipalCollection = new SimplePrincipalCollection(user, realm);
SecurityUtils.getSubject().runAs(simplePrincipalCollection);
}
@Override
public void flushOnlineUserPermission() {
DefaultWebSessionManager sessionManager = Mvcs.getIoc().get(DefaultWebSessionManager.class, "shiroWebSessionManager");
if (sessionManager == null || sessionManager.getSessionDAO() == null) {
return;
}
for (Session activeSession : sessionManager.getSessionDAO().getActiveSessions()) {
refreshSessionPermission(activeSession, null);
}
}
@Override
public void flushUserPermissionById(String id) {
public void flushUserPermissionById(String userId) {
if (Strings.isBlank(userId)) {
return;
}
DefaultWebSessionManager sessionManager = Mvcs.getIoc().get(DefaultWebSessionManager.class, "shiroWebSessionManager");
if (sessionManager == null || sessionManager.getSessionDAO() == null) {
return;
}
for (Session activeSession : sessionManager.getSessionDAO().getActiveSessions()) {
refreshSessionPermission(activeSession, userId);
}
}
/**
* 刷新在线会话中的用户 Principal,保证菜单、角色和单位信息与数据库保持一致。
* @param activeSession 在线 Shiro 会话
* @param userId 指定用户 ID;为空时刷新当前会话对应的用户
*/
private void refreshSessionPermission(Session activeSession, String userId) {
if (activeSession == null) {
return;
}
String sessionUserId = Strings.sNull(activeSession.getAttribute("platform_uid"));
if (Strings.isBlank(sessionUserId) || (Strings.isNotBlank(userId) && !userId.equals(sessionUserId))) {
return;
}
Sys_user user = fetch(Cnd.where("id", "=", sessionUserId));
if (Lang.isEmpty(user)) {
return;
}
fetchLinks(user, null);
user = fillMenu(user);
user = fillModuleMenus(user);
user = fillUnitUnion(user);
String realm = "platformRealm";
Object oldPrincipals = activeSession.getAttribute("org.apache.shiro.subject.support.DelegatingSubject.RUN_AS_PRINCIPALS_SESSION_KEY");
if (oldPrincipals instanceof Collection) {
Collection<?> principals = (Collection<?>) oldPrincipals;
if (!principals.isEmpty() && principals.iterator().next() instanceof PrincipalCollection) {
realm = ((PrincipalCollection) principals.iterator().next()).getRealmNames().iterator().next();
}
}
List<PrincipalCollection> refreshedPrincipals = new CopyOnWriteArrayList<>();
refreshedPrincipals.add(new SimplePrincipalCollection(user, realm));
activeSession.setAttribute("org.apache.shiro.subject.support.DefaultSubjectContext.PRINCIPALS_SESSION_KEY", refreshedPrincipals);
activeSession.setAttribute("org.apache.shiro.subject.support.DelegatingSubject.RUN_AS_PRINCIPALS_SESSION_KEY", refreshedPrincipals);
}
@CacheRemoveAll
public void clearCache() {
//清除角色缓存
sysRoleService.clearCache();
// //获取sessionDao
// DefaultWebSessionManager shiroWebSessionManager = Mvcs.getIoc().get(DefaultWebSessionManager.class, "shiroWebSessionManager");
// SessionDAO sessionDAO = shiroWebSessionManager.getSessionDAO();
// Collection<Session> activeSessions = sessionDAO.getActiveSessions();
//
// //获取所有在线的session
// for (Session activeSession : activeSessions) {
// Serializable id = activeSession.getId();
// Sys_user user = dao().fetch(Sys_user.class, Cnd.where("loginSessionId", "=", id));
// if (Lang.isEmpty(user)) {
// continue;
// }
// fetchLinks(user, null);
// fillModuleMenus(user);
// fillUnitUnion(user);
//
// //更新subject
// List<PrincipalCollection> list = new CopyOnWriteArrayList<>();
// Subject subject = SecurityUtils.getSubject();
// PrincipalCollection principals = subject.getPrincipals();
// String realName = principals.getRealmNames().iterator().next();
// PrincipalCollection newPrincipalCollection = new SimplePrincipalCollection(user, realName);
// list.add(0, newPrincipalCollection);
// activeSession.setAttribute("org.apache.shiro.subject.support.DelegatingSubject.RUN_AS_PRINCIPALS_SESSION_KEY", list);
// }
flushOnlineUserPermission();
}
}