【机构】机构增加缓存、异步树

This commit is contained in:
俞宝山
2026-02-10 23:28:20 +08:00
parent 0cded6758a
commit 62eeabfdb4
56 changed files with 1413 additions and 297 deletions

View File

@@ -14,6 +14,7 @@ package vip.xiaonuo.biz.modular.org.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.xingfudeshi.knife4j.annotations.ApiOperationSupport;
import com.github.xingfudeshi.knife4j.annotations.ApiSupport;
@@ -80,6 +81,20 @@ public class BizOrgController {
return CommonResult.data(bizOrgService.tree());
}
/**
* 获取机构树(懒加载)
*
* @author xuyuxiang
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 2)
@Operation(summary = "获取机构树(懒加载)")
@SaCheckPermission("/biz/org/treeLazy")
@GetMapping("/biz/org/treeLazy")
public CommonResult<List<JSONObject>> treeLazy(BizOrgTreeLazyParam bizOrgTreeLazyParam) {
return CommonResult.data(bizOrgService.treeLazy(bizOrgTreeLazyParam));
}
/**
* 添加机构
*
@@ -175,6 +190,20 @@ public class BizOrgController {
return CommonResult.data(bizOrgService.orgTreeSelector());
}
/**
* 获取机构树选择器(懒加载)
*
* @author xuyuxiang
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 8)
@Operation(summary = "获取机构树选择器(懒加载)")
@SaCheckPermission("/biz/org/orgTreeLazySelector")
@GetMapping("/biz/org/orgTreeLazySelector")
public CommonResult<List<JSONObject>> orgTreeLazySelector(BizOrgTreeLazyParam bizOrgTreeLazyParam) {
return CommonResult.data(bizOrgService.treeLazy(bizOrgTreeLazyParam));
}
/**
* 获取人员选择器
*

View File

@@ -0,0 +1,32 @@
/*
* Copyright [2022] [https://www.xiaonuo.vip]
*
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
*
* 1.请不要删除和修改根目录下的LICENSE文件.
* 2.请不要删除和修改Snowy源码头部的版权声明.
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等.
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
* 5.不可二次分发开源参与同类竞品如有想法可联系团队xiaonuobase@qq.com商议合作.
* 6.若您的项目无法满足以上几点需要更多功能代码获取Snowy商业授权许可请在官网购买授权地址为 https://www.xiaonuo.vip
*/
package vip.xiaonuo.biz.modular.org.param;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
/**
* 机构树懒加载参数
*
* @author xuyuxiang
* @date 2022/4/21 16:13
**/
@Getter
@Setter
public class BizOrgTreeLazyParam {
/** 父id */
@Schema(description = "父id")
private String parentId;
}

View File

@@ -20,6 +20,7 @@ import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import vip.xiaonuo.biz.api.BizOrgApi;
import vip.xiaonuo.biz.modular.org.param.BizOrgSelectorOrgListParam;
import vip.xiaonuo.biz.modular.org.param.BizOrgTreeLazyParam;
import vip.xiaonuo.biz.modular.org.service.BizOrgService;
import java.util.List;
@@ -41,6 +42,13 @@ public class BizOrgApiProvider implements BizOrgApi {
return bizOrgService.orgTreeSelector();
}
@Override
public List<JSONObject> orgTreeLazySelector(String parentId) {
BizOrgTreeLazyParam bizOrgTreeLazyParam = new BizOrgTreeLazyParam();
bizOrgTreeLazyParam.setParentId(parentId);
return bizOrgService.treeLazy(bizOrgTreeLazyParam);
}
@SuppressWarnings("ALL")
@Override
public Page<JSONObject> orgListSelector(String parentId) {

View File

@@ -13,6 +13,7 @@
package vip.xiaonuo.biz.modular.org.service;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import vip.xiaonuo.biz.modular.org.entity.BizOrg;
@@ -45,6 +46,14 @@ public interface BizOrgService extends IService<BizOrg> {
*/
List<Tree<String>> tree();
/**
* 获取机构树(懒加载)
*
* @author xuyuxiang
* @date 2022/4/24 20:08
*/
List<JSONObject> treeLazy(BizOrgTreeLazyParam bizOrgTreeLazyParam);
/**
* 添加机构
*

View File

@@ -43,6 +43,7 @@ import vip.xiaonuo.biz.modular.position.entity.BizPosition;
import vip.xiaonuo.biz.modular.position.service.BizPositionService;
import vip.xiaonuo.biz.modular.user.entity.BizUser;
import vip.xiaonuo.biz.modular.user.service.BizUserService;
import vip.xiaonuo.common.cache.CommonCacheOperator;
import vip.xiaonuo.common.enums.CommonSortOrderEnum;
import vip.xiaonuo.common.exception.CommonException;
import vip.xiaonuo.common.listener.CommonDataChangeEventCenter;
@@ -61,6 +62,11 @@ import java.util.stream.Collectors;
@Service
public class BizOrgServiceImpl extends ServiceImpl<BizOrgMapper, BizOrg> implements BizOrgService {
private static final String ORG_ALL_LIST_CACHE_KEY = "biz-org:all-list";
@Resource
private CommonCacheOperator commonCacheOperator;
@Resource
private SysRoleApi sysRoleApi;
@@ -105,7 +111,7 @@ public class BizOrgServiceImpl extends ServiceImpl<BizOrgMapper, BizOrg> impleme
@Override
public List<Tree<String>> tree() {
// 获取所有机构
List<BizOrg> allOrgList = this.list();
List<BizOrg> allOrgList = this.getAllOrgList();
// 定义机构集合
Set<BizOrg> bizOrgSet = CollectionUtil.newHashSet();
// 校验数据范围
@@ -130,6 +136,58 @@ public class BizOrgServiceImpl extends ServiceImpl<BizOrgMapper, BizOrg> impleme
return TreeUtil.build(treeNodeList, "0");
}
@Override
public List<JSONObject> treeLazy(BizOrgTreeLazyParam bizOrgTreeLazyParam) {
String parentId = ObjectUtil.isNotEmpty(bizOrgTreeLazyParam.getParentId()) ? bizOrgTreeLazyParam.getParentId() : "0";
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
// 获取所有机构
List<BizOrg> allOrgList = this.getAllOrgList();
Set<String> visibleOrgIds = null;
// 如果数据范围不为空则计算可见机构ID集合包含自身及其所有父级
if (ObjectUtil.isNotEmpty(loginUserDataScope)) {
Set<BizOrg> bizOrgSet = CollectionUtil.newHashSet();
loginUserDataScope.forEach(orgId -> bizOrgSet.addAll(this.getParentListById(allOrgList, orgId, true)));
visibleOrgIds = bizOrgSet.stream().map(BizOrg::getId).collect(Collectors.toSet());
}
// 过滤出当前父级下的可见子级
final Set<String> finalVisibleOrgIds = visibleOrgIds;
List<BizOrg> sysOrgList = allOrgList.stream()
.filter(bizOrg -> bizOrg.getParentId().equals(parentId))
.filter(bizOrg -> finalVisibleOrgIds == null || finalVisibleOrgIds.contains(bizOrg.getId()))
.sorted(Comparator.comparingInt(BizOrg::getSortCode).thenComparing(BizOrg::getId))
.collect(Collectors.toList());
if (ObjectUtil.isEmpty(sysOrgList)) {
return CollectionUtil.newArrayList();
}
// 判断这些机构是否还有可见子机构
return sysOrgList.stream().map(bizOrg -> {
JSONObject jsonObject = JSONUtil.parseObj(bizOrg);
// 计算是否有可见的子节点
boolean hasChildren = allOrgList.stream()
.anyMatch(item -> item.getParentId().equals(bizOrg.getId()) && (finalVisibleOrgIds == null || finalVisibleOrgIds.contains(item.getId())));
jsonObject.set("isLeaf", !hasChildren);
return jsonObject;
}).collect(Collectors.toList());
}
/**
* 获取机构树(懒加载)
*
* @author xuyuxiang
* @date 2022/4/24 20:08
*/
public List<JSONObject> treeLazy(String parentId) {
BizOrgTreeLazyParam bizOrgTreeLazyParam = new BizOrgTreeLazyParam();
bizOrgTreeLazyParam.setParentId(parentId);
return this.treeLazy(bizOrgTreeLazyParam);
}
@Transactional(rollbackFor = Exception.class)
@Override
public void add(BizOrgAddParam bizOrgAddParam, String sourceFromType) {
@@ -158,6 +216,8 @@ public class BizOrgServiceImpl extends ServiceImpl<BizOrgMapper, BizOrg> impleme
bizOrgExtService.createExtInfo(bizOrg.getId(), sourceFromType);
// 发布增加事件
CommonDataChangeEventCenter.doAddWithData(BizDataTypeEnum.ORG.getValue(), JSONUtil.createArray().put(bizOrg));
// 清除缓存
commonCacheOperator.remove(ORG_ALL_LIST_CACHE_KEY);
}
@Transactional(rollbackFor = Exception.class)
@@ -183,7 +243,7 @@ public class BizOrgServiceImpl extends ServiceImpl<BizOrgMapper, BizOrg> impleme
if(repeatName) {
throw new CommonException("存在重复的同级机构,名称为:{}", bizOrg.getName());
}
List<BizOrg> originDataList = this.list();
List<BizOrg> originDataList = this.getAllOrgList();
boolean errorLevel = this.getChildListById(originDataList, bizOrg.getId(), true).stream()
.map(BizOrg::getId).collect(Collectors.toList()).contains(bizOrg.getParentId());
if(errorLevel) {
@@ -193,6 +253,8 @@ public class BizOrgServiceImpl extends ServiceImpl<BizOrgMapper, BizOrg> impleme
this.updateById(bizOrg);
// 发布更新事件
CommonDataChangeEventCenter.doUpdateWithData(BizDataTypeEnum.ORG.getValue(), JSONUtil.createArray().put(bizOrg));
// 清除缓存
commonCacheOperator.remove(ORG_ALL_LIST_CACHE_KEY);
}
@Transactional(rollbackFor = Exception.class)
@@ -209,7 +271,7 @@ public class BizOrgServiceImpl extends ServiceImpl<BizOrgMapper, BizOrg> impleme
} else {
throw new CommonException("您没有权限删除这些机构机构id{}", orgIdList);
}
List<BizOrg> allOrgList = this.list();
List<BizOrg> allOrgList = this.getAllOrgList();
// 获取所有子机构
List<String> toDeleteOrgIdList = CollectionUtil.newArrayList();
orgIdList.forEach(orgId -> toDeleteOrgIdList.addAll(this.getChildListById(allOrgList, orgId, true).stream()
@@ -246,6 +308,8 @@ public class BizOrgServiceImpl extends ServiceImpl<BizOrgMapper, BizOrg> impleme
// 发布删除事件
CommonDataChangeEventCenter.doDeleteWithDataIdList(BizDataTypeEnum.ORG.getValue(), toDeleteOrgIdList);
// 清除缓存
commonCacheOperator.remove(ORG_ALL_LIST_CACHE_KEY);
}
}
@@ -265,7 +329,13 @@ public class BizOrgServiceImpl extends ServiceImpl<BizOrgMapper, BizOrg> impleme
@Override
public List<BizOrg> getAllOrgList() {
return this.list(new LambdaQueryWrapper<BizOrg>().orderByAsc(BizOrg::getSortCode));
Object cached = commonCacheOperator.get(ORG_ALL_LIST_CACHE_KEY);
if (cached != null) {
return JSONUtil.toList(JSONUtil.parseArray(cached), BizOrg.class);
}
List<BizOrg> list = this.list(new LambdaQueryWrapper<BizOrg>().orderByAsc(BizOrg::getSortCode));
commonCacheOperator.put(ORG_ALL_LIST_CACHE_KEY, list);
return list;
}
@Override
@@ -314,6 +384,8 @@ public class BizOrgServiceImpl extends ServiceImpl<BizOrgMapper, BizOrg> impleme
this.save(bizOrg);
// 发布增加事件
CommonDataChangeEventCenter.doAddWithData(BizDataTypeEnum.ORG.getValue(), JSONUtil.createArray().put(bizOrg));
// 清除缓存
commonCacheOperator.remove(ORG_ALL_LIST_CACHE_KEY);
return bizOrg.getId();
}
@@ -328,7 +400,7 @@ public class BizOrgServiceImpl extends ServiceImpl<BizOrgMapper, BizOrg> impleme
Set<BizOrg> bizOrgSet = CollectionUtil.newHashSet();
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
// 获取所有机构
List<BizOrg> allOrgList = this.list();
List<BizOrg> allOrgList = this.getAllOrgList();
loginUserDataScope.forEach(orgId -> bizOrgSet.addAll(this.getParentListById(allOrgList, orgId, true)));
List<String> loginUserDataScopeFullList = bizOrgSet.stream().map(BizOrg::getId).collect(Collectors.toList());
lambdaQueryWrapper.in(BizOrg::getId, loginUserDataScopeFullList);

View File

@@ -14,6 +14,7 @@ package vip.xiaonuo.biz.modular.position.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.xingfudeshi.knife4j.annotations.ApiOperationSupport;
import com.github.xingfudeshi.knife4j.annotations.ApiSupport;
@@ -31,6 +32,7 @@ import vip.xiaonuo.biz.modular.position.param.*;
import vip.xiaonuo.biz.modular.position.service.BizPositionService;
import vip.xiaonuo.common.annotation.CommonLog;
import vip.xiaonuo.common.pojo.CommonResult;
import vip.xiaonuo.biz.modular.org.param.BizOrgTreeLazyParam;
import javax.validation.Valid;
import java.util.List;
@@ -143,6 +145,20 @@ public class BizPositionController {
return CommonResult.data(bizPositionService.orgTreeSelector());
}
/**
* 获取组织树选择器(懒加载)
*
* @author xuyuxiang
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 6)
@Operation(summary = "获取组织树选择器(懒加载)")
@SaCheckPermission("/biz/position/orgTreeLazySelector")
@GetMapping("/biz/position/orgTreeLazySelector")
public CommonResult<List<JSONObject>> orgTreeLazySelector(BizOrgTreeLazyParam bizOrgTreeLazyParam) {
return CommonResult.data(bizPositionService.orgTreeLazySelector(bizOrgTreeLazyParam));
}
/**
* 获取岗位选择器
*

View File

@@ -13,10 +13,12 @@
package vip.xiaonuo.biz.modular.position.service;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import vip.xiaonuo.biz.modular.position.entity.BizPosition;
import vip.xiaonuo.biz.modular.position.param.*;
import vip.xiaonuo.biz.modular.org.param.BizOrgTreeLazyParam;
import java.util.List;
@@ -94,6 +96,14 @@ public interface BizPositionService extends IService<BizPosition> {
*/
List<Tree<String>> orgTreeSelector();
/**
* 获取机构树选择器(懒加载)
*
* @author xuyuxiang
* @date 2022/4/24 20:08
*/
List<JSONObject> orgTreeLazySelector(BizOrgTreeLazyParam bizOrgTreeLazyParam);
/**
* 获取岗位选择器
*

View File

@@ -32,8 +32,8 @@ import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vip.xiaonuo.auth.core.util.StpLoginUserUtil;
import vip.xiaonuo.biz.core.enums.BizDataTypeEnum;
import vip.xiaonuo.biz.modular.org.entity.BizOrg;
import vip.xiaonuo.biz.modular.org.param.BizOrgTreeLazyParam;
import vip.xiaonuo.biz.modular.org.service.BizOrgService;
import vip.xiaonuo.biz.modular.position.entity.BizPosition;
import vip.xiaonuo.biz.modular.position.enums.BizPositionCategoryEnum;
@@ -42,6 +42,7 @@ import vip.xiaonuo.biz.modular.position.param.*;
import vip.xiaonuo.biz.modular.position.service.BizPositionService;
import vip.xiaonuo.biz.modular.user.entity.BizUser;
import vip.xiaonuo.biz.modular.user.service.BizUserService;
import vip.xiaonuo.biz.core.enums.BizDataTypeEnum;
import vip.xiaonuo.common.enums.CommonSortOrderEnum;
import vip.xiaonuo.common.exception.CommonException;
import vip.xiaonuo.common.listener.CommonDataChangeEventCenter;
@@ -239,6 +240,11 @@ public class BizPositionServiceImpl extends ServiceImpl<BizPositionMapper, BizPo
return TreeUtil.build(treeNodeList, "0");
}
@Override
public List<JSONObject> orgTreeLazySelector(BizOrgTreeLazyParam bizOrgTreeLazyParam) {
return bizOrgService.treeLazy(bizOrgTreeLazyParam);
}
@Override
public Page<BizPosition> positionSelector(BizPositionSelectorPositionParam bizPositionSelectorPositionParam) {
QueryWrapper<BizPosition> queryWrapper = new QueryWrapper<BizPosition>();

View File

@@ -14,6 +14,7 @@ package vip.xiaonuo.biz.modular.user.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.xingfudeshi.knife4j.annotations.ApiOperationSupport;
import com.github.xingfudeshi.knife4j.annotations.ApiSupport;
@@ -30,6 +31,7 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import vip.xiaonuo.biz.modular.org.entity.BizOrg;
import vip.xiaonuo.biz.modular.position.entity.BizPosition;
import vip.xiaonuo.biz.modular.org.param.BizOrgTreeLazyParam;
import vip.xiaonuo.biz.modular.user.entity.BizUser;
import vip.xiaonuo.biz.modular.user.enums.BizUserSourceFromTypeEnum;
import vip.xiaonuo.biz.modular.user.param.*;
@@ -258,6 +260,20 @@ public class BizUserController {
return CommonResult.data(bizUserService.orgTreeSelector());
}
/**
* 获取机构树选择器(懒加载)
*
* @author xuyuxiang
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 13)
@Operation(summary = "获取机构树选择器(懒加载)")
@SaCheckPermission("/biz/user/orgTreeLazySelector")
@GetMapping("/biz/user/orgTreeLazySelector")
public CommonResult<List<JSONObject>> orgTreeLazySelector(BizOrgTreeLazyParam bizOrgTreeLazyParam) {
return CommonResult.data(bizUserService.orgTreeLazySelector(bizOrgTreeLazyParam));
}
/**
* 获取机构列表选择器
*

View File

@@ -13,10 +13,12 @@
package vip.xiaonuo.biz.modular.user.service;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import jakarta.servlet.http.HttpServletResponse;
import vip.xiaonuo.biz.modular.org.entity.BizOrg;
import vip.xiaonuo.biz.modular.org.param.BizOrgTreeLazyParam;
import vip.xiaonuo.biz.modular.position.entity.BizPosition;
import vip.xiaonuo.biz.modular.user.entity.BizUser;
import vip.xiaonuo.biz.modular.user.param.*;
@@ -147,6 +149,14 @@ public interface BizUserService extends IService<BizUser> {
*/
List<Tree<String>> orgTreeSelector();
/**
* 获取机构树选择器(懒加载)
*
* @author xuyuxiang
* @date 2022/5/13 21:00
*/
List<JSONObject> orgTreeLazySelector(BizOrgTreeLazyParam bizOrgTreeLazyParam);
/**
* 获取机构列表选择器
*

View File

@@ -57,6 +57,7 @@ import vip.xiaonuo.auth.core.util.StpLoginUserUtil;
import vip.xiaonuo.biz.core.enums.BizBuildInEnum;
import vip.xiaonuo.biz.core.enums.BizDataTypeEnum;
import vip.xiaonuo.biz.modular.org.entity.BizOrg;
import vip.xiaonuo.biz.modular.org.param.BizOrgTreeLazyParam;
import vip.xiaonuo.biz.modular.org.service.BizOrgService;
import vip.xiaonuo.biz.modular.position.entity.BizPosition;
import vip.xiaonuo.biz.modular.position.service.BizPositionService;
@@ -640,6 +641,11 @@ public class BizUserServiceImpl extends ServiceImpl<BizUserMapper, BizUser> impl
return TreeUtil.build(treeNodeList, "0");
}
@Override
public List<JSONObject> orgTreeLazySelector(BizOrgTreeLazyParam bizOrgTreeLazyParam) {
return bizOrgService.treeLazy(bizOrgTreeLazyParam);
}
@Override
public Page<BizOrg> orgListSelector(BizUserSelectorOrgListParam bizUserSelectorOrgListParam) {
QueryWrapper<BizOrg> queryWrapper = new QueryWrapper<BizOrg>().checkSqlInjection();

View File

@@ -201,6 +201,18 @@ public class DevConfigController {
return CommonResult.data(sysOrgApi.orgTreeSelector());
}
/**
* 获取机构选树(懒加载)
*
* @author yubaoshan
* @date 2025/4/23 20:00
*/
@Operation(summary = "获取机构选树(懒加载)")
@GetMapping("/dev/config/orgTreeLazy")
public CommonResult<List<JSONObject>> orgTreeLazy(String parentId) {
return CommonResult.data(sysOrgApi.orgTreeLazySelector(parentId));
}
/**
* 获取角色选择器
*

View File

@@ -13,6 +13,7 @@
package vip.xiaonuo.sys.modular.org.controller;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.xingfudeshi.knife4j.annotations.ApiOperationSupport;
import com.github.xingfudeshi.knife4j.annotations.ApiSupport;
@@ -77,6 +78,19 @@ public class SysOrgController {
return CommonResult.data(sysOrgService.tree());
}
/**
* 获取组织树(懒加载)
*
* @author xuyuxiang
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 2)
@Operation(summary = "获取组织树(懒加载)")
@GetMapping("/sys/org/treeLazy")
public CommonResult<List<JSONObject>> treeLazy(SysOrgTreeLazyParam sysOrgTreeLazyParam) {
return CommonResult.data(sysOrgService.treeLazy(sysOrgTreeLazyParam));
}
/**
* 添加组织
*
@@ -166,6 +180,19 @@ public class SysOrgController {
return CommonResult.data(sysOrgService.orgTreeSelector());
}
/**
* 获取组织树选择器(懒加载)
*
* @author xuyuxiang
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 8)
@Operation(summary = "获取组织树选择器(懒加载)")
@GetMapping("/sys/org/orgTreeLazySelector")
public CommonResult<List<JSONObject>> orgTreeLazySelector(SysOrgTreeLazyParam sysOrgTreeLazyParam) {
return CommonResult.data(sysOrgService.treeLazy(sysOrgTreeLazyParam));
}
/**
* 获取用户选择器
*

View File

@@ -0,0 +1,32 @@
/*
* Copyright [2022] [https://www.xiaonuo.vip]
*
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
*
* 1.请不要删除和修改根目录下的LICENSE文件.
* 2.请不要删除和修改Snowy源码头部的版权声明.
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等.
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
* 5.不可二次分发开源参与同类竞品如有想法可联系团队xiaonuobase@qq.com商议合作.
* 6.若您的项目无法满足以上几点需要更多功能代码获取Snowy商业授权许可请在官网购买授权地址为 https://www.xiaonuo.vip
*/
package vip.xiaonuo.sys.modular.org.param;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
/**
* 组织树懒加载参数
*
* @author xuyuxiang
* @date 2022/4/21 16:13
**/
@Getter
@Setter
public class SysOrgTreeLazyParam {
/** 父id */
@Schema(description = "父id")
private String parentId;
}

View File

@@ -23,6 +23,7 @@ import org.springframework.stereotype.Service;
import vip.xiaonuo.sys.api.SysOrgApi;
import vip.xiaonuo.sys.modular.org.entity.SysOrg;
import vip.xiaonuo.sys.modular.org.param.SysOrgSelectorOrgListParam;
import vip.xiaonuo.sys.modular.org.param.SysOrgTreeLazyParam;
import vip.xiaonuo.sys.modular.org.service.SysOrgService;
import java.util.List;
@@ -59,6 +60,13 @@ public class SysOrgApiProvider implements SysOrgApi {
return sysOrgService.orgTreeSelector();
}
@Override
public List<JSONObject> orgTreeLazySelector(String parentId) {
SysOrgTreeLazyParam sysOrgTreeLazyParam = new SysOrgTreeLazyParam();
sysOrgTreeLazyParam.setParentId(parentId);
return sysOrgService.treeLazy(sysOrgTreeLazyParam);
}
@SuppressWarnings("ALL")
@Override
public Page<JSONObject> orgListSelector(String parentId) {

View File

@@ -13,6 +13,7 @@
package vip.xiaonuo.sys.modular.org.service;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import vip.xiaonuo.sys.modular.org.entity.SysOrg;
@@ -45,6 +46,14 @@ public interface SysOrgService extends IService<SysOrg> {
*/
List<Tree<String>> tree();
/**
* 获取机构树(懒加载)
*
* @author xuyuxiang
* @date 2022/4/21 16:13
**/
List<JSONObject> treeLazy(SysOrgTreeLazyParam sysOrgTreeLazyParam);
/**
* 添加组织
*

View File

@@ -30,6 +30,8 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vip.xiaonuo.auth.core.util.StpLoginUserUtil;
import vip.xiaonuo.common.cache.CommonCacheOperator;
import vip.xiaonuo.common.enums.CommonSortOrderEnum;
import vip.xiaonuo.common.exception.CommonException;
import vip.xiaonuo.common.listener.CommonDataChangeEventCenter;
@@ -53,6 +55,7 @@ import vip.xiaonuo.sys.modular.user.service.SysUserService;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
@@ -64,6 +67,11 @@ import java.util.stream.Collectors;
@Service
public class SysOrgServiceImpl extends ServiceImpl<SysOrgMapper, SysOrg> implements SysOrgService {
private static final String ORG_ALL_LIST_CACHE_KEY = "sys-org:all-list";
@Resource
private CommonCacheOperator commonCacheOperator;
@Resource
private SysOrgExtService sysOrgExtService;
@@ -111,6 +119,58 @@ public class SysOrgServiceImpl extends ServiceImpl<SysOrgMapper, SysOrg> impleme
return TreeUtil.build(treeNodeList, "0");
}
@Override
public List<JSONObject> treeLazy(SysOrgTreeLazyParam sysOrgTreeLazyParam) {
String parentId = ObjectUtil.isNotEmpty(sysOrgTreeLazyParam.getParentId()) ? sysOrgTreeLazyParam.getParentId() : "0";
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
// 获取所有机构
List<SysOrg> allOrgList = this.getAllOrgList();
Set<String> visibleOrgIds = null;
// 如果数据范围不为空则计算可见机构ID集合包含自身及其所有父级
if (ObjectUtil.isNotEmpty(loginUserDataScope)) {
Set<SysOrg> sysOrgSet = CollectionUtil.newHashSet();
loginUserDataScope.forEach(orgId -> sysOrgSet.addAll(this.getParentListById(allOrgList, orgId, true)));
visibleOrgIds = sysOrgSet.stream().map(SysOrg::getId).collect(Collectors.toSet());
}
// 过滤出当前父级下的可见子级
final Set<String> finalVisibleOrgIds = visibleOrgIds;
List<SysOrg> sysOrgList = allOrgList.stream()
.filter(sysOrg -> sysOrg.getParentId().equals(parentId))
.filter(sysOrg -> finalVisibleOrgIds == null || finalVisibleOrgIds.contains(sysOrg.getId()))
.sorted(Comparator.comparingInt(SysOrg::getSortCode).thenComparing(SysOrg::getId))
.collect(Collectors.toList());
if (CollectionUtil.isEmpty(sysOrgList)) {
return CollectionUtil.newArrayList();
}
// 判断这些机构是否还有可见子机构
return sysOrgList.stream().map(sysOrg -> {
JSONObject jsonObject = JSONUtil.parseObj(sysOrg);
// 计算是否有可见的子节点
boolean hasChildren = allOrgList.stream()
.anyMatch(item -> item.getParentId().equals(sysOrg.getId()) && (finalVisibleOrgIds == null || finalVisibleOrgIds.contains(item.getId())));
jsonObject.set("isLeaf", !hasChildren);
return jsonObject;
}).collect(Collectors.toList());
}
/**
* 获取机构树(懒加载)
*
* @author xuyuxiang
* @date 2022/4/21 16:13
**/
public List<JSONObject> treeLazy(String parentId) {
SysOrgTreeLazyParam sysOrgTreeLazyParam = new SysOrgTreeLazyParam();
sysOrgTreeLazyParam.setParentId(parentId);
return this.treeLazy(sysOrgTreeLazyParam);
}
@Transactional(rollbackFor = Exception.class)
@Override
public void add(SysOrgAddParam sysOrgAddParam, String sourceFromType) {
@@ -129,6 +189,8 @@ public class SysOrgServiceImpl extends ServiceImpl<SysOrgMapper, SysOrg> impleme
sysOrgExtService.createExtInfo(sysOrg.getId(), sourceFromType);
// 发布增加事件
CommonDataChangeEventCenter.doAddWithData(SysDataTypeEnum.ORG.getValue(), JSONUtil.createArray().put(sysOrg));
// 清除缓存
commonCacheOperator.remove(ORG_ALL_LIST_CACHE_KEY);
}
@Transactional(rollbackFor = Exception.class)
@@ -152,6 +214,8 @@ public class SysOrgServiceImpl extends ServiceImpl<SysOrgMapper, SysOrg> impleme
this.updateById(sysOrg);
// 发布更新事件
CommonDataChangeEventCenter.doUpdateWithData(SysDataTypeEnum.ORG.getValue(), JSONUtil.createArray().put(sysOrg));
// 清除缓存
commonCacheOperator.remove(ORG_ALL_LIST_CACHE_KEY);
}
@Transactional(rollbackFor = Exception.class)
@@ -197,6 +261,8 @@ public class SysOrgServiceImpl extends ServiceImpl<SysOrgMapper, SysOrg> impleme
// 发布删除事件
CommonDataChangeEventCenter.doDeleteWithDataIdList(SysDataTypeEnum.ORG.getValue(), toDeleteOrgIdList);
// 清除缓存
commonCacheOperator.remove(ORG_ALL_LIST_CACHE_KEY);
}
}
@@ -245,6 +311,8 @@ public class SysOrgServiceImpl extends ServiceImpl<SysOrgMapper, SysOrg> impleme
}
}
});
// 清除缓存
commonCacheOperator.remove(ORG_ALL_LIST_CACHE_KEY);
}
}
@@ -259,7 +327,13 @@ public class SysOrgServiceImpl extends ServiceImpl<SysOrgMapper, SysOrg> impleme
@Override
public List<SysOrg> getAllOrgList() {
return this.list(new LambdaQueryWrapper<SysOrg>().orderByAsc(SysOrg::getSortCode));
Object cached = commonCacheOperator.get(ORG_ALL_LIST_CACHE_KEY);
if (cached != null) {
return JSONUtil.toList(JSONUtil.parseArray(cached), SysOrg.class);
}
List<SysOrg> list = this.list(new LambdaQueryWrapper<SysOrg>().orderByAsc(SysOrg::getSortCode));
commonCacheOperator.put(ORG_ALL_LIST_CACHE_KEY, list);
return list;
}
@Override
@@ -311,6 +385,8 @@ public class SysOrgServiceImpl extends ServiceImpl<SysOrgMapper, SysOrg> impleme
sysOrgExtService.createExtInfo(sysOrg.getId(), SysOrgSourceFromTypeEnum.SYSTEM_ADD.getValue());
// 发布增加事件
CommonDataChangeEventCenter.doAddWithData(SysDataTypeEnum.ORG.getValue(), JSONUtil.createArray().put(sysOrg));
// 清除缓存
commonCacheOperator.remove(ORG_ALL_LIST_CACHE_KEY);
return sysOrg.getId();
}

View File

@@ -13,6 +13,7 @@
package vip.xiaonuo.sys.modular.position.controller;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.xingfudeshi.knife4j.annotations.ApiOperationSupport;
import com.github.xingfudeshi.knife4j.annotations.ApiSupport;
@@ -27,6 +28,7 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import vip.xiaonuo.common.annotation.CommonLog;
import vip.xiaonuo.common.pojo.CommonResult;
import vip.xiaonuo.sys.modular.org.param.SysOrgTreeLazyParam;
import vip.xiaonuo.sys.modular.position.entity.SysPosition;
import vip.xiaonuo.sys.modular.position.param.*;
import vip.xiaonuo.sys.modular.position.service.SysPositionService;
@@ -136,6 +138,19 @@ public class SysPositionController {
return CommonResult.data(sysPositionService.orgTreeSelector());
}
/**
* 获取组织树选择器(懒加载)
*
* @author xuyuxiang
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 6)
@Operation(summary = "获取组织树选择器(懒加载)")
@GetMapping("/sys/position/orgTreeLazySelector")
public CommonResult<List<JSONObject>> orgTreeLazySelector(SysOrgTreeLazyParam sysOrgTreeLazyParam) {
return CommonResult.data(sysPositionService.orgTreeLazySelector(sysOrgTreeLazyParam));
}
/**
* 获取职位选择器
*

View File

@@ -13,8 +13,10 @@
package vip.xiaonuo.sys.modular.position.service;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import vip.xiaonuo.sys.modular.org.param.SysOrgTreeLazyParam;
import vip.xiaonuo.sys.modular.position.entity.SysPosition;
import vip.xiaonuo.sys.modular.position.param.*;
@@ -102,6 +104,14 @@ public interface SysPositionService extends IService<SysPosition> {
*/
List<Tree<String>> orgTreeSelector();
/**
* 获取组织树选择器(懒加载)
*
* @author xuyuxiang
* @date 2022/4/22 15:53
**/
List<JSONObject> orgTreeLazySelector(SysOrgTreeLazyParam sysOrgTreeLazyParam);
/**
* 获取职位选择器
*

View File

@@ -36,6 +36,7 @@ import vip.xiaonuo.common.listener.CommonDataChangeEventCenter;
import vip.xiaonuo.common.page.CommonPageRequest;
import vip.xiaonuo.sys.core.enums.SysDataTypeEnum;
import vip.xiaonuo.sys.modular.org.entity.SysOrg;
import vip.xiaonuo.sys.modular.org.param.SysOrgTreeLazyParam;
import vip.xiaonuo.sys.modular.org.service.SysOrgService;
import vip.xiaonuo.sys.modular.position.entity.SysPosition;
import vip.xiaonuo.sys.modular.position.enums.SysPositionCategoryEnum;
@@ -200,6 +201,11 @@ public class SysPositionServiceImpl extends ServiceImpl<SysPositionMapper, SysPo
return TreeUtil.build(treeNodeList, "0");
}
@Override
public List<JSONObject> orgTreeLazySelector(SysOrgTreeLazyParam sysOrgTreeLazyParam) {
return sysOrgService.treeLazy(sysOrgTreeLazyParam);
}
@Override
public Page<SysPosition> positionSelector(SysPositionSelectorPositionParam sysPositionSelectorPositionParam) {
QueryWrapper<SysPosition> queryWrapper = new QueryWrapper<SysPosition>().checkSqlInjection();

View File

@@ -13,6 +13,7 @@
package vip.xiaonuo.sys.modular.role.controller;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.xingfudeshi.knife4j.annotations.ApiOperationSupport;
import com.github.xingfudeshi.knife4j.annotations.ApiSupport;
@@ -27,6 +28,7 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import vip.xiaonuo.common.annotation.CommonLog;
import vip.xiaonuo.common.pojo.CommonResult;
import vip.xiaonuo.sys.modular.org.param.SysOrgTreeLazyParam;
import vip.xiaonuo.sys.modular.role.entity.SysRole;
import vip.xiaonuo.sys.modular.role.param.*;
import vip.xiaonuo.sys.modular.role.result.*;
@@ -251,6 +253,19 @@ public class SysRoleController {
return CommonResult.data(sysRoleService.orgTreeSelector());
}
/**
* 获取组织树选择器(懒加载)
*
* @author xuyuxiang
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 15)
@Operation(summary = "获取组织树选择器(懒加载)")
@GetMapping("/sys/role/orgTreeLazySelector")
public CommonResult<List<JSONObject>> orgTreeLazySelector(SysOrgTreeLazyParam sysOrgTreeLazyParam) {
return CommonResult.data(sysRoleService.orgTreeLazySelector(sysOrgTreeLazyParam));
}
/**
* 获取资源授权树
*

View File

@@ -16,6 +16,7 @@ import cn.hutool.core.lang.tree.Tree;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import vip.xiaonuo.sys.modular.org.param.SysOrgTreeLazyParam;
import vip.xiaonuo.sys.modular.resource.entity.SysMenu;
import vip.xiaonuo.sys.modular.role.entity.SysRole;
import vip.xiaonuo.sys.modular.role.param.*;
@@ -154,6 +155,14 @@ public interface SysRoleService extends IService<SysRole> {
*/
List<Tree<String>> orgTreeSelector();
/**
* 获取组织树选择器(懒加载)
*
* @author xuyuxiang
* @date 2022/4/24 20:00
*/
List<JSONObject> orgTreeLazySelector(SysOrgTreeLazyParam sysOrgTreeLazyParam);
/**
* 获取资源授权树
*

View File

@@ -41,6 +41,7 @@ import vip.xiaonuo.mobile.api.MobileMenuApi;
import vip.xiaonuo.sys.core.enums.SysBuildInEnum;
import vip.xiaonuo.sys.core.enums.SysDataTypeEnum;
import vip.xiaonuo.sys.modular.org.entity.SysOrg;
import vip.xiaonuo.sys.modular.org.param.SysOrgTreeLazyParam;
import vip.xiaonuo.sys.modular.org.service.SysOrgService;
import vip.xiaonuo.sys.modular.relation.entity.SysRelation;
import vip.xiaonuo.sys.modular.relation.enums.SysRelationCategoryEnum;
@@ -357,6 +358,11 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
return TreeUtil.build(treeNodeList, "0");
}
@Override
public List<JSONObject> orgTreeLazySelector(SysOrgTreeLazyParam sysOrgTreeLazyParam) {
return sysOrgService.treeLazy(sysOrgTreeLazyParam);
}
@Override
public List<SysRoleGrantResourceTreeResult> resourceTreeSelector(boolean containsTen) {
LambdaQueryWrapper<SysMenu> lambdaQueryWrapper = new LambdaQueryWrapper<>();

View File

@@ -31,6 +31,7 @@ import vip.xiaonuo.common.pojo.CommonResult;
import vip.xiaonuo.sys.modular.org.entity.SysOrg;
import vip.xiaonuo.sys.modular.position.entity.SysPosition;
import vip.xiaonuo.sys.modular.role.entity.SysRole;
import vip.xiaonuo.sys.modular.org.param.SysOrgTreeLazyParam;
import vip.xiaonuo.sys.modular.user.entity.SysUser;
import vip.xiaonuo.sys.modular.user.enums.SysUserSourceFromTypeEnum;
import vip.xiaonuo.sys.modular.user.param.*;
@@ -329,6 +330,19 @@ public class SysUserController {
return CommonResult.data(sysUserService.orgTreeSelector());
}
/**
* 获取组织树选择器(懒加载)
*
* @author xuyuxiang
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 19)
@Operation(summary = "获取组织树选择器(懒加载)")
@GetMapping("/sys/user/orgTreeLazySelector")
public CommonResult<List<JSONObject>> orgTreeLazySelector(SysOrgTreeLazyParam sysOrgTreeLazyParam) {
return CommonResult.data(sysUserService.orgTreeLazySelector(sysOrgTreeLazyParam));
}
/**
* 获取组织列表选择器
*

View File

@@ -22,6 +22,7 @@ import vip.xiaonuo.sys.modular.group.entity.SysGroup;
import vip.xiaonuo.sys.modular.org.entity.SysOrg;
import vip.xiaonuo.sys.modular.position.entity.SysPosition;
import vip.xiaonuo.sys.modular.role.entity.SysRole;
import vip.xiaonuo.sys.modular.org.param.SysOrgTreeLazyParam;
import vip.xiaonuo.sys.modular.user.entity.SysUser;
import vip.xiaonuo.sys.modular.user.entity.SysUserExt;
import vip.xiaonuo.sys.modular.user.param.*;
@@ -480,6 +481,14 @@ public interface SysUserService extends IService<SysUser> {
*/
List<Tree<String>> orgTreeSelector();
/**
* 获取组织树选择器(懒加载)
*
* @author xuyuxiang
* @date 2022/5/13 21:00
*/
List<JSONObject> orgTreeLazySelector(SysOrgTreeLazyParam sysOrgTreeLazyParam);
/**
* 获取组织列表选择器
*

View File

@@ -88,6 +88,7 @@ import vip.xiaonuo.sys.core.util.SysPasswordUtl;
import vip.xiaonuo.sys.modular.group.entity.SysGroup;
import vip.xiaonuo.sys.modular.group.service.SysGroupService;
import vip.xiaonuo.sys.modular.org.entity.SysOrg;
import vip.xiaonuo.sys.modular.org.param.SysOrgTreeLazyParam;
import vip.xiaonuo.sys.modular.org.service.SysOrgService;
import vip.xiaonuo.sys.modular.position.entity.SysPosition;
import vip.xiaonuo.sys.modular.position.service.SysPositionService;
@@ -2004,6 +2005,11 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
return TreeUtil.build(treeNodeList, "0");
}
@Override
public List<JSONObject> orgTreeLazySelector(SysOrgTreeLazyParam sysOrgTreeLazyParam) {
return sysOrgService.treeLazy(sysOrgTreeLazyParam);
}
@Override
public Page<SysOrg> orgListSelector(SysUserSelectorOrgListParam sysUserSelectorOrgListParam) {
QueryWrapper<SysOrg> queryWrapper = new QueryWrapper<SysOrg>().checkSqlInjection();