【更新】机构大数据优化(待完善)

This commit is contained in:
xuyuxiang
2026-03-03 00:43:40 +08:00
parent a5f313fd00
commit c4ee8c428c
9 changed files with 395 additions and 165 deletions

View File

@@ -73,6 +73,7 @@
<xn-user-selector
ref="userSelectorRef"
:org-tree-api="selectorApiFunction.orgTreeApi"
:org-tree-lazy-api="selectorApiFunction.orgTreeLazyApi"
:user-page-api="selectorApiFunction.userPageApi"
data-type="object"
:user-show="false"
@@ -183,6 +184,11 @@
}
// 传递设计器需要的API
const selectorApiFunction = {
orgTreeApi: (param) => {
return bizGroupApi.groupOrgTreeLazySelector(param).then((data) => {
return Promise.resolve(data)
})
},
orgTreeLazyApi: (param) => {
return bizGroupApi.groupOrgTreeLazySelector(param).then((data) => {
return Promise.resolve(data)

View File

@@ -8,6 +8,7 @@
>
<a-form ref="formRef" :model="formData" :rules="formRules" layout="vertical">
<a-form-item label="上级机构:" name="parentId">
<a-spin :spinning="treeLoading">
<a-tree-select
v-model:value="formData.parentId"
class="xn-wd"
@@ -15,10 +16,12 @@
placeholder="请选择上级机构"
allow-clear
:tree-data="treeData"
v-model:treeExpandedKeys="treeDefaultExpandedKeys"
:field-names="treeFieldNames"
tree-line
:load-data="onLoadData"
:load-data="isEditMode ? undefined : onLoadData"
/>
</a-spin>
</a-form-item>
<a-form-item label="机构名称:" name="name">
<a-input v-model:value="formData.name" placeholder="请输入机构名称" allow-clear />
@@ -54,7 +57,6 @@
<script setup name="bizOrgForm">
import { required } from '@/utils/formRules'
import bizOrgApi from '@/api/biz/bizOrgApi'
import userCenterApi from '@/api/sys/userCenterApi'
import tool from '@/utils/tool'
// 定义emit事件
@@ -67,43 +69,76 @@
// 定义机构元素
const treeData = ref([])
const submitLoading = ref(false)
const treeLoading = ref(false)
const treeDefaultExpandedKeys = ref([])
const treeFieldNames = { children: 'children', label: 'name', value: 'id' }
// 在树中递归查找节点
const findNodeInTree = (nodes, id) => {
if (!nodes) return false
// 是否为编辑模式(编辑时加载全量树,新增时懒加载)
const isEditMode = ref(false)
// 在全量树中查找目标节点的所有祖先ID用于展开树到选中节点
const collectAncestorKeys = (nodes, targetId, path = []) => {
if (!nodes) return null
for (const node of nodes) {
if (node.id === id) return true
if (node.children && findNodeInTree(node.children, id)) return true
if (node.id === targetId) return path
if (node.children) {
const found = collectAncestorKeys(node.children, targetId, [...path, node.id])
if (found) return found
}
return false
}
// 确保选中的机构节点在树中可回显名称
const ensureOrgInTree = (orgId) => {
if (!orgId || orgId === '0' || findNodeInTree(treeData.value, orgId)) return
userCenterApi.userCenterGetOrgListByIdList({ idList: [orgId] }).then((data) => {
if (data && data.length > 0 && treeData.value.length > 0) {
const topNode = treeData.value[0]
if (topNode.children) {
topNode.children.push({ ...data[0], isLeaf: true })
} else {
topNode.children = [{ ...data[0], isLeaf: true }]
return null
}
treeData.value = [...treeData.value]
// 展开树到选中的机构节点
const expandToSelectedOrgs = () => {
if (formData.value.parentId) {
const ancestors = collectAncestorKeys(treeData.value, formData.value.parentId)
if (ancestors) {
ancestors.forEach((id) => {
if (!treeDefaultExpandedKeys.value.includes(id)) {
treeDefaultExpandedKeys.value.push(id)
}
})
}
}
}
// 打开抽屉
const onOpen = (record, parentId) => {
visible.value = true
isEditMode.value = !!record
formData.value = {
sortCode: 99
}
if (parentId) {
formData.value.parentId = parentId
}
// 获取机构树并加入顶级
const treePromise = bizOrgApi.orgTreeLazySelector().then((res) => {
nextTick(() => {
if (isEditMode.value) {
// 编辑模式:加载全量树 + 详情,等都完成后展开到选中节点
treeLoading.value = true
const treePromise = bizOrgApi.orgTreeLazySelector({ searchKey: '' }).then((res) => {
if (res !== null) {
treeData.value = [
{
id: '0',
parentId: '-1',
name: '顶级',
children: res,
isLeaf: false
}
]
treeDefaultExpandedKeys.value.push('0')
}
})
const detailPromise = bizOrgApi.orgDetail({ id: record.id }).then((data) => {
formData.value = Object.assign({}, data)
return data
})
Promise.all([treePromise, detailPromise]).then(() => {
expandToSelectedOrgs()
}).finally(() => {
treeLoading.value = false
})
} else {
// 新增模式:懒加载树
bizOrgApi.orgTreeLazySelector().then((res) => {
treeData.value = [
{
id: '0',
@@ -118,19 +153,10 @@
isLeaf: false
}
]
})
if (record) {
const detailPromise = bizOrgApi.orgDetail({ id: record.id }).then((data) => {
formData.value = Object.assign({}, data)
return data
})
// 等待树和详情都加载完成后,确保父节点可回显
Promise.all([treePromise, detailPromise]).then(([_, detail]) => {
if (detail.parentId) {
ensureOrgInTree(detail.parentId)
}
treeDefaultExpandedKeys.value.push('0')
})
}
})
}
// 懒加载子节点
const onLoadData = (treeNode) => {
@@ -157,6 +183,8 @@
}
// 关闭抽屉
const onClose = () => {
treeData.value = []
treeDefaultExpandedKeys.value = []
visible.value = false
}
// 默认要校验的

View File

@@ -8,6 +8,7 @@
>
<a-form ref="formRef" :model="formData" :rules="formRules" layout="vertical">
<a-form-item label="所属组织:" name="orgId">
<a-spin :spinning="treeLoading">
<a-tree-select
v-model:value="formData.orgId"
class="xn-wd"
@@ -15,10 +16,12 @@
placeholder="请选择组织"
allow-clear
:tree-data="treeData"
v-model:treeExpandedKeys="treeDefaultExpandedKeys"
:field-names="treeFieldNames"
tree-line
:load-data="onLoadData"
:load-data="isEditMode ? undefined : onLoadData"
></a-tree-select>
</a-spin>
</a-form-item>
<a-form-item label="岗位名称:" name="name">
<a-input v-model:value="formData.name" placeholder="请输入岗位名称" allow-clear />
@@ -46,7 +49,6 @@
<script setup name="bizPositionForm">
import { required } from '@/utils/formRules'
import bizPositionApi from '@/api/biz/bizPositionApi'
import userCenterApi from '@/api/sys/userCenterApi'
import tool from '@/utils/tool'
// 定义emit事件
@@ -59,29 +61,40 @@
// 定义机构元素
const treeData = ref([])
const submitLoading = ref(false)
const treeLoading = ref(false)
const treeDefaultExpandedKeys = ref([])
const treeFieldNames = { children: 'children', label: 'name', value: 'id' }
// 在树中递归查找节点
const findNodeInTree = (nodes, id) => {
if (!nodes) return false
// 是否为编辑模式(编辑时加载全量树,新增时懒加载)
const isEditMode = ref(false)
// 在全量树中查找目标节点的所有祖先ID用于展开树到选中节点
const collectAncestorKeys = (nodes, targetId, path = []) => {
if (!nodes) return null
for (const node of nodes) {
if (node.id === id) return true
if (node.children && findNodeInTree(node.children, id)) return true
if (node.id === targetId) return path
if (node.children) {
const found = collectAncestorKeys(node.children, targetId, [...path, node.id])
if (found) return found
}
return false
}
// 确保选中的机构节点在树中可回显名称
const ensureOrgInTree = (orgId) => {
if (!orgId || findNodeInTree(treeData.value, orgId)) return
userCenterApi.userCenterGetOrgListByIdList({ idList: [orgId] }).then((data) => {
if (data && data.length > 0) {
treeData.value.push({ ...data[0], isLeaf: true })
treeData.value = [...treeData.value]
return null
}
// 展开树到选中的组织节点
const expandToSelectedOrgs = () => {
if (formData.value.orgId) {
const ancestors = collectAncestorKeys(treeData.value, formData.value.orgId)
if (ancestors) {
ancestors.forEach((id) => {
if (!treeDefaultExpandedKeys.value.includes(id)) {
treeDefaultExpandedKeys.value.push(id)
}
})
}
}
}
// 打开抽屉
const onOpen = (record, orgId) => {
visible.value = true
isEditMode.value = !!record
formData.value = {
sortCode: 99
}
@@ -91,7 +104,24 @@
if (record) {
formData.value = Object.assign({}, record)
}
// 获取机构树
nextTick(() => {
if (isEditMode.value) {
// 编辑模式:加载全量树,等完成后展开到选中节点
treeLoading.value = true
bizPositionApi.positionOrgTreeLazySelector({ searchKey: '' }).then((res) => {
if (res !== null) {
treeData.value = res
// 只有一个根节点时才自动展开
if (treeData.value.length === 1) {
treeDefaultExpandedKeys.value.push(treeData.value[0].id)
}
}
expandToSelectedOrgs()
}).finally(() => {
treeLoading.value = false
})
} else {
// 新增模式:懒加载树
bizPositionApi.positionOrgTreeLazySelector().then((res) => {
treeData.value = res.map((item) => {
return {
@@ -99,9 +129,11 @@
isLeaf: item.isLeaf === undefined ? false : item.isLeaf
}
})
// 编辑时确保选中的机构可回显
if (record && formData.value.orgId) {
ensureOrgInTree(formData.value.orgId)
// 只有一个根节点时才自动展开
if (treeData.value.length === 1) {
treeDefaultExpandedKeys.value.push(treeData.value[0].id)
}
})
}
})
}
@@ -130,6 +162,8 @@
}
// 关闭抽屉
const onClose = () => {
treeData.value = []
treeDefaultExpandedKeys.value = []
visible.value = false
}
// 默认要校验的

View File

@@ -74,6 +74,7 @@
<xn-user-selector
ref="userSelectorRef"
:org-tree-api="selectorApiFunction.orgTreeApi"
:org-tree-lazy-api="selectorApiFunction.orgTreeLazyApi"
:user-page-api="selectorApiFunction.userPageApi"
data-type="object"
:user-show="false"
@@ -182,6 +183,11 @@
}
// 传递设计器需要的API
const selectorApiFunction = {
orgTreeApi: (param) => {
return sysGroupApi.groupOrgTreeLazySelector(param).then((data) => {
return Promise.resolve(data)
})
},
orgTreeLazyApi: (param) => {
return sysGroupApi.groupOrgTreeLazySelector(param).then((data) => {
return Promise.resolve(data)

View File

@@ -8,6 +8,7 @@
>
<a-form ref="formRef" :model="formData" :rules="formRules" layout="vertical">
<a-form-item label="上级组织:" name="parentId">
<a-spin :spinning="treeLoading">
<a-tree-select
v-model:value="formData.parentId"
class="xn-wd"
@@ -15,10 +16,12 @@
placeholder="请选择上级组织"
allow-clear
:tree-data="treeData"
v-model:treeExpandedKeys="treeDefaultExpandedKeys"
:field-names="treeFieldNames"
tree-line
:load-data="onLoadData"
:load-data="isEditMode ? undefined : onLoadData"
/>
</a-spin>
</a-form-item>
<a-form-item label="组织名称:" name="name">
<a-input v-model:value="formData.name" placeholder="请输入组织名称" allow-clear />
@@ -54,7 +57,6 @@
<script setup name="orgForm">
import { required } from '@/utils/formRules'
import orgApi from '@/api/sys/orgApi'
import userCenterApi from '@/api/sys/userCenterApi'
import tool from '@/utils/tool'
// 定义emit事件
@@ -67,42 +69,76 @@
// 定义机构元素
const treeData = ref([])
const submitLoading = ref(false)
const treeLoading = ref(false)
const treeDefaultExpandedKeys = ref([])
const treeFieldNames = { children: 'children', label: 'name', value: 'id' }
// 在树中递归查找节点
const findNodeInTree = (nodes, id) => {
if (!nodes) return false
// 是否为编辑模式(编辑时加载全量树,新增时懒加载)
const isEditMode = ref(false)
// 在全量树中查找目标节点的所有祖先ID用于展开树到选中节点
const collectAncestorKeys = (nodes, targetId, path = []) => {
if (!nodes) return null
for (const node of nodes) {
if (node.id === id) return true
if (node.children && findNodeInTree(node.children, id)) return true
if (node.id === targetId) return path
if (node.children) {
const found = collectAncestorKeys(node.children, targetId, [...path, node.id])
if (found) return found
}
return false
}
// 确保选中的机构节点在树中可回显名称
const ensureOrgInTree = (orgId) => {
if (!orgId || orgId === '0' || findNodeInTree(treeData.value, orgId)) return
userCenterApi.userCenterGetOrgListByIdList({ idList: [orgId] }).then((data) => {
if (data && data.length > 0 && treeData.value.length > 0) {
const topNode = treeData.value[0]
if (topNode.children) {
topNode.children.push({ ...data[0], isLeaf: true })
} else {
topNode.children = [{ ...data[0], isLeaf: true }]
return null
}
treeData.value = [...treeData.value]
// 展开树到选中的组织节点
const expandToSelectedOrgs = () => {
if (formData.value.parentId) {
const ancestors = collectAncestorKeys(treeData.value, formData.value.parentId)
if (ancestors) {
ancestors.forEach((id) => {
if (!treeDefaultExpandedKeys.value.includes(id)) {
treeDefaultExpandedKeys.value.push(id)
}
})
}
}
}
// 打开抽屉
const onOpen = (record, parentId) => {
visible.value = true
isEditMode.value = !!record
formData.value = {
sortCode: 99
}
if (parentId) {
formData.value.parentId = parentId
}
// 获取机构树并加入顶级
const treePromise = orgApi.orgOrgTreeLazySelector().then((res) => {
nextTick(() => {
if (isEditMode.value) {
// 编辑模式:加载全量树 + 详情,等都完成后展开到选中节点
treeLoading.value = true
const treePromise = orgApi.orgOrgTreeLazySelector({ searchKey: '' }).then((res) => {
if (res !== null) {
treeData.value = [
{
id: '0',
parentId: '-1',
name: '顶级',
children: res,
isLeaf: false
}
]
treeDefaultExpandedKeys.value.push('0')
}
})
const detailPromise = orgApi.orgDetail({ id: record.id }).then((data) => {
formData.value = Object.assign({}, data)
return data
})
Promise.all([treePromise, detailPromise]).then(() => {
expandToSelectedOrgs()
}).finally(() => {
treeLoading.value = false
})
} else {
// 新增模式:懒加载树
orgApi.orgOrgTreeLazySelector().then((res) => {
treeData.value = [
{
id: '0',
@@ -117,19 +153,10 @@
isLeaf: false
}
]
})
if (record) {
const detailPromise = orgApi.orgDetail({ id: record.id }).then((data) => {
formData.value = Object.assign({}, data)
return data
})
// 等待树和详情都加载完成后,确保父节点可回显
Promise.all([treePromise, detailPromise]).then(([_, detail]) => {
if (detail.parentId) {
ensureOrgInTree(detail.parentId)
}
treeDefaultExpandedKeys.value.push('0')
})
}
})
}
// 懒加载子节点
const onLoadData = (treeNode) => {
@@ -156,6 +183,8 @@
}
// 关闭抽屉
const onClose = () => {
treeData.value = []
treeDefaultExpandedKeys.value = []
visible.value = false
}
// 默认要校验的

View File

@@ -8,6 +8,7 @@
>
<a-form ref="formRef" :model="formData" :rules="formRules" layout="vertical">
<a-form-item label="所属组织:" name="orgId">
<a-spin :spinning="treeLoading">
<a-tree-select
v-model:value="formData.orgId"
class="xn-wd"
@@ -15,10 +16,12 @@
placeholder="请选择组织"
allow-clear
:tree-data="treeData"
v-model:treeExpandedKeys="treeDefaultExpandedKeys"
:field-names="treeFieldNames"
tree-line
:load-data="onLoadData"
:load-data="isEditMode ? undefined : onLoadData"
></a-tree-select>
</a-spin>
</a-form-item>
<a-form-item label="职位名称:" name="name">
<a-input v-model:value="formData.name" placeholder="请输入职位名称" allow-clear />
@@ -45,7 +48,6 @@
<script setup name="positionForm">
import { required } from '@/utils/formRules'
import positionApi from '@/api/sys/positionApi'
import userCenterApi from '@/api/sys/userCenterApi'
import tool from '@/utils/tool'
// 定义emit事件
@@ -58,29 +60,40 @@
// 定义机构元素
const treeData = ref([])
const submitLoading = ref(false)
const treeLoading = ref(false)
const treeDefaultExpandedKeys = ref([])
const treeFieldNames = { children: 'children', label: 'name', value: 'id' }
// 在树中递归查找节点
const findNodeInTree = (nodes, id) => {
if (!nodes) return false
// 是否为编辑模式(编辑时加载全量树,新增时懒加载)
const isEditMode = ref(false)
// 在全量树中查找目标节点的所有祖先ID用于展开树到选中节点
const collectAncestorKeys = (nodes, targetId, path = []) => {
if (!nodes) return null
for (const node of nodes) {
if (node.id === id) return true
if (node.children && findNodeInTree(node.children, id)) return true
if (node.id === targetId) return path
if (node.children) {
const found = collectAncestorKeys(node.children, targetId, [...path, node.id])
if (found) return found
}
return false
}
// 确保选中的机构节点在树中可回显名称
const ensureOrgInTree = (orgId) => {
if (!orgId || findNodeInTree(treeData.value, orgId)) return
userCenterApi.userCenterGetOrgListByIdList({ idList: [orgId] }).then((data) => {
if (data && data.length > 0) {
treeData.value.push({ ...data[0], isLeaf: true })
treeData.value = [...treeData.value]
return null
}
// 展开树到选中的组织节点
const expandToSelectedOrgs = () => {
if (formData.value.orgId) {
const ancestors = collectAncestorKeys(treeData.value, formData.value.orgId)
if (ancestors) {
ancestors.forEach((id) => {
if (!treeDefaultExpandedKeys.value.includes(id)) {
treeDefaultExpandedKeys.value.push(id)
}
})
}
}
}
// 打开抽屉
const onOpen = (record, orgId) => {
visible.value = true
isEditMode.value = !!record
formData.value = {
sortCode: 99
}
@@ -90,7 +103,24 @@
if (record) {
formData.value = Object.assign({}, record)
}
// 获取机构树
nextTick(() => {
if (isEditMode.value) {
// 编辑模式:加载全量树,等完成后展开到选中节点
treeLoading.value = true
positionApi.positionOrgTreeLazySelector({ searchKey: '' }).then((res) => {
if (res !== null) {
treeData.value = res
// 只有一个根节点时才自动展开
if (treeData.value.length === 1) {
treeDefaultExpandedKeys.value.push(treeData.value[0].id)
}
}
expandToSelectedOrgs()
}).finally(() => {
treeLoading.value = false
})
} else {
// 新增模式:懒加载树
positionApi.positionOrgTreeLazySelector().then((res) => {
treeData.value = res.map((item) => {
return {
@@ -98,9 +128,11 @@
isLeaf: item.isLeaf === undefined ? false : item.isLeaf
}
})
// 编辑时确保选中的机构可回显
if (record && formData.value.orgId) {
ensureOrgInTree(formData.value.orgId)
// 只有一个根节点时才自动展开
if (treeData.value.length === 1) {
treeDefaultExpandedKeys.value.push(treeData.value[0].id)
}
})
}
})
}
@@ -129,6 +161,8 @@
}
// 关闭抽屉
const onClose = () => {
treeData.value = []
treeDefaultExpandedKeys.value = []
visible.value = false
}
// 默认要校验的

View File

@@ -22,18 +22,20 @@
/>
</a-form-item>
<a-form-item v-if="formData.category === 'ORG'" label="所属机构:" name="orgId">
<a-spin :spinning="treeLoading">
<a-tree-select
v-model:value="formData.orgId"
class="xn-wd"
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
placeholder="请选择组织"
allow-clear
tree-default-expand-all
:tree-data="treeData"
v-model:treeExpandedKeys="treeDefaultExpandedKeys"
:field-names="treeFieldNames"
selectable="false"
tree-line
:load-data="isEditMode ? undefined : onLoadData"
/>
</a-spin>
</a-form-item>
<a-form-item label="排序:" name="sortCode">
<a-input-number class="xn-wd" v-model:value="formData.sortCode" :max="100" />
@@ -61,10 +63,41 @@
// 定义机构元素
const treeData = ref([])
const submitLoading = ref(false)
const treeLoading = ref(false)
const treeDefaultExpandedKeys = ref([])
const treeFieldNames = { children: 'children', label: 'name', value: 'id' }
// 是否为编辑模式(编辑时加载全量树,新增时懒加载)
const isEditMode = ref(false)
// 在全量树中查找目标节点的所有祖先ID用于展开树到选中节点
const collectAncestorKeys = (nodes, targetId, path = []) => {
if (!nodes) return null
for (const node of nodes) {
if (node.id === targetId) return path
if (node.children) {
const found = collectAncestorKeys(node.children, targetId, [...path, node.id])
if (found) return found
}
}
return null
}
// 展开树到选中的组织节点
const expandToSelectedOrgs = () => {
if (formData.value.orgId) {
const ancestors = collectAncestorKeys(treeData.value, formData.value.orgId)
if (ancestors) {
ancestors.forEach((id) => {
if (!treeDefaultExpandedKeys.value.includes(id)) {
treeDefaultExpandedKeys.value.push(id)
}
})
}
}
}
// 打开抽屉
const onOpen = (record, category, orgId) => {
visible.value = true
isEditMode.value = !!record
formData.value = {}
// 判断角色的类型
if (category) {
formData.value.category = category
@@ -79,13 +112,68 @@
formData.value.sortCode = 99
formData.value.code = tool.generateString(10)
}
// 获取机构树并加入顶级
roleApi.roleOrgTreeSelector().then((res) => {
nextTick(() => {
if (isEditMode.value) {
// 编辑模式:加载全量树,等完成后展开到选中节点
treeLoading.value = true
roleApi.roleOrgTreeLazySelector({ searchKey: '' }).then((res) => {
if (res !== null) {
treeData.value = res
// 只有一个根节点时才自动展开
if (treeData.value.length === 1) {
treeDefaultExpandedKeys.value.push(treeData.value[0].id)
}
}
expandToSelectedOrgs()
}).finally(() => {
treeLoading.value = false
})
} else {
// 新增模式:懒加载树
roleApi.roleOrgTreeLazySelector().then((res) => {
if (res !== null) {
treeData.value = res.map((item) => {
return {
...item,
isLeaf: item.isLeaf === undefined ? false : item.isLeaf
}
})
// 只有一个根节点时才自动展开
if (treeData.value.length === 1) {
treeDefaultExpandedKeys.value.push(treeData.value[0].id)
}
}
})
}
})
}
// 懒加载子节点
const onLoadData = (treeNode) => {
return new Promise((resolve) => {
if (treeNode.dataRef.children) {
resolve()
return
}
roleApi
.roleOrgTreeLazySelector({
parentId: treeNode.dataRef.id
})
.then((res) => {
treeNode.dataRef.children = res.map((item) => {
return {
...item,
isLeaf: item.isLeaf === undefined ? false : item.isLeaf
}
})
treeData.value = [...treeData.value]
resolve()
})
})
}
// 关闭抽屉
const onClose = () => {
treeData.value = []
treeDefaultExpandedKeys.value = []
visible.value = false
formData.value = {}
}

View File

@@ -418,6 +418,11 @@
}
// 传递设计器需要的API
const selectorApiFunction = {
orgTreeApi: (param) => {
return orgApi.orgOrgTreeLazySelector(param).then((data) => {
return Promise.resolve(data)
})
},
orgTreeLazyApi: (param) => {
return orgApi.orgOrgTreeLazySelector(param).then((data) => {
return Promise.resolve(data)

View File

@@ -148,7 +148,7 @@ public class SysGroupServiceImpl extends ServiceImpl<SysGroupMapper, SysGroup> i
@Override
public List<JSONObject> orgTreeLazySelector(SysOrgTreeLazyParam sysOrgTreeLazyParam) {
return List.of();
return sysOrgService.treeLazy(sysOrgTreeLazyParam);
}
@Override