mirror of
https://gitee.com/xiaonuobase/snowy.git
synced 2026-03-22 02:37:16 +08:00
【更新】更新实时刷新数据权限范围及产品readme
This commit is contained in:
16
README.md
16
README.md
@@ -8,7 +8,8 @@
|
|||||||
|
|
||||||
Snowy(SnowyAdmin)是国内首个国密前后端分离快速开发平台,集成国密加解密插件,
|
Snowy(SnowyAdmin)是国内首个国密前后端分离快速开发平台,集成国密加解密插件,
|
||||||
软件层面完全符合等保测评要求,同时实现国产化机型、中间件、数据库适配,是您的不二之选!
|
软件层面完全符合等保测评要求,同时实现国产化机型、中间件、数据库适配,是您的不二之选!
|
||||||
技术框架与密码结合,让更多的人认识密码,使用密码;更是让前后分离“密”不可分。
|
将国密能力内置于技术框架底层,让密码技术从"专业门槛"变为"开箱即用",真正实现业务安全从底层做起。
|
||||||
|
历经多年开源社区打磨与企业客户实践验证,新版本在大数据处理能力与安全体系方面实现了全面升级。
|
||||||
|
|
||||||
采用SpringBoot+MybatisPlus+AntDesignVue+Vite 等更多组件及前沿技术开发,注释丰富,代码简洁,开箱即用!
|
采用SpringBoot+MybatisPlus+AntDesignVue+Vite 等更多组件及前沿技术开发,注释丰富,代码简洁,开箱即用!
|
||||||
|
|
||||||
@@ -61,6 +62,15 @@ gitcode下载地址:[https://gitcode.com/xiaonuobase/Snowy](https://gitcode.co
|
|||||||
|
|
||||||
文档地址:[https://xiaonuo.vip/doc](https://xiaonuo.vip/doc)
|
文档地址:[https://xiaonuo.vip/doc](https://xiaonuo.vip/doc)
|
||||||
|
|
||||||
|
## 商业产品
|
||||||
|
|
||||||
|
- 如果开源版本不能满足您的需求,还可以看看我们官方推出的基于开源版开发的商业化产品
|
||||||
|
|
||||||
|
| 产品名称 | 演示 | 用途 |
|
||||||
|
|-------------|------------------------------------------------------|---------------------------------|
|
||||||
|
| AI智能化零代码开发平台 | [https://alsc.xiaonuo.vip](https://alsc.xiaonuo.vip) | AI智能驱动,拖拉拽即可搭建业务系统,无需编写一行代码 |
|
||||||
|
| 国产数据中台 | [https://data.xiaonuo.vip](https://data.xiaonuo.vip) | 覆盖数据采集、存储、治理、安全、资产化、服务全流程的一站式数据管理平台 |
|
||||||
|
|
||||||
## 快速启动
|
## 快速启动
|
||||||
|
|
||||||
全栈工程师推荐idea
|
全栈工程师推荐idea
|
||||||
@@ -240,7 +250,7 @@ QQ技术群:732230670(已满)、685395081
|
|||||||
|
|
||||||
微信技术群:
|
微信技术群:
|
||||||
|
|
||||||
因群达到200人以上,需加微信拉群,禁止群内艾特群主及管理员,私信提问技术问题无时间精力回答(免开尊口),请群内互动互助才是建群的意义,否则我认为你没有加群的必要
|
因群达到200人以上,需加微信拉群,禁止群内艾特群主及管理员,私信提问技术问题无时间精力回答,请群内互动互助交流技术才是建群的意义
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -326,6 +336,6 @@ QQ技术群:732230670(已满)、685395081
|
|||||||
|
|
||||||
- 代码可用于个人项目等接私活或企业项目脚手架使用,Snowy全系开源版完全免费
|
- 代码可用于个人项目等接私活或企业项目脚手架使用,Snowy全系开源版完全免费
|
||||||
|
|
||||||
- 二次开发如用于开源竞品请先联系群主沟通,禁止任何变相的二开行为,未经审核视为侵权
|
- 二次开源不可参与同类竞争,可在其他赛道进行,有好的案例可以提供,我们会挂在本页进行宣传
|
||||||
|
|
||||||
- 请不要删除和修改Snowy源码头部的版权与作者声明及出处
|
- 请不要删除和修改Snowy源码头部的版权与作者声明及出处
|
||||||
|
|||||||
@@ -22,10 +22,6 @@ export default {
|
|||||||
orgPage(data) {
|
orgPage(data) {
|
||||||
return request('page', data, 'get')
|
return request('page', data, 'get')
|
||||||
},
|
},
|
||||||
// 获取机构列表
|
|
||||||
orgList(data) {
|
|
||||||
return request('list', data, 'get')
|
|
||||||
},
|
|
||||||
// 获取机构树(懒加载)
|
// 获取机构树(懒加载)
|
||||||
orgTree(data) {
|
orgTree(data) {
|
||||||
return request('tree', data, 'get')
|
return request('tree', data, 'get')
|
||||||
|
|||||||
@@ -337,7 +337,7 @@
|
|||||||
const isFullTree = ref(false)
|
const isFullTree = ref(false)
|
||||||
// 加载全量树(用于需要展开到指定节点的场景)
|
// 加载全量树(用于需要展开到指定节点的场景)
|
||||||
const loadFullTree = () => {
|
const loadFullTree = () => {
|
||||||
return bizUserApi.userOrgTreeSelector({ searchKey: '' }).then((res) => {
|
return bizUserApi.orgTreeSelector({ searchKey: '' }).then((res) => {
|
||||||
if (res !== null) {
|
if (res !== null) {
|
||||||
treeData.value = res
|
treeData.value = res
|
||||||
// 只有一个根节点时才自动展开
|
// 只有一个根节点时才自动展开
|
||||||
@@ -349,7 +349,7 @@
|
|||||||
}
|
}
|
||||||
// 加载懒加载树(无需展开到指定节点时使用)
|
// 加载懒加载树(无需展开到指定节点时使用)
|
||||||
const loadLazyTree = () => {
|
const loadLazyTree = () => {
|
||||||
return bizUserApi.userOrgTreeSelector().then((res) => {
|
return bizUserApi.orgTreeSelector().then((res) => {
|
||||||
if (res !== null) {
|
if (res !== null) {
|
||||||
treeData.value = res.map((item) => {
|
treeData.value = res.map((item) => {
|
||||||
return {
|
return {
|
||||||
@@ -418,7 +418,7 @@
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
bizUserApi
|
bizUserApi
|
||||||
.userOrgTreeSelector({
|
.orgTreeSelector({
|
||||||
parentId: treeNode.dataRef.id
|
parentId: treeNode.dataRef.id
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
|
|||||||
@@ -187,4 +187,14 @@ public interface SaBaseLoginUserApi {
|
|||||||
* @date 2026/2/12
|
* @date 2026/2/12
|
||||||
*/
|
*/
|
||||||
void refreshUserDataScope(String userId, List<SaBaseLoginUser.DataScope> dataScopeList);
|
void refreshUserDataScope(String userId, List<SaBaseLoginUser.DataScope> dataScopeList);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 刷新在线用户的权限缓存(Session),权限变更后调用,确保实时生效。
|
||||||
|
* 如果用户不在线则跳过。
|
||||||
|
*
|
||||||
|
* @param userId 用户ID
|
||||||
|
* @author xuyuxiang
|
||||||
|
* @date 2026/3/12
|
||||||
|
*/
|
||||||
|
void refreshOnlineUserPermission(String userId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -223,4 +223,9 @@ public class ClientLoginUserApiProvider implements SaBaseLoginUserApi {
|
|||||||
public void refreshUserDataScope(String userId, List<SaBaseLoginUser.DataScope> dataScopeList) {
|
public void refreshUserDataScope(String userId, List<SaBaseLoginUser.DataScope> dataScopeList) {
|
||||||
// C端用户无数据范围,无需刷新预计算表
|
// C端用户无数据范围,无需刷新预计算表
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void refreshOnlineUserPermission(String userId) {
|
||||||
|
// C端用户暂无数据权限机制,无需刷新
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ import vip.xiaonuo.sys.modular.role.mapper.SysRoleMapper;
|
|||||||
import vip.xiaonuo.sys.modular.role.param.*;
|
import vip.xiaonuo.sys.modular.role.param.*;
|
||||||
import vip.xiaonuo.sys.modular.role.result.*;
|
import vip.xiaonuo.sys.modular.role.result.*;
|
||||||
import vip.xiaonuo.sys.modular.role.service.SysRoleService;
|
import vip.xiaonuo.sys.modular.role.service.SysRoleService;
|
||||||
|
import vip.xiaonuo.auth.api.SaBaseLoginUserApi;
|
||||||
import vip.xiaonuo.sys.modular.user.entity.SysUser;
|
import vip.xiaonuo.sys.modular.user.entity.SysUser;
|
||||||
import vip.xiaonuo.sys.modular.user.enums.SysUserStatusEnum;
|
import vip.xiaonuo.sys.modular.user.enums.SysUserStatusEnum;
|
||||||
import vip.xiaonuo.sys.modular.user.service.SysUserService;
|
import vip.xiaonuo.sys.modular.user.service.SysUserService;
|
||||||
@@ -95,6 +96,9 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||||||
@Resource
|
@Resource
|
||||||
private CommonCacheOperator commonCacheOperator;
|
private CommonCacheOperator commonCacheOperator;
|
||||||
|
|
||||||
|
@Resource(name = "loginUserApi")
|
||||||
|
private SaBaseLoginUserApi loginUserApi;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Page<SysRole> page(SysRolePageParam sysRolePageParam) {
|
public Page<SysRole> page(SysRolePageParam sysRolePageParam) {
|
||||||
QueryWrapper<SysRole> queryWrapper = new QueryWrapper<SysRole>().checkSqlInjection();
|
QueryWrapper<SysRole> queryWrapper = new QueryWrapper<SysRole>().checkSqlInjection();
|
||||||
@@ -313,6 +317,10 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||||||
.map(JSONUtil::toJsonStr).collect(Collectors.toList());
|
.map(JSONUtil::toJsonStr).collect(Collectors.toList());
|
||||||
sysRelationService.saveRelationBatchWithClear(id, apiUrlList, SysRelationCategoryEnum.SYS_ROLE_HAS_PERMISSION.getValue(),
|
sysRelationService.saveRelationBatchWithClear(id, apiUrlList, SysRelationCategoryEnum.SYS_ROLE_HAS_PERMISSION.getValue(),
|
||||||
extJsonList);
|
extJsonList);
|
||||||
|
// 刷新拥有该角色的所有在线用户的权限缓存
|
||||||
|
List<String> userIdList = sysRelationService.getRelationObjectIdListByTargetIdAndCategory(
|
||||||
|
id, SysRelationCategoryEnum.SYS_USER_HAS_ROLE.getValue());
|
||||||
|
userIdList.forEach(loginUserApi::refreshOnlineUserPermission);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -325,7 +333,11 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||||||
public void grantUser(SysRoleGrantUserParam sysRoleGrantUserParam) {
|
public void grantUser(SysRoleGrantUserParam sysRoleGrantUserParam) {
|
||||||
String id = sysRoleGrantUserParam.getId();
|
String id = sysRoleGrantUserParam.getId();
|
||||||
List<String> grantInfoList = sysRoleGrantUserParam.getGrantInfoList();
|
List<String> grantInfoList = sysRoleGrantUserParam.getGrantInfoList();
|
||||||
|
// 记录变更前拥有该角色的用户(用于后续刷新被移除用户的权限)
|
||||||
|
Set<String> affectedUserIds = new HashSet<>();
|
||||||
if(sysRoleGrantUserParam.getRemoveFirst()) {
|
if(sysRoleGrantUserParam.getRemoveFirst()) {
|
||||||
|
affectedUserIds.addAll(sysRelationService.getRelationObjectIdListByTargetIdAndCategory(
|
||||||
|
id, SysRelationCategoryEnum.SYS_USER_HAS_ROLE.getValue()));
|
||||||
sysRelationService.remove(new LambdaQueryWrapper<SysRelation>().eq(SysRelation::getTargetId, id)
|
sysRelationService.remove(new LambdaQueryWrapper<SysRelation>().eq(SysRelation::getTargetId, id)
|
||||||
.eq(SysRelation::getCategory, SysRelationCategoryEnum.SYS_USER_HAS_ROLE.getValue()));
|
.eq(SysRelation::getCategory, SysRelationCategoryEnum.SYS_USER_HAS_ROLE.getValue()));
|
||||||
}
|
}
|
||||||
@@ -336,6 +348,9 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||||||
sysRelation.setCategory(SysRelationCategoryEnum.SYS_USER_HAS_ROLE.getValue());
|
sysRelation.setCategory(SysRelationCategoryEnum.SYS_USER_HAS_ROLE.getValue());
|
||||||
return sysRelation;
|
return sysRelation;
|
||||||
}).collect(Collectors.toList()));
|
}).collect(Collectors.toList()));
|
||||||
|
// 合并新增用户,刷新所有受影响用户的权限缓存
|
||||||
|
affectedUserIds.addAll(grantInfoList);
|
||||||
|
affectedUserIds.forEach(loginUserApi::refreshOnlineUserPermission);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -12,10 +12,16 @@
|
|||||||
*/
|
*/
|
||||||
package vip.xiaonuo.sys.modular.user.provider;
|
package vip.xiaonuo.sys.modular.user.provider;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.session.SaSession;
|
||||||
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
import cn.hutool.core.bean.BeanUtil;
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
|
import cn.hutool.core.collection.CollectionUtil;
|
||||||
|
import cn.hutool.core.convert.Convert;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.json.JSONObject;
|
import cn.hutool.json.JSONObject;
|
||||||
import cn.hutool.json.JSONUtil;
|
import cn.hutool.json.JSONUtil;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import vip.xiaonuo.auth.api.SaBaseLoginUserApi;
|
import vip.xiaonuo.auth.api.SaBaseLoginUserApi;
|
||||||
import vip.xiaonuo.auth.core.pojo.SaBaseClientLoginUser;
|
import vip.xiaonuo.auth.core.pojo.SaBaseClientLoginUser;
|
||||||
@@ -34,6 +40,7 @@ import java.util.stream.Collectors;
|
|||||||
* @author xuyuxiang
|
* @author xuyuxiang
|
||||||
* @date 2022/4/29 13:36
|
* @date 2022/4/29 13:36
|
||||||
**/
|
**/
|
||||||
|
@Slf4j
|
||||||
@Service("loginUserApi")
|
@Service("loginUserApi")
|
||||||
public class SysLoginUserApiProvider implements SaBaseLoginUserApi {
|
public class SysLoginUserApiProvider implements SaBaseLoginUserApi {
|
||||||
|
|
||||||
@@ -216,4 +223,50 @@ public class SysLoginUserApiProvider implements SaBaseLoginUserApi {
|
|||||||
public void refreshUserDataScope(String userId, List<SaBaseLoginUser.DataScope> dataScopeList) {
|
public void refreshUserDataScope(String userId, List<SaBaseLoginUser.DataScope> dataScopeList) {
|
||||||
sysUserDataScopeService.refreshByUserId(userId, dataScopeList);
|
sysUserDataScopeService.refreshByUserId(userId, dataScopeList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void refreshOnlineUserPermission(String userId) {
|
||||||
|
// 获取该用户所有在线token
|
||||||
|
List<String> tokenList = StpUtil.getTokenValueListByLoginId(userId);
|
||||||
|
if (ObjectUtil.isEmpty(tokenList)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 获取用户基本信息
|
||||||
|
SaBaseLoginUser saBaseLoginUser = this.getUserById(userId);
|
||||||
|
if (ObjectUtil.isEmpty(saBaseLoginUser)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 获取角色列表
|
||||||
|
List<JSONObject> roleList = this.getRoleListByUserId(userId);
|
||||||
|
List<String> roleIdList = roleList.stream().map(j -> j.getStr("id")).collect(Collectors.toList());
|
||||||
|
List<String> roleCodeList = roleList.stream().map(j -> j.getStr("code")).collect(Collectors.toList());
|
||||||
|
List<String> userAndRoleIdList = CollectionUtil.unionAll(roleIdList, CollectionUtil.newArrayList(userId));
|
||||||
|
// 重新计算权限数据
|
||||||
|
List<String> buttonCodeList = this.getButtonCodeListListByUserAndRoleIdList(userAndRoleIdList);
|
||||||
|
List<String> mobileButtonCodeList = this.getMobileButtonCodeListListByUserIdAndRoleIdList(userAndRoleIdList);
|
||||||
|
List<SaBaseLoginUser.DataScope> dataScopeList = Convert.toList(SaBaseLoginUser.DataScope.class,
|
||||||
|
this.getPermissionListByUserIdAndRoleIdList(userAndRoleIdList, saBaseLoginUser.getOrgId()));
|
||||||
|
List<String> permissionCodeList = dataScopeList.stream()
|
||||||
|
.map(SaBaseLoginUser.DataScope::getApiUrl).collect(Collectors.toList());
|
||||||
|
// 填充到用户对象
|
||||||
|
saBaseLoginUser.setButtonCodeList(buttonCodeList);
|
||||||
|
saBaseLoginUser.setMobileButtonCodeList(mobileButtonCodeList);
|
||||||
|
saBaseLoginUser.setDataScopeList(dataScopeList);
|
||||||
|
saBaseLoginUser.setPermissionCodeList(permissionCodeList);
|
||||||
|
saBaseLoginUser.setRoleCodeList(roleCodeList);
|
||||||
|
// 写入该用户的所有TokenSession
|
||||||
|
for (String token : tokenList) {
|
||||||
|
try {
|
||||||
|
SaSession session = StpUtil.getTokenSessionByToken(token);
|
||||||
|
if (session != null) {
|
||||||
|
session.set("loginUser", saBaseLoginUser);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn(">>> 刷新用户权限缓存时跳过无效token,userId:{},token:{}", userId, token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 刷新预计算表
|
||||||
|
this.refreshUserDataScope(userId, dataScopeList);
|
||||||
|
log.info(">>> 已刷新在线用户权限缓存,userId:{},token数:{}", userId, tokenList.size());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ import org.apache.poi.xwpf.usermodel.XWPFDocument;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import vip.xiaonuo.auth.api.SaBaseLoginUserApi;
|
||||||
import vip.xiaonuo.auth.core.util.StpLoginUserUtil;
|
import vip.xiaonuo.auth.core.util.StpLoginUserUtil;
|
||||||
import vip.xiaonuo.common.cache.CommonCacheOperator;
|
import vip.xiaonuo.common.cache.CommonCacheOperator;
|
||||||
import vip.xiaonuo.common.enums.CommonGenderEnum;
|
import vip.xiaonuo.common.enums.CommonGenderEnum;
|
||||||
@@ -260,6 +261,9 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
|||||||
@Resource
|
@Resource
|
||||||
private SysUserPasswordService sysUserPasswordService;
|
private SysUserPasswordService sysUserPasswordService;
|
||||||
|
|
||||||
|
@Resource(name = "loginUserApi")
|
||||||
|
private SaBaseLoginUserApi loginUserApi;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SysLoginUser getUserById(String id) {
|
public SysLoginUser getUserById(String id) {
|
||||||
SysUser sysUser = this.getById(id);
|
SysUser sysUser = this.getById(id);
|
||||||
@@ -1340,6 +1344,8 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
|||||||
public void grantRole(SysUserGrantRoleParam sysUserGrantRoleParam) {
|
public void grantRole(SysUserGrantRoleParam sysUserGrantRoleParam) {
|
||||||
sysRelationService.saveRelationBatchWithClear(sysUserGrantRoleParam.getId(), sysUserGrantRoleParam.getRoleIdList(),
|
sysRelationService.saveRelationBatchWithClear(sysUserGrantRoleParam.getId(), sysUserGrantRoleParam.getRoleIdList(),
|
||||||
SysRelationCategoryEnum.SYS_USER_HAS_ROLE.getValue());
|
SysRelationCategoryEnum.SYS_USER_HAS_ROLE.getValue());
|
||||||
|
// 刷新该用户的权限缓存
|
||||||
|
loginUserApi.refreshOnlineUserPermission(sysUserGrantRoleParam.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1378,6 +1384,8 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
|||||||
List<String> extJsonList = sysUserGrantResourceParam.getGrantInfoList().stream()
|
List<String> extJsonList = sysUserGrantResourceParam.getGrantInfoList().stream()
|
||||||
.map(JSONUtil::toJsonStr).collect(Collectors.toList());
|
.map(JSONUtil::toJsonStr).collect(Collectors.toList());
|
||||||
sysRelationService.saveRelationBatchWithClear(sysUserGrantResourceParam.getId(), menuIdList, SysRelationCategoryEnum.SYS_USER_HAS_RESOURCE.getValue(), extJsonList);
|
sysRelationService.saveRelationBatchWithClear(sysUserGrantResourceParam.getId(), menuIdList, SysRelationCategoryEnum.SYS_USER_HAS_RESOURCE.getValue(), extJsonList);
|
||||||
|
// 刷新该用户的权限缓存
|
||||||
|
loginUserApi.refreshOnlineUserPermission(sysUserGrantResourceParam.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1399,6 +1407,8 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
|||||||
.map(JSONUtil::toJsonStr).collect(Collectors.toList());
|
.map(JSONUtil::toJsonStr).collect(Collectors.toList());
|
||||||
sysRelationService.saveRelationBatchWithClear(id, apiUrlList, SysRelationCategoryEnum.SYS_USER_HAS_PERMISSION.getValue(),
|
sysRelationService.saveRelationBatchWithClear(id, apiUrlList, SysRelationCategoryEnum.SYS_USER_HAS_PERMISSION.getValue(),
|
||||||
extJsonList);
|
extJsonList);
|
||||||
|
// 刷新该用户的权限缓存
|
||||||
|
loginUserApi.refreshOnlineUserPermission(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user