【机构】再次优化大数据下的机构授权接口、界面体验

This commit is contained in:
俞宝山
2026-02-11 01:23:13 +08:00
parent 1c086d5b52
commit 93779db584
12 changed files with 320 additions and 170 deletions

View File

@@ -36,6 +36,7 @@
:tree-data="treeData"
:field-names="treeFieldNames"
:load-data="onLoadData"
:height="treeHeight"
@select="treeSelect"
>
</a-tree>
@@ -153,7 +154,7 @@
import { message } from 'ant-design-vue'
import { remove, isEmpty, cloneDeep } from 'lodash-es'
import userCenterApi from '@/api/sys/userCenterApi'
import { useSlots } from 'vue'
import { useSlots, triggerRef } from 'vue'
// 弹窗是否打开
const visible = ref(false)
// 主表格common
@@ -252,11 +253,12 @@
const current = ref(0) // 当前页数
const pageSize = ref(10) // 每页条数
const total = ref(0) // 数据总数
const treeHeight = ref(400)
// 懒加载子节点
const onLoadData = (treeNode) => {
return new Promise((resolve) => {
if (typeof props.orgTreeLazyApi !== 'function' || treeNode.dataRef.children) {
if (typeof props.orgTreeLazyApi !== 'function' || treeNode.dataRef.children || treeNode.dataRef.isLeaf) {
resolve()
return
}
@@ -271,7 +273,7 @@
isLeaf: item.isLeaf === undefined ? false : item.isLeaf
}
})
treeData.value = [...treeData.value]
triggerRef(treeData)
resolve()
})
})
@@ -321,6 +323,8 @@
return
}
visible.value = true
// 动态计算树高度,适配不同屏幕
treeHeight.value = Math.min(Math.max(window.innerHeight - 350, 250), 460)
// 获取机构树
if (typeof props.orgTreeLazyApi === 'function') {
props

View File

@@ -36,6 +36,7 @@
:tree-data="treeData"
:field-names="treeFieldNames"
:load-data="onLoadData"
:height="treeHeight"
@select="treeSelect"
>
</a-tree>
@@ -153,7 +154,7 @@
import { message } from 'ant-design-vue'
import { remove, isEmpty, cloneDeep } from 'lodash-es'
import userCenterApi from '@/api/sys/userCenterApi'
import { useSlots } from 'vue'
import { useSlots, triggerRef } from 'vue'
// 弹窗是否打开
const visible = ref(false)
// 主表格common
@@ -248,11 +249,12 @@
const current = ref(0) // 当前页数
const pageSize = ref(10) // 每页条数
const total = ref(0) // 数据总数
const treeHeight = ref(400)
// 懒加载子节点
const onLoadData = (treeNode) => {
return new Promise((resolve) => {
if (typeof props.orgTreeLazyApi !== 'function' || treeNode.dataRef.children) {
if (typeof props.orgTreeLazyApi !== 'function' || treeNode.dataRef.children || treeNode.dataRef.isLeaf) {
resolve()
return
}
@@ -267,7 +269,7 @@
isLeaf: item.isLeaf === undefined ? false : item.isLeaf
}
})
treeData.value = [...treeData.value]
triggerRef(treeData)
resolve()
})
})
@@ -317,6 +319,8 @@
return
}
visible.value = true
// 动态计算树高度,适配不同屏幕
treeHeight.value = Math.min(Math.max(window.innerHeight - 350, 250), 460)
// 获取机构树
if (typeof props.orgTreeLazyApi === 'function') {
props

View File

@@ -36,6 +36,7 @@
:tree-data="treeData"
:field-names="treeFieldNames"
:load-data="onLoadData"
:height="treeHeight"
@select="treeSelect"
>
</a-tree>
@@ -154,7 +155,7 @@
import { message } from 'ant-design-vue'
import { remove, isEmpty, cloneDeep } from 'lodash-es'
import userCenterApi from '@/api/sys/userCenterApi'
import { useSlots } from 'vue'
import { useSlots, triggerRef, nextTick } from 'vue'
// 弹窗是否打开
const visible = ref(false)
// 主表格common
@@ -255,11 +256,12 @@
const current = ref(0) // 当前页数
const pageSize = ref(10) // 每页条数
const total = ref(0) // 数据总数
const treeHeight = ref(400)
// 懒加载子节点
const onLoadData = (treeNode) => {
return new Promise((resolve) => {
if (typeof props.orgTreeLazyApi !== 'function' || treeNode.dataRef.children) {
if (typeof props.orgTreeLazyApi !== 'function' || treeNode.dataRef.children || treeNode.dataRef.isLeaf) {
resolve()
return
}
@@ -274,7 +276,7 @@
isLeaf: item.isLeaf === undefined ? false : item.isLeaf
}
})
treeData.value = [...treeData.value]
triggerRef(treeData)
resolve()
})
})
@@ -324,6 +326,8 @@
return
}
visible.value = true
// 动态计算树高度,适配不同屏幕
treeHeight.value = Math.min(Math.max(window.innerHeight - 350, 250), 460)
// 获取机构树
if (typeof props.orgTreeLazyApi === 'function') {
props

View File

@@ -43,6 +43,7 @@
:tree-data="treeData"
:field-names="treeFieldNames"
:load-data="onLoadData"
:height="treeHeight"
@select="treeSelect"
>
</a-tree>
@@ -163,6 +164,7 @@
import { message } from 'ant-design-vue'
import { remove, isEmpty, cloneDeep } from 'lodash-es'
import userCenterApi from '@/api/sys/userCenterApi'
import { triggerRef } from 'vue'
// 弹窗是否打开
const visible = ref(false)
const deleteShow = ref('')
@@ -261,6 +263,7 @@
const current = ref(0) // 当前页数
const pageSize = ref(10) // 每页条数
const total = ref(0) // 数据总数
const treeHeight = ref(400)
// 获取选中列表的api
const userListByIdList = (param) => {
if (typeof props.userListByIdListApi === 'function') {
@@ -287,7 +290,7 @@
// 懒加载子节点
const onLoadData = (treeNode) => {
return new Promise((resolve) => {
if (typeof props.orgTreeLazyApi !== 'function' || treeNode.dataRef.children) {
if (typeof props.orgTreeLazyApi !== 'function' || treeNode.dataRef.children || treeNode.dataRef.isLeaf) {
resolve()
return
}
@@ -302,7 +305,7 @@
isLeaf: item.isLeaf === undefined ? false : item.isLeaf
}
})
treeData.value = [...treeData.value]
triggerRef(treeData)
resolve()
})
})
@@ -315,6 +318,8 @@
return
}
visible.value = true
// 动态计算树高度,适配不同屏幕
treeHeight.value = Math.min(Math.max(window.innerHeight - 350, 250), 460)
// 获取机构树
if (typeof props.orgTreeLazyApi === 'function') {
props

View File

@@ -2,8 +2,14 @@
<XnResizablePanel direction="row" :initial-size="300" :min-size="200" :max-size="500" :md="0">
<template #left>
<div ref="treeContainerRef" style="height: 100%">
<div
v-if="treeLoading && treeData.length === 0"
style="display: flex; height: 100%; align-items: center; justify-content: center"
>
<a-spin />
</div>
<a-tree
v-if="treeData.length > 0"
v-else-if="treeData.length > 0"
v-model:expandedKeys="defaultExpandedKeys"
:tree-data="treeData"
:field-names="treeFieldNames"
@@ -206,9 +212,13 @@
searchFormRef.value.resetFields()
tableRef.value.refresh(true)
}
const treeLoading = ref(true)
// 加载左侧的树
const loadTreeData = () => {
bizOrgApi.orgTreeLazy().then((res) => {
treeLoading.value = true
bizOrgApi
.orgTreeLazy()
.then((res) => {
if (res !== null) {
treeData.value = res.map((item) => {
return {
@@ -224,6 +234,9 @@
}
}
})
.finally(() => {
treeLoading.value = false
})
}
loadTreeData()
// 懒加载子节点

View File

@@ -2,8 +2,14 @@
<XnResizablePanel direction="row" :initial-size="300" :min-size="200" :max-size="500" :md="0">
<template #left>
<div ref="treeContainerRef" style="height: 100%">
<div
v-if="treeLoading && treeData.length === 0"
style="display: flex; height: 100%; align-items: center; justify-content: center"
>
<a-spin />
</div>
<a-tree
v-if="treeData.length > 0"
v-else-if="treeData.length > 0"
v-model:expandedKeys="defaultExpandedKeys"
:tree-data="treeData"
:field-names="treeFieldNames"
@@ -197,9 +203,13 @@
searchFormRef.value.resetFields()
tableRef.value.refresh(true)
}
const treeLoading = ref(true)
// 加载左侧的树
const loadTreeData = () => {
bizOrgApi.orgTreeLazy().then((res) => {
treeLoading.value = true
bizOrgApi
.orgTreeLazy()
.then((res) => {
if (res !== null) {
treeData.value = res.map((item) => {
return {
@@ -208,15 +218,14 @@
}
})
if (isEmpty(defaultExpandedKeys.value)) {
// 默认展开顶级
treeData.value.forEach((item) => {
// 因为0的顶级
if (item.parentId === '0') {
defaultExpandedKeys.value.push(item.id)
if (treeData.value.length > 0) {
defaultExpandedKeys.value.push(treeData.value[0].id)
}
}
}
})
}
}
.finally(() => {
treeLoading.value = false
})
}
loadTreeData()

View File

@@ -2,8 +2,14 @@
<XnResizablePanel direction="row" :initial-size="300" :min-size="200" :max-size="500" :md="0">
<template #left>
<div ref="treeContainerRef" style="height: 100%">
<div
v-if="treeLoading && treeData.length === 0"
style="display: flex; height: 100%; align-items: center; justify-content: center"
>
<a-spin />
</div>
<a-tree
v-if="treeData.length > 0"
v-else-if="treeData.length > 0"
v-model:expandedKeys="defaultExpandedKeys"
:tree-data="treeData"
:field-names="treeFieldNames"
@@ -272,9 +278,13 @@
searchFormRef.value.resetFields()
tableRef.value.refresh(true)
}
const treeLoading = ref(true)
// 加载左侧树
const loadTreeData = () => {
bizOrgApi.orgTreeLazy().then((res) => {
treeLoading.value = true
bizOrgApi
.orgTreeLazy()
.then((res) => {
if (res !== null) {
treeData.value = res.map((item) => {
return {
@@ -283,15 +293,14 @@
}
})
if (isEmpty(defaultExpandedKeys.value)) {
// 默认展开顶级
treeData.value.forEach((item) => {
// 因为0的顶级
if (item.parentId === '0') {
defaultExpandedKeys.value.push(item.id)
if (treeData.value.length > 0) {
defaultExpandedKeys.value.push(treeData.value[0].id)
}
}
}
})
}
}
.finally(() => {
treeLoading.value = false
})
}
loadTreeData()

View File

@@ -2,8 +2,14 @@
<XnResizablePanel direction="row" :initial-size="300" :min-size="200" :max-size="500" :md="0">
<template #left>
<div ref="treeContainerRef" style="height: 100%">
<div
v-if="treeLoading && treeData.length === 0"
style="display: flex; height: 100%; align-items: center; justify-content: center"
>
<a-spin />
</div>
<a-tree
v-if="treeData.length > 0"
v-else-if="treeData.length > 0"
v-model:expandedKeys="defaultExpandedKeys"
:tree-data="treeData"
:field-names="treeFieldNames"
@@ -203,9 +209,13 @@
searchFormRef.value.resetFields()
tableRef.value.refresh(true)
}
const treeLoading = ref(true)
// 加载左侧的树
const loadTreeData = () => {
orgApi.orgTreeLazy().then((res) => {
treeLoading.value = true
orgApi
.orgTreeLazy()
.then((res) => {
if (res !== null) {
treeData.value = res.map((item) => {
return {
@@ -221,6 +231,9 @@
}
}
})
.finally(() => {
treeLoading.value = false
})
}
loadTreeData()
// 懒加载子节点

View File

@@ -2,8 +2,14 @@
<XnResizablePanel direction="row" :initial-size="300" :min-size="200" :max-size="500" :md="0">
<template #left>
<div ref="treeContainerRef" style="height: 100%">
<div
v-if="treeLoading && treeData.length === 0"
style="display: flex; height: 100%; align-items: center; justify-content: center"
>
<a-spin />
</div>
<a-tree
v-if="treeData.length > 0"
v-else-if="treeData.length > 0"
v-model:expandedKeys="defaultExpandedKeys"
:tree-data="treeData"
:field-names="treeFieldNames"
@@ -194,8 +200,11 @@
searchFormRef.value.resetFields()
tableRef.value.refresh(true)
}
const treeLoading = ref(true)
// 加载左侧的树
orgApi.orgTreeLazy().then((res) => {
orgApi
.orgTreeLazy()
.then((res) => {
if (res !== null) {
treeData.value = res.map((item) => {
return {
@@ -211,6 +220,9 @@
}
}
})
.finally(() => {
treeLoading.value = false
})
// 懒加载子节点
const onLoadData = (treeNode) => {
return new Promise((resolve) => {

View File

@@ -2,8 +2,14 @@
<XnResizablePanel direction="row" :initial-size="300" :min-size="200" :max-size="500" :md="0">
<template #left>
<div ref="treeContainerRef" style="height: 100%">
<div
v-if="treeLoading && treeData.length === 0"
style="display: flex; height: 100%; align-items: center; justify-content: center"
>
<a-spin />
</div>
<a-tree
v-if="treeData.length > 0"
v-else-if="treeData.length > 0"
v-model:expandedKeys="defaultExpandedKeys"
:tree-data="treeData"
:field-names="treeFieldNames"
@@ -244,9 +250,13 @@
delete searchFormState.value.category
tableRef.value.refresh(true)
}
const treeLoading = ref(true)
// 加载左侧的树
const loadTreeData = () => {
orgApi.orgTreeLazy().then((res) => {
treeLoading.value = true
orgApi
.orgTreeLazy()
.then((res) => {
if (res !== null) {
// 树中插入全局角色类型
const globalRoleType = [
@@ -266,15 +276,14 @@
})
)
if (isEmpty(defaultExpandedKeys.value)) {
// 默认展开顶级
treeData.value.forEach((item) => {
// 因为0的顶级
if (item.parentId === '0') {
defaultExpandedKeys.value.push(item.id)
if (treeData.value.length > 0) {
defaultExpandedKeys.value.push(treeData.value[0].id)
}
}
}
})
}
}
.finally(() => {
treeLoading.value = false
})
}
loadTreeData()

View File

@@ -2,8 +2,14 @@
<XnResizablePanel direction="row" :initial-size="300" :min-size="200" :max-size="500" :md="0">
<template #left>
<div ref="treeContainerRef" style="height: 100%">
<div
v-if="treeLoading && treeData.length === 0"
style="display: flex; height: 100%; align-items: center; justify-content: center"
>
<a-spin />
</div>
<a-tree
v-if="treeData.length > 0"
v-else-if="treeData.length > 0"
v-model:expandedKeys="defaultExpandedKeys"
:tree-data="treeData"
:field-names="treeFieldNames"
@@ -288,8 +294,11 @@
return res
})
}
const treeLoading = ref(true)
// 左侧树查询
orgApi.orgTreeLazy().then((res) => {
orgApi
.orgTreeLazy()
.then((res) => {
if (res !== null) {
treeData.value = res.map((item) => {
return {
@@ -305,6 +314,9 @@
}
}
})
.finally(() => {
treeLoading.value = false
})
// 懒加载子节点
const onLoadData = (treeNode) => {
return new Promise((resolve) => {

View File

@@ -64,6 +64,15 @@ public class BizOrgServiceImpl extends ServiceImpl<BizOrgMapper, BizOrg> impleme
private static final String ORG_ALL_LIST_CACHE_KEY = "biz-org:all-list";
/** 机构数据版本号缓存key机构增删改时递增用于使 visibleOrgIds 缓存自动失效 */
private static final String ORG_CACHE_VERSION_KEY = "biz-org:cache-version";
/** 可见机构ID集合缓存key前缀完整key = 前缀 + 版本号 + : + 数据范围hash */
private static final String VISIBLE_ORG_IDS_CACHE_KEY_PREFIX = "biz-org:visible-ids:";
/** visibleOrgIds 缓存TTL用于自动清理旧版本的缓存条目 */
private static final long VISIBLE_ORG_IDS_CACHE_TTL = 300;
@Resource
private CommonCacheOperator commonCacheOperator;
@@ -145,47 +154,33 @@ public class BizOrgServiceImpl extends ServiceImpl<BizOrgMapper, BizOrg> impleme
return CollectionUtil.newArrayList();
}
// 获取所有机构
List<BizOrg> allOrgList = this.getAllOrgList();
// 构建索引避免重复线性遍历O(N) 一次性构建)
Map<String, BizOrg> orgById = allOrgList.stream()
.collect(Collectors.toMap(BizOrg::getId, org -> org, (a, b) -> a));
Map<String, List<BizOrg>> childrenByParentId = allOrgList.stream()
.collect(Collectors.groupingBy(BizOrg::getParentId));
// 计算可见机构ID集合包含自身及其所有父级使用索引将复杂度从 O(M*N*D) 降至 O(M*D)
Set<String> visibleOrgIds = new HashSet<>();
for (String orgId : loginUserDataScope) {
if (orgById.containsKey(orgId)) {
visibleOrgIds.add(orgId);
// 向上遍历添加所有父级
String currentId = orgById.get(orgId).getParentId();
while (ObjectUtil.isNotEmpty(currentId) && !"0".equals(currentId) && orgById.containsKey(currentId)) {
if (!visibleOrgIds.add(currentId)) {
break; // 已经添加过,停止遍历
}
currentId = orgById.get(currentId).getParentId();
}
}
// 从版本化缓存获取可见机构ID集合命中时无需加载全量数据
Set<String> visibleOrgIds = this.getVisibleOrgIds(loginUserDataScope);
if (ObjectUtil.isEmpty(visibleOrgIds)) {
return CollectionUtil.newArrayList();
}
// 过滤出当前父级下的可见子级(使用 parentId 索引O(K) 而非 O(N)
List<BizOrg> childList = childrenByParentId.getOrDefault(parentId, Collections.emptyList()).stream()
.filter(bizOrg -> visibleOrgIds.contains(bizOrg.getId()))
.sorted(Comparator.comparingInt(BizOrg::getSortCode).thenComparing(BizOrg::getId))
.collect(Collectors.toList());
// SQL直查获取当前父级下的可见子机构替代内存过滤2万条记录
List<BizOrg> childList = this.list(new LambdaQueryWrapper<BizOrg>()
.eq(BizOrg::getParentId, parentId)
.in(BizOrg::getId, visibleOrgIds)
.orderByAsc(BizOrg::getSortCode));
if (ObjectUtil.isEmpty(childList)) {
return CollectionUtil.newArrayList();
}
// 判断这些机构是否还有可见子机构(使用 parentId 索引O(1) 查找子节点列表
// SQL批量查询判断哪些子机构还有可见的下级单次SQL替代N次遍历
List<String> childIds = childList.stream().map(BizOrg::getId).collect(Collectors.toList());
Set<String> hasChildrenParentIds = this.list(new LambdaQueryWrapper<BizOrg>()
.select(BizOrg::getParentId)
.in(BizOrg::getParentId, childIds)
.in(BizOrg::getId, visibleOrgIds))
.stream().map(BizOrg::getParentId).collect(Collectors.toSet());
return childList.stream().map(bizOrg -> {
JSONObject jsonObject = JSONUtil.parseObj(bizOrg);
List<BizOrg> subChildren = childrenByParentId.getOrDefault(bizOrg.getId(), Collections.emptyList());
boolean hasChildren = subChildren.stream().anyMatch(item -> visibleOrgIds.contains(item.getId()));
jsonObject.set("isLeaf", !hasChildren);
jsonObject.set("isLeaf", !hasChildrenParentIds.contains(bizOrg.getId()));
return jsonObject;
}).collect(Collectors.toList());
}
@@ -231,7 +226,7 @@ public class BizOrgServiceImpl extends ServiceImpl<BizOrgMapper, BizOrg> impleme
// 发布增加事件
CommonDataChangeEventCenter.doAddWithData(BizDataTypeEnum.ORG.getValue(), JSONUtil.createArray().put(bizOrg));
// 清除缓存
commonCacheOperator.remove(ORG_ALL_LIST_CACHE_KEY);
this.invalidateOrgCaches();
}
@Transactional(rollbackFor = Exception.class)
@@ -268,7 +263,7 @@ public class BizOrgServiceImpl extends ServiceImpl<BizOrgMapper, BizOrg> impleme
// 发布更新事件
CommonDataChangeEventCenter.doUpdateWithData(BizDataTypeEnum.ORG.getValue(), JSONUtil.createArray().put(bizOrg));
// 清除缓存
commonCacheOperator.remove(ORG_ALL_LIST_CACHE_KEY);
this.invalidateOrgCaches();
}
@Transactional(rollbackFor = Exception.class)
@@ -323,7 +318,7 @@ public class BizOrgServiceImpl extends ServiceImpl<BizOrgMapper, BizOrg> impleme
// 发布删除事件
CommonDataChangeEventCenter.doDeleteWithDataIdList(BizDataTypeEnum.ORG.getValue(), toDeleteOrgIdList);
// 清除缓存
commonCacheOperator.remove(ORG_ALL_LIST_CACHE_KEY);
this.invalidateOrgCaches();
}
}
@@ -352,6 +347,65 @@ public class BizOrgServiceImpl extends ServiceImpl<BizOrgMapper, BizOrg> impleme
return list;
}
/**
* 使机构相关缓存失效(版本号递增 + 清除全量列表缓存)
* 机构增删改时调用visibleOrgIds 缓存通过版本号自动失效,旧条目由 TTL 自动清理
*/
private void invalidateOrgCaches() {
commonCacheOperator.remove(ORG_ALL_LIST_CACHE_KEY);
commonCacheOperator.put(ORG_CACHE_VERSION_KEY, String.valueOf(System.currentTimeMillis()));
}
/**
* 获取当前用户可见的机构ID集合带版本化缓存
* 缓存命中时直接返回,无需加载全量机构数据;缓存未命中时计算并缓存
*
* @param loginUserDataScope 当前用户的数据范围直接授权的机构ID列表
* @return 可见机构ID集合包含授权机构及其所有父级
*/
private Set<String> getVisibleOrgIds(List<String> loginUserDataScope) {
if (ObjectUtil.isEmpty(loginUserDataScope)) {
return Collections.emptySet();
}
// 获取当前缓存版本号
Object versionObj = commonCacheOperator.get(ORG_CACHE_VERSION_KEY);
String version = versionObj != null ? versionObj.toString() : "0";
// 构建缓存key前缀 + 版本号 + : + 数据范围hash
int scopeHash = loginUserDataScope.stream().sorted().collect(Collectors.joining(",")).hashCode();
String cacheKey = VISIBLE_ORG_IDS_CACHE_KEY_PREFIX + version + ":" + scopeHash;
// 尝试从缓存获取
Object cached = commonCacheOperator.get(cacheKey);
if (cached != null) {
return new HashSet<>(JSONUtil.toList(JSONUtil.parseArray(cached), String.class));
}
// 缓存未命中计算可见机构ID集合
List<BizOrg> allOrgList = this.getAllOrgList();
Map<String, BizOrg> orgById = allOrgList.stream()
.collect(Collectors.toMap(BizOrg::getId, org -> org, (a, b) -> a));
Set<String> visibleOrgIds = new HashSet<>();
for (String orgId : loginUserDataScope) {
if (orgById.containsKey(orgId)) {
visibleOrgIds.add(orgId);
// 向上遍历添加所有父级
String currentId = orgById.get(orgId).getParentId();
while (ObjectUtil.isNotEmpty(currentId) && !"0".equals(currentId) && orgById.containsKey(currentId)) {
if (!visibleOrgIds.add(currentId)) {
break; // 已经添加过,停止遍历
}
currentId = orgById.get(currentId).getParentId();
}
}
}
// 写入缓存带TTL旧版本条目自动过期
commonCacheOperator.put(cacheKey, JSONUtil.toJsonStr(visibleOrgIds), VISIBLE_ORG_IDS_CACHE_TTL);
return visibleOrgIds;
}
@Override
public String getOrgIdByOrgFullNameWithCreate(String orgFullName) {
List<BizOrg> allOrgList = this.getAllOrgList();
@@ -399,7 +453,7 @@ public class BizOrgServiceImpl extends ServiceImpl<BizOrgMapper, BizOrg> impleme
// 发布增加事件
CommonDataChangeEventCenter.doAddWithData(BizDataTypeEnum.ORG.getValue(), JSONUtil.createArray().put(bizOrg));
// 清除缓存
commonCacheOperator.remove(ORG_ALL_LIST_CACHE_KEY);
this.invalidateOrgCaches();
return bizOrg.getId();
}
@@ -536,6 +590,8 @@ public class BizOrgServiceImpl extends ServiceImpl<BizOrgMapper, BizOrg> impleme
}
}
});
// 清除缓存
this.invalidateOrgCaches();
}
}